diff options
author | Shirish Pargaonkar <shirishpargaonkar@gmail.com> | 2011-08-25 00:05:46 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2011-09-19 22:16:58 -0400 |
commit | cfbd6f84c2e26c13ded16b6bb0871edb7d75974f (patch) | |
tree | 395e9fb411b4501fcc85d00ecd7b19d4256e5edb /fs | |
parent | c9c7fa0064f4afe1d040e72f24c2256dd8ac402d (diff) |
cifs: Fix broken sec=ntlmv2/i sec option (try #2)
Fix sec=ntlmv2/i authentication option during mount of Samba shares.
cifs client was coding ntlmv2 response incorrectly.
All that is needed in temp as specified in MS-NLMP seciton 3.3.2
"Define ComputeResponse(NegFlg, ResponseKeyNT, ResponseKeyLM,
CHALLENGE_MESSAGE.ServerChallenge, ClientChallenge, Time, ServerName)
as
Set temp to ConcatenationOf(Responserversion, HiResponserversion,
Z(6), Time, ClientChallenge, Z(4), ServerName, Z(4)"
is MsvAvNbDomainName.
For sec=ntlmsspi, build_av_pair is not used, a blob is plucked from
type 2 response sent by the server to use in authentication.
I tested sec=ntlmv2/i and sec=ntlmssp/i mount options against
Samba (3.6) and Windows - XP, 2003 Server and 7.
They all worked.
Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/cifsencrypt.c | 54 |
1 files changed, 11 insertions, 43 deletions
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index e76bfeb68267..30acd22147e1 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
@@ -351,9 +351,7 @@ static int | |||
351 | build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp) | 351 | build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp) |
352 | { | 352 | { |
353 | unsigned int dlen; | 353 | unsigned int dlen; |
354 | unsigned int wlen; | 354 | unsigned int size = 2 * sizeof(struct ntlmssp2_name); |
355 | unsigned int size = 6 * sizeof(struct ntlmssp2_name); | ||
356 | __le64 curtime; | ||
357 | char *defdmname = "WORKGROUP"; | 355 | char *defdmname = "WORKGROUP"; |
358 | unsigned char *blobptr; | 356 | unsigned char *blobptr; |
359 | struct ntlmssp2_name *attrptr; | 357 | struct ntlmssp2_name *attrptr; |
@@ -365,15 +363,14 @@ build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp) | |||
365 | } | 363 | } |
366 | 364 | ||
367 | dlen = strlen(ses->domainName); | 365 | dlen = strlen(ses->domainName); |
368 | wlen = strlen(ses->server->hostname); | ||
369 | 366 | ||
370 | /* The length of this blob is a size which is | 367 | /* |
371 | * six times the size of a structure which holds name/size + | 368 | * The length of this blob is two times the size of a |
372 | * two times the unicode length of a domain name + | 369 | * structure (av pair) which holds name/size |
373 | * two times the unicode length of a server name + | 370 | * ( for NTLMSSP_AV_NB_DOMAIN_NAME followed by NTLMSSP_AV_EOL ) + |
374 | * size of a timestamp (which is 8 bytes). | 371 | * unicode length of a netbios domain name |
375 | */ | 372 | */ |
376 | ses->auth_key.len = size + 2 * (2 * dlen) + 2 * (2 * wlen) + 8; | 373 | ses->auth_key.len = size + 2 * dlen; |
377 | ses->auth_key.response = kzalloc(ses->auth_key.len, GFP_KERNEL); | 374 | ses->auth_key.response = kzalloc(ses->auth_key.len, GFP_KERNEL); |
378 | if (!ses->auth_key.response) { | 375 | if (!ses->auth_key.response) { |
379 | ses->auth_key.len = 0; | 376 | ses->auth_key.len = 0; |
@@ -384,44 +381,15 @@ build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp) | |||
384 | blobptr = ses->auth_key.response; | 381 | blobptr = ses->auth_key.response; |
385 | attrptr = (struct ntlmssp2_name *) blobptr; | 382 | attrptr = (struct ntlmssp2_name *) blobptr; |
386 | 383 | ||
384 | /* | ||
385 | * As defined in MS-NTLM 3.3.2, just this av pair field | ||
386 | * is sufficient as part of the temp | ||
387 | */ | ||
387 | attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME); | 388 | attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME); |
388 | attrptr->length = cpu_to_le16(2 * dlen); | 389 | attrptr->length = cpu_to_le16(2 * dlen); |
389 | blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name); | 390 | blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name); |
390 | cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp); | 391 | cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp); |
391 | 392 | ||
392 | blobptr += 2 * dlen; | ||
393 | attrptr = (struct ntlmssp2_name *) blobptr; | ||
394 | |||
395 | attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_COMPUTER_NAME); | ||
396 | attrptr->length = cpu_to_le16(2 * wlen); | ||
397 | blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name); | ||
398 | cifs_strtoUCS((__le16 *)blobptr, ses->server->hostname, wlen, nls_cp); | ||
399 | |||
400 | blobptr += 2 * wlen; | ||
401 | attrptr = (struct ntlmssp2_name *) blobptr; | ||
402 | |||
403 | attrptr->type = cpu_to_le16(NTLMSSP_AV_DNS_DOMAIN_NAME); | ||
404 | attrptr->length = cpu_to_le16(2 * dlen); | ||
405 | blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name); | ||
406 | cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp); | ||
407 | |||
408 | blobptr += 2 * dlen; | ||
409 | attrptr = (struct ntlmssp2_name *) blobptr; | ||
410 | |||
411 | attrptr->type = cpu_to_le16(NTLMSSP_AV_DNS_COMPUTER_NAME); | ||
412 | attrptr->length = cpu_to_le16(2 * wlen); | ||
413 | blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name); | ||
414 | cifs_strtoUCS((__le16 *)blobptr, ses->server->hostname, wlen, nls_cp); | ||
415 | |||
416 | blobptr += 2 * wlen; | ||
417 | attrptr = (struct ntlmssp2_name *) blobptr; | ||
418 | |||
419 | attrptr->type = cpu_to_le16(NTLMSSP_AV_TIMESTAMP); | ||
420 | attrptr->length = cpu_to_le16(sizeof(__le64)); | ||
421 | blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name); | ||
422 | curtime = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); | ||
423 | memcpy(blobptr, &curtime, sizeof(__le64)); | ||
424 | |||
425 | return 0; | 393 | return 0; |
426 | } | 394 | } |
427 | 395 | ||