diff options
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/CHANGES | 7 | ||||
-rw-r--r-- | fs/cifs/cifsfs.h | 2 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 2 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 40 | ||||
-rw-r--r-- | fs/cifs/connect.c | 97 | ||||
-rw-r--r-- | fs/cifs/file.c | 12 |
6 files changed, 140 insertions, 20 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 1a27ecb46c9a..7271bb0257f6 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -1,3 +1,10 @@ | |||
1 | Version 1.43 | ||
2 | ------------ | ||
3 | POSIX locking to servers which support CIFS POSIX Extensions | ||
4 | (disabled by default controlled by proc/fs/cifs/Experimental). | ||
5 | Handle conversion of long share names (especially Asian languages) | ||
6 | to Unicode during mount. | ||
7 | |||
1 | Version 1.42 | 8 | Version 1.42 |
2 | ------------ | 9 | ------------ |
3 | Fix slow oplock break when mounted to different servers at the same time and | 10 | Fix slow oplock break when mounted to different servers at the same time and |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 4e829dc672a6..c98755dca868 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -99,5 +99,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); | |||
99 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); | 99 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); |
100 | extern int cifs_ioctl (struct inode * inode, struct file * filep, | 100 | extern int cifs_ioctl (struct inode * inode, struct file * filep, |
101 | unsigned int command, unsigned long arg); | 101 | unsigned int command, unsigned long arg); |
102 | #define CIFS_VERSION "1.42" | 102 | #define CIFS_VERSION "1.43" |
103 | #endif /* _CIFSFS_H */ | 103 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 2879ba343ca7..310ea2f0e0bf 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -267,7 +267,7 @@ extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, | |||
267 | const int waitFlag); | 267 | const int waitFlag); |
268 | extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, | 268 | extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, |
269 | const __u16 smb_file_id, const int get_flag, | 269 | const __u16 smb_file_id, const int get_flag, |
270 | const __u64 len, const __u64 offset, | 270 | const __u64 len, struct file_lock *, |
271 | const __u16 lock_type, const int waitFlag); | 271 | const __u16 lock_type, const int waitFlag); |
272 | extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); | 272 | extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); |
273 | extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); | 273 | extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index fd36892eda55..925881e00ff2 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -1355,7 +1355,8 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, | |||
1355 | int | 1355 | int |
1356 | CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, | 1356 | CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, |
1357 | const __u16 smb_file_id, const int get_flag, const __u64 len, | 1357 | const __u16 smb_file_id, const int get_flag, const __u64 len, |
1358 | const __u64 lkoffset, const __u16 lock_type, const int waitFlag) | 1358 | struct file_lock *pLockData, const __u16 lock_type, |
1359 | const int waitFlag) | ||
1359 | { | 1360 | { |
1360 | struct smb_com_transaction2_sfi_req *pSMB = NULL; | 1361 | struct smb_com_transaction2_sfi_req *pSMB = NULL; |
1361 | struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; | 1362 | struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; |
@@ -1366,6 +1367,10 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, | |||
1366 | __u16 params, param_offset, offset, byte_count, count; | 1367 | __u16 params, param_offset, offset, byte_count, count; |
1367 | 1368 | ||
1368 | cFYI(1, ("Posix Lock")); | 1369 | cFYI(1, ("Posix Lock")); |
1370 | |||
1371 | if(pLockData == NULL) | ||
1372 | return EINVAL; | ||
1373 | |||
1369 | rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); | 1374 | rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); |
1370 | 1375 | ||
1371 | if (rc) | 1376 | if (rc) |
@@ -1404,10 +1409,10 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, | |||
1404 | 1409 | ||
1405 | parm_data->lock_type = cpu_to_le16(lock_type); | 1410 | parm_data->lock_type = cpu_to_le16(lock_type); |
1406 | if(waitFlag) | 1411 | if(waitFlag) |
1407 | parm_data->lock_flags = 1; | 1412 | parm_data->lock_flags = cpu_to_le16(1); |
1408 | parm_data->pid = cpu_to_le32(current->tgid); | 1413 | parm_data->pid = cpu_to_le32(current->tgid); |
1409 | parm_data->start = lkoffset; | 1414 | parm_data->start = cpu_to_le64(pLockData->fl_start); |
1410 | parm_data->length = len; /* normalize negative numbers */ | 1415 | parm_data->length = cpu_to_le64(len); /* normalize negative numbers */ |
1411 | 1416 | ||
1412 | pSMB->DataOffset = cpu_to_le16(offset); | 1417 | pSMB->DataOffset = cpu_to_le16(offset); |
1413 | pSMB->Fid = smb_file_id; | 1418 | pSMB->Fid = smb_file_id; |
@@ -1419,8 +1424,33 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, | |||
1419 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 1424 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
1420 | if (rc) { | 1425 | if (rc) { |
1421 | cFYI(1, ("Send error in Posix Lock = %d", rc)); | 1426 | cFYI(1, ("Send error in Posix Lock = %d", rc)); |
1422 | } | 1427 | } else if (get_flag) { |
1428 | /* lock structure can be returned on get */ | ||
1429 | __u16 data_offset; | ||
1430 | __u16 data_count; | ||
1431 | rc = validate_t2((struct smb_t2_rsp *)pSMBr); | ||
1423 | 1432 | ||
1433 | if (rc || (pSMBr->ByteCount < sizeof(struct cifs_posix_lock))) { | ||
1434 | rc = -EIO; /* bad smb */ | ||
1435 | goto plk_err_exit; | ||
1436 | } | ||
1437 | if(pLockData == NULL) { | ||
1438 | rc = -EINVAL; | ||
1439 | goto plk_err_exit; | ||
1440 | } | ||
1441 | data_offset = le16_to_cpu(pSMBr->t2.DataOffset); | ||
1442 | data_count = le16_to_cpu(pSMBr->t2.DataCount); | ||
1443 | if(data_count < sizeof(struct cifs_posix_lock)) { | ||
1444 | rc = -EIO; | ||
1445 | goto plk_err_exit; | ||
1446 | } | ||
1447 | parm_data = (struct cifs_posix_lock *) | ||
1448 | ((char *)&pSMBr->hdr.Protocol + data_offset); | ||
1449 | if(parm_data->lock_type == cpu_to_le16(CIFS_UNLCK)) | ||
1450 | pLockData->fl_type = F_UNLCK; | ||
1451 | } | ||
1452 | |||
1453 | plk_err_exit: | ||
1424 | if (pSMB) | 1454 | if (pSMB) |
1425 | cifs_small_buf_release(pSMB); | 1455 | cifs_small_buf_release(pSMB); |
1426 | 1456 | ||
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index d2ec806a4f32..bae1479318d1 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -2148,6 +2148,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2148 | /* We look for obvious messed up bcc or strings in response so we do not go off | 2148 | /* We look for obvious messed up bcc or strings in response so we do not go off |
2149 | the end since (at least) WIN2K and Windows XP have a major bug in not null | 2149 | the end since (at least) WIN2K and Windows XP have a major bug in not null |
2150 | terminating last Unicode string in response */ | 2150 | terminating last Unicode string in response */ |
2151 | if(ses->serverOS) | ||
2152 | kfree(ses->serverOS); | ||
2151 | ses->serverOS = kzalloc(2 * (len + 1), GFP_KERNEL); | 2153 | ses->serverOS = kzalloc(2 * (len + 1), GFP_KERNEL); |
2152 | if(ses->serverOS == NULL) | 2154 | if(ses->serverOS == NULL) |
2153 | goto sesssetup_nomem; | 2155 | goto sesssetup_nomem; |
@@ -2160,6 +2162,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2160 | if (remaining_words > 0) { | 2162 | if (remaining_words > 0) { |
2161 | len = UniStrnlen((wchar_t *)bcc_ptr, | 2163 | len = UniStrnlen((wchar_t *)bcc_ptr, |
2162 | remaining_words-1); | 2164 | remaining_words-1); |
2165 | if(ses->serverNOS) | ||
2166 | kfree(ses->serverNOS); | ||
2163 | ses->serverNOS = kzalloc(2 * (len + 1),GFP_KERNEL); | 2167 | ses->serverNOS = kzalloc(2 * (len + 1),GFP_KERNEL); |
2164 | if(ses->serverNOS == NULL) | 2168 | if(ses->serverNOS == NULL) |
2165 | goto sesssetup_nomem; | 2169 | goto sesssetup_nomem; |
@@ -2177,6 +2181,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2177 | if (remaining_words > 0) { | 2181 | if (remaining_words > 0) { |
2178 | len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); | 2182 | len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); |
2179 | /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ | 2183 | /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ |
2184 | if(ses->serverDomain) | ||
2185 | kfree(ses->serverDomain); | ||
2180 | ses->serverDomain = | 2186 | ses->serverDomain = |
2181 | kzalloc(2*(len+1),GFP_KERNEL); | 2187 | kzalloc(2*(len+1),GFP_KERNEL); |
2182 | if(ses->serverDomain == NULL) | 2188 | if(ses->serverDomain == NULL) |
@@ -2187,15 +2193,22 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2187 | ses->serverDomain[2*len] = 0; | 2193 | ses->serverDomain[2*len] = 0; |
2188 | ses->serverDomain[1+(2*len)] = 0; | 2194 | ses->serverDomain[1+(2*len)] = 0; |
2189 | } /* else no more room so create dummy domain string */ | 2195 | } /* else no more room so create dummy domain string */ |
2190 | else | 2196 | else { |
2197 | if(ses->serverDomain) | ||
2198 | kfree(ses->serverDomain); | ||
2191 | ses->serverDomain = | 2199 | ses->serverDomain = |
2192 | kzalloc(2, GFP_KERNEL); | 2200 | kzalloc(2, GFP_KERNEL); |
2201 | } | ||
2193 | } else { /* no room so create dummy domain and NOS string */ | 2202 | } else { /* no room so create dummy domain and NOS string */ |
2194 | /* if these kcallocs fail not much we | 2203 | /* if these kcallocs fail not much we |
2195 | can do, but better to not fail the | 2204 | can do, but better to not fail the |
2196 | sesssetup itself */ | 2205 | sesssetup itself */ |
2206 | if(ses->serverDomain) | ||
2207 | kfree(ses->serverDomain); | ||
2197 | ses->serverDomain = | 2208 | ses->serverDomain = |
2198 | kzalloc(2, GFP_KERNEL); | 2209 | kzalloc(2, GFP_KERNEL); |
2210 | if(ses->serverNOS) | ||
2211 | kfree(ses->serverNOS); | ||
2199 | ses->serverNOS = | 2212 | ses->serverNOS = |
2200 | kzalloc(2, GFP_KERNEL); | 2213 | kzalloc(2, GFP_KERNEL); |
2201 | } | 2214 | } |
@@ -2204,6 +2217,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2204 | if (((long) bcc_ptr + len) - (long) | 2217 | if (((long) bcc_ptr + len) - (long) |
2205 | pByteArea(smb_buffer_response) | 2218 | pByteArea(smb_buffer_response) |
2206 | <= BCC(smb_buffer_response)) { | 2219 | <= BCC(smb_buffer_response)) { |
2220 | if(ses->serverOS) | ||
2221 | kfree(ses->serverOS); | ||
2207 | ses->serverOS = kzalloc(len + 1,GFP_KERNEL); | 2222 | ses->serverOS = kzalloc(len + 1,GFP_KERNEL); |
2208 | if(ses->serverOS == NULL) | 2223 | if(ses->serverOS == NULL) |
2209 | goto sesssetup_nomem; | 2224 | goto sesssetup_nomem; |
@@ -2214,6 +2229,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2214 | bcc_ptr++; | 2229 | bcc_ptr++; |
2215 | 2230 | ||
2216 | len = strnlen(bcc_ptr, 1024); | 2231 | len = strnlen(bcc_ptr, 1024); |
2232 | if(ses->serverNOS) | ||
2233 | kfree(ses->serverNOS); | ||
2217 | ses->serverNOS = kzalloc(len + 1,GFP_KERNEL); | 2234 | ses->serverNOS = kzalloc(len + 1,GFP_KERNEL); |
2218 | if(ses->serverNOS == NULL) | 2235 | if(ses->serverNOS == NULL) |
2219 | goto sesssetup_nomem; | 2236 | goto sesssetup_nomem; |
@@ -2223,6 +2240,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2223 | bcc_ptr++; | 2240 | bcc_ptr++; |
2224 | 2241 | ||
2225 | len = strnlen(bcc_ptr, 1024); | 2242 | len = strnlen(bcc_ptr, 1024); |
2243 | if(ses->serverDomain) | ||
2244 | kfree(ses->serverDomain); | ||
2226 | ses->serverDomain = kzalloc(len + 1,GFP_KERNEL); | 2245 | ses->serverDomain = kzalloc(len + 1,GFP_KERNEL); |
2227 | if(ses->serverDomain == NULL) | 2246 | if(ses->serverDomain == NULL) |
2228 | goto sesssetup_nomem; | 2247 | goto sesssetup_nomem; |
@@ -2427,6 +2446,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2427 | /* We look for obvious messed up bcc or strings in response so we do not go off | 2446 | /* We look for obvious messed up bcc or strings in response so we do not go off |
2428 | the end since (at least) WIN2K and Windows XP have a major bug in not null | 2447 | the end since (at least) WIN2K and Windows XP have a major bug in not null |
2429 | terminating last Unicode string in response */ | 2448 | terminating last Unicode string in response */ |
2449 | if(ses->serverOS) | ||
2450 | kfree(ses->serverOS); | ||
2430 | ses->serverOS = | 2451 | ses->serverOS = |
2431 | kzalloc(2 * (len + 1), GFP_KERNEL); | 2452 | kzalloc(2 * (len + 1), GFP_KERNEL); |
2432 | cifs_strfromUCS_le(ses->serverOS, | 2453 | cifs_strfromUCS_le(ses->serverOS, |
@@ -2441,6 +2462,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2441 | len = UniStrnlen((wchar_t *)bcc_ptr, | 2462 | len = UniStrnlen((wchar_t *)bcc_ptr, |
2442 | remaining_words | 2463 | remaining_words |
2443 | - 1); | 2464 | - 1); |
2465 | if(ses->serverNOS) | ||
2466 | kfree(ses->serverNOS); | ||
2444 | ses->serverNOS = | 2467 | ses->serverNOS = |
2445 | kzalloc(2 * (len + 1), | 2468 | kzalloc(2 * (len + 1), |
2446 | GFP_KERNEL); | 2469 | GFP_KERNEL); |
@@ -2454,7 +2477,9 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2454 | remaining_words -= len + 1; | 2477 | remaining_words -= len + 1; |
2455 | if (remaining_words > 0) { | 2478 | if (remaining_words > 0) { |
2456 | len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); | 2479 | len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); |
2457 | /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ | 2480 | /* last string not null terminated (e.g.Windows XP/2000) */ |
2481 | if(ses->serverDomain) | ||
2482 | kfree(ses->serverDomain); | ||
2458 | ses->serverDomain = kzalloc(2*(len+1),GFP_KERNEL); | 2483 | ses->serverDomain = kzalloc(2*(len+1),GFP_KERNEL); |
2459 | cifs_strfromUCS_le(ses->serverDomain, | 2484 | cifs_strfromUCS_le(ses->serverDomain, |
2460 | (__le16 *)bcc_ptr, | 2485 | (__le16 *)bcc_ptr, |
@@ -2463,11 +2488,18 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2463 | ses->serverDomain[2*len] = 0; | 2488 | ses->serverDomain[2*len] = 0; |
2464 | ses->serverDomain[1+(2*len)] = 0; | 2489 | ses->serverDomain[1+(2*len)] = 0; |
2465 | } /* else no more room so create dummy domain string */ | 2490 | } /* else no more room so create dummy domain string */ |
2466 | else | 2491 | else { |
2492 | if(ses->serverDomain) | ||
2493 | kfree(ses->serverDomain); | ||
2467 | ses->serverDomain = | 2494 | ses->serverDomain = |
2468 | kzalloc(2,GFP_KERNEL); | 2495 | kzalloc(2,GFP_KERNEL); |
2469 | } else { /* no room so create dummy domain and NOS string */ | 2496 | } |
2497 | } else {/* no room use dummy domain&NOS */ | ||
2498 | if(ses->serverDomain) | ||
2499 | kfree(ses->serverDomain); | ||
2470 | ses->serverDomain = kzalloc(2, GFP_KERNEL); | 2500 | ses->serverDomain = kzalloc(2, GFP_KERNEL); |
2501 | if(ses->serverNOS) | ||
2502 | kfree(ses->serverNOS); | ||
2471 | ses->serverNOS = kzalloc(2, GFP_KERNEL); | 2503 | ses->serverNOS = kzalloc(2, GFP_KERNEL); |
2472 | } | 2504 | } |
2473 | } else { /* ASCII */ | 2505 | } else { /* ASCII */ |
@@ -2476,6 +2508,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2476 | if (((long) bcc_ptr + len) - (long) | 2508 | if (((long) bcc_ptr + len) - (long) |
2477 | pByteArea(smb_buffer_response) | 2509 | pByteArea(smb_buffer_response) |
2478 | <= BCC(smb_buffer_response)) { | 2510 | <= BCC(smb_buffer_response)) { |
2511 | if(ses->serverOS) | ||
2512 | kfree(ses->serverOS); | ||
2479 | ses->serverOS = kzalloc(len + 1, GFP_KERNEL); | 2513 | ses->serverOS = kzalloc(len + 1, GFP_KERNEL); |
2480 | strncpy(ses->serverOS, bcc_ptr, len); | 2514 | strncpy(ses->serverOS, bcc_ptr, len); |
2481 | 2515 | ||
@@ -2484,6 +2518,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2484 | bcc_ptr++; | 2518 | bcc_ptr++; |
2485 | 2519 | ||
2486 | len = strnlen(bcc_ptr, 1024); | 2520 | len = strnlen(bcc_ptr, 1024); |
2521 | if(ses->serverNOS) | ||
2522 | kfree(ses->serverNOS); | ||
2487 | ses->serverNOS = kzalloc(len + 1,GFP_KERNEL); | 2523 | ses->serverNOS = kzalloc(len + 1,GFP_KERNEL); |
2488 | strncpy(ses->serverNOS, bcc_ptr, len); | 2524 | strncpy(ses->serverNOS, bcc_ptr, len); |
2489 | bcc_ptr += len; | 2525 | bcc_ptr += len; |
@@ -2491,6 +2527,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2491 | bcc_ptr++; | 2527 | bcc_ptr++; |
2492 | 2528 | ||
2493 | len = strnlen(bcc_ptr, 1024); | 2529 | len = strnlen(bcc_ptr, 1024); |
2530 | if(ses->serverDomain) | ||
2531 | kfree(ses->serverDomain); | ||
2494 | ses->serverDomain = kzalloc(len + 1, GFP_KERNEL); | 2532 | ses->serverDomain = kzalloc(len + 1, GFP_KERNEL); |
2495 | strncpy(ses->serverDomain, bcc_ptr, len); | 2533 | strncpy(ses->serverDomain, bcc_ptr, len); |
2496 | bcc_ptr += len; | 2534 | bcc_ptr += len; |
@@ -2728,6 +2766,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2728 | /* We look for obvious messed up bcc or strings in response so we do not go off | 2766 | /* We look for obvious messed up bcc or strings in response so we do not go off |
2729 | the end since (at least) WIN2K and Windows XP have a major bug in not null | 2767 | the end since (at least) WIN2K and Windows XP have a major bug in not null |
2730 | terminating last Unicode string in response */ | 2768 | terminating last Unicode string in response */ |
2769 | if(ses->serverOS) | ||
2770 | kfree(ses->serverOS); | ||
2731 | ses->serverOS = | 2771 | ses->serverOS = |
2732 | kzalloc(2 * (len + 1), GFP_KERNEL); | 2772 | kzalloc(2 * (len + 1), GFP_KERNEL); |
2733 | cifs_strfromUCS_le(ses->serverOS, | 2773 | cifs_strfromUCS_le(ses->serverOS, |
@@ -2743,6 +2783,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2743 | bcc_ptr, | 2783 | bcc_ptr, |
2744 | remaining_words | 2784 | remaining_words |
2745 | - 1); | 2785 | - 1); |
2786 | if(ses->serverNOS) | ||
2787 | kfree(ses->serverNOS); | ||
2746 | ses->serverNOS = | 2788 | ses->serverNOS = |
2747 | kzalloc(2 * (len + 1), | 2789 | kzalloc(2 * (len + 1), |
2748 | GFP_KERNEL); | 2790 | GFP_KERNEL); |
@@ -2760,6 +2802,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2760 | if (remaining_words > 0) { | 2802 | if (remaining_words > 0) { |
2761 | len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); | 2803 | len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); |
2762 | /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ | 2804 | /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ |
2805 | if(ses->serverDomain) | ||
2806 | kfree(ses->serverDomain); | ||
2763 | ses->serverDomain = | 2807 | ses->serverDomain = |
2764 | kzalloc(2 * | 2808 | kzalloc(2 * |
2765 | (len + | 2809 | (len + |
@@ -2777,13 +2821,20 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2777 | [1 + (2 * len)] | 2821 | [1 + (2 * len)] |
2778 | = 0; | 2822 | = 0; |
2779 | } /* else no more room so create dummy domain string */ | 2823 | } /* else no more room so create dummy domain string */ |
2780 | else | 2824 | else { |
2825 | if(ses->serverDomain) | ||
2826 | kfree(ses->serverDomain); | ||
2781 | ses->serverDomain = | 2827 | ses->serverDomain = |
2782 | kzalloc(2, | 2828 | kzalloc(2, |
2783 | GFP_KERNEL); | 2829 | GFP_KERNEL); |
2830 | } | ||
2784 | } else { /* no room so create dummy domain and NOS string */ | 2831 | } else { /* no room so create dummy domain and NOS string */ |
2832 | if(ses->serverDomain); | ||
2833 | kfree(ses->serverDomain); | ||
2785 | ses->serverDomain = | 2834 | ses->serverDomain = |
2786 | kzalloc(2, GFP_KERNEL); | 2835 | kzalloc(2, GFP_KERNEL); |
2836 | if(ses->serverNOS) | ||
2837 | kfree(ses->serverNOS); | ||
2787 | ses->serverNOS = | 2838 | ses->serverNOS = |
2788 | kzalloc(2, GFP_KERNEL); | 2839 | kzalloc(2, GFP_KERNEL); |
2789 | } | 2840 | } |
@@ -2792,6 +2843,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2792 | if (((long) bcc_ptr + len) - (long) | 2843 | if (((long) bcc_ptr + len) - (long) |
2793 | pByteArea(smb_buffer_response) | 2844 | pByteArea(smb_buffer_response) |
2794 | <= BCC(smb_buffer_response)) { | 2845 | <= BCC(smb_buffer_response)) { |
2846 | if(ses->serverOS) | ||
2847 | kfree(ses->serverOS); | ||
2795 | ses->serverOS = | 2848 | ses->serverOS = |
2796 | kzalloc(len + 1, | 2849 | kzalloc(len + 1, |
2797 | GFP_KERNEL); | 2850 | GFP_KERNEL); |
@@ -2803,6 +2856,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2803 | bcc_ptr++; | 2856 | bcc_ptr++; |
2804 | 2857 | ||
2805 | len = strnlen(bcc_ptr, 1024); | 2858 | len = strnlen(bcc_ptr, 1024); |
2859 | if(ses->serverNOS) | ||
2860 | kfree(ses->serverNOS); | ||
2806 | ses->serverNOS = | 2861 | ses->serverNOS = |
2807 | kzalloc(len + 1, | 2862 | kzalloc(len + 1, |
2808 | GFP_KERNEL); | 2863 | GFP_KERNEL); |
@@ -2812,6 +2867,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2812 | bcc_ptr++; | 2867 | bcc_ptr++; |
2813 | 2868 | ||
2814 | len = strnlen(bcc_ptr, 1024); | 2869 | len = strnlen(bcc_ptr, 1024); |
2870 | if(ses->serverDomain) | ||
2871 | kfree(ses->serverDomain); | ||
2815 | ses->serverDomain = | 2872 | ses->serverDomain = |
2816 | kzalloc(len + 1, | 2873 | kzalloc(len + 1, |
2817 | GFP_KERNEL); | 2874 | GFP_KERNEL); |
@@ -3116,6 +3173,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
3116 | /* We look for obvious messed up bcc or strings in response so we do not go off | 3173 | /* We look for obvious messed up bcc or strings in response so we do not go off |
3117 | the end since (at least) WIN2K and Windows XP have a major bug in not null | 3174 | the end since (at least) WIN2K and Windows XP have a major bug in not null |
3118 | terminating last Unicode string in response */ | 3175 | terminating last Unicode string in response */ |
3176 | if(ses->serverOS) | ||
3177 | kfree(ses->serverOS); | ||
3119 | ses->serverOS = | 3178 | ses->serverOS = |
3120 | kzalloc(2 * (len + 1), GFP_KERNEL); | 3179 | kzalloc(2 * (len + 1), GFP_KERNEL); |
3121 | cifs_strfromUCS_le(ses->serverOS, | 3180 | cifs_strfromUCS_le(ses->serverOS, |
@@ -3131,6 +3190,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
3131 | bcc_ptr, | 3190 | bcc_ptr, |
3132 | remaining_words | 3191 | remaining_words |
3133 | - 1); | 3192 | - 1); |
3193 | if(ses->serverNOS) | ||
3194 | kfree(ses->serverNOS); | ||
3134 | ses->serverNOS = | 3195 | ses->serverNOS = |
3135 | kzalloc(2 * (len + 1), | 3196 | kzalloc(2 * (len + 1), |
3136 | GFP_KERNEL); | 3197 | GFP_KERNEL); |
@@ -3147,6 +3208,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
3147 | if (remaining_words > 0) { | 3208 | if (remaining_words > 0) { |
3148 | len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); | 3209 | len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); |
3149 | /* last string not always null terminated (e.g. for Windows XP & 2000) */ | 3210 | /* last string not always null terminated (e.g. for Windows XP & 2000) */ |
3211 | if(ses->serverDomain) | ||
3212 | kfree(ses->serverDomain); | ||
3150 | ses->serverDomain = | 3213 | ses->serverDomain = |
3151 | kzalloc(2 * | 3214 | kzalloc(2 * |
3152 | (len + | 3215 | (len + |
@@ -3172,10 +3235,17 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
3172 | len)] | 3235 | len)] |
3173 | = 0; | 3236 | = 0; |
3174 | } /* else no more room so create dummy domain string */ | 3237 | } /* else no more room so create dummy domain string */ |
3175 | else | 3238 | else { |
3239 | if(ses->serverDomain) | ||
3240 | kfree(ses->serverDomain); | ||
3176 | ses->serverDomain = kzalloc(2,GFP_KERNEL); | 3241 | ses->serverDomain = kzalloc(2,GFP_KERNEL); |
3242 | } | ||
3177 | } else { /* no room so create dummy domain and NOS string */ | 3243 | } else { /* no room so create dummy domain and NOS string */ |
3244 | if(ses->serverDomain) | ||
3245 | kfree(ses->serverDomain); | ||
3178 | ses->serverDomain = kzalloc(2, GFP_KERNEL); | 3246 | ses->serverDomain = kzalloc(2, GFP_KERNEL); |
3247 | if(ses->serverNOS) | ||
3248 | kfree(ses->serverNOS); | ||
3179 | ses->serverNOS = kzalloc(2, GFP_KERNEL); | 3249 | ses->serverNOS = kzalloc(2, GFP_KERNEL); |
3180 | } | 3250 | } |
3181 | } else { /* ASCII */ | 3251 | } else { /* ASCII */ |
@@ -3183,6 +3253,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
3183 | if (((long) bcc_ptr + len) - | 3253 | if (((long) bcc_ptr + len) - |
3184 | (long) pByteArea(smb_buffer_response) | 3254 | (long) pByteArea(smb_buffer_response) |
3185 | <= BCC(smb_buffer_response)) { | 3255 | <= BCC(smb_buffer_response)) { |
3256 | if(ses->serverOS) | ||
3257 | kfree(ses->serverOS); | ||
3186 | ses->serverOS = kzalloc(len + 1,GFP_KERNEL); | 3258 | ses->serverOS = kzalloc(len + 1,GFP_KERNEL); |
3187 | strncpy(ses->serverOS,bcc_ptr, len); | 3259 | strncpy(ses->serverOS,bcc_ptr, len); |
3188 | 3260 | ||
@@ -3191,6 +3263,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
3191 | bcc_ptr++; | 3263 | bcc_ptr++; |
3192 | 3264 | ||
3193 | len = strnlen(bcc_ptr, 1024); | 3265 | len = strnlen(bcc_ptr, 1024); |
3266 | if(ses->serverNOS) | ||
3267 | kfree(ses->serverNOS); | ||
3194 | ses->serverNOS = kzalloc(len+1,GFP_KERNEL); | 3268 | ses->serverNOS = kzalloc(len+1,GFP_KERNEL); |
3195 | strncpy(ses->serverNOS, bcc_ptr, len); | 3269 | strncpy(ses->serverNOS, bcc_ptr, len); |
3196 | bcc_ptr += len; | 3270 | bcc_ptr += len; |
@@ -3198,6 +3272,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
3198 | bcc_ptr++; | 3272 | bcc_ptr++; |
3199 | 3273 | ||
3200 | len = strnlen(bcc_ptr, 1024); | 3274 | len = strnlen(bcc_ptr, 1024); |
3275 | if(ses->serverDomain) | ||
3276 | kfree(ses->serverDomain); | ||
3201 | ses->serverDomain = kzalloc(len+1,GFP_KERNEL); | 3277 | ses->serverDomain = kzalloc(len+1,GFP_KERNEL); |
3202 | strncpy(ses->serverDomain, bcc_ptr, len); | 3278 | strncpy(ses->serverDomain, bcc_ptr, len); |
3203 | bcc_ptr += len; | 3279 | bcc_ptr += len; |
@@ -3282,7 +3358,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
3282 | bcc_ptr++; /* align */ | 3358 | bcc_ptr++; /* align */ |
3283 | } | 3359 | } |
3284 | 3360 | ||
3285 | if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | 3361 | if(ses->server->secMode & |
3362 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | ||
3286 | smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; | 3363 | smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; |
3287 | 3364 | ||
3288 | if (ses->capabilities & CAP_STATUS32) { | 3365 | if (ses->capabilities & CAP_STATUS32) { |
@@ -3294,8 +3371,10 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
3294 | if (ses->capabilities & CAP_UNICODE) { | 3371 | if (ses->capabilities & CAP_UNICODE) { |
3295 | smb_buffer->Flags2 |= SMBFLG2_UNICODE; | 3372 | smb_buffer->Flags2 |= SMBFLG2_UNICODE; |
3296 | length = | 3373 | length = |
3297 | cifs_strtoUCS((__le16 *) bcc_ptr, tree, 100, nls_codepage); | 3374 | cifs_strtoUCS((__le16 *) bcc_ptr, tree, |
3298 | bcc_ptr += 2 * length; /* convert num of 16 bit words to bytes */ | 3375 | 6 /* max utf8 char length in bytes */ * |
3376 | (/* server len*/ + 256 /* share len */), nls_codepage); | ||
3377 | bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */ | ||
3299 | bcc_ptr += 2; /* skip trailing null */ | 3378 | bcc_ptr += 2; /* skip trailing null */ |
3300 | } else { /* ASCII */ | 3379 | } else { /* ASCII */ |
3301 | strcpy(bcc_ptr, tree); | 3380 | strcpy(bcc_ptr, tree); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index e152bf6afa60..e2b4ce1dad66 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -84,6 +84,8 @@ static inline int cifs_get_disposition(unsigned int flags) | |||
84 | return FILE_OVERWRITE_IF; | 84 | return FILE_OVERWRITE_IF; |
85 | else if ((flags & O_CREAT) == O_CREAT) | 85 | else if ((flags & O_CREAT) == O_CREAT) |
86 | return FILE_OPEN_IF; | 86 | return FILE_OPEN_IF; |
87 | else if ((flags & O_TRUNC) == O_TRUNC) | ||
88 | return FILE_OVERWRITE; | ||
87 | else | 89 | else |
88 | return FILE_OPEN; | 90 | return FILE_OPEN; |
89 | } | 91 | } |
@@ -656,7 +658,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
656 | else | 658 | else |
657 | posix_lock_type = CIFS_WRLCK; | 659 | posix_lock_type = CIFS_WRLCK; |
658 | rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */, | 660 | rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */, |
659 | length, pfLock->fl_start, | 661 | length, pfLock, |
660 | posix_lock_type, wait_flag); | 662 | posix_lock_type, wait_flag); |
661 | FreeXid(xid); | 663 | FreeXid(xid); |
662 | return rc; | 664 | return rc; |
@@ -704,7 +706,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
704 | return -EOPNOTSUPP; | 706 | return -EOPNOTSUPP; |
705 | } | 707 | } |
706 | rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */, | 708 | rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */, |
707 | length, pfLock->fl_start, | 709 | length, pfLock, |
708 | posix_lock_type, wait_flag); | 710 | posix_lock_type, wait_flag); |
709 | } else | 711 | } else |
710 | rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, | 712 | rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, |
@@ -904,8 +906,10 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
904 | if (rc != 0) | 906 | if (rc != 0) |
905 | break; | 907 | break; |
906 | } | 908 | } |
907 | if(experimEnabled || (pTcon->ses->server->secMode & | 909 | if(experimEnabled || (pTcon->ses->server && |
908 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) { | 910 | ((pTcon->ses->server->secMode & |
911 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | ||
912 | == 0))) { | ||
909 | struct kvec iov[2]; | 913 | struct kvec iov[2]; |
910 | unsigned int len; | 914 | unsigned int len; |
911 | 915 | ||