diff options
| author | Anton Altaparmakov <aia21@cantab.net> | 2006-01-19 11:39:33 -0500 |
|---|---|---|
| committer | Anton Altaparmakov <aia21@cantab.net> | 2006-01-19 11:39:33 -0500 |
| commit | 944d79559d154c12becde0dab327016cf438f46c (patch) | |
| tree | 50c101806f4d3b6585222dda060559eb4f3e005a /fs/cifs/connect.c | |
| parent | d087e4bdd24ebe3ae3d0b265b6573ec901af4b4b (diff) | |
| parent | 0f36b018b2e314d45af86449f1a97facb1fbe300 (diff) | |
Merge branch 'master' of /usr/src/ntfs-2.6/
Diffstat (limited to 'fs/cifs/connect.c')
| -rw-r--r-- | fs/cifs/connect.c | 89 |
1 files changed, 76 insertions, 13 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index c467de857610..88f60aa52058 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -76,12 +76,19 @@ struct smb_vol { | |||
| 76 | unsigned setuids:1; | 76 | unsigned setuids:1; |
| 77 | unsigned noperm:1; | 77 | unsigned noperm:1; |
| 78 | unsigned no_psx_acl:1; /* set if posix acl support should be disabled */ | 78 | unsigned no_psx_acl:1; /* set if posix acl support should be disabled */ |
| 79 | unsigned cifs_acl:1; | ||
| 79 | unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/ | 80 | unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/ |
| 80 | unsigned server_ino:1; /* use inode numbers from server ie UniqueId */ | 81 | unsigned server_ino:1; /* use inode numbers from server ie UniqueId */ |
| 81 | unsigned direct_io:1; | 82 | unsigned direct_io:1; |
| 82 | unsigned remap:1; /* set to remap seven reserved chars in filenames */ | 83 | unsigned remap:1; /* set to remap seven reserved chars in filenames */ |
| 83 | unsigned posix_paths:1; /* unset to not ask for posix pathnames. */ | 84 | unsigned posix_paths:1; /* unset to not ask for posix pathnames. */ |
| 84 | unsigned sfu_emul:1; | 85 | unsigned sfu_emul:1; |
| 86 | unsigned krb5:1; | ||
| 87 | unsigned ntlm:1; | ||
| 88 | unsigned ntlmv2:1; | ||
| 89 | unsigned nullauth:1; /* attempt to authenticate with null user */ | ||
| 90 | unsigned sign:1; | ||
| 91 | unsigned seal:1; /* encrypt */ | ||
| 85 | unsigned nocase; /* request case insensitive filenames */ | 92 | unsigned nocase; /* request case insensitive filenames */ |
| 86 | unsigned nobrl; /* disable sending byte range locks to srv */ | 93 | unsigned nobrl; /* disable sending byte range locks to srv */ |
| 87 | unsigned int rsize; | 94 | unsigned int rsize; |
| @@ -508,7 +515,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
| 508 | /* else length ok */ | 515 | /* else length ok */ |
| 509 | reconnect = 0; | 516 | reconnect = 0; |
| 510 | 517 | ||
| 511 | if(pdu_length > MAX_CIFS_HDR_SIZE - 4) { | 518 | if(pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { |
| 512 | isLargeBuf = TRUE; | 519 | isLargeBuf = TRUE; |
| 513 | memcpy(bigbuf, smallbuf, 4); | 520 | memcpy(bigbuf, smallbuf, 4); |
| 514 | smb_buffer = bigbuf; | 521 | smb_buffer = bigbuf; |
| @@ -777,7 +784,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | |||
| 777 | 784 | ||
| 778 | /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ | 785 | /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ |
| 779 | vol->rw = TRUE; | 786 | vol->rw = TRUE; |
| 780 | 787 | vol->ntlm = TRUE; | |
| 781 | /* default is always to request posix paths. */ | 788 | /* default is always to request posix paths. */ |
| 782 | vol->posix_paths = 1; | 789 | vol->posix_paths = 1; |
| 783 | 790 | ||
| @@ -903,6 +910,39 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | |||
| 903 | printk(KERN_WARNING "CIFS: ip address too long\n"); | 910 | printk(KERN_WARNING "CIFS: ip address too long\n"); |
| 904 | return 1; | 911 | return 1; |
| 905 | } | 912 | } |
| 913 | } else if (strnicmp(data, "sec", 3) == 0) { | ||
| 914 | if (!value || !*value) { | ||
| 915 | cERROR(1,("no security value specified")); | ||
| 916 | continue; | ||
| 917 | } else if (strnicmp(value, "krb5i", 5) == 0) { | ||
| 918 | vol->sign = 1; | ||
| 919 | vol->krb5 = 1; | ||
| 920 | } else if (strnicmp(value, "krb5p", 5) == 0) { | ||
| 921 | /* vol->seal = 1; | ||
| 922 | vol->krb5 = 1; */ | ||
| 923 | cERROR(1,("Krb5 cifs privacy not supported")); | ||
| 924 | return 1; | ||
| 925 | } else if (strnicmp(value, "krb5", 4) == 0) { | ||
| 926 | vol->krb5 = 1; | ||
| 927 | } else if (strnicmp(value, "ntlmv2i", 7) == 0) { | ||
| 928 | vol->ntlmv2 = 1; | ||
| 929 | vol->sign = 1; | ||
| 930 | } else if (strnicmp(value, "ntlmv2", 6) == 0) { | ||
| 931 | vol->ntlmv2 = 1; | ||
| 932 | } else if (strnicmp(value, "ntlmi", 5) == 0) { | ||
| 933 | vol->ntlm = 1; | ||
| 934 | vol->sign = 1; | ||
| 935 | } else if (strnicmp(value, "ntlm", 4) == 0) { | ||
| 936 | /* ntlm is default so can be turned off too */ | ||
| 937 | vol->ntlm = 1; | ||
| 938 | } else if (strnicmp(value, "nontlm", 6) == 0) { | ||
| 939 | vol->ntlm = 0; | ||
| 940 | } else if (strnicmp(value, "none", 4) == 0) { | ||
| 941 | vol->nullauth = 1; | ||
| 942 | } else { | ||
| 943 | cERROR(1,("bad security option: %s", value)); | ||
| 944 | return 1; | ||
| 945 | } | ||
| 906 | } else if ((strnicmp(data, "unc", 3) == 0) | 946 | } else if ((strnicmp(data, "unc", 3) == 0) |
| 907 | || (strnicmp(data, "target", 6) == 0) | 947 | || (strnicmp(data, "target", 6) == 0) |
| 908 | || (strnicmp(data, "path", 4) == 0)) { | 948 | || (strnicmp(data, "path", 4) == 0)) { |
| @@ -1120,6 +1160,10 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | |||
| 1120 | vol->server_ino = 1; | 1160 | vol->server_ino = 1; |
| 1121 | } else if (strnicmp(data, "noserverino",9) == 0) { | 1161 | } else if (strnicmp(data, "noserverino",9) == 0) { |
| 1122 | vol->server_ino = 0; | 1162 | vol->server_ino = 0; |
| 1163 | } else if (strnicmp(data, "cifsacl",7) == 0) { | ||
| 1164 | vol->cifs_acl = 1; | ||
| 1165 | } else if (strnicmp(data, "nocifsacl", 9) == 0) { | ||
| 1166 | vol->cifs_acl = 0; | ||
| 1123 | } else if (strnicmp(data, "acl",3) == 0) { | 1167 | } else if (strnicmp(data, "acl",3) == 0) { |
| 1124 | vol->no_psx_acl = 0; | 1168 | vol->no_psx_acl = 0; |
| 1125 | } else if (strnicmp(data, "noacl",5) == 0) { | 1169 | } else if (strnicmp(data, "noacl",5) == 0) { |
| @@ -1546,7 +1590,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 1546 | cFYI(1, ("Username: %s ", volume_info.username)); | 1590 | cFYI(1, ("Username: %s ", volume_info.username)); |
| 1547 | 1591 | ||
| 1548 | } else { | 1592 | } else { |
| 1549 | cifserror("No username specified "); | 1593 | cifserror("No username specified"); |
| 1550 | /* In userspace mount helper we can get user name from alternate | 1594 | /* In userspace mount helper we can get user name from alternate |
| 1551 | locations such as env variables and files on disk */ | 1595 | locations such as env variables and files on disk */ |
| 1552 | kfree(volume_info.UNC); | 1596 | kfree(volume_info.UNC); |
| @@ -1587,7 +1631,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 1587 | return -EINVAL; | 1631 | return -EINVAL; |
| 1588 | } else /* which servers DFS root would we conect to */ { | 1632 | } else /* which servers DFS root would we conect to */ { |
| 1589 | cERROR(1, | 1633 | cERROR(1, |
| 1590 | ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified ")); | 1634 | ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified")); |
| 1591 | kfree(volume_info.UNC); | 1635 | kfree(volume_info.UNC); |
| 1592 | kfree(volume_info.password); | 1636 | kfree(volume_info.password); |
| 1593 | FreeXid(xid); | 1637 | FreeXid(xid); |
| @@ -1626,7 +1670,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 1626 | 1670 | ||
| 1627 | 1671 | ||
| 1628 | if (srvTcp) { | 1672 | if (srvTcp) { |
| 1629 | cFYI(1, ("Existing tcp session with server found ")); | 1673 | cFYI(1, ("Existing tcp session with server found")); |
| 1630 | } else { /* create socket */ | 1674 | } else { /* create socket */ |
| 1631 | if(volume_info.port) | 1675 | if(volume_info.port) |
| 1632 | sin_server.sin_port = htons(volume_info.port); | 1676 | sin_server.sin_port = htons(volume_info.port); |
| @@ -1689,11 +1733,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 1689 | 1733 | ||
| 1690 | if (existingCifsSes) { | 1734 | if (existingCifsSes) { |
| 1691 | pSesInfo = existingCifsSes; | 1735 | pSesInfo = existingCifsSes; |
| 1692 | cFYI(1, ("Existing smb sess found ")); | 1736 | cFYI(1, ("Existing smb sess found")); |
| 1693 | kfree(volume_info.password); | 1737 | kfree(volume_info.password); |
| 1694 | /* volume_info.UNC freed at end of function */ | 1738 | /* volume_info.UNC freed at end of function */ |
| 1695 | } else if (!rc) { | 1739 | } else if (!rc) { |
| 1696 | cFYI(1, ("Existing smb sess not found ")); | 1740 | cFYI(1, ("Existing smb sess not found")); |
| 1697 | pSesInfo = sesInfoAlloc(); | 1741 | pSesInfo = sesInfoAlloc(); |
| 1698 | if (pSesInfo == NULL) | 1742 | if (pSesInfo == NULL) |
| 1699 | rc = -ENOMEM; | 1743 | rc = -ENOMEM; |
| @@ -1751,7 +1795,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 1751 | cifs_sb->mnt_gid = volume_info.linux_gid; | 1795 | cifs_sb->mnt_gid = volume_info.linux_gid; |
| 1752 | cifs_sb->mnt_file_mode = volume_info.file_mode; | 1796 | cifs_sb->mnt_file_mode = volume_info.file_mode; |
| 1753 | cifs_sb->mnt_dir_mode = volume_info.dir_mode; | 1797 | cifs_sb->mnt_dir_mode = volume_info.dir_mode; |
| 1754 | cFYI(1,("file mode: 0x%x dir mode: 0x%x",cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode)); | 1798 | cFYI(1,("file mode: 0x%x dir mode: 0x%x", |
| 1799 | cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode)); | ||
| 1755 | 1800 | ||
| 1756 | if(volume_info.noperm) | 1801 | if(volume_info.noperm) |
| 1757 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; | 1802 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; |
| @@ -1767,6 +1812,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 1767 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; | 1812 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; |
| 1768 | if(volume_info.nobrl) | 1813 | if(volume_info.nobrl) |
| 1769 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; | 1814 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; |
| 1815 | if(volume_info.cifs_acl) | ||
| 1816 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; | ||
| 1770 | 1817 | ||
| 1771 | if(volume_info.direct_io) { | 1818 | if(volume_info.direct_io) { |
| 1772 | cFYI(1,("mounting share using direct i/o")); | 1819 | cFYI(1,("mounting share using direct i/o")); |
| @@ -1777,7 +1824,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 1777 | find_unc(sin_server.sin_addr.s_addr, volume_info.UNC, | 1824 | find_unc(sin_server.sin_addr.s_addr, volume_info.UNC, |
| 1778 | volume_info.username); | 1825 | volume_info.username); |
| 1779 | if (tcon) { | 1826 | if (tcon) { |
| 1780 | cFYI(1, ("Found match on UNC path ")); | 1827 | cFYI(1, ("Found match on UNC path")); |
| 1781 | /* we can have only one retry value for a connection | 1828 | /* we can have only one retry value for a connection |
| 1782 | to a share so for resources mounted more than once | 1829 | to a share so for resources mounted more than once |
| 1783 | to the same server share the last value passed in | 1830 | to the same server share the last value passed in |
| @@ -1926,7 +1973,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
| 1926 | __u32 capabilities; | 1973 | __u32 capabilities; |
| 1927 | __u16 count; | 1974 | __u16 count; |
| 1928 | 1975 | ||
| 1929 | cFYI(1, ("In sesssetup ")); | 1976 | cFYI(1, ("In sesssetup")); |
| 1930 | if(ses == NULL) | 1977 | if(ses == NULL) |
| 1931 | return -EINVAL; | 1978 | return -EINVAL; |
| 1932 | user = ses->userName; | 1979 | user = ses->userName; |
| @@ -3202,9 +3249,26 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
| 3202 | 3249 | ||
| 3203 | pSMB->AndXCommand = 0xFF; | 3250 | pSMB->AndXCommand = 0xFF; |
| 3204 | pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); | 3251 | pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); |
| 3205 | pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ | ||
| 3206 | bcc_ptr = &pSMB->Password[0]; | 3252 | bcc_ptr = &pSMB->Password[0]; |
| 3207 | bcc_ptr++; /* skip password */ | 3253 | if((ses->server->secMode) & SECMODE_USER) { |
| 3254 | pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ | ||
| 3255 | bcc_ptr++; /* skip password */ | ||
| 3256 | } else { | ||
| 3257 | pSMB->PasswordLength = cpu_to_le16(CIFS_SESSION_KEY_SIZE); | ||
| 3258 | /* BB FIXME add code to fail this if NTLMv2 or Kerberos | ||
| 3259 | specified as required (when that support is added to | ||
| 3260 | the vfs in the future) as only NTLM or the much | ||
| 3261 | weaker LANMAN (which we do not send) is accepted | ||
| 3262 | by Samba (not sure whether other servers allow | ||
| 3263 | NTLMv2 password here) */ | ||
| 3264 | SMBNTencrypt(ses->password, | ||
| 3265 | ses->server->cryptKey, | ||
| 3266 | bcc_ptr); | ||
| 3267 | |||
| 3268 | bcc_ptr += CIFS_SESSION_KEY_SIZE; | ||
| 3269 | *bcc_ptr = 0; | ||
| 3270 | bcc_ptr++; /* align */ | ||
| 3271 | } | ||
| 3208 | 3272 | ||
| 3209 | if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | 3273 | if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) |
| 3210 | smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; | 3274 | smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; |
| @@ -3222,7 +3286,6 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
| 3222 | bcc_ptr += 2 * length; /* convert num of 16 bit words to bytes */ | 3286 | bcc_ptr += 2 * length; /* convert num of 16 bit words to bytes */ |
| 3223 | bcc_ptr += 2; /* skip trailing null */ | 3287 | bcc_ptr += 2; /* skip trailing null */ |
| 3224 | } else { /* ASCII */ | 3288 | } else { /* ASCII */ |
| 3225 | |||
| 3226 | strcpy(bcc_ptr, tree); | 3289 | strcpy(bcc_ptr, tree); |
| 3227 | bcc_ptr += strlen(tree) + 1; | 3290 | bcc_ptr += strlen(tree) + 1; |
| 3228 | } | 3291 | } |
