diff options
author | Jeff Layton <jlayton@redhat.com> | 2013-05-26 07:00:57 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2013-06-24 02:56:41 -0400 |
commit | 31d9e2bd5f83839408a1de83bfaafbda0d309f2b (patch) | |
tree | 0e7e38e88cf16fa52c178aac53261cf81ff1a15a /fs/cifs/cifssmb.c | |
parent | 281e2e7d06c42ce8dfd423fa2ae5616af0e0323f (diff) |
cifs: break out decoding of security blob into separate function
...cleanup.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Acked-by: Pavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r-- | fs/cifs/cifssmb.c | 109 |
1 files changed, 60 insertions, 49 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index c1c2006376a1..9b4aea85b15c 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -367,6 +367,56 @@ vt2_err: | |||
367 | return -EINVAL; | 367 | return -EINVAL; |
368 | } | 368 | } |
369 | 369 | ||
370 | static int | ||
371 | decode_ext_sec_blob(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr) | ||
372 | { | ||
373 | int rc = 0; | ||
374 | u16 count; | ||
375 | char *guid = pSMBr->u.extended_response.GUID; | ||
376 | |||
377 | count = get_bcc(&pSMBr->hdr); | ||
378 | if (count < SMB1_CLIENT_GUID_SIZE) | ||
379 | return -EIO; | ||
380 | |||
381 | spin_lock(&cifs_tcp_ses_lock); | ||
382 | if (server->srv_count > 1) { | ||
383 | spin_unlock(&cifs_tcp_ses_lock); | ||
384 | if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) { | ||
385 | cifs_dbg(FYI, "server UID changed\n"); | ||
386 | memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE); | ||
387 | } | ||
388 | } else { | ||
389 | spin_unlock(&cifs_tcp_ses_lock); | ||
390 | memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE); | ||
391 | } | ||
392 | |||
393 | if (count == SMB1_CLIENT_GUID_SIZE) { | ||
394 | server->secType = RawNTLMSSP; | ||
395 | } else { | ||
396 | count -= SMB1_CLIENT_GUID_SIZE; | ||
397 | rc = decode_negTokenInit( | ||
398 | pSMBr->u.extended_response.SecurityBlob, count, server); | ||
399 | if (rc != 1) | ||
400 | return -EINVAL; | ||
401 | |||
402 | /* Make sure server supports what we want to use */ | ||
403 | switch(server->secType) { | ||
404 | case Kerberos: | ||
405 | if (!server->sec_kerberos && !server->sec_mskerberos) | ||
406 | return -EOPNOTSUPP; | ||
407 | break; | ||
408 | case RawNTLMSSP: | ||
409 | if (!server->sec_ntlmssp) | ||
410 | return -EOPNOTSUPP; | ||
411 | break; | ||
412 | default: | ||
413 | return -EOPNOTSUPP; | ||
414 | } | ||
415 | } | ||
416 | |||
417 | return 0; | ||
418 | } | ||
419 | |||
370 | int | 420 | int |
371 | CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses) | 421 | CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses) |
372 | { | 422 | { |
@@ -568,61 +618,22 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses) | |||
568 | server->capabilities = le32_to_cpu(pSMBr->Capabilities); | 618 | server->capabilities = le32_to_cpu(pSMBr->Capabilities); |
569 | server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone); | 619 | server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone); |
570 | server->timeAdj *= 60; | 620 | server->timeAdj *= 60; |
571 | if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { | 621 | |
622 | if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) | ||
572 | memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey, | 623 | memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey, |
573 | CIFS_CRYPTO_KEY_SIZE); | 624 | CIFS_CRYPTO_KEY_SIZE); |
574 | } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC || | 625 | else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC || |
575 | server->capabilities & CAP_EXTENDED_SECURITY) && | 626 | server->capabilities & CAP_EXTENDED_SECURITY) && |
576 | (pSMBr->EncryptionKeyLength == 0)) { | 627 | (pSMBr->EncryptionKeyLength == 0)) |
577 | /* decode security blob */ | 628 | rc = decode_ext_sec_blob(server, pSMBr); |
578 | count = get_bcc(&pSMBr->hdr); | 629 | else if (server->sec_mode & SECMODE_PW_ENCRYPT) |
579 | if (count < 16) { | ||
580 | rc = -EIO; | ||
581 | goto neg_err_exit; | ||
582 | } | ||
583 | spin_lock(&cifs_tcp_ses_lock); | ||
584 | if (server->srv_count > 1) { | ||
585 | spin_unlock(&cifs_tcp_ses_lock); | ||
586 | if (memcmp(server->server_GUID, | ||
587 | pSMBr->u.extended_response. | ||
588 | GUID, 16) != 0) { | ||
589 | cifs_dbg(FYI, "server UID changed\n"); | ||
590 | memcpy(server->server_GUID, | ||
591 | pSMBr->u.extended_response.GUID, | ||
592 | 16); | ||
593 | } | ||
594 | } else { | ||
595 | spin_unlock(&cifs_tcp_ses_lock); | ||
596 | memcpy(server->server_GUID, | ||
597 | pSMBr->u.extended_response.GUID, 16); | ||
598 | } | ||
599 | |||
600 | if (count == 16) { | ||
601 | server->secType = RawNTLMSSP; | ||
602 | } else { | ||
603 | rc = decode_negTokenInit(pSMBr->u.extended_response. | ||
604 | SecurityBlob, count - 16, | ||
605 | server); | ||
606 | if (rc == 1) | ||
607 | rc = 0; | ||
608 | else | ||
609 | rc = -EINVAL; | ||
610 | if (server->secType == Kerberos) { | ||
611 | if (!server->sec_kerberos && | ||
612 | !server->sec_mskerberos) | ||
613 | rc = -EOPNOTSUPP; | ||
614 | } else if (server->secType == RawNTLMSSP) { | ||
615 | if (!server->sec_ntlmssp) | ||
616 | rc = -EOPNOTSUPP; | ||
617 | } else | ||
618 | rc = -EOPNOTSUPP; | ||
619 | } | ||
620 | } else if (server->sec_mode & SECMODE_PW_ENCRYPT) { | ||
621 | rc = -EIO; /* no crypt key only if plain text pwd */ | 630 | rc = -EIO; /* no crypt key only if plain text pwd */ |
622 | goto neg_err_exit; | 631 | else |
623 | } else | ||
624 | server->capabilities &= ~CAP_EXTENDED_SECURITY; | 632 | server->capabilities &= ~CAP_EXTENDED_SECURITY; |
625 | 633 | ||
634 | if (rc) | ||
635 | goto neg_err_exit; | ||
636 | |||
626 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | 637 | #ifdef CONFIG_CIFS_WEAK_PW_HASH |
627 | signing_check: | 638 | signing_check: |
628 | #endif | 639 | #endif |