Merge master.kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
[CIFS] Fix typo in earlier cifs_unlink change and protect one
[CIFS] Incorrect signature sent on SMB Read
[CIFS] Fix unlink oops when indirectly called in rename error path
[CIFS] Fix two remaining coverity scan tool warnings.
[CIFS] Set correct lock type on new posix unlock call
[CIFS] Upate cifs change log
[CIFS] Fix slow oplock break response when mounts to different
[CIFS] Workaround various server bugs found in testing at connectathon
[CIFS] Allow fallback for setting file size to Procom SMB server when
[CIFS] Make POSIX CIFS Extensions SetFSInfo match exactly what we want
[CIFS] Move noisy debug message (triggerred by some older servers) from
[CIFS] Use correct pid on new cifs posix byte range lock call
[CIFS] Add posix (advisory) byte range locking support to cifs client
[CIFS] CIFS readdir perf optimizations part 1
[CIFS] Free small buffers earlier so we exceed the cifs
[CIFS] Fix large (ie over 64K for MaxCIFSBufSize) buffer case for wrapping
[CIFS] Convert remaining places in fs/cifs from
[CIFS] SessionSetup cleanup part 2
[CIFS] fix compile error (typo) and warning in cifssmb.c
[CIFS] Cleanup NTLMSSP session setup handling

