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 | ||