diff options
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r-- | fs/cifs/connect.c | 91 |
1 files changed, 49 insertions, 42 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 56095b24d5b9..c2ed0f57a66c 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -2185,27 +2185,30 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2185 | { | 2185 | { |
2186 | int rc = 0; | 2186 | int rc = 0; |
2187 | int xid; | 2187 | int xid; |
2188 | struct smb_vol volume_info; | 2188 | struct smb_vol *volume_info; |
2189 | struct cifsSesInfo *pSesInfo = NULL; | 2189 | struct cifsSesInfo *pSesInfo = NULL; |
2190 | struct cifsTconInfo *tcon = NULL; | 2190 | struct cifsTconInfo *tcon = NULL; |
2191 | struct TCP_Server_Info *srvTcp = NULL; | 2191 | struct TCP_Server_Info *srvTcp = NULL; |
2192 | 2192 | ||
2193 | xid = GetXid(); | 2193 | xid = GetXid(); |
2194 | 2194 | ||
2195 | /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */ | 2195 | volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL); |
2196 | if (!volume_info) { | ||
2197 | rc = -ENOMEM; | ||
2198 | goto out; | ||
2199 | } | ||
2196 | 2200 | ||
2197 | memset(&volume_info, 0, sizeof(struct smb_vol)); | 2201 | if (cifs_parse_mount_options(mount_data, devname, volume_info)) { |
2198 | if (cifs_parse_mount_options(mount_data, devname, &volume_info)) { | ||
2199 | rc = -EINVAL; | 2202 | rc = -EINVAL; |
2200 | goto out; | 2203 | goto out; |
2201 | } | 2204 | } |
2202 | 2205 | ||
2203 | if (volume_info.nullauth) { | 2206 | if (volume_info->nullauth) { |
2204 | cFYI(1, ("null user")); | 2207 | cFYI(1, ("null user")); |
2205 | volume_info.username = ""; | 2208 | volume_info->username = ""; |
2206 | } else if (volume_info.username) { | 2209 | } else if (volume_info->username) { |
2207 | /* BB fixme parse for domain name here */ | 2210 | /* BB fixme parse for domain name here */ |
2208 | cFYI(1, ("Username: %s", volume_info.username)); | 2211 | cFYI(1, ("Username: %s", volume_info->username)); |
2209 | } else { | 2212 | } else { |
2210 | cifserror("No username specified"); | 2213 | cifserror("No username specified"); |
2211 | /* In userspace mount helper we can get user name from alternate | 2214 | /* In userspace mount helper we can get user name from alternate |
@@ -2216,27 +2219,27 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2216 | 2219 | ||
2217 | 2220 | ||
2218 | /* this is needed for ASCII cp to Unicode converts */ | 2221 | /* this is needed for ASCII cp to Unicode converts */ |
2219 | if (volume_info.iocharset == NULL) { | 2222 | if (volume_info->iocharset == NULL) { |
2220 | cifs_sb->local_nls = load_nls_default(); | 2223 | cifs_sb->local_nls = load_nls_default(); |
2221 | /* load_nls_default can not return null */ | 2224 | /* load_nls_default can not return null */ |
2222 | } else { | 2225 | } else { |
2223 | cifs_sb->local_nls = load_nls(volume_info.iocharset); | 2226 | cifs_sb->local_nls = load_nls(volume_info->iocharset); |
2224 | if (cifs_sb->local_nls == NULL) { | 2227 | if (cifs_sb->local_nls == NULL) { |
2225 | cERROR(1, ("CIFS mount error: iocharset %s not found", | 2228 | cERROR(1, ("CIFS mount error: iocharset %s not found", |
2226 | volume_info.iocharset)); | 2229 | volume_info->iocharset)); |
2227 | rc = -ELIBACC; | 2230 | rc = -ELIBACC; |
2228 | goto out; | 2231 | goto out; |
2229 | } | 2232 | } |
2230 | } | 2233 | } |
2231 | 2234 | ||
2232 | /* get a reference to a tcp session */ | 2235 | /* get a reference to a tcp session */ |
2233 | srvTcp = cifs_get_tcp_session(&volume_info); | 2236 | srvTcp = cifs_get_tcp_session(volume_info); |
2234 | if (IS_ERR(srvTcp)) { | 2237 | if (IS_ERR(srvTcp)) { |
2235 | rc = PTR_ERR(srvTcp); | 2238 | rc = PTR_ERR(srvTcp); |
2236 | goto out; | 2239 | goto out; |
2237 | } | 2240 | } |
2238 | 2241 | ||
2239 | pSesInfo = cifs_find_smb_ses(srvTcp, volume_info.username); | 2242 | pSesInfo = cifs_find_smb_ses(srvTcp, volume_info->username); |
2240 | if (pSesInfo) { | 2243 | if (pSesInfo) { |
2241 | cFYI(1, ("Existing smb sess found (status=%d)", | 2244 | cFYI(1, ("Existing smb sess found (status=%d)", |
2242 | pSesInfo->status)); | 2245 | pSesInfo->status)); |
@@ -2274,24 +2277,24 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2274 | list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list); | 2277 | list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list); |
2275 | write_unlock(&cifs_tcp_ses_lock); | 2278 | write_unlock(&cifs_tcp_ses_lock); |
2276 | 2279 | ||
2277 | /* volume_info.password freed at unmount */ | 2280 | /* volume_info->password freed at unmount */ |
2278 | if (volume_info.password) { | 2281 | if (volume_info->password) { |
2279 | pSesInfo->password = volume_info.password; | 2282 | pSesInfo->password = volume_info->password; |
2280 | /* set to NULL to prevent freeing on exit */ | 2283 | /* set to NULL to prevent freeing on exit */ |
2281 | volume_info.password = NULL; | 2284 | volume_info->password = NULL; |
2282 | } | 2285 | } |
2283 | if (volume_info.username) | 2286 | if (volume_info->username) |
2284 | strncpy(pSesInfo->userName, volume_info.username, | 2287 | strncpy(pSesInfo->userName, volume_info->username, |
2285 | MAX_USERNAME_SIZE); | 2288 | MAX_USERNAME_SIZE); |
2286 | if (volume_info.domainname) { | 2289 | if (volume_info->domainname) { |
2287 | int len = strlen(volume_info.domainname); | 2290 | int len = strlen(volume_info->domainname); |
2288 | pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL); | 2291 | pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL); |
2289 | if (pSesInfo->domainName) | 2292 | if (pSesInfo->domainName) |
2290 | strcpy(pSesInfo->domainName, | 2293 | strcpy(pSesInfo->domainName, |
2291 | volume_info.domainname); | 2294 | volume_info->domainname); |
2292 | } | 2295 | } |
2293 | pSesInfo->linux_uid = volume_info.linux_uid; | 2296 | pSesInfo->linux_uid = volume_info->linux_uid; |
2294 | pSesInfo->overrideSecFlg = volume_info.secFlg; | 2297 | pSesInfo->overrideSecFlg = volume_info->secFlg; |
2295 | down(&pSesInfo->sesSem); | 2298 | down(&pSesInfo->sesSem); |
2296 | 2299 | ||
2297 | /* BB FIXME need to pass vol->secFlgs BB */ | 2300 | /* BB FIXME need to pass vol->secFlgs BB */ |
@@ -2302,14 +2305,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2302 | 2305 | ||
2303 | /* search for existing tcon to this server share */ | 2306 | /* search for existing tcon to this server share */ |
2304 | if (!rc) { | 2307 | if (!rc) { |
2305 | setup_cifs_sb(&volume_info, cifs_sb); | 2308 | setup_cifs_sb(volume_info, cifs_sb); |
2306 | 2309 | ||
2307 | tcon = cifs_find_tcon(pSesInfo, volume_info.UNC); | 2310 | tcon = cifs_find_tcon(pSesInfo, volume_info->UNC); |
2308 | if (tcon) { | 2311 | if (tcon) { |
2309 | cFYI(1, ("Found match on UNC path")); | 2312 | cFYI(1, ("Found match on UNC path")); |
2310 | /* existing tcon already has a reference */ | 2313 | /* existing tcon already has a reference */ |
2311 | cifs_put_smb_ses(pSesInfo); | 2314 | cifs_put_smb_ses(pSesInfo); |
2312 | if (tcon->seal != volume_info.seal) | 2315 | if (tcon->seal != volume_info->seal) |
2313 | cERROR(1, ("transport encryption setting " | 2316 | cERROR(1, ("transport encryption setting " |
2314 | "conflicts with existing tid")); | 2317 | "conflicts with existing tid")); |
2315 | } else { | 2318 | } else { |
@@ -2321,8 +2324,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2321 | tcon->ses = pSesInfo; | 2324 | tcon->ses = pSesInfo; |
2322 | 2325 | ||
2323 | /* check for null share name ie connect to dfs root */ | 2326 | /* check for null share name ie connect to dfs root */ |
2324 | if ((strchr(volume_info.UNC + 3, '\\') == NULL) | 2327 | if ((strchr(volume_info->UNC + 3, '\\') == NULL) |
2325 | && (strchr(volume_info.UNC + 3, '/') == NULL)) { | 2328 | && (strchr(volume_info->UNC + 3, '/') == NULL)) { |
2326 | /* rc = connect_to_dfs_path(...) */ | 2329 | /* rc = connect_to_dfs_path(...) */ |
2327 | cFYI(1, ("DFS root not supported")); | 2330 | cFYI(1, ("DFS root not supported")); |
2328 | rc = -ENODEV; | 2331 | rc = -ENODEV; |
@@ -2331,10 +2334,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2331 | /* BB Do we need to wrap sesSem around | 2334 | /* BB Do we need to wrap sesSem around |
2332 | * this TCon call and Unix SetFS as | 2335 | * this TCon call and Unix SetFS as |
2333 | * we do on SessSetup and reconnect? */ | 2336 | * we do on SessSetup and reconnect? */ |
2334 | rc = CIFSTCon(xid, pSesInfo, volume_info.UNC, | 2337 | rc = CIFSTCon(xid, pSesInfo, volume_info->UNC, |
2335 | tcon, cifs_sb->local_nls); | 2338 | tcon, cifs_sb->local_nls); |
2336 | cFYI(1, ("CIFS Tcon rc = %d", rc)); | 2339 | cFYI(1, ("CIFS Tcon rc = %d", rc)); |
2337 | if (volume_info.nodfs) { | 2340 | if (volume_info->nodfs) { |
2338 | tcon->Flags &= ~SMB_SHARE_IS_IN_DFS; | 2341 | tcon->Flags &= ~SMB_SHARE_IS_IN_DFS; |
2339 | cFYI(1, ("DFS disabled (%d)", | 2342 | cFYI(1, ("DFS disabled (%d)", |
2340 | tcon->Flags)); | 2343 | tcon->Flags)); |
@@ -2342,7 +2345,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2342 | } | 2345 | } |
2343 | if (rc) | 2346 | if (rc) |
2344 | goto mount_fail_check; | 2347 | goto mount_fail_check; |
2345 | tcon->seal = volume_info.seal; | 2348 | tcon->seal = volume_info->seal; |
2346 | write_lock(&cifs_tcp_ses_lock); | 2349 | write_lock(&cifs_tcp_ses_lock); |
2347 | list_add(&tcon->tcon_list, &pSesInfo->tcon_list); | 2350 | list_add(&tcon->tcon_list, &pSesInfo->tcon_list); |
2348 | write_unlock(&cifs_tcp_ses_lock); | 2351 | write_unlock(&cifs_tcp_ses_lock); |
@@ -2352,9 +2355,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2352 | to a share so for resources mounted more than once | 2355 | to a share so for resources mounted more than once |
2353 | to the same server share the last value passed in | 2356 | to the same server share the last value passed in |
2354 | for the retry flag is used */ | 2357 | for the retry flag is used */ |
2355 | tcon->retry = volume_info.retry; | 2358 | tcon->retry = volume_info->retry; |
2356 | tcon->nocase = volume_info.nocase; | 2359 | tcon->nocase = volume_info->nocase; |
2357 | tcon->local_lease = volume_info.local_lease; | 2360 | tcon->local_lease = volume_info->local_lease; |
2358 | } | 2361 | } |
2359 | if (pSesInfo) { | 2362 | if (pSesInfo) { |
2360 | if (pSesInfo->capabilities & CAP_LARGE_FILES) { | 2363 | if (pSesInfo->capabilities & CAP_LARGE_FILES) { |
@@ -2391,7 +2394,7 @@ mount_fail_check: | |||
2391 | if (tcon->ses->capabilities & CAP_UNIX) | 2394 | if (tcon->ses->capabilities & CAP_UNIX) |
2392 | /* reset of caps checks mount to see if unix extensions | 2395 | /* reset of caps checks mount to see if unix extensions |
2393 | disabled for just this mount */ | 2396 | disabled for just this mount */ |
2394 | reset_cifs_unix_caps(xid, tcon, sb, &volume_info); | 2397 | reset_cifs_unix_caps(xid, tcon, sb, volume_info); |
2395 | else | 2398 | else |
2396 | tcon->unix_ext = 0; /* server does not support them */ | 2399 | tcon->unix_ext = 0; /* server does not support them */ |
2397 | 2400 | ||
@@ -2410,18 +2413,22 @@ mount_fail_check: | |||
2410 | cifs_sb->rsize = min(cifs_sb->rsize, | 2413 | cifs_sb->rsize = min(cifs_sb->rsize, |
2411 | (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); | 2414 | (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); |
2412 | 2415 | ||
2413 | /* volume_info.password is freed above when existing session found | 2416 | /* volume_info->password is freed above when existing session found |
2414 | (in which case it is not needed anymore) but when new sesion is created | 2417 | (in which case it is not needed anymore) but when new sesion is created |
2415 | the password ptr is put in the new session structure (in which case the | 2418 | the password ptr is put in the new session structure (in which case the |
2416 | password will be freed at unmount time) */ | 2419 | password will be freed at unmount time) */ |
2417 | out: | 2420 | out: |
2418 | /* zero out password before freeing */ | 2421 | /* zero out password before freeing */ |
2419 | if (volume_info.password != NULL) { | 2422 | if (volume_info) { |
2420 | memset(volume_info.password, 0, strlen(volume_info.password)); | 2423 | if (volume_info->password != NULL) { |
2421 | kfree(volume_info.password); | 2424 | memset(volume_info->password, 0, |
2425 | strlen(volume_info->password)); | ||
2426 | kfree(volume_info->password); | ||
2427 | } | ||
2428 | kfree(volume_info->UNC); | ||
2429 | kfree(volume_info->prepath); | ||
2430 | kfree(volume_info); | ||
2422 | } | 2431 | } |
2423 | kfree(volume_info.UNC); | ||
2424 | kfree(volume_info.prepath); | ||
2425 | FreeXid(xid); | 2432 | FreeXid(xid); |
2426 | return rc; | 2433 | return rc; |
2427 | } | 2434 | } |