+524 -156
+18
fs/cifs/CHANGES
··· 1 + Version 1.42 2 + ------------ 3 + Fix slow oplock break when mounted to different servers at the same time and 4 + the tids match and we try to find matching fid on wrong server. 5 + 6 + Version 1.41 7 + ------------ 8 + Fix NTLMv2 security (can be enabled in /proc/fs/cifs) so customers can 9 + configure stronger authentication. Fix sfu symlinks so they can 10 + be followed (not just recognized). Fix wraparound of bcc on 11 + read responses when buffer size over 64K and also fix wrap of 12 + max smb buffer size when CIFSMaxBufSize over 64K. Fix oops in 13 + cifs_user_read and cifs_readpages (when EAGAIN on send of smb 14 + on socket is returned over and over). Add POSIX (advisory) byte range 15 + locking support (requires server with newest CIFS UNIX Extensions 16 + to the protocol implemented). Slow down negprot slightly in port 139 17 + RFC1001 case to give session_init time on buggy servers. 18 + 1 19 Version 1.40 2 20 ------------ 3 21 Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance
+1 -1
fs/cifs/Makefile
··· 3 3 # 4 4 obj-$(CONFIG_CIFS) += cifs.o 5 5 6 - cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o 6 + cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o ntlmssp.o
+7
fs/cifs/README
··· 422 422 nomapchars Do not translate any of these seven characters (default). 423 423 nocase Request case insensitive path name matching (case 424 424 sensitive is the default if the server suports it). 425 + posixpaths If CIFS Unix extensions are supported, attempt to 426 + negotiate posix path name support which allows certain 427 + characters forbidden in typical CIFS filenames, without 428 + requiring remapping. (default) 429 + noposixpaths If CIFS Unix extensions are supported, do not request 430 + posix path name support (this may cause servers to 431 + reject creatingfile with certain reserved characters). 425 432 nobrl Do not send byte range lock requests to the server. 426 433 This is necessary for certain applications that break 427 434 with cifs style mandatory byte range locks (and most
+27 -15
fs/cifs/cifsencrypt.c
··· 1 1 /* 2 2 * fs/cifs/cifsencrypt.c 3 3 * 4 - * Copyright (C) International Business Machines Corp., 2005 4 + * Copyright (C) International Business Machines Corp., 2005,2006 5 5 * Author(s): Steve French (sfrench@us.ibm.com) 6 6 * 7 7 * This library is free software; you can redistribute it and/or modify ··· 36 36 extern void mdfour(unsigned char *out, unsigned char *in, int n); 37 37 extern void E_md4hash(const unsigned char *passwd, unsigned char *p16); 38 38 39 - static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, const char * key, char * signature) 39 + static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, 40 + const char * key, char * signature) 40 41 { 41 42 struct MD5Context context; 42 43 ··· 56 55 { 57 56 int rc = 0; 58 57 char smb_signature[20]; 59 - 60 - /* BB remember to initialize sequence number elsewhere and initialize mac_signing key elsewhere BB */ 61 - /* BB remember to add code to save expected sequence number in midQ entry BB */ 62 58 63 59 if((cifs_pdu == NULL) || (server == NULL)) 64 60 return -EINVAL; ··· 83 85 static int cifs_calc_signature2(const struct kvec * iov, int n_vec, 84 86 const char * key, char * signature) 85 87 { 86 - struct MD5Context context; 88 + struct MD5Context context; 89 + int i; 87 90 88 - if((iov == NULL) || (signature == NULL)) 89 - return -EINVAL; 91 + if((iov == NULL) || (signature == NULL)) 92 + return -EINVAL; 90 93 91 - MD5Init(&context); 92 - MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16); 94 + MD5Init(&context); 95 + MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16); 96 + for(i=0;i<n_vec;i++) { 97 + if(iov[i].iov_base == NULL) { 98 + cERROR(1,("null iovec entry")); 99 + return -EIO; 100 + } else if(iov[i].iov_len == 0) 101 + break; /* bail out if we are sent nothing to sign */ 102 + /* The first entry includes a length field (which does not get 103 + signed that occupies the first 4 bytes before the header */ 104 + if(i==0) { 105 + if (iov[0].iov_len <= 8 ) /* cmd field at offset 9 */ 106 + break; /* nothing to sign or corrupt header */ 107 + MD5Update(&context,iov[0].iov_base+4, iov[0].iov_len-4); 108 + } else 109 + MD5Update(&context,iov[i].iov_base, iov[i].iov_len); 110 + } 93 111 94 - /* MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); */ /* BB FIXME BB */ 112 + MD5Final(signature,&context); 95 113 96 - MD5Final(signature,&context); 97 - 98 - return -EOPNOTSUPP; 99 - /* return 0; */ 114 + return 0; 100 115 } 101 116 102 117 ··· 270 259 /* hmac_md5_update(v2_session_response+16)client thing,8,&context); */ /* BB fix */ 271 260 272 261 hmac_md5_final(v2_session_response,&context); 262 + cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); /* BB removeme BB */ 273 263 }
+1 -4
fs/cifs/cifsfs.c
··· 93 93 int rc = 0; 94 94 95 95 sb->s_flags |= MS_NODIRATIME; /* and probably even noatime */ 96 - sb->s_fs_info = kmalloc(sizeof(struct cifs_sb_info),GFP_KERNEL); 96 + sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info),GFP_KERNEL); 97 97 cifs_sb = CIFS_SB(sb); 98 98 if(cifs_sb == NULL) 99 99 return -ENOMEM; 100 - else 101 - memset(cifs_sb,0,sizeof(struct cifs_sb_info)); 102 - 103 100 104 101 rc = cifs_mount(sb, cifs_sb, data, devname); 105 102
+1 -1
fs/cifs/cifsfs.h
··· 99 99 extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 100 100 extern int cifs_ioctl (struct inode * inode, struct file * filep, 101 101 unsigned int command, unsigned long arg); 102 - #define CIFS_VERSION "1.40" 102 + #define CIFS_VERSION "1.42" 103 103 #endif /* _CIFSFS_H */
+10 -1
fs/cifs/cifsglob.h
··· 1 1 /* 2 2 * fs/cifs/cifsglob.h 3 3 * 4 - * Copyright (C) International Business Machines Corp., 2002,2005 4 + * Copyright (C) International Business Machines Corp., 2002,2006 5 5 * Author(s): Steve French (sfrench@us.ibm.com) 6 6 * 7 7 * This library is free software; you can redistribute it and/or modify ··· 429 429 #define CIFS_SMALL_BUFFER 1 430 430 #define CIFS_LARGE_BUFFER 2 431 431 #define CIFS_IOVEC 4 /* array of response buffers */ 432 + 433 + /* Type of session setup needed */ 434 + #define CIFS_PLAINTEXT 0 435 + #define CIFS_LANMAN 1 436 + #define CIFS_NTLM 2 437 + #define CIFS_NTLMSSP_NEG 3 438 + #define CIFS_NTLMSSP_AUTH 4 439 + #define CIFS_SPNEGO_INIT 5 440 + #define CIFS_SPNEGO_TARG 6 432 441 433 442 /* 434 443 *****************************************************************
+11 -2
fs/cifs/cifspdu.h
··· 859 859 LOCKING_ANDX_RANGE Locks[1]; 860 860 } __attribute__((packed)) LOCK_REQ; 861 861 862 - 862 + /* lock type */ 863 + #define CIFS_RDLCK 0 864 + #define CIFS_WRLCK 1 865 + #define CIFS_UNLCK 2 863 866 typedef struct cifs_posix_lock { 864 867 __le16 lock_type; /* 0 = Read, 1 = Write, 2 = Unlock */ 865 868 __le16 lock_flags; /* 1 = Wait (only valid for setlock) */ ··· 1789 1786 #define CIFS_UNIX_POSIX_ACL_CAP 0x00000002 /* support getfacl/setfacl */ 1790 1787 #define CIFS_UNIX_XATTR_CAP 0x00000004 /* support new namespace */ 1791 1788 #define CIFS_UNIX_EXTATTR_CAP 0x00000008 /* support chattr/chflag */ 1792 - #define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x00000010 /* Use POSIX pathnames on the wire. */ 1789 + #define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x00000010 /* Allow POSIX path chars */ 1790 + #ifdef CONFIG_CIFS_POSIX 1791 + #define CIFS_UNIX_CAP_MASK 0x0000001b 1792 + #else 1793 + #define CIFS_UNIX_CAP_MASK 0x00000013 1794 + #endif /* CONFIG_CIFS_POSIX */ 1795 + 1793 1796 1794 1797 #define CIFS_POSIX_EXTENSIONS 0x00000010 /* support for new QFSInfo */ 1795 1798
+13 -2
fs/cifs/cifsproto.h
··· 1 1 /* 2 2 * fs/cifs/cifsproto.h 3 3 * 4 - * Copyright (c) International Business Machines Corp., 2002,2005 4 + * Copyright (c) International Business Machines Corp., 2002,2006 5 5 * Author(s): Steve French (sfrench@us.ibm.com) 6 6 * 7 7 * This library is free software; you can redistribute it and/or modify ··· 64 64 extern void header_assemble(struct smb_hdr *, char /* command */ , 65 65 const struct cifsTconInfo *, int /* length of 66 66 fixed section (word count) in two byte units */); 67 + #ifdef CONFIG_CIFS_EXPERIMENTAL 68 + extern int small_smb_init_no_tc(const int smb_cmd, const int wct, 69 + struct cifsSesInfo *ses, 70 + void ** request_buf); 71 + extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, 72 + const int stage, int * pNTLMv2_flg, 73 + const struct nls_table *nls_cp); 74 + #endif 67 75 extern __u16 GetNextMid(struct TCP_Server_Info *server); 68 76 extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, 69 77 struct cifsTconInfo *); ··· 265 257 const __u64 offset, const __u32 numUnlock, 266 258 const __u32 numLock, const __u8 lockType, 267 259 const int waitFlag); 268 - 260 + extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, 261 + const __u16 smb_file_id, const int get_flag, 262 + const __u64 len, const __u64 offset, 263 + const __u16 lock_type, const int waitFlag); 269 264 extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); 270 265 extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); 271 266
+125 -10
fs/cifs/cifssmb.c
··· 1 1 /* 2 2 * fs/cifs/cifssmb.c 3 3 * 4 - * Copyright (C) International Business Machines Corp., 2002,2005 4 + * Copyright (C) International Business Machines Corp., 2002,2006 5 5 * Author(s): Steve French (sfrench@us.ibm.com) 6 6 * 7 7 * Contains the routines for constructing the SMB PDUs themselves ··· 186 186 cifs_stats_inc(&tcon->num_smbs_sent); 187 187 188 188 return rc; 189 - } 189 + } 190 + 191 + #ifdef CONFIG_CIFS_EXPERIMENTAL 192 + int 193 + small_smb_init_no_tc(const int smb_command, const int wct, 194 + struct cifsSesInfo *ses, void **request_buf) 195 + { 196 + int rc; 197 + struct smb_hdr * buffer; 198 + 199 + rc = small_smb_init(smb_command, wct, NULL, request_buf); 200 + if(rc) 201 + return rc; 202 + 203 + buffer = (struct smb_hdr *)*request_buf; 204 + buffer->Mid = GetNextMid(ses->server); 205 + if (ses->capabilities & CAP_UNICODE) 206 + buffer->Flags2 |= SMBFLG2_UNICODE; 207 + if (ses->capabilities & CAP_STATUS32) 208 + buffer->Flags2 |= SMBFLG2_ERR_STATUS; 209 + 210 + /* uid, tid can stay at zero as set in header assemble */ 211 + 212 + /* BB add support for turning on the signing when 213 + this function is used after 1st of session setup requests */ 214 + 215 + return rc; 216 + } 217 + #endif /* CONFIG_CIFS_EXPERIMENTAL */ 190 218 191 219 /* If the return code is zero, this function must fill in request_buf pointer */ 192 220 static int ··· 1070 1042 } 1071 1043 } 1072 1044 1073 - cifs_small_buf_release(pSMB); 1045 + /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ 1074 1046 if(*buf) { 1075 1047 if(resp_buf_type == CIFS_SMALL_BUFFER) 1076 1048 cifs_small_buf_release(iov[0].iov_base); ··· 1274 1246 *nbytes += le16_to_cpu(pSMBr->Count); 1275 1247 } 1276 1248 1277 - cifs_small_buf_release(pSMB); 1249 + /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ 1278 1250 if(resp_buf_type == CIFS_SMALL_BUFFER) 1279 1251 cifs_small_buf_release(iov[0].iov_base); 1280 1252 else if(resp_buf_type == CIFS_LARGE_BUFFER) ··· 1351 1323 since file handle passed in no longer valid */ 1352 1324 return rc; 1353 1325 } 1326 + 1327 + int 1328 + CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, 1329 + const __u16 smb_file_id, const int get_flag, const __u64 len, 1330 + const __u64 lkoffset, const __u16 lock_type, const int waitFlag) 1331 + { 1332 + struct smb_com_transaction2_sfi_req *pSMB = NULL; 1333 + struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 1334 + char *data_offset; 1335 + struct cifs_posix_lock *parm_data; 1336 + int rc = 0; 1337 + int bytes_returned = 0; 1338 + __u16 params, param_offset, offset, byte_count, count; 1339 + 1340 + cFYI(1, ("Posix Lock")); 1341 + rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 1342 + 1343 + if (rc) 1344 + return rc; 1345 + 1346 + pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB; 1347 + 1348 + params = 6; 1349 + pSMB->MaxSetupCount = 0; 1350 + pSMB->Reserved = 0; 1351 + pSMB->Flags = 0; 1352 + pSMB->Timeout = 0; 1353 + pSMB->Reserved2 = 0; 1354 + param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 1355 + offset = param_offset + params; 1356 + 1357 + data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 1358 + 1359 + count = sizeof(struct cifs_posix_lock); 1360 + pSMB->MaxParameterCount = cpu_to_le16(2); 1361 + pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ 1362 + pSMB->SetupCount = 1; 1363 + pSMB->Reserved3 = 0; 1364 + if(get_flag) 1365 + pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 1366 + else 1367 + pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 1368 + byte_count = 3 /* pad */ + params + count; 1369 + pSMB->DataCount = cpu_to_le16(count); 1370 + pSMB->ParameterCount = cpu_to_le16(params); 1371 + pSMB->TotalDataCount = pSMB->DataCount; 1372 + pSMB->TotalParameterCount = pSMB->ParameterCount; 1373 + pSMB->ParameterOffset = cpu_to_le16(param_offset); 1374 + parm_data = (struct cifs_posix_lock *) 1375 + (((char *) &pSMB->hdr.Protocol) + offset); 1376 + 1377 + parm_data->lock_type = cpu_to_le16(lock_type); 1378 + if(waitFlag) 1379 + parm_data->lock_flags = 1; 1380 + parm_data->pid = cpu_to_le32(current->tgid); 1381 + parm_data->start = lkoffset; 1382 + parm_data->length = len; /* normalize negative numbers */ 1383 + 1384 + pSMB->DataOffset = cpu_to_le16(offset); 1385 + pSMB->Fid = smb_file_id; 1386 + pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK); 1387 + pSMB->Reserved4 = 0; 1388 + pSMB->hdr.smb_buf_length += byte_count; 1389 + pSMB->ByteCount = cpu_to_le16(byte_count); 1390 + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1391 + (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1392 + if (rc) { 1393 + cFYI(1, ("Send error in Posix Lock = %d", rc)); 1394 + } 1395 + 1396 + if (pSMB) 1397 + cifs_small_buf_release(pSMB); 1398 + 1399 + /* Note: On -EAGAIN error only caller can retry on handle based calls 1400 + since file handle passed in no longer valid */ 1401 + 1402 + return rc; 1403 + } 1404 + 1354 1405 1355 1406 int 1356 1407 CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id) ··· 2685 2578 cifs_small_buf_release(iov[0].iov_base); 2686 2579 else if(buf_type == CIFS_LARGE_BUFFER) 2687 2580 cifs_buf_release(iov[0].iov_base); 2688 - cifs_small_buf_release(pSMB); 2581 + /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ 2689 2582 return rc; 2690 2583 } 2691 2584 ··· 3061 2954 pSMB->TotalParameterCount = cpu_to_le16(params); 3062 2955 pSMB->ParameterCount = pSMB->TotalParameterCount; 3063 2956 pSMB->ParameterOffset = cpu_to_le16( 3064 - offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes) - 4); 2957 + offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes) 2958 + - 4); 3065 2959 pSMB->DataCount = 0; 3066 2960 pSMB->DataOffset = 0; 3067 2961 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */ ··· 3085 2977 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3086 2978 cifs_stats_inc(&tcon->num_ffirst); 3087 2979 3088 - if (rc) {/* BB add logic to retry regular search if Unix search rejected unexpectedly by server */ 2980 + if (rc) {/* BB add logic to retry regular search if Unix search 2981 + rejected unexpectedly by server */ 3089 2982 /* BB Add code to handle unsupported level rc */ 3090 2983 cFYI(1, ("Error in FindFirst = %d", rc)); 3091 2984 3092 - if (pSMB) 3093 - cifs_buf_release(pSMB); 2985 + cifs_buf_release(pSMB); 3094 2986 3095 2987 /* BB eventually could optimize out free and realloc of buf */ 3096 2988 /* for this case */ ··· 3106 2998 psrch_inf->unicode = FALSE; 3107 2999 3108 3000 psrch_inf->ntwrk_buf_start = (char *)pSMBr; 3001 + psrch_inf->smallBuf = 0; 3109 3002 psrch_inf->srch_entries_start = 3110 3003 (char *) &pSMBr->hdr.Protocol + 3111 3004 le16_to_cpu(pSMBr->t2.DataOffset); ··· 3227 3118 parms = (T2_FNEXT_RSP_PARMS *)response_data; 3228 3119 response_data = (char *)&pSMBr->hdr.Protocol + 3229 3120 le16_to_cpu(pSMBr->t2.DataOffset); 3230 - cifs_buf_release(psrch_inf->ntwrk_buf_start); 3121 + if(psrch_inf->smallBuf) 3122 + cifs_small_buf_release( 3123 + psrch_inf->ntwrk_buf_start); 3124 + else 3125 + cifs_buf_release(psrch_inf->ntwrk_buf_start); 3231 3126 psrch_inf->srch_entries_start = response_data; 3232 3127 psrch_inf->ntwrk_buf_start = (char *)pSMB; 3128 + psrch_inf->smallBuf = 0; 3233 3129 if(parms->EndofSearch) 3234 3130 psrch_inf->endOfSearch = TRUE; 3235 3131 else ··· 3948 3834 3949 3835 cFYI(1, ("In SETFSUnixInfo")); 3950 3836 SETFSUnixRetry: 3837 + /* BB switch to small buf init to save memory */ 3951 3838 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3952 3839 (void **) &pSMBr); 3953 3840 if (rc)
+51 -48
fs/cifs/connect.c
··· 1 1 /* 2 2 * fs/cifs/connect.c 3 3 * 4 - * Copyright (C) International Business Machines Corp., 2002,2005 4 + * Copyright (C) International Business Machines Corp., 2002,2006 5 5 * Author(s): Steve French (sfrench@us.ibm.com) 6 6 * 7 7 * This library is free software; you can redistribute it and/or modify ··· 564 564 565 565 566 566 dump_smb(smb_buffer, length); 567 - if (checkSMB (smb_buffer, smb_buffer->Mid, total_read+4)) { 567 + if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) { 568 568 cifs_dump_mem("Bad SMB: ", smb_buffer, 48); 569 569 continue; 570 570 } ··· 1476 1476 rc = smb_send(*csocket, smb_buf, 0x44, 1477 1477 (struct sockaddr *)psin_server); 1478 1478 kfree(ses_init_buf); 1479 + msleep(1); /* RFC1001 layer in at least one server 1480 + requires very short break before negprot 1481 + presumably because not expecting negprot 1482 + to follow so fast. This is a simple 1483 + solution that works without 1484 + complicating the code and causes no 1485 + significant slowing down on mount 1486 + for everyone else */ 1479 1487 } 1480 1488 /* else the negprot may still work without this 1481 1489 even though malloc failed */ ··· 1928 1920 cifs_sb->tcon = tcon; 1929 1921 tcon->ses = pSesInfo; 1930 1922 1931 - /* do not care if following two calls succeed - informational only */ 1923 + /* do not care if following two calls succeed - informational */ 1932 1924 CIFSSMBQFSDeviceInfo(xid, tcon); 1933 1925 CIFSSMBQFSAttributeInfo(xid, tcon); 1926 + 1934 1927 if (tcon->ses->capabilities & CAP_UNIX) { 1935 1928 if(!CIFSSMBQFSUnixInfo(xid, tcon)) { 1936 - if(!volume_info.no_psx_acl) { 1937 - if(CIFS_UNIX_POSIX_ACL_CAP & 1938 - le64_to_cpu(tcon->fsUnixInfo.Capability)) 1939 - cFYI(1,("server negotiated posix acl support")); 1940 - sb->s_flags |= MS_POSIXACL; 1929 + __u64 cap = 1930 + le64_to_cpu(tcon->fsUnixInfo.Capability); 1931 + cap &= CIFS_UNIX_CAP_MASK; 1932 + if(volume_info.no_psx_acl) 1933 + cap &= ~CIFS_UNIX_POSIX_ACL_CAP; 1934 + else if(CIFS_UNIX_POSIX_ACL_CAP & cap) { 1935 + cFYI(1,("negotiated posix acl support")); 1936 + sb->s_flags |= MS_POSIXACL; 1941 1937 } 1942 1938 1943 - /* Try and negotiate POSIX pathnames if we can. */ 1944 - if (volume_info.posix_paths && (CIFS_UNIX_POSIX_PATHNAMES_CAP & 1945 - le64_to_cpu(tcon->fsUnixInfo.Capability))) { 1946 - if (!CIFSSMBSetFSUnixInfo(xid, tcon, CIFS_UNIX_POSIX_PATHNAMES_CAP)) { 1947 - cFYI(1,("negotiated posix pathnames support")); 1948 - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS; 1949 - } else { 1950 - cFYI(1,("posix pathnames support requested but not supported")); 1951 - } 1939 + if(volume_info.posix_paths == 0) 1940 + cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; 1941 + else if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) { 1942 + cFYI(1,("negotiate posix pathnames")); 1943 + cifs_sb->mnt_cifs_flags |= 1944 + CIFS_MOUNT_POSIX_PATHS; 1945 + } 1946 + 1947 + cFYI(1,("Negotiate caps 0x%x",(int)cap)); 1948 + 1949 + if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { 1950 + cFYI(1,("setting capabilities failed")); 1952 1951 } 1953 1952 } 1954 1953 } ··· 2293 2278 smb_buffer->Mid = GetNextMid(ses->server); 2294 2279 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 2295 2280 pSMB->req.AndXCommand = 0xFF; 2281 + if(ses->server->maxBuf > 64*1024) 2282 + ses->server->maxBuf = (64*1023); 2296 2283 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); 2297 2284 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); 2298 2285 ··· 2542 2525 __u32 negotiate_flags, capabilities; 2543 2526 __u16 count; 2544 2527 2545 - cFYI(1, ("In NTLMSSP sesssetup (negotiate) ")); 2528 + cFYI(1, ("In NTLMSSP sesssetup (negotiate)")); 2546 2529 if(ses == NULL) 2547 2530 return -EINVAL; 2548 2531 domain = ses->domainName; ··· 2592 2575 SecurityBlob->MessageType = NtLmNegotiate; 2593 2576 negotiate_flags = 2594 2577 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM | 2595 - NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | 0x80000000 | 2578 + NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | 2579 + NTLMSSP_NEGOTIATE_56 | 2596 2580 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128; 2597 2581 if(sign_CIFS_PDUs) 2598 2582 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN; ··· 2606 2588 SecurityBlob->WorkstationName.Length = 0; 2607 2589 SecurityBlob->WorkstationName.MaximumLength = 0; 2608 2590 2609 - if (domain == NULL) { 2610 - SecurityBlob->DomainName.Buffer = 0; 2611 - SecurityBlob->DomainName.Length = 0; 2612 - SecurityBlob->DomainName.MaximumLength = 0; 2613 - } else { 2614 - __u16 len; 2615 - negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED; 2616 - strncpy(bcc_ptr, domain, 63); 2617 - len = strnlen(domain, 64); 2618 - SecurityBlob->DomainName.MaximumLength = 2619 - cpu_to_le16(len); 2620 - SecurityBlob->DomainName.Buffer = 2621 - cpu_to_le32((long) &SecurityBlob-> 2622 - DomainString - 2623 - (long) &SecurityBlob->Signature); 2624 - bcc_ptr += len; 2625 - SecurityBlobLength += len; 2626 - SecurityBlob->DomainName.Length = 2627 - cpu_to_le16(len); 2628 - } 2591 + /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent 2592 + along with username on auth request (ie the response to challenge) */ 2593 + SecurityBlob->DomainName.Buffer = 0; 2594 + SecurityBlob->DomainName.Length = 0; 2595 + SecurityBlob->DomainName.MaximumLength = 0; 2629 2596 if (ses->capabilities & CAP_UNICODE) { 2630 2597 if ((long) bcc_ptr % 2) { 2631 2598 *bcc_ptr = 0; ··· 2680 2677 SecurityBlob2->MessageType)); 2681 2678 } else if (ses) { 2682 2679 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */ 2683 - cFYI(1, ("UID = %d ", ses->Suid)); 2680 + cFYI(1, ("UID = %d", ses->Suid)); 2684 2681 if ((pSMBr->resp.hdr.WordCount == 3) 2685 2682 || ((pSMBr->resp.hdr.WordCount == 4) 2686 2683 && (blob_len < ··· 2688 2685 2689 2686 if (pSMBr->resp.hdr.WordCount == 4) { 2690 2687 bcc_ptr += blob_len; 2691 - cFYI(1, 2692 - ("Security Blob Length %d ", 2688 + cFYI(1, ("Security Blob Length %d", 2693 2689 blob_len)); 2694 2690 } 2695 2691 2696 - cFYI(1, ("NTLMSSP Challenge rcvd ")); 2692 + cFYI(1, ("NTLMSSP Challenge rcvd")); 2697 2693 2698 2694 memcpy(ses->server->cryptKey, 2699 2695 SecurityBlob2->Challenge, 2700 2696 CIFS_CRYPTO_KEY_SIZE); 2701 - if(SecurityBlob2->NegotiateFlags & cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2)) 2697 + if(SecurityBlob2->NegotiateFlags & 2698 + cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2)) 2702 2699 *pNTLMv2_flag = TRUE; 2703 2700 2704 2701 if((SecurityBlob2->NegotiateFlags & ··· 2821 2818 bcc_ptr++; 2822 2819 } else 2823 2820 cFYI(1, 2824 - ("Variable field of length %d extends beyond end of smb ", 2821 + ("Variable field of length %d extends beyond end of smb", 2825 2822 len)); 2826 2823 } 2827 2824 } else { ··· 2833 2830 } 2834 2831 } else { 2835 2832 cERROR(1, 2836 - (" Invalid Word count %d: ", 2833 + (" Invalid Word count %d:", 2837 2834 smb_buffer_response->WordCount)); 2838 2835 rc = -EIO; 2839 2836 } ··· 3450 3447 if (extended_security 3451 3448 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) 3452 3449 && (pSesInfo->server->secType == NTLMSSP)) { 3453 - cFYI(1, ("New style sesssetup ")); 3450 + cFYI(1, ("New style sesssetup")); 3454 3451 rc = CIFSSpnegoSessSetup(xid, pSesInfo, 3455 3452 NULL /* security blob */, 3456 3453 0 /* blob length */, ··· 3458 3455 } else if (extended_security 3459 3456 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) 3460 3457 && (pSesInfo->server->secType == RawNTLMSSP)) { 3461 - cFYI(1, ("NTLMSSP sesssetup ")); 3458 + cFYI(1, ("NTLMSSP sesssetup")); 3462 3459 rc = CIFSNTLMSSPNegotiateSessSetup(xid, 3463 3460 pSesInfo, 3464 3461 &ntlmv2_flag,
+3 -4
fs/cifs/dir.c
··· 48 48 struct dentry *temp; 49 49 int namelen = 0; 50 50 char *full_path; 51 - char dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb)); 51 + char dirsep; 52 52 53 53 if(direntry == NULL) 54 54 return NULL; /* not much we can do if dentry is freed and 55 55 we need to reopen the file after it was closed implicitly 56 56 when the server crashed */ 57 57 58 + dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb)); 58 59 cifs_bp_rename_retry: 59 60 for (temp = direntry; !IS_ROOT(temp);) { 60 61 namelen += (1 + temp->d_name.len); ··· 256 255 CIFSSMBClose(xid, pTcon, fileHandle); 257 256 } else if(newinode) { 258 257 pCifsFile = 259 - kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL); 258 + kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL); 260 259 261 260 if(pCifsFile == NULL) 262 261 goto cifs_create_out; 263 - memset((char *)pCifsFile, 0, 264 - sizeof (struct cifsFileInfo)); 265 262 pCifsFile->netfid = fileHandle; 266 263 pCifsFile->pid = current->tgid; 267 264 pCifsFile->pInode = newinode;
+66 -28
fs/cifs/file.c
··· 555 555 if (ptmp) { 556 556 cFYI(1, ("closedir free smb buf in srch struct")); 557 557 pCFileStruct->srch_inf.ntwrk_buf_start = NULL; 558 - cifs_buf_release(ptmp); 558 + if(pCFileStruct->srch_inf.smallBuf) 559 + cifs_small_buf_release(ptmp); 560 + else 561 + cifs_buf_release(ptmp); 559 562 } 560 563 ptmp = pCFileStruct->search_resume_name; 561 564 if (ptmp) { ··· 577 574 int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) 578 575 { 579 576 int rc, xid; 580 - __u32 lockType = LOCKING_ANDX_LARGE_FILES; 581 577 __u32 numLock = 0; 582 578 __u32 numUnlock = 0; 583 579 __u64 length; 584 580 int wait_flag = FALSE; 585 581 struct cifs_sb_info *cifs_sb; 586 582 struct cifsTconInfo *pTcon; 583 + __u16 netfid; 584 + __u8 lockType = LOCKING_ANDX_LARGE_FILES; 587 585 588 586 length = 1 + pfLock->fl_end - pfLock->fl_start; 589 587 rc = -EACCES; ··· 596 592 pfLock->fl_end)); 597 593 598 594 if (pfLock->fl_flags & FL_POSIX) 599 - cFYI(1, ("Posix ")); 595 + cFYI(1, ("Posix")); 600 596 if (pfLock->fl_flags & FL_FLOCK) 601 - cFYI(1, ("Flock ")); 597 + cFYI(1, ("Flock")); 602 598 if (pfLock->fl_flags & FL_SLEEP) { 603 - cFYI(1, ("Blocking lock ")); 599 + cFYI(1, ("Blocking lock")); 604 600 wait_flag = TRUE; 605 601 } 606 602 if (pfLock->fl_flags & FL_ACCESS) ··· 616 612 cFYI(1, ("F_WRLCK ")); 617 613 numLock = 1; 618 614 } else if (pfLock->fl_type == F_UNLCK) { 619 - cFYI(1, ("F_UNLCK ")); 615 + cFYI(1, ("F_UNLCK")); 620 616 numUnlock = 1; 617 + /* Check if unlock includes more than 618 + one lock range */ 621 619 } else if (pfLock->fl_type == F_RDLCK) { 622 - cFYI(1, ("F_RDLCK ")); 620 + cFYI(1, ("F_RDLCK")); 623 621 lockType |= LOCKING_ANDX_SHARED_LOCK; 624 622 numLock = 1; 625 623 } else if (pfLock->fl_type == F_EXLCK) { 626 - cFYI(1, ("F_EXLCK ")); 624 + cFYI(1, ("F_EXLCK")); 627 625 numLock = 1; 628 626 } else if (pfLock->fl_type == F_SHLCK) { 629 - cFYI(1, ("F_SHLCK ")); 627 + cFYI(1, ("F_SHLCK")); 630 628 lockType |= LOCKING_ANDX_SHARED_LOCK; 631 629 numLock = 1; 632 630 } else 633 - cFYI(1, ("Unknown type of lock ")); 631 + cFYI(1, ("Unknown type of lock")); 634 632 635 633 cifs_sb = CIFS_SB(file->f_dentry->d_sb); 636 634 pTcon = cifs_sb->tcon; ··· 641 635 FreeXid(xid); 642 636 return -EBADF; 643 637 } 638 + netfid = ((struct cifsFileInfo *)file->private_data)->netfid; 644 639 640 + 641 + /* BB add code here to normalize offset and length to 642 + account for negative length which we can not accept over the 643 + wire */ 645 644 if (IS_GETLK(cmd)) { 646 - rc = CIFSSMBLock(xid, pTcon, 647 - ((struct cifsFileInfo *)file-> 648 - private_data)->netfid, 649 - length, 650 - pfLock->fl_start, 0, 1, lockType, 651 - 0 /* wait flag */ ); 645 + if(experimEnabled && 646 + (cifs_sb->tcon->ses->capabilities & CAP_UNIX) && 647 + (CIFS_UNIX_FCNTL_CAP & 648 + le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability))) { 649 + int posix_lock_type; 650 + if(lockType & LOCKING_ANDX_SHARED_LOCK) 651 + posix_lock_type = CIFS_RDLCK; 652 + else 653 + posix_lock_type = CIFS_WRLCK; 654 + rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */, 655 + length, pfLock->fl_start, 656 + posix_lock_type, wait_flag); 657 + FreeXid(xid); 658 + return rc; 659 + } 660 + 661 + /* BB we could chain these into one lock request BB */ 662 + rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, 663 + 0, 1, lockType, 0 /* wait flag */ ); 652 664 if (rc == 0) { 653 - rc = CIFSSMBLock(xid, pTcon, 654 - ((struct cifsFileInfo *) file-> 655 - private_data)->netfid, 656 - length, 665 + rc = CIFSSMBLock(xid, pTcon, netfid, length, 657 666 pfLock->fl_start, 1 /* numUnlock */ , 658 667 0 /* numLock */ , lockType, 659 668 0 /* wait flag */ ); 660 669 pfLock->fl_type = F_UNLCK; 661 670 if (rc != 0) 662 671 cERROR(1, ("Error unlocking previously locked " 663 - "range %d during test of lock ", 664 - rc)); 672 + "range %d during test of lock", rc)); 665 673 rc = 0; 666 674 667 675 } else { ··· 687 667 FreeXid(xid); 688 668 return rc; 689 669 } 690 - 691 - rc = CIFSSMBLock(xid, pTcon, 692 - ((struct cifsFileInfo *) file->private_data)-> 693 - netfid, length, 694 - pfLock->fl_start, numUnlock, numLock, lockType, 695 - wait_flag); 670 + if (experimEnabled && 671 + (cifs_sb->tcon->ses->capabilities & CAP_UNIX) && 672 + (CIFS_UNIX_FCNTL_CAP & 673 + le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability))) { 674 + int posix_lock_type; 675 + if(lockType & LOCKING_ANDX_SHARED_LOCK) 676 + posix_lock_type = CIFS_RDLCK; 677 + else 678 + posix_lock_type = CIFS_WRLCK; 679 + 680 + if(numUnlock == 1) 681 + posix_lock_type = CIFS_UNLCK; 682 + else if(numLock == 0) { 683 + /* if no lock or unlock then nothing 684 + to do since we do not know what it is */ 685 + FreeXid(xid); 686 + return -EOPNOTSUPP; 687 + } 688 + rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */, 689 + length, pfLock->fl_start, 690 + posix_lock_type, wait_flag); 691 + } else 692 + rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, 693 + numUnlock, numLock, lockType, wait_flag); 696 694 if (pfLock->fl_flags & FL_POSIX) 697 695 posix_lock_file_wait(file, pfLock); 698 696 FreeXid(xid);
+13 -9
fs/cifs/inode.c
··· 565 565 struct cifsInodeInfo *cifsInode; 566 566 FILE_BASIC_INFO *pinfo_buf; 567 567 568 - cFYI(1, ("cifs_unlink, inode = 0x%p with ", inode)); 568 + cFYI(1, ("cifs_unlink, inode = 0x%p", inode)); 569 569 570 570 xid = GetXid(); 571 571 572 - cifs_sb = CIFS_SB(inode->i_sb); 572 + if(inode) 573 + cifs_sb = CIFS_SB(inode->i_sb); 574 + else 575 + cifs_sb = CIFS_SB(direntry->d_sb); 573 576 pTcon = cifs_sb->tcon; 574 577 575 578 /* Unlink can be called from rename so we can not grab the sem here ··· 612 609 } 613 610 } else if (rc == -EACCES) { 614 611 /* try only if r/o attribute set in local lookup data? */ 615 - pinfo_buf = kmalloc(sizeof(FILE_BASIC_INFO), GFP_KERNEL); 612 + pinfo_buf = kzalloc(sizeof(FILE_BASIC_INFO), GFP_KERNEL); 616 613 if (pinfo_buf) { 617 - memset(pinfo_buf, 0, sizeof(FILE_BASIC_INFO)); 618 614 /* ATTRS set to normal clears r/o bit */ 619 615 pinfo_buf->Attributes = cpu_to_le32(ATTR_NORMAL); 620 616 if (!(pTcon->ses->flags & CIFS_SES_NT4)) ··· 695 693 when needed */ 696 694 direntry->d_inode->i_ctime = current_fs_time(inode->i_sb); 697 695 } 698 - inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); 699 - cifsInode = CIFS_I(inode); 700 - cifsInode->time = 0; /* force revalidate of dir as well */ 696 + if(inode) { 697 + inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); 698 + cifsInode = CIFS_I(inode); 699 + cifsInode->time = 0; /* force revalidate of dir as well */ 700 + } 701 701 702 702 kfree(full_path); 703 703 FreeXid(xid); ··· 1171 1167 nfid, npid, FALSE); 1172 1168 atomic_dec(&open_file->wrtPending); 1173 1169 cFYI(1,("SetFSize for attrs rc = %d", rc)); 1174 - if(rc == -EINVAL) { 1170 + if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { 1175 1171 int bytes_written; 1176 1172 rc = CIFSSMBWrite(xid, pTcon, 1177 1173 nfid, 0, attrs->ia_size, ··· 1193 1189 cifs_sb->mnt_cifs_flags & 1194 1190 CIFS_MOUNT_MAP_SPECIAL_CHR); 1195 1191 cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc)); 1196 - if(rc == -EINVAL) { 1192 + if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { 1197 1193 __u16 netfid; 1198 1194 int oplock = FALSE; 1199 1195
+1 -1
fs/cifs/link.c
··· 67 67 cifs_sb_target->local_nls, 68 68 cifs_sb_target->mnt_cifs_flags & 69 69 CIFS_MOUNT_MAP_SPECIAL_CHR); 70 - if(rc == -EIO) 70 + if((rc == -EIO) || (rc == -EINVAL)) 71 71 rc = -EOPNOTSUPP; 72 72 } 73 73
+26 -20
fs/cifs/misc.c
··· 72 72 struct cifsSesInfo *ret_buf; 73 73 74 74 ret_buf = 75 - (struct cifsSesInfo *) kmalloc(sizeof (struct cifsSesInfo), 75 + (struct cifsSesInfo *) kzalloc(sizeof (struct cifsSesInfo), 76 76 GFP_KERNEL); 77 77 if (ret_buf) { 78 - memset(ret_buf, 0, sizeof (struct cifsSesInfo)); 79 78 write_lock(&GlobalSMBSeslock); 80 79 atomic_inc(&sesInfoAllocCount); 81 80 ret_buf->status = CifsNew; ··· 109 110 { 110 111 struct cifsTconInfo *ret_buf; 111 112 ret_buf = 112 - (struct cifsTconInfo *) kmalloc(sizeof (struct cifsTconInfo), 113 + (struct cifsTconInfo *) kzalloc(sizeof (struct cifsTconInfo), 113 114 GFP_KERNEL); 114 115 if (ret_buf) { 115 - memset(ret_buf, 0, sizeof (struct cifsTconInfo)); 116 116 write_lock(&GlobalSMBSeslock); 117 117 atomic_inc(&tconInfoAllocCount); 118 118 list_add(&ret_buf->cifsConnectionList, ··· 421 423 { 422 424 __u32 len = smb->smb_buf_length; 423 425 __u32 clc_len; /* calculated length */ 424 - cFYI(0, 425 - ("Entering checkSMB with Length: %x, smb_buf_length: %x", 426 - length, len)); 426 + cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len)); 427 427 if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) || 428 428 (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) { 429 429 if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) { ··· 429 433 sizeof (struct smb_hdr) - 1) 430 434 && (smb->Status.CifsError != 0)) { 431 435 smb->WordCount = 0; 432 - return 0; /* some error cases do not return wct and bcc */ 436 + /* some error cases do not return wct and bcc */ 437 + return 0; 433 438 } else { 434 439 cERROR(1, ("Length less than smb header size")); 435 440 } 436 - 437 441 } 438 442 if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) 439 - cERROR(1, 440 - ("smb_buf_length greater than MaxBufSize")); 441 - cERROR(1, 442 - ("bad smb detected. Illegal length. mid=%d", 443 - smb->Mid)); 443 + cERROR(1, ("smb length greater than MaxBufSize, mid=%d", 444 + smb->Mid)); 444 445 return 1; 445 446 } 446 447 447 448 if (checkSMBhdr(smb, mid)) 448 449 return 1; 449 450 clc_len = smbCalcSize_LE(smb); 450 - if ((4 + len != clc_len) 451 - || (4 + len != (unsigned int)length)) { 452 - cERROR(1, ("Calculated size 0x%x vs actual length 0x%x", 453 - clc_len, 4 + len)); 454 - cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid)); 451 + 452 + if(4 + len != (unsigned int)length) { 453 + cERROR(1, ("Length read does not match RFC1001 length %d",len)); 454 + return 1; 455 + } 456 + 457 + if (4 + len != clc_len) { 458 + /* check if bcc wrapped around for large read responses */ 459 + if((len > 64 * 1024) && (len > clc_len)) { 460 + /* check if lengths match mod 64K */ 461 + if(((4 + len) & 0xFFFF) == (clc_len & 0xFFFF)) 462 + return 0; /* bcc wrapped */ 463 + } 464 + cFYI(1, ("Calculated size %d vs length %d mismatch for mid %d", 465 + clc_len, 4 + len, smb->Mid)); 455 466 /* Windows XP can return a few bytes too much, presumably 456 467 an illegal pad, at the end of byte range lock responses 457 468 so we allow for that three byte pad, as long as actual ··· 472 469 wct and bcc to minimum size and drop the t2 parms and data */ 473 470 if((4+len > clc_len) && (len <= clc_len + 512)) 474 471 return 0; 475 - else 472 + else { 473 + cERROR(1, ("RFC1001 size %d bigger than SMB for Mid=%d", 474 + len, smb->Mid)); 476 475 return 1; 476 + } 477 477 } 478 478 return 0; 479 479 }
+129
fs/cifs/ntlmssp.c
··· 1 + /* 2 + * fs/cifs/ntlmssp.h 3 + * 4 + * Copyright (c) International Business Machines Corp., 2006 5 + * Author(s): Steve French (sfrench@us.ibm.com) 6 + * 7 + * This library is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU Lesser General Public License as published 9 + * by the Free Software Foundation; either version 2.1 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This library is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 15 + * the GNU Lesser General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU Lesser General Public License 18 + * along with this library; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + */ 21 + 22 + #include "cifspdu.h" 23 + #include "cifsglob.h" 24 + #include "cifsproto.h" 25 + #include "cifs_unicode.h" 26 + #include "cifs_debug.h" 27 + #include "ntlmssp.h" 28 + #include "nterr.h" 29 + 30 + #ifdef CONFIG_CIFS_EXPERIMENTAL 31 + static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) 32 + { 33 + __u32 capabilities = 0; 34 + 35 + /* init fields common to all four types of SessSetup */ 36 + /* note that header is initialized to zero in header_assemble */ 37 + pSMB->req.AndXCommand = 0xFF; 38 + pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); 39 + pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); 40 + 41 + /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */ 42 + 43 + /* BB verify whether signing required on neg or just on auth frame 44 + (and NTLM case) */ 45 + 46 + capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | 47 + CAP_LARGE_WRITE_X | CAP_LARGE_READ_X; 48 + 49 + if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 50 + pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 51 + 52 + if (ses->capabilities & CAP_UNICODE) { 53 + pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE; 54 + capabilities |= CAP_UNICODE; 55 + } 56 + if (ses->capabilities & CAP_STATUS32) { 57 + pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS; 58 + capabilities |= CAP_STATUS32; 59 + } 60 + if (ses->capabilities & CAP_DFS) { 61 + pSMB->req.hdr.Flags2 |= SMBFLG2_DFS; 62 + capabilities |= CAP_DFS; 63 + } 64 + 65 + /* BB check whether to init vcnum BB */ 66 + return capabilities; 67 + } 68 + int 69 + CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, const int type, 70 + int * pNTLMv2_flg, const struct nls_table *nls_cp) 71 + { 72 + int rc = 0; 73 + int wct; 74 + struct smb_hdr *smb_buffer; 75 + char *bcc_ptr; 76 + SESSION_SETUP_ANDX *pSMB; 77 + __u32 capabilities; 78 + 79 + if(ses == NULL) 80 + return -EINVAL; 81 + 82 + cFYI(1,("SStp type: %d",type)); 83 + if(type < CIFS_NTLM) { 84 + #ifndef CONFIG_CIFS_WEAK_PW_HASH 85 + /* LANMAN and plaintext are less secure and off by default. 86 + So we make this explicitly be turned on in kconfig (in the 87 + build) and turned on at runtime (changed from the default) 88 + in proc/fs/cifs or via mount parm. Unfortunately this is 89 + needed for old Win (e.g. Win95), some obscure NAS and OS/2 */ 90 + return -EOPNOTSUPP; 91 + #endif 92 + wct = 10; /* lanman 2 style sessionsetup */ 93 + } else if(type < CIFS_NTLMSSP_NEG) 94 + wct = 13; /* old style NTLM sessionsetup */ 95 + else /* same size for negotiate or auth, NTLMSSP or extended security */ 96 + wct = 12; 97 + 98 + rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses, 99 + (void **)&smb_buffer); 100 + if(rc) 101 + return rc; 102 + 103 + pSMB = (SESSION_SETUP_ANDX *)smb_buffer; 104 + 105 + capabilities = cifs_ssetup_hdr(ses, pSMB); 106 + bcc_ptr = pByteArea(smb_buffer); 107 + if(type > CIFS_NTLM) { 108 + pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 109 + capabilities |= CAP_EXTENDED_SECURITY; 110 + pSMB->req.Capabilities = cpu_to_le32(capabilities); 111 + /* BB set password lengths */ 112 + } else if(type < CIFS_NTLM) /* lanman */ { 113 + /* no capabilities flags in old lanman negotiation */ 114 + /* pSMB->old_req.PasswordLength = */ /* BB fixme BB */ 115 + } else /* type CIFS_NTLM */ { 116 + pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities); 117 + pSMB->req_no_secext.CaseInsensitivePasswordLength = 118 + cpu_to_le16(CIFS_SESSION_KEY_SIZE); 119 + pSMB->req_no_secext.CaseSensitivePasswordLength = 120 + cpu_to_le16(CIFS_SESSION_KEY_SIZE); 121 + } 122 + 123 + 124 + /* rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buf_type, 0); */ 125 + /* SMB request buf freed in SendReceive2 */ 126 + 127 + return rc; 128 + } 129 + #endif /* CONFIG_CIFS_EXPERIMENTAL */
+1 -1
fs/cifs/ntlmssp.h
··· 1 1 /* 2 2 * fs/cifs/ntlmssp.h 3 3 * 4 - * Copyright (c) International Business Machines Corp., 2002 4 + * Copyright (c) International Business Machines Corp., 2002,2006 5 5 * Author(s): Steve French (sfrench@us.ibm.com) 6 6 * 7 7 * This library is free software; you can redistribute it and/or modify
+6 -1
fs/cifs/readdir.c
··· 604 604 cifsFile->search_resume_name = NULL; 605 605 if(cifsFile->srch_inf.ntwrk_buf_start) { 606 606 cFYI(1,("freeing SMB ff cache buf on search rewind")); 607 - cifs_buf_release(cifsFile->srch_inf.ntwrk_buf_start); 607 + if(cifsFile->srch_inf.smallBuf) 608 + cifs_small_buf_release(cifsFile->srch_inf. 609 + ntwrk_buf_start); 610 + else 611 + cifs_buf_release(cifsFile->srch_inf. 612 + ntwrk_buf_start); 608 613 } 609 614 rc = initiate_cifs_search(xid,file); 610 615 if(rc) {
+14 -8
fs/cifs/transport.c
··· 309 309 310 310 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */ 311 311 312 - if (ses == NULL) { 313 - cERROR(1,("Null smb session")); 314 - return -EIO; 315 - } 316 - if(ses->server == NULL) { 317 - cERROR(1,("Null tcp session")); 312 + if ((ses == NULL) || (ses->server == NULL)) { 313 + cifs_small_buf_release(in_buf); 314 + cERROR(1,("Null session")); 318 315 return -EIO; 319 316 } 320 317 321 - if(ses->server->tcpStatus == CifsExiting) 318 + if(ses->server->tcpStatus == CifsExiting) { 319 + cifs_small_buf_release(in_buf); 322 320 return -ENOENT; 321 + } 323 322 324 323 /* Ensure that we do not send more than 50 overlapping requests 325 324 to the same server. We may make this configurable later or ··· 345 346 } else { 346 347 if(ses->server->tcpStatus == CifsExiting) { 347 348 spin_unlock(&GlobalMid_Lock); 349 + cifs_small_buf_release(in_buf); 348 350 return -ENOENT; 349 351 } 350 352 ··· 385 385 midQ = AllocMidQEntry(in_buf, ses); 386 386 if (midQ == NULL) { 387 387 up(&ses->server->tcpSem); 388 + cifs_small_buf_release(in_buf); 388 389 /* If not lock req, update # of requests on wire to server */ 389 390 if(long_op < 3) { 390 391 atomic_dec(&ses->server->inFlight); ··· 409 408 if(rc < 0) { 410 409 DeleteMidQEntry(midQ); 411 410 up(&ses->server->tcpSem); 411 + cifs_small_buf_release(in_buf); 412 412 /* If not lock req, update # of requests on wire to server */ 413 413 if(long_op < 3) { 414 414 atomic_dec(&ses->server->inFlight); 415 415 wake_up(&ses->server->request_q); 416 416 } 417 417 return rc; 418 - } else 418 + } else { 419 419 up(&ses->server->tcpSem); 420 + cifs_small_buf_release(in_buf); 421 + } 422 + 420 423 if (long_op == -1) 421 424 goto cifs_no_response_exit2; 422 425 else if (long_op == 2) /* writes past end of file can take loong time */ ··· 548 543 549 544 out_unlock2: 550 545 up(&ses->server->tcpSem); 546 + cifs_small_buf_release(in_buf); 551 547 /* If not lock req, update # of requests on wire to server */ 552 548 if(long_op < 3) { 553 549 atomic_dec(&ses->server->inFlight);