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

* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
Eliminate sparse warning - bad constant expression
cifs: check for NULL session password
missing changes during ntlmv2/ntlmssp auth and sign
[CIFS] Fix ntlmv2 auth with ntlmssp
cifs: correction of unicode header files
cifs: fix NULL pointer dereference in cifs_find_smb_ses
cifs: consolidate error handling in several functions
cifs: clean up error handling in cifs_mknod

+624 -281
+2
fs/cifs/Kconfig
··· 2 tristate "CIFS support (advanced network filesystem, SMBFS successor)" 3 depends on INET 4 select NLS 5 help 6 This is the client VFS module for the Common Internet File System 7 (CIFS) protocol which is the successor to the Server Message Block
··· 2 tristate "CIFS support (advanced network filesystem, SMBFS successor)" 3 depends on INET 4 select NLS 5 + select CRYPTO_MD5 6 + select CRYPTO_ARC4 7 help 8 This is the client VFS module for the Common Internet File System 9 (CIFS) protocol which is the successor to the Server Message Block
+3 -3
fs/cifs/asn1.c
··· 597 if (compare_oid(oid, oidlen, MSKRB5_OID, 598 MSKRB5_OID_LEN)) 599 server->sec_mskerberos = true; 600 - else if (compare_oid(oid, oidlen, KRB5U2U_OID, 601 KRB5U2U_OID_LEN)) 602 server->sec_kerberosu2u = true; 603 - else if (compare_oid(oid, oidlen, KRB5_OID, 604 KRB5_OID_LEN)) 605 server->sec_kerberos = true; 606 - else if (compare_oid(oid, oidlen, NTLMSSP_OID, 607 NTLMSSP_OID_LEN)) 608 server->sec_ntlmssp = true; 609
··· 597 if (compare_oid(oid, oidlen, MSKRB5_OID, 598 MSKRB5_OID_LEN)) 599 server->sec_mskerberos = true; 600 + if (compare_oid(oid, oidlen, KRB5U2U_OID, 601 KRB5U2U_OID_LEN)) 602 server->sec_kerberosu2u = true; 603 + if (compare_oid(oid, oidlen, KRB5_OID, 604 KRB5_OID_LEN)) 605 server->sec_kerberos = true; 606 + if (compare_oid(oid, oidlen, NTLMSSP_OID, 607 NTLMSSP_OID_LEN)) 608 server->sec_ntlmssp = true; 609
+11 -7
fs/cifs/cifs_unicode.h
··· 30 * This is a compressed table of upper and lower case conversion. 31 * 32 */ 33 34 #include <asm/byteorder.h> 35 #include <linux/types.h> ··· 69 #endif /* UNIUPR_NOUPPER */ 70 71 #ifndef UNIUPR_NOLOWER 72 - extern signed char UniLowerTable[512]; 73 - extern struct UniCaseRange UniLowerRange[]; 74 #endif /* UNIUPR_NOLOWER */ 75 76 #ifdef __KERNEL__ ··· 339 * UniTolower: Convert a unicode character to lower case 340 */ 341 static inline wchar_t 342 - UniTolower(wchar_t uc) 343 { 344 - register struct UniCaseRange *rp; 345 346 - if (uc < sizeof(UniLowerTable)) { 347 /* Latin characters */ 348 - return uc + UniLowerTable[uc]; /* Use base tables */ 349 } else { 350 - rp = UniLowerRange; /* Use range tables */ 351 while (rp->start) { 352 if (uc < rp->start) /* Before start of range */ 353 return uc; /* Uppercase = input */ ··· 376 } 377 378 #endif
··· 30 * This is a compressed table of upper and lower case conversion. 31 * 32 */ 33 + #ifndef _CIFS_UNICODE_H 34 + #define _CIFS_UNICODE_H 35 36 #include <asm/byteorder.h> 37 #include <linux/types.h> ··· 67 #endif /* UNIUPR_NOUPPER */ 68 69 #ifndef UNIUPR_NOLOWER 70 + extern signed char CifsUniLowerTable[512]; 71 + extern const struct UniCaseRange CifsUniLowerRange[]; 72 #endif /* UNIUPR_NOLOWER */ 73 74 #ifdef __KERNEL__ ··· 337 * UniTolower: Convert a unicode character to lower case 338 */ 339 static inline wchar_t 340 + UniTolower(register wchar_t uc) 341 { 342 + register const struct UniCaseRange *rp; 343 344 + if (uc < sizeof(CifsUniLowerTable)) { 345 /* Latin characters */ 346 + return uc + CifsUniLowerTable[uc]; /* Use base tables */ 347 } else { 348 + rp = CifsUniLowerRange; /* Use range tables */ 349 while (rp->start) { 350 if (uc < rp->start) /* Before start of range */ 351 return uc; /* Uppercase = input */ ··· 374 } 375 376 #endif 377 + 378 + #endif /* _CIFS_UNICODE_H */
+8 -8
fs/cifs/cifs_uniupr.h
··· 140 /* 141 * Latin lower case 142 */ 143 - static signed char CifsUniLowerTable[512] = { 144 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 000-00f */ 145 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 010-01f */ 146 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 020-02f */ ··· 242 /* 243 * Lower Case Range 244 */ 245 - static const struct UniCaseRange CifsUniLowerRange[] = { 246 - 0x0380, 0x03ab, UniCaseRangeL0380, 247 - 0x0400, 0x042f, UniCaseRangeL0400, 248 - 0x0490, 0x04cb, UniCaseRangeL0490, 249 - 0x1e00, 0x1ff7, UniCaseRangeL1e00, 250 - 0xff20, 0xff3a, UniCaseRangeLff20, 251 - 0, 0, 0 252 }; 253 #endif
··· 140 /* 141 * Latin lower case 142 */ 143 + signed char CifsUniLowerTable[512] = { 144 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 000-00f */ 145 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 010-01f */ 146 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 020-02f */ ··· 242 /* 243 * Lower Case Range 244 */ 245 + const struct UniCaseRange CifsUniLowerRange[] = { 246 + {0x0380, 0x03ab, UniCaseRangeL0380}, 247 + {0x0400, 0x042f, UniCaseRangeL0400}, 248 + {0x0490, 0x04cb, UniCaseRangeL0490}, 249 + {0x1e00, 0x1ff7, UniCaseRangeL1e00}, 250 + {0xff20, 0xff3a, UniCaseRangeLff20}, 251 + {0} 252 }; 253 #endif
+349 -126
fs/cifs/cifsencrypt.c
··· 27 #include "md5.h" 28 #include "cifs_unicode.h" 29 #include "cifsproto.h" 30 #include <linux/ctype.h> 31 #include <linux/random.h> 32 ··· 43 unsigned char *p24); 44 45 static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, 46 - const struct mac_key *key, char *signature) 47 { 48 - struct MD5Context context; 49 50 - if ((cifs_pdu == NULL) || (signature == NULL) || (key == NULL)) 51 return -EINVAL; 52 53 - cifs_MD5_init(&context); 54 - cifs_MD5_update(&context, (char *)&key->data, key->len); 55 - cifs_MD5_update(&context, cifs_pdu->Protocol, cifs_pdu->smb_buf_length); 56 57 - cifs_MD5_final(signature, &context); 58 - return 0; 59 } 60 61 int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, 62 __u32 *pexpected_response_sequence_number) ··· 101 server->sequence_number++; 102 spin_unlock(&GlobalMid_Lock); 103 104 - rc = cifs_calculate_signature(cifs_pdu, &server->mac_signing_key, 105 - smb_signature); 106 if (rc) 107 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 108 else ··· 111 } 112 113 static int cifs_calc_signature2(const struct kvec *iov, int n_vec, 114 - const struct mac_key *key, char *signature) 115 { 116 - struct MD5Context context; 117 int i; 118 119 - if ((iov == NULL) || (signature == NULL) || (key == NULL)) 120 return -EINVAL; 121 122 - cifs_MD5_init(&context); 123 - cifs_MD5_update(&context, (char *)&key->data, key->len); 124 for (i = 0; i < n_vec; i++) { 125 if (iov[i].iov_len == 0) 126 continue; 127 if (iov[i].iov_base == NULL) { 128 - cERROR(1, "null iovec entry"); 129 return -EIO; 130 } 131 /* The first entry includes a length field (which does not get ··· 151 if (i == 0) { 152 if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ 153 break; /* nothing to sign or corrupt header */ 154 - cifs_MD5_update(&context, iov[0].iov_base+4, 155 - iov[0].iov_len-4); 156 } else 157 - cifs_MD5_update(&context, iov[i].iov_base, iov[i].iov_len); 158 } 159 160 - cifs_MD5_final(signature, &context); 161 162 - return 0; 163 } 164 - 165 166 int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, 167 __u32 *pexpected_response_sequence_number) ··· 185 server->sequence_number++; 186 spin_unlock(&GlobalMid_Lock); 187 188 - rc = cifs_calc_signature2(iov, n_vec, &server->mac_signing_key, 189 - smb_signature); 190 if (rc) 191 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 192 else ··· 195 } 196 197 int cifs_verify_signature(struct smb_hdr *cifs_pdu, 198 - const struct mac_key *mac_key, 199 __u32 expected_sequence_number) 200 { 201 - unsigned int rc; 202 char server_response_sig[8]; 203 char what_we_think_sig_should_be[20]; 204 205 - if ((cifs_pdu == NULL) || (mac_key == NULL)) 206 return -EINVAL; 207 208 if (cifs_pdu->Command == SMB_COM_NEGOTIATE) ··· 231 cpu_to_le32(expected_sequence_number); 232 cifs_pdu->Signature.Sequence.Reserved = 0; 233 234 - rc = cifs_calculate_signature(cifs_pdu, mac_key, 235 what_we_think_sig_should_be); 236 237 if (rc) ··· 248 } 249 250 /* We fill in key by putting in 40 byte array which was allocated by caller */ 251 - int cifs_calculate_mac_key(struct mac_key *key, const char *rn, 252 const char *password) 253 { 254 char temp_key[16]; ··· 259 mdfour(key->data.ntlm, temp_key, 16); 260 memcpy(key->data.ntlm+16, rn, CIFS_SESS_KEY_SIZE); 261 key->len = 40; 262 - return 0; 263 - } 264 - 265 - int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *ses, 266 - const struct nls_table *nls_info) 267 - { 268 - char temp_hash[16]; 269 - struct HMACMD5Context ctx; 270 - char *ucase_buf; 271 - __le16 *unicode_buf; 272 - unsigned int i, user_name_len, dom_name_len; 273 - 274 - if (ses == NULL) 275 - return -EINVAL; 276 - 277 - E_md4hash(ses->password, temp_hash); 278 - 279 - hmac_md5_init_limK_to_64(temp_hash, 16, &ctx); 280 - user_name_len = strlen(ses->userName); 281 - if (user_name_len > MAX_USERNAME_SIZE) 282 - return -EINVAL; 283 - if (ses->domainName == NULL) 284 - return -EINVAL; /* BB should we use CIFS_LINUX_DOM */ 285 - dom_name_len = strlen(ses->domainName); 286 - if (dom_name_len > MAX_USERNAME_SIZE) 287 - return -EINVAL; 288 - 289 - ucase_buf = kmalloc((MAX_USERNAME_SIZE+1), GFP_KERNEL); 290 - if (ucase_buf == NULL) 291 - return -ENOMEM; 292 - unicode_buf = kmalloc((MAX_USERNAME_SIZE+1)*4, GFP_KERNEL); 293 - if (unicode_buf == NULL) { 294 - kfree(ucase_buf); 295 - return -ENOMEM; 296 - } 297 - 298 - for (i = 0; i < user_name_len; i++) 299 - ucase_buf[i] = nls_info->charset2upper[(int)ses->userName[i]]; 300 - ucase_buf[i] = 0; 301 - user_name_len = cifs_strtoUCS(unicode_buf, ucase_buf, 302 - MAX_USERNAME_SIZE*2, nls_info); 303 - unicode_buf[user_name_len] = 0; 304 - user_name_len++; 305 - 306 - for (i = 0; i < dom_name_len; i++) 307 - ucase_buf[i] = nls_info->charset2upper[(int)ses->domainName[i]]; 308 - ucase_buf[i] = 0; 309 - dom_name_len = cifs_strtoUCS(unicode_buf+user_name_len, ucase_buf, 310 - MAX_USERNAME_SIZE*2, nls_info); 311 - 312 - unicode_buf[user_name_len + dom_name_len] = 0; 313 - hmac_md5_update((const unsigned char *) unicode_buf, 314 - (user_name_len+dom_name_len)*2, &ctx); 315 - 316 - hmac_md5_final(ses->server->ntlmv2_hash, &ctx); 317 - kfree(ucase_buf); 318 - kfree(unicode_buf); 319 return 0; 320 } 321 ··· 306 { 307 int rc = 0; 308 int len; 309 - char nt_hash[16]; 310 - struct HMACMD5Context *pctxt; 311 wchar_t *user; 312 wchar_t *domain; 313 314 - pctxt = kmalloc(sizeof(struct HMACMD5Context), GFP_KERNEL); 315 - 316 - if (pctxt == NULL) 317 - return -ENOMEM; 318 319 /* calculate md4 hash of password */ 320 E_md4hash(ses->password, nt_hash); 321 322 - /* convert Domainname to unicode and uppercase */ 323 - hmac_md5_init_limK_to_64(nt_hash, 16, pctxt); 324 325 /* convert ses->userName to unicode and uppercase */ 326 len = strlen(ses->userName); 327 user = kmalloc(2 + (len * 2), GFP_KERNEL); 328 - if (user == NULL) 329 goto calc_exit_2; 330 len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp); 331 UniStrupr(user); 332 - hmac_md5_update((char *)user, 2*len, pctxt); 333 334 /* convert ses->domainName to unicode and uppercase */ 335 if (ses->domainName) { 336 len = strlen(ses->domainName); 337 338 domain = kmalloc(2 + (len * 2), GFP_KERNEL); 339 - if (domain == NULL) 340 goto calc_exit_1; 341 len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len, 342 nls_cp); 343 /* the following line was removed since it didn't work well ··· 359 Maybe converting the domain name earlier makes sense */ 360 /* UniStrupr(domain); */ 361 362 - hmac_md5_update((char *)domain, 2*len, pctxt); 363 364 kfree(domain); 365 } 366 calc_exit_1: 367 kfree(user); 368 calc_exit_2: 369 /* BB FIXME what about bytes 24 through 40 of the signing key? 370 compare with the NTLM example */ 371 - hmac_md5_final(ses->server->ntlmv2_hash, pctxt); 372 373 - kfree(pctxt); 374 return rc; 375 } 376 377 - void setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf, 378 - const struct nls_table *nls_cp) 379 { 380 int rc; 381 struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf; 382 - struct HMACMD5Context context; 383 384 buf->blob_signature = cpu_to_le32(0x00000101); 385 buf->reserved = 0; 386 buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 387 get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); 388 buf->reserved2 = 0; 389 - buf->names[0].type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE); 390 - buf->names[0].length = 0; 391 - buf->names[1].type = 0; 392 - buf->names[1].length = 0; 393 394 /* calculate buf->ntlmv2_hash */ 395 rc = calc_ntlmv2_hash(ses, nls_cp); 396 - if (rc) 397 cERROR(1, "could not get v2 hash rc %d", rc); 398 - CalcNTLMv2_response(ses, resp_buf); 399 400 - /* now calculate the MAC key for NTLMv2 */ 401 - hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context); 402 - hmac_md5_update(resp_buf, 16, &context); 403 - hmac_md5_final(ses->server->mac_signing_key.data.ntlmv2.key, &context); 404 405 - memcpy(&ses->server->mac_signing_key.data.ntlmv2.resp, resp_buf, 406 - sizeof(struct ntlmv2_resp)); 407 - ses->server->mac_signing_key.len = 16 + sizeof(struct ntlmv2_resp); 408 } 409 410 - void CalcNTLMv2_response(const struct cifsSesInfo *ses, 411 - char *v2_session_response) 412 { 413 - struct HMACMD5Context context; 414 - /* rest of v2 struct already generated */ 415 - memcpy(v2_session_response + 8, ses->server->cryptKey, 8); 416 - hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context); 417 418 - hmac_md5_update(v2_session_response+8, 419 - sizeof(struct ntlmv2_resp) - 8, &context); 420 421 - hmac_md5_final(v2_session_response, &context); 422 - /* cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */ 423 }
··· 27 #include "md5.h" 28 #include "cifs_unicode.h" 29 #include "cifsproto.h" 30 + #include "ntlmssp.h" 31 #include <linux/ctype.h> 32 #include <linux/random.h> 33 ··· 42 unsigned char *p24); 43 44 static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, 45 + struct TCP_Server_Info *server, char *signature) 46 { 47 + int rc; 48 49 + if (cifs_pdu == NULL || server == NULL || signature == NULL) 50 return -EINVAL; 51 52 + if (!server->ntlmssp.sdescmd5) { 53 + cERROR(1, 54 + "cifs_calculate_signature: can't generate signature\n"); 55 + return -1; 56 + } 57 58 + rc = crypto_shash_init(&server->ntlmssp.sdescmd5->shash); 59 + if (rc) { 60 + cERROR(1, "cifs_calculate_signature: oould not init md5\n"); 61 + return rc; 62 + } 63 + 64 + if (server->secType == RawNTLMSSP) 65 + crypto_shash_update(&server->ntlmssp.sdescmd5->shash, 66 + server->session_key.data.ntlmv2.key, 67 + CIFS_NTLMV2_SESSKEY_SIZE); 68 + else 69 + crypto_shash_update(&server->ntlmssp.sdescmd5->shash, 70 + (char *)&server->session_key.data, 71 + server->session_key.len); 72 + 73 + crypto_shash_update(&server->ntlmssp.sdescmd5->shash, 74 + cifs_pdu->Protocol, cifs_pdu->smb_buf_length); 75 + 76 + rc = crypto_shash_final(&server->ntlmssp.sdescmd5->shash, signature); 77 + 78 + return rc; 79 } 80 + 81 82 int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, 83 __u32 *pexpected_response_sequence_number) ··· 78 server->sequence_number++; 79 spin_unlock(&GlobalMid_Lock); 80 81 + rc = cifs_calculate_signature(cifs_pdu, server, smb_signature); 82 if (rc) 83 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 84 else ··· 89 } 90 91 static int cifs_calc_signature2(const struct kvec *iov, int n_vec, 92 + struct TCP_Server_Info *server, char *signature) 93 { 94 int i; 95 + int rc; 96 97 + if (iov == NULL || server == NULL || signature == NULL) 98 return -EINVAL; 99 100 + if (!server->ntlmssp.sdescmd5) { 101 + cERROR(1, "cifs_calc_signature2: can't generate signature\n"); 102 + return -1; 103 + } 104 + 105 + rc = crypto_shash_init(&server->ntlmssp.sdescmd5->shash); 106 + if (rc) { 107 + cERROR(1, "cifs_calc_signature2: oould not init md5\n"); 108 + return rc; 109 + } 110 + 111 + if (server->secType == RawNTLMSSP) 112 + crypto_shash_update(&server->ntlmssp.sdescmd5->shash, 113 + server->session_key.data.ntlmv2.key, 114 + CIFS_NTLMV2_SESSKEY_SIZE); 115 + else 116 + crypto_shash_update(&server->ntlmssp.sdescmd5->shash, 117 + (char *)&server->session_key.data, 118 + server->session_key.len); 119 + 120 for (i = 0; i < n_vec; i++) { 121 if (iov[i].iov_len == 0) 122 continue; 123 if (iov[i].iov_base == NULL) { 124 + cERROR(1, "cifs_calc_signature2: null iovec entry"); 125 return -EIO; 126 } 127 /* The first entry includes a length field (which does not get ··· 111 if (i == 0) { 112 if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ 113 break; /* nothing to sign or corrupt header */ 114 + crypto_shash_update(&server->ntlmssp.sdescmd5->shash, 115 + iov[i].iov_base + 4, iov[i].iov_len - 4); 116 } else 117 + crypto_shash_update(&server->ntlmssp.sdescmd5->shash, 118 + iov[i].iov_base, iov[i].iov_len); 119 } 120 121 + rc = crypto_shash_final(&server->ntlmssp.sdescmd5->shash, signature); 122 123 + return rc; 124 } 125 126 int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, 127 __u32 *pexpected_response_sequence_number) ··· 145 server->sequence_number++; 146 spin_unlock(&GlobalMid_Lock); 147 148 + rc = cifs_calc_signature2(iov, n_vec, server, smb_signature); 149 if (rc) 150 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 151 else ··· 156 } 157 158 int cifs_verify_signature(struct smb_hdr *cifs_pdu, 159 + struct TCP_Server_Info *server, 160 __u32 expected_sequence_number) 161 { 162 + int rc; 163 char server_response_sig[8]; 164 char what_we_think_sig_should_be[20]; 165 166 + if (cifs_pdu == NULL || server == NULL) 167 return -EINVAL; 168 169 if (cifs_pdu->Command == SMB_COM_NEGOTIATE) ··· 192 cpu_to_le32(expected_sequence_number); 193 cifs_pdu->Signature.Sequence.Reserved = 0; 194 195 + rc = cifs_calculate_signature(cifs_pdu, server, 196 what_we_think_sig_should_be); 197 198 if (rc) ··· 209 } 210 211 /* We fill in key by putting in 40 byte array which was allocated by caller */ 212 + int cifs_calculate_session_key(struct session_key *key, const char *rn, 213 const char *password) 214 { 215 char temp_key[16]; ··· 220 mdfour(key->data.ntlm, temp_key, 16); 221 memcpy(key->data.ntlm+16, rn, CIFS_SESS_KEY_SIZE); 222 key->len = 40; 223 return 0; 224 } 225 ··· 324 { 325 int rc = 0; 326 int len; 327 + char nt_hash[CIFS_NTHASH_SIZE]; 328 wchar_t *user; 329 wchar_t *domain; 330 + wchar_t *server; 331 332 + if (!ses->server->ntlmssp.sdeschmacmd5) { 333 + cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); 334 + return -1; 335 + } 336 337 /* calculate md4 hash of password */ 338 E_md4hash(ses->password, nt_hash); 339 340 + crypto_shash_setkey(ses->server->ntlmssp.hmacmd5, nt_hash, 341 + CIFS_NTHASH_SIZE); 342 + 343 + rc = crypto_shash_init(&ses->server->ntlmssp.sdeschmacmd5->shash); 344 + if (rc) { 345 + cERROR(1, "calc_ntlmv2_hash: could not init hmacmd5\n"); 346 + return rc; 347 + } 348 349 /* convert ses->userName to unicode and uppercase */ 350 len = strlen(ses->userName); 351 user = kmalloc(2 + (len * 2), GFP_KERNEL); 352 + if (user == NULL) { 353 + cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n"); 354 + rc = -ENOMEM; 355 goto calc_exit_2; 356 + } 357 len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp); 358 UniStrupr(user); 359 + 360 + crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash, 361 + (char *)user, 2 * len); 362 363 /* convert ses->domainName to unicode and uppercase */ 364 if (ses->domainName) { 365 len = strlen(ses->domainName); 366 367 domain = kmalloc(2 + (len * 2), GFP_KERNEL); 368 + if (domain == NULL) { 369 + cERROR(1, "calc_ntlmv2_hash: domain mem alloc failure"); 370 + rc = -ENOMEM; 371 goto calc_exit_1; 372 + } 373 len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len, 374 nls_cp); 375 /* the following line was removed since it didn't work well ··· 363 Maybe converting the domain name earlier makes sense */ 364 /* UniStrupr(domain); */ 365 366 + crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash, 367 + (char *)domain, 2 * len); 368 369 kfree(domain); 370 + } else if (ses->serverName) { 371 + len = strlen(ses->serverName); 372 + 373 + server = kmalloc(2 + (len * 2), GFP_KERNEL); 374 + if (server == NULL) { 375 + cERROR(1, "calc_ntlmv2_hash: server mem alloc failure"); 376 + rc = -ENOMEM; 377 + goto calc_exit_1; 378 + } 379 + len = cifs_strtoUCS((__le16 *)server, ses->serverName, len, 380 + nls_cp); 381 + /* the following line was removed since it didn't work well 382 + with lower cased domain name that passed as an option. 383 + Maybe converting the domain name earlier makes sense */ 384 + /* UniStrupr(domain); */ 385 + 386 + crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash, 387 + (char *)server, 2 * len); 388 + 389 + kfree(server); 390 } 391 + 392 + rc = crypto_shash_final(&ses->server->ntlmssp.sdeschmacmd5->shash, 393 + ses->server->ntlmv2_hash); 394 + 395 calc_exit_1: 396 kfree(user); 397 calc_exit_2: 398 /* BB FIXME what about bytes 24 through 40 of the signing key? 399 compare with the NTLM example */ 400 401 return rc; 402 } 403 404 + static int 405 + find_domain_name(struct cifsSesInfo *ses) 406 + { 407 + int rc = 0; 408 + unsigned int attrsize; 409 + unsigned int type; 410 + unsigned char *blobptr; 411 + struct ntlmssp2_name *attrptr; 412 + 413 + if (ses->server->tiblob) { 414 + blobptr = ses->server->tiblob; 415 + attrptr = (struct ntlmssp2_name *) blobptr; 416 + 417 + while ((type = attrptr->type) != 0) { 418 + blobptr += 2; /* advance attr type */ 419 + attrsize = attrptr->length; 420 + blobptr += 2; /* advance attr size */ 421 + if (type == NTLMSSP_AV_NB_DOMAIN_NAME) { 422 + if (!ses->domainName) { 423 + ses->domainName = 424 + kmalloc(attrptr->length + 1, 425 + GFP_KERNEL); 426 + if (!ses->domainName) 427 + return -ENOMEM; 428 + cifs_from_ucs2(ses->domainName, 429 + (__le16 *)blobptr, 430 + attrptr->length, 431 + attrptr->length, 432 + load_nls_default(), false); 433 + } 434 + } 435 + blobptr += attrsize; /* advance attr value */ 436 + attrptr = (struct ntlmssp2_name *) blobptr; 437 + } 438 + } else { 439 + ses->server->tilen = 2 * sizeof(struct ntlmssp2_name); 440 + ses->server->tiblob = kmalloc(ses->server->tilen, GFP_KERNEL); 441 + if (!ses->server->tiblob) { 442 + ses->server->tilen = 0; 443 + cERROR(1, "Challenge target info allocation failure"); 444 + return -ENOMEM; 445 + } 446 + memset(ses->server->tiblob, 0x0, ses->server->tilen); 447 + attrptr = (struct ntlmssp2_name *) ses->server->tiblob; 448 + attrptr->type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE); 449 + } 450 + 451 + return rc; 452 + } 453 + 454 + static int 455 + CalcNTLMv2_response(const struct TCP_Server_Info *server, 456 + char *v2_session_response) 457 { 458 int rc; 459 + 460 + if (!server->ntlmssp.sdeschmacmd5) { 461 + cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); 462 + return -1; 463 + } 464 + 465 + crypto_shash_setkey(server->ntlmssp.hmacmd5, server->ntlmv2_hash, 466 + CIFS_HMAC_MD5_HASH_SIZE); 467 + 468 + rc = crypto_shash_init(&server->ntlmssp.sdeschmacmd5->shash); 469 + if (rc) { 470 + cERROR(1, "CalcNTLMv2_response: could not init hmacmd5"); 471 + return rc; 472 + } 473 + 474 + memcpy(v2_session_response + CIFS_SERVER_CHALLENGE_SIZE, 475 + server->cryptKey, CIFS_SERVER_CHALLENGE_SIZE); 476 + crypto_shash_update(&server->ntlmssp.sdeschmacmd5->shash, 477 + v2_session_response + CIFS_SERVER_CHALLENGE_SIZE, 478 + sizeof(struct ntlmv2_resp) - CIFS_SERVER_CHALLENGE_SIZE); 479 + 480 + if (server->tilen) 481 + crypto_shash_update(&server->ntlmssp.sdeschmacmd5->shash, 482 + server->tiblob, server->tilen); 483 + 484 + rc = crypto_shash_final(&server->ntlmssp.sdeschmacmd5->shash, 485 + v2_session_response); 486 + 487 + return rc; 488 + } 489 + 490 + int 491 + setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf, 492 + const struct nls_table *nls_cp) 493 + { 494 + int rc = 0; 495 struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf; 496 497 buf->blob_signature = cpu_to_le32(0x00000101); 498 buf->reserved = 0; 499 buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 500 get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); 501 buf->reserved2 = 0; 502 + 503 + if (!ses->domainName) { 504 + rc = find_domain_name(ses); 505 + if (rc) { 506 + cERROR(1, "could not get domain/server name rc %d", rc); 507 + return rc; 508 + } 509 + } 510 511 /* calculate buf->ntlmv2_hash */ 512 rc = calc_ntlmv2_hash(ses, nls_cp); 513 + if (rc) { 514 cERROR(1, "could not get v2 hash rc %d", rc); 515 + return rc; 516 + } 517 + rc = CalcNTLMv2_response(ses->server, resp_buf); 518 + if (rc) { 519 + cERROR(1, "could not get v2 hash rc %d", rc); 520 + return rc; 521 + } 522 523 + if (!ses->server->ntlmssp.sdeschmacmd5) { 524 + cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n"); 525 + return -1; 526 + } 527 528 + crypto_shash_setkey(ses->server->ntlmssp.hmacmd5, 529 + ses->server->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); 530 + 531 + rc = crypto_shash_init(&ses->server->ntlmssp.sdeschmacmd5->shash); 532 + if (rc) { 533 + cERROR(1, "setup_ntlmv2_rsp: could not init hmacmd5\n"); 534 + return rc; 535 + } 536 + 537 + crypto_shash_update(&ses->server->ntlmssp.sdeschmacmd5->shash, 538 + resp_buf, CIFS_HMAC_MD5_HASH_SIZE); 539 + 540 + rc = crypto_shash_final(&ses->server->ntlmssp.sdeschmacmd5->shash, 541 + ses->server->session_key.data.ntlmv2.key); 542 + 543 + memcpy(&ses->server->session_key.data.ntlmv2.resp, resp_buf, 544 + sizeof(struct ntlmv2_resp)); 545 + ses->server->session_key.len = 16 + sizeof(struct ntlmv2_resp); 546 + 547 + return rc; 548 } 549 550 + int 551 + calc_seckey(struct TCP_Server_Info *server) 552 { 553 + int rc; 554 + unsigned char sec_key[CIFS_NTLMV2_SESSKEY_SIZE]; 555 + struct crypto_blkcipher *tfm_arc4; 556 + struct scatterlist sgin, sgout; 557 + struct blkcipher_desc desc; 558 559 + get_random_bytes(sec_key, CIFS_NTLMV2_SESSKEY_SIZE); 560 561 + tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 562 + 0, CRYPTO_ALG_ASYNC); 563 + if (!tfm_arc4 || IS_ERR(tfm_arc4)) { 564 + cERROR(1, "could not allocate " "master crypto API arc4\n"); 565 + return 1; 566 + } 567 + 568 + desc.tfm = tfm_arc4; 569 + 570 + crypto_blkcipher_setkey(tfm_arc4, 571 + server->session_key.data.ntlmv2.key, CIFS_CPHTXT_SIZE); 572 + sg_init_one(&sgin, sec_key, CIFS_CPHTXT_SIZE); 573 + sg_init_one(&sgout, server->ntlmssp.ciphertext, CIFS_CPHTXT_SIZE); 574 + rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, CIFS_CPHTXT_SIZE); 575 + 576 + if (!rc) 577 + memcpy(server->session_key.data.ntlmv2.key, 578 + sec_key, CIFS_NTLMV2_SESSKEY_SIZE); 579 + 580 + crypto_free_blkcipher(tfm_arc4); 581 + 582 + return 0; 583 + } 584 + 585 + void 586 + cifs_crypto_shash_release(struct TCP_Server_Info *server) 587 + { 588 + if (server->ntlmssp.md5) 589 + crypto_free_shash(server->ntlmssp.md5); 590 + 591 + if (server->ntlmssp.hmacmd5) 592 + crypto_free_shash(server->ntlmssp.hmacmd5); 593 + 594 + kfree(server->ntlmssp.sdeschmacmd5); 595 + 596 + kfree(server->ntlmssp.sdescmd5); 597 + } 598 + 599 + int 600 + cifs_crypto_shash_allocate(struct TCP_Server_Info *server) 601 + { 602 + int rc; 603 + unsigned int size; 604 + 605 + server->ntlmssp.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0); 606 + if (!server->ntlmssp.hmacmd5 || 607 + IS_ERR(server->ntlmssp.hmacmd5)) { 608 + cERROR(1, "could not allocate crypto hmacmd5\n"); 609 + return 1; 610 + } 611 + 612 + server->ntlmssp.md5 = crypto_alloc_shash("md5", 0, 0); 613 + if (!server->ntlmssp.md5 || IS_ERR(server->ntlmssp.md5)) { 614 + cERROR(1, "could not allocate crypto md5\n"); 615 + rc = 1; 616 + goto cifs_crypto_shash_allocate_ret1; 617 + } 618 + 619 + size = sizeof(struct shash_desc) + 620 + crypto_shash_descsize(server->ntlmssp.hmacmd5); 621 + server->ntlmssp.sdeschmacmd5 = kmalloc(size, GFP_KERNEL); 622 + if (!server->ntlmssp.sdeschmacmd5) { 623 + cERROR(1, "cifs_crypto_shash_allocate: can't alloc hmacmd5\n"); 624 + rc = -ENOMEM; 625 + goto cifs_crypto_shash_allocate_ret2; 626 + } 627 + server->ntlmssp.sdeschmacmd5->shash.tfm = server->ntlmssp.hmacmd5; 628 + server->ntlmssp.sdeschmacmd5->shash.flags = 0x0; 629 + 630 + 631 + size = sizeof(struct shash_desc) + 632 + crypto_shash_descsize(server->ntlmssp.md5); 633 + server->ntlmssp.sdescmd5 = kmalloc(size, GFP_KERNEL); 634 + if (!server->ntlmssp.sdescmd5) { 635 + cERROR(1, "cifs_crypto_shash_allocate: can't alloc md5\n"); 636 + rc = -ENOMEM; 637 + goto cifs_crypto_shash_allocate_ret3; 638 + } 639 + server->ntlmssp.sdescmd5->shash.tfm = server->ntlmssp.md5; 640 + server->ntlmssp.sdescmd5->shash.flags = 0x0; 641 + 642 + return 0; 643 + 644 + cifs_crypto_shash_allocate_ret3: 645 + kfree(server->ntlmssp.sdeschmacmd5); 646 + 647 + cifs_crypto_shash_allocate_ret2: 648 + crypto_free_shash(server->ntlmssp.md5); 649 + 650 + cifs_crypto_shash_allocate_ret1: 651 + crypto_free_shash(server->ntlmssp.hmacmd5); 652 + 653 + return rc; 654 }
+23 -2
fs/cifs/cifsglob.h
··· 25 #include <linux/workqueue.h> 26 #include "cifs_fs_sb.h" 27 #include "cifsacl.h" 28 /* 29 * The sizes of various internal tables and strings 30 */ ··· 100 /* Netbios frames protocol not supported at this time */ 101 }; 102 103 - struct mac_key { 104 unsigned int len; 105 union { 106 char ntlm[CIFS_SESS_KEY_SIZE + 16]; ··· 121 struct cifs_sid gsid; 122 struct cifs_ntace *ntaces; 123 struct cifs_ace *aces; 124 }; 125 126 /* ··· 200 /* 16th byte of RFC1001 workstation name is always null */ 201 char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; 202 __u32 sequence_number; /* needed for CIFS PDU signature */ 203 - struct mac_key mac_signing_key; 204 char ntlmv2_hash[16]; 205 unsigned long lstrp; /* when we got last response from this server */ 206 u16 dialect; /* dialect index that server chose */ 207 /* extended security flavors that server supports */ 208 bool sec_kerberos; /* supports plain Kerberos */ 209 bool sec_mskerberos; /* supports legacy MS Kerberos */ 210 bool sec_kerberosu2u; /* supports U2U Kerberos */
··· 25 #include <linux/workqueue.h> 26 #include "cifs_fs_sb.h" 27 #include "cifsacl.h" 28 + #include <crypto/internal/hash.h> 29 + #include <linux/scatterlist.h> 30 + 31 /* 32 * The sizes of various internal tables and strings 33 */ ··· 97 /* Netbios frames protocol not supported at this time */ 98 }; 99 100 + struct session_key { 101 unsigned int len; 102 union { 103 char ntlm[CIFS_SESS_KEY_SIZE + 16]; ··· 118 struct cifs_sid gsid; 119 struct cifs_ntace *ntaces; 120 struct cifs_ace *aces; 121 + }; 122 + 123 + struct sdesc { 124 + struct shash_desc shash; 125 + char ctx[]; 126 + }; 127 + 128 + struct ntlmssp_auth { 129 + __u32 client_flags; 130 + __u32 server_flags; 131 + unsigned char ciphertext[CIFS_CPHTXT_SIZE]; 132 + struct crypto_shash *hmacmd5; 133 + struct crypto_shash *md5; 134 + struct sdesc *sdeschmacmd5; 135 + struct sdesc *sdescmd5; 136 }; 137 138 /* ··· 182 /* 16th byte of RFC1001 workstation name is always null */ 183 char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; 184 __u32 sequence_number; /* needed for CIFS PDU signature */ 185 + struct session_key session_key; 186 char ntlmv2_hash[16]; 187 unsigned long lstrp; /* when we got last response from this server */ 188 u16 dialect; /* dialect index that server chose */ 189 /* extended security flavors that server supports */ 190 + unsigned int tilen; /* length of the target info blob */ 191 + unsigned char *tiblob; /* target info blob in challenge response */ 192 + struct ntlmssp_auth ntlmssp; /* various keys, ciphers, flags */ 193 bool sec_kerberos; /* supports plain Kerberos */ 194 bool sec_mskerberos; /* supports legacy MS Kerberos */ 195 bool sec_kerberosu2u; /* supports U2U Kerberos */
+6 -1
fs/cifs/cifspdu.h
··· 134 * Size of the session key (crypto key encrypted with the password 135 */ 136 #define CIFS_SESS_KEY_SIZE (24) 137 138 /* 139 * Maximum user name length ··· 669 __le64 time; 670 __u64 client_chal; /* random */ 671 __u32 reserved2; 672 - struct ntlmssp2_name names[2]; 673 /* array of name entries could follow ending in minimum 4 byte struct */ 674 } __attribute__((packed)); 675
··· 134 * Size of the session key (crypto key encrypted with the password 135 */ 136 #define CIFS_SESS_KEY_SIZE (24) 137 + #define CIFS_CLIENT_CHALLENGE_SIZE (8) 138 + #define CIFS_SERVER_CHALLENGE_SIZE (8) 139 + #define CIFS_HMAC_MD5_HASH_SIZE (16) 140 + #define CIFS_CPHTXT_SIZE (16) 141 + #define CIFS_NTLMV2_SESSKEY_SIZE (16) 142 + #define CIFS_NTHASH_SIZE (16) 143 144 /* 145 * Maximum user name length ··· 663 __le64 time; 664 __u64 client_chal; /* random */ 665 __u32 reserved2; 666 /* array of name entries could follow ending in minimum 4 byte struct */ 667 } __attribute__((packed)); 668
+6 -6
fs/cifs/cifsproto.h
··· 361 extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, 362 __u32 *); 363 extern int cifs_verify_signature(struct smb_hdr *, 364 - const struct mac_key *mac_key, 365 __u32 expected_sequence_number); 366 - extern int cifs_calculate_mac_key(struct mac_key *key, const char *rn, 367 const char *pass); 368 - extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, 369 - const struct nls_table *); 370 - extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *); 371 - extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *, 372 const struct nls_table *); 373 #ifdef CONFIG_CIFS_WEAK_PW_HASH 374 extern void calc_lanman_hash(const char *password, const char *cryptkey, 375 bool encrypt, char *lnm_session_key);
··· 361 extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, 362 __u32 *); 363 extern int cifs_verify_signature(struct smb_hdr *, 364 + struct TCP_Server_Info *server, 365 __u32 expected_sequence_number); 366 + extern int cifs_calculate_session_key(struct session_key *key, const char *rn, 367 const char *pass); 368 + extern int setup_ntlmv2_rsp(struct cifsSesInfo *, char *, 369 const struct nls_table *); 370 + extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); 371 + extern void cifs_crypto_shash_release(struct TCP_Server_Info *); 372 + extern int calc_seckey(struct TCP_Server_Info *); 373 #ifdef CONFIG_CIFS_WEAK_PW_HASH 374 extern void calc_lanman_hash(const char *password, const char *cryptkey, 375 bool encrypt, char *lnm_session_key);
+8 -5
fs/cifs/cifssmb.c
··· 604 else 605 rc = -EINVAL; 606 607 - if (server->sec_kerberos || server->sec_mskerberos) 608 - server->secType = Kerberos; 609 - else if (server->sec_ntlmssp) 610 - server->secType = RawNTLMSSP; 611 - else 612 rc = -EOPNOTSUPP; 613 } 614 } else
··· 604 else 605 rc = -EINVAL; 606 607 + if (server->secType == Kerberos) { 608 + if (!server->sec_kerberos && 609 + !server->sec_mskerberos) 610 + rc = -EOPNOTSUPP; 611 + } else if (server->secType == RawNTLMSSP) { 612 + if (!server->sec_ntlmssp) 613 + rc = -EOPNOTSUPP; 614 + } else 615 rc = -EOPNOTSUPP; 616 } 617 } else
+15 -2
fs/cifs/connect.c
··· 1673 MAX_USERNAME_SIZE)) 1674 continue; 1675 if (strlen(vol->username) != 0 && 1676 - strncmp(ses->password, vol->password, 1677 MAX_PASSWORD_SIZE)) 1678 continue; 1679 } ··· 1708 CIFSSMBLogoff(xid, ses); 1709 _FreeXid(xid); 1710 } 1711 sesInfoFree(ses); 1712 cifs_put_tcp_session(server); 1713 } ··· 1788 ses->linux_uid = volume_info->linux_uid; 1789 ses->overrideSecFlg = volume_info->secFlg; 1790 1791 mutex_lock(&ses->session_mutex); 1792 rc = cifs_negotiate_protocol(xid, ses); 1793 if (!rc) 1794 rc = cifs_setup_session(xid, ses, volume_info->local_nls); 1795 mutex_unlock(&ses->session_mutex); 1796 - if (rc) 1797 goto get_ses_fail; 1798 1799 /* success, put it on the list */ 1800 write_lock(&cifs_tcp_ses_lock);
··· 1673 MAX_USERNAME_SIZE)) 1674 continue; 1675 if (strlen(vol->username) != 0 && 1676 + ses->password != NULL && 1677 + strncmp(ses->password, 1678 + vol->password ? vol->password : "", 1679 MAX_PASSWORD_SIZE)) 1680 continue; 1681 } ··· 1706 CIFSSMBLogoff(xid, ses); 1707 _FreeXid(xid); 1708 } 1709 + cifs_crypto_shash_release(server); 1710 sesInfoFree(ses); 1711 cifs_put_tcp_session(server); 1712 } ··· 1785 ses->linux_uid = volume_info->linux_uid; 1786 ses->overrideSecFlg = volume_info->secFlg; 1787 1788 + rc = cifs_crypto_shash_allocate(server); 1789 + if (rc) { 1790 + cERROR(1, "could not setup hash structures rc %d", rc); 1791 + goto get_ses_fail; 1792 + } 1793 + server->tilen = 0; 1794 + server->tiblob = NULL; 1795 + 1796 mutex_lock(&ses->session_mutex); 1797 rc = cifs_negotiate_protocol(xid, ses); 1798 if (!rc) 1799 rc = cifs_setup_session(xid, ses, volume_info->local_nls); 1800 mutex_unlock(&ses->session_mutex); 1801 + if (rc) { 1802 + cifs_crypto_shash_release(ses->server); 1803 goto get_ses_fail; 1804 + } 1805 1806 /* success, put it on the list */ 1807 write_lock(&cifs_tcp_ses_lock);
+79 -82
fs/cifs/dir.c
··· 305 full_path = build_path_from_dentry(direntry); 306 if (full_path == NULL) { 307 rc = -ENOMEM; 308 - FreeXid(xid); 309 - return rc; 310 } 311 312 if (oplockEnabled) ··· 364 365 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); 366 if (buf == NULL) { 367 - kfree(full_path); 368 - FreeXid(xid); 369 - return -ENOMEM; 370 } 371 372 /* ··· 494 struct cifsTconInfo *pTcon; 495 char *full_path = NULL; 496 struct inode *newinode = NULL; 497 498 if (!old_valid_dev(device_number)) 499 return -EINVAL; ··· 509 pTcon = cifs_sb->tcon; 510 511 full_path = build_path_from_dentry(direntry); 512 - if (full_path == NULL) 513 rc = -ENOMEM; 514 - else if (pTcon->unix_ext) { 515 struct cifs_unix_set_info_args args = { 516 .mode = mode & ~current_umask(), 517 .ctime = NO_CHANGE_64, ··· 533 cifs_sb->local_nls, 534 cifs_sb->mnt_cifs_flags & 535 CIFS_MOUNT_MAP_SPECIAL_CHR); 536 537 - if (!rc) { 538 - rc = cifs_get_inode_info_unix(&newinode, full_path, 539 inode->i_sb, xid); 540 - if (pTcon->nocase) 541 - direntry->d_op = &cifs_ci_dentry_ops; 542 - else 543 - direntry->d_op = &cifs_dentry_ops; 544 - if (rc == 0) 545 - d_instantiate(direntry, newinode); 546 - } 547 - } else { 548 - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { 549 - int oplock = 0; 550 - u16 fileHandle; 551 - FILE_ALL_INFO *buf; 552 553 - cFYI(1, "sfu compat create special file"); 554 - 555 - buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); 556 - if (buf == NULL) { 557 - kfree(full_path); 558 - rc = -ENOMEM; 559 - FreeXid(xid); 560 - return rc; 561 - } 562 - 563 - rc = CIFSSMBOpen(xid, pTcon, full_path, 564 - FILE_CREATE, /* fail if exists */ 565 - GENERIC_WRITE /* BB would 566 - WRITE_OWNER | WRITE_DAC be better? */, 567 - /* Create a file and set the 568 - file attribute to SYSTEM */ 569 - CREATE_NOT_DIR | CREATE_OPTION_SPECIAL, 570 - &fileHandle, &oplock, buf, 571 - cifs_sb->local_nls, 572 - cifs_sb->mnt_cifs_flags & 573 - CIFS_MOUNT_MAP_SPECIAL_CHR); 574 - 575 - /* BB FIXME - add handling for backlevel servers 576 - which need legacy open and check for all 577 - calls to SMBOpen for fallback to SMBLeagcyOpen */ 578 - if (!rc) { 579 - /* BB Do not bother to decode buf since no 580 - local inode yet to put timestamps in, 581 - but we can reuse it safely */ 582 - unsigned int bytes_written; 583 - struct win_dev *pdev; 584 - pdev = (struct win_dev *)buf; 585 - if (S_ISCHR(mode)) { 586 - memcpy(pdev->type, "IntxCHR", 8); 587 - pdev->major = 588 - cpu_to_le64(MAJOR(device_number)); 589 - pdev->minor = 590 - cpu_to_le64(MINOR(device_number)); 591 - rc = CIFSSMBWrite(xid, pTcon, 592 - fileHandle, 593 - sizeof(struct win_dev), 594 - 0, &bytes_written, (char *)pdev, 595 - NULL, 0); 596 - } else if (S_ISBLK(mode)) { 597 - memcpy(pdev->type, "IntxBLK", 8); 598 - pdev->major = 599 - cpu_to_le64(MAJOR(device_number)); 600 - pdev->minor = 601 - cpu_to_le64(MINOR(device_number)); 602 - rc = CIFSSMBWrite(xid, pTcon, 603 - fileHandle, 604 - sizeof(struct win_dev), 605 - 0, &bytes_written, (char *)pdev, 606 - NULL, 0); 607 - } /* else if(S_ISFIFO */ 608 - CIFSSMBClose(xid, pTcon, fileHandle); 609 - d_drop(direntry); 610 - } 611 - kfree(buf); 612 - /* add code here to set EAs */ 613 - } 614 } 615 616 kfree(full_path); 617 FreeXid(xid); 618 return rc; 619 }
··· 305 full_path = build_path_from_dentry(direntry); 306 if (full_path == NULL) { 307 rc = -ENOMEM; 308 + goto cifs_create_out; 309 } 310 311 if (oplockEnabled) ··· 365 366 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); 367 if (buf == NULL) { 368 + rc = -ENOMEM; 369 + goto cifs_create_out; 370 } 371 372 /* ··· 496 struct cifsTconInfo *pTcon; 497 char *full_path = NULL; 498 struct inode *newinode = NULL; 499 + int oplock = 0; 500 + u16 fileHandle; 501 + FILE_ALL_INFO *buf = NULL; 502 + unsigned int bytes_written; 503 + struct win_dev *pdev; 504 505 if (!old_valid_dev(device_number)) 506 return -EINVAL; ··· 506 pTcon = cifs_sb->tcon; 507 508 full_path = build_path_from_dentry(direntry); 509 + if (full_path == NULL) { 510 rc = -ENOMEM; 511 + goto mknod_out; 512 + } 513 + 514 + if (pTcon->unix_ext) { 515 struct cifs_unix_set_info_args args = { 516 .mode = mode & ~current_umask(), 517 .ctime = NO_CHANGE_64, ··· 527 cifs_sb->local_nls, 528 cifs_sb->mnt_cifs_flags & 529 CIFS_MOUNT_MAP_SPECIAL_CHR); 530 + if (rc) 531 + goto mknod_out; 532 533 + rc = cifs_get_inode_info_unix(&newinode, full_path, 534 inode->i_sb, xid); 535 + if (pTcon->nocase) 536 + direntry->d_op = &cifs_ci_dentry_ops; 537 + else 538 + direntry->d_op = &cifs_dentry_ops; 539 540 + if (rc == 0) 541 + d_instantiate(direntry, newinode); 542 + goto mknod_out; 543 } 544 545 + if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) 546 + goto mknod_out; 547 + 548 + 549 + cFYI(1, "sfu compat create special file"); 550 + 551 + buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); 552 + if (buf == NULL) { 553 + kfree(full_path); 554 + rc = -ENOMEM; 555 + FreeXid(xid); 556 + return rc; 557 + } 558 + 559 + /* FIXME: would WRITE_OWNER | WRITE_DAC be better? */ 560 + rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE, 561 + GENERIC_WRITE, CREATE_NOT_DIR | CREATE_OPTION_SPECIAL, 562 + &fileHandle, &oplock, buf, cifs_sb->local_nls, 563 + cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 564 + if (rc) 565 + goto mknod_out; 566 + 567 + /* BB Do not bother to decode buf since no local inode yet to put 568 + * timestamps in, but we can reuse it safely */ 569 + 570 + pdev = (struct win_dev *)buf; 571 + if (S_ISCHR(mode)) { 572 + memcpy(pdev->type, "IntxCHR", 8); 573 + pdev->major = 574 + cpu_to_le64(MAJOR(device_number)); 575 + pdev->minor = 576 + cpu_to_le64(MINOR(device_number)); 577 + rc = CIFSSMBWrite(xid, pTcon, 578 + fileHandle, 579 + sizeof(struct win_dev), 580 + 0, &bytes_written, (char *)pdev, 581 + NULL, 0); 582 + } else if (S_ISBLK(mode)) { 583 + memcpy(pdev->type, "IntxBLK", 8); 584 + pdev->major = 585 + cpu_to_le64(MAJOR(device_number)); 586 + pdev->minor = 587 + cpu_to_le64(MINOR(device_number)); 588 + rc = CIFSSMBWrite(xid, pTcon, 589 + fileHandle, 590 + sizeof(struct win_dev), 591 + 0, &bytes_written, (char *)pdev, 592 + NULL, 0); 593 + } /* else if (S_ISFIFO) */ 594 + CIFSSMBClose(xid, pTcon, fileHandle); 595 + d_drop(direntry); 596 + 597 + /* FIXME: add code here to set EAs */ 598 + 599 + mknod_out: 600 kfree(full_path); 601 + kfree(buf); 602 FreeXid(xid); 603 return rc; 604 }
+1 -2
fs/cifs/file.c
··· 242 full_path = build_path_from_dentry(file->f_path.dentry); 243 if (full_path == NULL) { 244 rc = -ENOMEM; 245 - FreeXid(xid); 246 - return rc; 247 } 248 249 cFYI(1, "inode = 0x%p file flags are 0x%x for %s",
··· 242 full_path = build_path_from_dentry(file->f_path.dentry); 243 if (full_path == NULL) { 244 rc = -ENOMEM; 245 + goto out; 246 } 247 248 cFYI(1, "inode = 0x%p file flags are 0x%x for %s",
+13
fs/cifs/ntlmssp.h
··· 61 #define NTLMSSP_NEGOTIATE_KEY_XCH 0x40000000 62 #define NTLMSSP_NEGOTIATE_56 0x80000000 63 64 /* Although typedefs are not commonly used for structure definitions */ 65 /* in the Linux kernel, in this particular case they are useful */ 66 /* to more closely match the standards document for NTLMSSP from */
··· 61 #define NTLMSSP_NEGOTIATE_KEY_XCH 0x40000000 62 #define NTLMSSP_NEGOTIATE_56 0x80000000 63 64 + /* Define AV Pair Field IDs */ 65 + #define NTLMSSP_AV_EOL 0 66 + #define NTLMSSP_AV_NB_COMPUTER_NAME 1 67 + #define NTLMSSP_AV_NB_DOMAIN_NAME 2 68 + #define NTLMSSP_AV_DNS_COMPUTER_NAME 3 69 + #define NTLMSSP_AV_DNS_DOMAIN_NAME 4 70 + #define NTLMSSP_AV_DNS_TREE_NAME 5 71 + #define NTLMSSP_AV_FLAGS 6 72 + #define NTLMSSP_AV_TIMESTAMP 7 73 + #define NTLMSSP_AV_RESTRICTION 8 74 + #define NTLMSSP_AV_TARGET_NAME 9 75 + #define NTLMSSP_AV_CHANNEL_BINDINGS 10 76 + 77 /* Although typedefs are not commonly used for structure definitions */ 78 /* in the Linux kernel, in this particular case they are useful */ 79 /* to more closely match the standards document for NTLMSSP from */
+97 -34
fs/cifs/sess.c
··· 383 static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, 384 struct cifsSesInfo *ses) 385 { 386 CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr; 387 388 if (blob_len < sizeof(CHALLENGE_MESSAGE)) { ··· 408 /* BB spec says that if AvId field of MsvAvTimestamp is populated then 409 we must set the MIC field of the AUTHENTICATE_MESSAGE */ 410 411 return 0; 412 } 413 ··· 442 /* BB is NTLMV2 session security format easier to use here? */ 443 flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | 444 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | 445 - NTLMSSP_NEGOTIATE_NT_ONLY | NTLMSSP_NEGOTIATE_NTLM; 446 if (ses->server->secMode & 447 - (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 448 - flags |= NTLMSSP_NEGOTIATE_SIGN; 449 - if (ses->server->secMode & SECMODE_SIGN_REQUIRED) 450 - flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; 451 452 sec_blob->NegotiateFlags |= cpu_to_le32(flags); 453 ··· 469 struct cifsSesInfo *ses, 470 const struct nls_table *nls_cp, bool first) 471 { 472 AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer; 473 __u32 flags; 474 unsigned char *tmp; 475 - char ntlm_session_key[CIFS_SESS_KEY_SIZE]; 476 477 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); 478 sec_blob->MessageType = NtLmAuthenticate; ··· 497 sec_blob->LmChallengeResponse.Length = 0; 498 sec_blob->LmChallengeResponse.MaximumLength = 0; 499 500 - /* calculate session key, BB what about adding similar ntlmv2 path? */ 501 - SMBNTencrypt(ses->password, ses->server->cryptKey, ntlm_session_key); 502 - if (first) 503 - cifs_calculate_mac_key(&ses->server->mac_signing_key, 504 - ntlm_session_key, ses->password); 505 - 506 - memcpy(tmp, ntlm_session_key, CIFS_SESS_KEY_SIZE); 507 sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer); 508 - sec_blob->NtChallengeResponse.Length = cpu_to_le16(CIFS_SESS_KEY_SIZE); 509 - sec_blob->NtChallengeResponse.MaximumLength = 510 - cpu_to_le16(CIFS_SESS_KEY_SIZE); 511 512 - tmp += CIFS_SESS_KEY_SIZE; 513 514 if (ses->domainName == NULL) { 515 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); ··· 527 len = cifs_strtoUCS((__le16 *)tmp, ses->domainName, 528 MAX_USERNAME_SIZE, nls_cp); 529 len *= 2; /* unicode is 2 bytes each */ 530 - len += 2; /* trailing null */ 531 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); 532 sec_blob->DomainName.Length = cpu_to_le16(len); 533 sec_blob->DomainName.MaximumLength = cpu_to_le16(len); ··· 543 len = cifs_strtoUCS((__le16 *)tmp, ses->userName, 544 MAX_USERNAME_SIZE, nls_cp); 545 len *= 2; /* unicode is 2 bytes each */ 546 - len += 2; /* trailing null */ 547 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer); 548 sec_blob->UserName.Length = cpu_to_le16(len); 549 sec_blob->UserName.MaximumLength = cpu_to_le16(len); ··· 554 sec_blob->WorkstationName.MaximumLength = 0; 555 tmp += 2; 556 557 - sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); 558 - sec_blob->SessionKey.Length = 0; 559 - sec_blob->SessionKey.MaximumLength = 0; 560 return tmp - pbuffer; 561 } 562 ··· 587 return; 588 } 589 590 - static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB, 591 struct cifsSesInfo *ses, 592 const struct nls_table *nls, bool first_time) 593 { 594 int bloblen; 595 596 - bloblen = build_ntlmssp_auth_blob(&pSMB->req.SecurityBlob[0], ses, nls, 597 first_time); 598 - pSMB->req.SecurityBlobLength = cpu_to_le16(bloblen); 599 600 return bloblen; 601 } ··· 620 struct key *spnego_key = NULL; 621 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */ 622 bool first_time; 623 624 if (ses == NULL) 625 return -EINVAL; ··· 731 732 if (first_time) /* should this be moved into common code 733 with similar ntlmv2 path? */ 734 - cifs_calculate_mac_key(&ses->server->mac_signing_key, 735 ntlm_session_key, ses->password); 736 /* copy session key */ 737 ··· 770 cpu_to_le16(sizeof(struct ntlmv2_resp)); 771 772 /* calculate session key */ 773 - setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); 774 /* FIXME: calculate MAC key */ 775 memcpy(bcc_ptr, (char *)v2_sess_key, 776 sizeof(struct ntlmv2_resp)); 777 bcc_ptr += sizeof(struct ntlmv2_resp); 778 kfree(v2_sess_key); 779 if (ses->capabilities & CAP_UNICODE) { 780 if (iov[0].iov_len % 2) { 781 *bcc_ptr = 0; ··· 815 } 816 /* bail out if key is too long */ 817 if (msg->sesskey_len > 818 - sizeof(ses->server->mac_signing_key.data.krb5)) { 819 cERROR(1, "Kerberos signing key too long (%u bytes)", 820 msg->sesskey_len); 821 rc = -EOVERFLOW; 822 goto ssetup_exit; 823 } 824 if (first_time) { 825 - ses->server->mac_signing_key.len = msg->sesskey_len; 826 - memcpy(ses->server->mac_signing_key.data.krb5, 827 msg->data, msg->sesskey_len); 828 } 829 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; ··· 865 if (phase == NtLmNegotiate) { 866 setup_ntlmssp_neg_req(pSMB, ses); 867 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE); 868 } else if (phase == NtLmAuthenticate) { 869 int blob_len; 870 - blob_len = setup_ntlmssp_auth_req(pSMB, ses, 871 - nls_cp, 872 - first_time); 873 iov[1].iov_len = blob_len; 874 /* Make sure that we tell the server that we 875 are using the uid that it just gave us back 876 on the response (challenge) */ ··· 894 rc = -ENOSYS; 895 goto ssetup_exit; 896 } 897 - iov[1].iov_base = &pSMB->req.SecurityBlob[0]; 898 /* unicode strings must be word aligned */ 899 if ((iov[0].iov_len + iov[1].iov_len) % 2) { 900 *bcc_ptr = 0;
··· 383 static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, 384 struct cifsSesInfo *ses) 385 { 386 + unsigned int tioffset; /* challeng message target info area */ 387 + unsigned int tilen; /* challeng message target info area length */ 388 + 389 CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr; 390 391 if (blob_len < sizeof(CHALLENGE_MESSAGE)) { ··· 405 /* BB spec says that if AvId field of MsvAvTimestamp is populated then 406 we must set the MIC field of the AUTHENTICATE_MESSAGE */ 407 408 + ses->server->ntlmssp.server_flags = le32_to_cpu(pblob->NegotiateFlags); 409 + 410 + tioffset = cpu_to_le16(pblob->TargetInfoArray.BufferOffset); 411 + tilen = cpu_to_le16(pblob->TargetInfoArray.Length); 412 + ses->server->tilen = tilen; 413 + if (tilen) { 414 + ses->server->tiblob = kmalloc(tilen, GFP_KERNEL); 415 + if (!ses->server->tiblob) { 416 + cERROR(1, "Challenge target info allocation failure"); 417 + return -ENOMEM; 418 + } 419 + memcpy(ses->server->tiblob, bcc_ptr + tioffset, tilen); 420 + } 421 + 422 return 0; 423 } 424 ··· 425 /* BB is NTLMV2 session security format easier to use here? */ 426 flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | 427 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | 428 + NTLMSSP_NEGOTIATE_NTLM; 429 if (ses->server->secMode & 430 + (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { 431 + flags |= NTLMSSP_NEGOTIATE_SIGN | 432 + NTLMSSP_NEGOTIATE_KEY_XCH | 433 + NTLMSSP_NEGOTIATE_EXTENDED_SEC; 434 + } 435 436 sec_blob->NegotiateFlags |= cpu_to_le32(flags); 437 ··· 451 struct cifsSesInfo *ses, 452 const struct nls_table *nls_cp, bool first) 453 { 454 + int rc; 455 + unsigned int size; 456 AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer; 457 __u32 flags; 458 unsigned char *tmp; 459 + struct ntlmv2_resp ntlmv2_response = {}; 460 461 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); 462 sec_blob->MessageType = NtLmAuthenticate; ··· 477 sec_blob->LmChallengeResponse.Length = 0; 478 sec_blob->LmChallengeResponse.MaximumLength = 0; 479 480 sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer); 481 + rc = setup_ntlmv2_rsp(ses, (char *)&ntlmv2_response, nls_cp); 482 + if (rc) { 483 + cERROR(1, "error rc: %d during ntlmssp ntlmv2 setup", rc); 484 + goto setup_ntlmv2_ret; 485 + } 486 + size = sizeof(struct ntlmv2_resp); 487 + memcpy(tmp, (char *)&ntlmv2_response, size); 488 + tmp += size; 489 + if (ses->server->tilen > 0) { 490 + memcpy(tmp, ses->server->tiblob, ses->server->tilen); 491 + tmp += ses->server->tilen; 492 + } else 493 + ses->server->tilen = 0; 494 495 + sec_blob->NtChallengeResponse.Length = cpu_to_le16(size + 496 + ses->server->tilen); 497 + sec_blob->NtChallengeResponse.MaximumLength = 498 + cpu_to_le16(size + ses->server->tilen); 499 500 if (ses->domainName == NULL) { 501 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); ··· 501 len = cifs_strtoUCS((__le16 *)tmp, ses->domainName, 502 MAX_USERNAME_SIZE, nls_cp); 503 len *= 2; /* unicode is 2 bytes each */ 504 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); 505 sec_blob->DomainName.Length = cpu_to_le16(len); 506 sec_blob->DomainName.MaximumLength = cpu_to_le16(len); ··· 518 len = cifs_strtoUCS((__le16 *)tmp, ses->userName, 519 MAX_USERNAME_SIZE, nls_cp); 520 len *= 2; /* unicode is 2 bytes each */ 521 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer); 522 sec_blob->UserName.Length = cpu_to_le16(len); 523 sec_blob->UserName.MaximumLength = cpu_to_le16(len); ··· 530 sec_blob->WorkstationName.MaximumLength = 0; 531 tmp += 2; 532 533 + if ((ses->server->ntlmssp.server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) && 534 + !calc_seckey(ses->server)) { 535 + memcpy(tmp, ses->server->ntlmssp.ciphertext, CIFS_CPHTXT_SIZE); 536 + sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); 537 + sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE); 538 + sec_blob->SessionKey.MaximumLength = 539 + cpu_to_le16(CIFS_CPHTXT_SIZE); 540 + tmp += CIFS_CPHTXT_SIZE; 541 + } else { 542 + sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); 543 + sec_blob->SessionKey.Length = 0; 544 + sec_blob->SessionKey.MaximumLength = 0; 545 + } 546 + 547 + ses->server->sequence_number = 0; 548 + 549 + setup_ntlmv2_ret: 550 + if (ses->server->tilen > 0) 551 + kfree(ses->server->tiblob); 552 + 553 return tmp - pbuffer; 554 } 555 ··· 546 return; 547 } 548 549 + static int setup_ntlmssp_auth_req(char *ntlmsspblob, 550 struct cifsSesInfo *ses, 551 const struct nls_table *nls, bool first_time) 552 { 553 int bloblen; 554 555 + bloblen = build_ntlmssp_auth_blob(ntlmsspblob, ses, nls, 556 first_time); 557 558 return bloblen; 559 } ··· 580 struct key *spnego_key = NULL; 581 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */ 582 bool first_time; 583 + char *ntlmsspblob; 584 585 if (ses == NULL) 586 return -EINVAL; ··· 690 691 if (first_time) /* should this be moved into common code 692 with similar ntlmv2 path? */ 693 + cifs_calculate_session_key(&ses->server->session_key, 694 ntlm_session_key, ses->password); 695 /* copy session key */ 696 ··· 729 cpu_to_le16(sizeof(struct ntlmv2_resp)); 730 731 /* calculate session key */ 732 + rc = setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); 733 + if (rc) { 734 + kfree(v2_sess_key); 735 + goto ssetup_exit; 736 + } 737 /* FIXME: calculate MAC key */ 738 memcpy(bcc_ptr, (char *)v2_sess_key, 739 sizeof(struct ntlmv2_resp)); 740 bcc_ptr += sizeof(struct ntlmv2_resp); 741 kfree(v2_sess_key); 742 + if (ses->server->tilen > 0) { 743 + memcpy(bcc_ptr, ses->server->tiblob, 744 + ses->server->tilen); 745 + bcc_ptr += ses->server->tilen; 746 + } 747 if (ses->capabilities & CAP_UNICODE) { 748 if (iov[0].iov_len % 2) { 749 *bcc_ptr = 0; ··· 765 } 766 /* bail out if key is too long */ 767 if (msg->sesskey_len > 768 + sizeof(ses->server->session_key.data.krb5)) { 769 cERROR(1, "Kerberos signing key too long (%u bytes)", 770 msg->sesskey_len); 771 rc = -EOVERFLOW; 772 goto ssetup_exit; 773 } 774 if (first_time) { 775 + ses->server->session_key.len = msg->sesskey_len; 776 + memcpy(ses->server->session_key.data.krb5, 777 msg->data, msg->sesskey_len); 778 } 779 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; ··· 815 if (phase == NtLmNegotiate) { 816 setup_ntlmssp_neg_req(pSMB, ses); 817 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE); 818 + iov[1].iov_base = &pSMB->req.SecurityBlob[0]; 819 } else if (phase == NtLmAuthenticate) { 820 int blob_len; 821 + ntlmsspblob = kmalloc(5 * 822 + sizeof(struct _AUTHENTICATE_MESSAGE), 823 + GFP_KERNEL); 824 + if (!ntlmsspblob) { 825 + cERROR(1, "Can't allocate NTLMSSP"); 826 + rc = -ENOMEM; 827 + goto ssetup_exit; 828 + } 829 + 830 + blob_len = setup_ntlmssp_auth_req(ntlmsspblob, 831 + ses, 832 + nls_cp, 833 + first_time); 834 iov[1].iov_len = blob_len; 835 + iov[1].iov_base = ntlmsspblob; 836 + pSMB->req.SecurityBlobLength = 837 + cpu_to_le16(blob_len); 838 /* Make sure that we tell the server that we 839 are using the uid that it just gave us back 840 on the response (challenge) */ ··· 830 rc = -ENOSYS; 831 goto ssetup_exit; 832 } 833 /* unicode strings must be word aligned */ 834 if ((iov[0].iov_len + iov[1].iov_len) % 2) { 835 *bcc_ptr = 0;
+3 -3
fs/cifs/transport.c
··· 543 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 544 SECMODE_SIGN_ENABLED))) { 545 rc = cifs_verify_signature(midQ->resp_buf, 546 - &ses->server->mac_signing_key, 547 midQ->sequence_number+1); 548 if (rc) { 549 cERROR(1, "Unexpected SMB signature"); ··· 731 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 732 SECMODE_SIGN_ENABLED))) { 733 rc = cifs_verify_signature(out_buf, 734 - &ses->server->mac_signing_key, 735 midQ->sequence_number+1); 736 if (rc) { 737 cERROR(1, "Unexpected SMB signature"); ··· 981 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 982 SECMODE_SIGN_ENABLED))) { 983 rc = cifs_verify_signature(out_buf, 984 - &ses->server->mac_signing_key, 985 midQ->sequence_number+1); 986 if (rc) { 987 cERROR(1, "Unexpected SMB signature");
··· 543 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 544 SECMODE_SIGN_ENABLED))) { 545 rc = cifs_verify_signature(midQ->resp_buf, 546 + ses->server, 547 midQ->sequence_number+1); 548 if (rc) { 549 cERROR(1, "Unexpected SMB signature"); ··· 731 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 732 SECMODE_SIGN_ENABLED))) { 733 rc = cifs_verify_signature(out_buf, 734 + ses->server, 735 midQ->sequence_number+1); 736 if (rc) { 737 cERROR(1, "Unexpected SMB signature"); ··· 981 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 982 SECMODE_SIGN_ENABLED))) { 983 rc = cifs_verify_signature(out_buf, 984 + ses->server, 985 midQ->sequence_number+1); 986 if (rc) { 987 cERROR(1, "Unexpected SMB signature");