diff options
Diffstat (limited to 'fs/cifs/connect.c')
| -rw-r--r-- | fs/cifs/connect.c | 73 |
1 files changed, 37 insertions, 36 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index f428bf3bf1a9..e8fa46c7cff2 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -60,7 +60,7 @@ struct smb_vol { | |||
| 60 | char *domainname; | 60 | char *domainname; |
| 61 | char *UNC; | 61 | char *UNC; |
| 62 | char *UNCip; | 62 | char *UNCip; |
| 63 | char *in6_addr; /* ipv6 address as human readable form of in6_addr */ | 63 | char *in6_addr; /* ipv6 address as human readable form of in6_addr */ |
| 64 | char *iocharset; /* local code page for mapping to and from Unicode */ | 64 | char *iocharset; /* local code page for mapping to and from Unicode */ |
| 65 | char source_rfc1001_name[16]; /* netbios name of client */ | 65 | char source_rfc1001_name[16]; /* netbios name of client */ |
| 66 | char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */ | 66 | char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */ |
| @@ -75,19 +75,21 @@ struct smb_vol { | |||
| 75 | bool setuids:1; | 75 | bool setuids:1; |
| 76 | bool override_uid:1; | 76 | bool override_uid:1; |
| 77 | bool override_gid:1; | 77 | bool override_gid:1; |
| 78 | bool dynperm:1; | ||
| 78 | bool noperm:1; | 79 | bool noperm:1; |
| 79 | bool no_psx_acl:1; /* set if posix acl support should be disabled */ | 80 | bool no_psx_acl:1; /* set if posix acl support should be disabled */ |
| 80 | bool cifs_acl:1; | 81 | bool cifs_acl:1; |
| 81 | bool no_xattr:1; /* set if xattr (EA) support should be disabled*/ | 82 | bool no_xattr:1; /* set if xattr (EA) support should be disabled*/ |
| 82 | bool server_ino:1; /* use inode numbers from server ie UniqueId */ | 83 | bool server_ino:1; /* use inode numbers from server ie UniqueId */ |
| 83 | bool direct_io:1; | 84 | bool direct_io:1; |
| 84 | bool remap:1; /* set to remap seven reserved chars in filenames */ | 85 | bool remap:1; /* set to remap seven reserved chars in filenames */ |
| 85 | bool posix_paths:1; /* unset to not ask for posix pathnames. */ | 86 | bool posix_paths:1; /* unset to not ask for posix pathnames. */ |
| 86 | bool no_linux_ext:1; | 87 | bool no_linux_ext:1; |
| 87 | bool sfu_emul:1; | 88 | bool sfu_emul:1; |
| 88 | bool nullauth:1; /* attempt to authenticate with null user */ | 89 | bool nullauth:1; /* attempt to authenticate with null user */ |
| 89 | unsigned nocase; /* request case insensitive filenames */ | 90 | bool nocase:1; /* request case insensitive filenames */ |
| 90 | unsigned nobrl; /* disable sending byte range locks to srv */ | 91 | bool nobrl:1; /* disable sending byte range locks to srv */ |
| 92 | bool seal:1; /* request transport encryption on share */ | ||
| 91 | unsigned int rsize; | 93 | unsigned int rsize; |
| 92 | unsigned int wsize; | 94 | unsigned int wsize; |
| 93 | unsigned int sockopt; | 95 | unsigned int sockopt; |
| @@ -651,6 +653,7 @@ multi_t2_fnd: | |||
| 651 | spin_lock(&GlobalMid_Lock); | 653 | spin_lock(&GlobalMid_Lock); |
| 652 | server->tcpStatus = CifsExiting; | 654 | server->tcpStatus = CifsExiting; |
| 653 | spin_unlock(&GlobalMid_Lock); | 655 | spin_unlock(&GlobalMid_Lock); |
| 656 | wake_up_all(&server->response_q); | ||
| 654 | 657 | ||
| 655 | /* don't exit until kthread_stop is called */ | 658 | /* don't exit until kthread_stop is called */ |
| 656 | set_current_state(TASK_UNINTERRUPTIBLE); | 659 | set_current_state(TASK_UNINTERRUPTIBLE); |
| @@ -1246,6 +1249,10 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
| 1246 | vol->setuids = 1; | 1249 | vol->setuids = 1; |
| 1247 | } else if (strnicmp(data, "nosetuids", 9) == 0) { | 1250 | } else if (strnicmp(data, "nosetuids", 9) == 0) { |
| 1248 | vol->setuids = 0; | 1251 | vol->setuids = 0; |
| 1252 | } else if (strnicmp(data, "dynperm", 7) == 0) { | ||
| 1253 | vol->dynperm = true; | ||
| 1254 | } else if (strnicmp(data, "nodynperm", 9) == 0) { | ||
| 1255 | vol->dynperm = false; | ||
| 1249 | } else if (strnicmp(data, "nohard", 6) == 0) { | 1256 | } else if (strnicmp(data, "nohard", 6) == 0) { |
| 1250 | vol->retry = 0; | 1257 | vol->retry = 0; |
| 1251 | } else if (strnicmp(data, "nosoft", 6) == 0) { | 1258 | } else if (strnicmp(data, "nosoft", 6) == 0) { |
| @@ -1268,8 +1275,12 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
| 1268 | vol->no_psx_acl = 1; | 1275 | vol->no_psx_acl = 1; |
| 1269 | } else if (strnicmp(data, "sign", 4) == 0) { | 1276 | } else if (strnicmp(data, "sign", 4) == 0) { |
| 1270 | vol->secFlg |= CIFSSEC_MUST_SIGN; | 1277 | vol->secFlg |= CIFSSEC_MUST_SIGN; |
| 1271 | /* } else if (strnicmp(data, "seal",4) == 0) { | 1278 | } else if (strnicmp(data, "seal", 4) == 0) { |
| 1272 | vol->secFlg |= CIFSSEC_MUST_SEAL; */ | 1279 | /* we do not do the following in secFlags because seal |
| 1280 | is a per tree connection (mount) not a per socket | ||
| 1281 | or per-smb connection option in the protocol */ | ||
| 1282 | /* vol->secFlg |= CIFSSEC_MUST_SEAL; */ | ||
| 1283 | vol->seal = 1; | ||
| 1273 | } else if (strnicmp(data, "direct", 6) == 0) { | 1284 | } else if (strnicmp(data, "direct", 6) == 0) { |
| 1274 | vol->direct_io = 1; | 1285 | vol->direct_io = 1; |
| 1275 | } else if (strnicmp(data, "forcedirectio", 13) == 0) { | 1286 | } else if (strnicmp(data, "forcedirectio", 13) == 0) { |
| @@ -1414,34 +1425,12 @@ find_unc(__be32 new_target_ip_addr, char *uncName, char *userName) | |||
| 1414 | } | 1425 | } |
| 1415 | 1426 | ||
| 1416 | int | 1427 | int |
| 1417 | connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo, | ||
| 1418 | const char *old_path, const struct nls_table *nls_codepage, | ||
| 1419 | int remap) | ||
| 1420 | { | ||
| 1421 | struct dfs_info3_param *referrals = NULL; | ||
| 1422 | unsigned int num_referrals; | ||
| 1423 | int rc = 0; | ||
| 1424 | |||
| 1425 | rc = get_dfs_path(xid, pSesInfo, old_path, nls_codepage, | ||
| 1426 | &num_referrals, &referrals, remap); | ||
| 1427 | |||
| 1428 | /* BB Add in code to: if valid refrl, if not ip address contact | ||
| 1429 | the helper that resolves tcp names, mount to it, try to | ||
| 1430 | tcon to it unmount it if fail */ | ||
| 1431 | |||
| 1432 | kfree(referrals); | ||
| 1433 | |||
| 1434 | return rc; | ||
| 1435 | } | ||
| 1436 | |||
| 1437 | int | ||
| 1438 | get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, | 1428 | get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, |
| 1439 | const struct nls_table *nls_codepage, unsigned int *pnum_referrals, | 1429 | const struct nls_table *nls_codepage, unsigned int *pnum_referrals, |
| 1440 | struct dfs_info3_param **preferrals, int remap) | 1430 | struct dfs_info3_param **preferrals, int remap) |
| 1441 | { | 1431 | { |
| 1442 | char *temp_unc; | 1432 | char *temp_unc; |
| 1443 | int rc = 0; | 1433 | int rc = 0; |
| 1444 | unsigned char *targetUNCs; | ||
| 1445 | 1434 | ||
| 1446 | *pnum_referrals = 0; | 1435 | *pnum_referrals = 0; |
| 1447 | *preferrals = NULL; | 1436 | *preferrals = NULL; |
| @@ -1464,7 +1453,7 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, | |||
| 1464 | kfree(temp_unc); | 1453 | kfree(temp_unc); |
| 1465 | } | 1454 | } |
| 1466 | if (rc == 0) | 1455 | if (rc == 0) |
| 1467 | rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, &targetUNCs, | 1456 | rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals, |
| 1468 | pnum_referrals, nls_codepage, remap); | 1457 | pnum_referrals, nls_codepage, remap); |
| 1469 | /* BB map targetUNCs to dfs_info3 structures, here or | 1458 | /* BB map targetUNCs to dfs_info3 structures, here or |
| 1470 | in CIFSGetDFSRefer BB */ | 1459 | in CIFSGetDFSRefer BB */ |
| @@ -1815,7 +1804,7 @@ convert_delimiter(char *path, char delim) | |||
| 1815 | if (path == NULL) | 1804 | if (path == NULL) |
| 1816 | return; | 1805 | return; |
| 1817 | 1806 | ||
| 1818 | if (delim == '/') | 1807 | if (delim == '/') |
| 1819 | old_delim = '\\'; | 1808 | old_delim = '\\'; |
| 1820 | else | 1809 | else |
| 1821 | old_delim = '/'; | 1810 | old_delim = '/'; |
| @@ -2125,11 +2114,17 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 2125 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID; | 2114 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID; |
| 2126 | if (volume_info.override_gid) | 2115 | if (volume_info.override_gid) |
| 2127 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID; | 2116 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID; |
| 2117 | if (volume_info.dynperm) | ||
| 2118 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM; | ||
| 2128 | if (volume_info.direct_io) { | 2119 | if (volume_info.direct_io) { |
| 2129 | cFYI(1, ("mounting share using direct i/o")); | 2120 | cFYI(1, ("mounting share using direct i/o")); |
| 2130 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; | 2121 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; |
| 2131 | } | 2122 | } |
| 2132 | 2123 | ||
| 2124 | if ((volume_info.cifs_acl) && (volume_info.dynperm)) | ||
| 2125 | cERROR(1, ("mount option dynperm ignored if cifsacl " | ||
| 2126 | "mount option supported")); | ||
| 2127 | |||
| 2133 | tcon = | 2128 | tcon = |
| 2134 | find_unc(sin_server.sin_addr.s_addr, volume_info.UNC, | 2129 | find_unc(sin_server.sin_addr.s_addr, volume_info.UNC, |
| 2135 | volume_info.username); | 2130 | volume_info.username); |
| @@ -2141,6 +2136,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 2141 | for the retry flag is used */ | 2136 | for the retry flag is used */ |
| 2142 | tcon->retry = volume_info.retry; | 2137 | tcon->retry = volume_info.retry; |
| 2143 | tcon->nocase = volume_info.nocase; | 2138 | tcon->nocase = volume_info.nocase; |
| 2139 | if (tcon->seal != volume_info.seal) | ||
| 2140 | cERROR(1, ("transport encryption setting " | ||
| 2141 | "conflicts with existing tid")); | ||
| 2144 | } else { | 2142 | } else { |
| 2145 | tcon = tconInfoAlloc(); | 2143 | tcon = tconInfoAlloc(); |
| 2146 | if (tcon == NULL) | 2144 | if (tcon == NULL) |
| @@ -2154,10 +2152,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 2154 | if ((strchr(volume_info.UNC + 3, '\\') == NULL) | 2152 | if ((strchr(volume_info.UNC + 3, '\\') == NULL) |
| 2155 | && (strchr(volume_info.UNC + 3, '/') == | 2153 | && (strchr(volume_info.UNC + 3, '/') == |
| 2156 | NULL)) { | 2154 | NULL)) { |
| 2157 | rc = connect_to_dfs_path(xid, pSesInfo, | 2155 | /* rc = connect_to_dfs_path(xid, pSesInfo, |
| 2158 | "", cifs_sb->local_nls, | 2156 | "", cifs_sb->local_nls, |
| 2159 | cifs_sb->mnt_cifs_flags & | 2157 | cifs_sb->mnt_cifs_flags & |
| 2160 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 2158 | CIFS_MOUNT_MAP_SPECIAL_CHR);*/ |
| 2159 | cFYI(1, ("DFS root not supported")); | ||
| 2161 | rc = -ENODEV; | 2160 | rc = -ENODEV; |
| 2162 | goto out; | 2161 | goto out; |
| 2163 | } else { | 2162 | } else { |
| @@ -2173,6 +2172,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 2173 | atomic_inc(&pSesInfo->inUse); | 2172 | atomic_inc(&pSesInfo->inUse); |
| 2174 | tcon->retry = volume_info.retry; | 2173 | tcon->retry = volume_info.retry; |
| 2175 | tcon->nocase = volume_info.nocase; | 2174 | tcon->nocase = volume_info.nocase; |
| 2175 | tcon->seal = volume_info.seal; | ||
| 2176 | } | 2176 | } |
| 2177 | } | 2177 | } |
| 2178 | } | 2178 | } |
| @@ -2314,9 +2314,10 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
| 2314 | user = ses->userName; | 2314 | user = ses->userName; |
| 2315 | domain = ses->domainName; | 2315 | domain = ses->domainName; |
| 2316 | smb_buffer = cifs_buf_get(); | 2316 | smb_buffer = cifs_buf_get(); |
| 2317 | if (smb_buffer == NULL) { | 2317 | |
| 2318 | if (smb_buffer == NULL) | ||
| 2318 | return -ENOMEM; | 2319 | return -ENOMEM; |
| 2319 | } | 2320 | |
| 2320 | smb_buffer_response = smb_buffer; | 2321 | smb_buffer_response = smb_buffer; |
| 2321 | pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer; | 2322 | pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer; |
| 2322 | 2323 | ||
