diff options
| author | Steve French <sfrench@us.ibm.com> | 2006-06-04 01:53:15 -0400 |
|---|---|---|
| committer | Steve French <sfrench@us.ibm.com> | 2006-06-04 01:53:15 -0400 |
| commit | 254e55ed03e2e8d23089b4a468eec2fd2e1ead9b (patch) | |
| tree | af99361609403301ab1c758e2988e79dc155a710 | |
| parent | bdc4bf6e8ac8cc29c61c2f0dc61d9776ef9a8ed4 (diff) | |
CIFS] Support for older servers which require plaintext passwords - part 2
Signed-off-by: Steve French <sfrench@us.ibm.com>
| -rw-r--r-- | fs/cifs/README | 32 | ||||
| -rw-r--r-- | fs/cifs/cifsglob.h | 17 | ||||
| -rw-r--r-- | fs/cifs/cifspdu.h | 4 | ||||
| -rw-r--r-- | fs/cifs/cifssmb.c | 279 | ||||
| -rw-r--r-- | fs/cifs/sess.c | 3 |
5 files changed, 184 insertions, 151 deletions
diff --git a/fs/cifs/README b/fs/cifs/README index 0355003f4f0a..a68f8e3db2d2 100644 --- a/fs/cifs/README +++ b/fs/cifs/README | |||
| @@ -485,14 +485,34 @@ PacketSigningEnabled If set to one, cifs packet signing is enabled | |||
| 485 | it. If set to two, cifs packet signing is | 485 | it. If set to two, cifs packet signing is |
| 486 | required even if the server considers packet | 486 | required even if the server considers packet |
| 487 | signing optional. (default 1) | 487 | signing optional. (default 1) |
| 488 | SecurityFlags Flags which control security negotiation and | ||
| 489 | also packet signing. Authentication (may/must) | ||
| 490 | flags (e.g. for NTLM and/or NTLMv2) may be combined with | ||
| 491 | the signing flags. Specifying two different password | ||
| 492 | hashing mechanisms (as "must use") on the other hand | ||
| 493 | does not make much sense. Default flags are | ||
| 494 | 0x07007 | ||
| 495 | (NTLM, NTLMv2 and packet signing allowed). Maximum | ||
| 496 | allowable flags if you want to allow mounts to servers | ||
| 497 | using weaker password hashes is 0x37037 (lanman, | ||
| 498 | plaintext, ntlm, ntlmv2, signing allowed): | ||
| 499 | |||
| 500 | may use packet signing 0x00001 | ||
| 501 | must use packet signing 0x01001 | ||
| 502 | may use NTLM (most common password hash) 0x00002 | ||
| 503 | must use NTLM 0x02002 | ||
| 504 | may use NTLMv2 0x00004 | ||
| 505 | must use NTLMv2 0x04004 | ||
| 506 | may use Kerberos security (not implemented yet) 0x00008 | ||
| 507 | must use Kerberos (not implemented yet) 0x08008 | ||
| 508 | may use lanman (weak) password hash 0x00010 | ||
| 509 | must use lanman password hash 0x10010 | ||
| 510 | may use plaintext passwords 0x00020 | ||
| 511 | must use plaintext passwords 0x20020 | ||
| 512 | (reserved for future packet encryption) 0x00040 | ||
| 513 | |||
| 488 | cifsFYI If set to one, additional debug information is | 514 | cifsFYI If set to one, additional debug information is |
| 489 | logged to the system error log. (default 0) | 515 | logged to the system error log. (default 0) |
| 490 | ExtendedSecurity If set to one, SPNEGO session establishment | ||
| 491 | is allowed which enables more advanced | ||
| 492 | secure CIFS session establishment (default 0) | ||
| 493 | NTLMV2Enabled If set to one, more secure password hashes | ||
| 494 | are used when the server supports them and | ||
| 495 | when kerberos is not negotiated (default 0) | ||
| 496 | traceSMB If set to one, debug information is logged to the | 516 | traceSMB If set to one, debug information is logged to the |
| 497 | system error log with the start of smb requests | 517 | system error log with the start of smb requests |
| 498 | and responses (default 0) | 518 | and responses (default 0) |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 975e69a2e1c4..87453a6bcaf8 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -212,12 +212,12 @@ struct cifsTconInfo { | |||
| 212 | struct list_head openFileList; | 212 | struct list_head openFileList; |
| 213 | struct semaphore tconSem; | 213 | struct semaphore tconSem; |
| 214 | struct cifsSesInfo *ses; /* pointer to session associated with */ | 214 | struct cifsSesInfo *ses; /* pointer to session associated with */ |
| 215 | char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource (in ASCII not UTF) */ | 215 | char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */ |
| 216 | char *nativeFileSystem; | 216 | char *nativeFileSystem; |
| 217 | __u16 tid; /* The 2 byte tree id */ | 217 | __u16 tid; /* The 2 byte tree id */ |
| 218 | __u16 Flags; /* optional support bits */ | 218 | __u16 Flags; /* optional support bits */ |
| 219 | enum statusEnum tidStatus; | 219 | enum statusEnum tidStatus; |
| 220 | atomic_t useCount; /* how many mounts (explicit or implicit) to this share */ | 220 | atomic_t useCount; /* how many explicit/implicit mounts to share */ |
| 221 | #ifdef CONFIG_CIFS_STATS | 221 | #ifdef CONFIG_CIFS_STATS |
| 222 | atomic_t num_smbs_sent; | 222 | atomic_t num_smbs_sent; |
| 223 | atomic_t num_writes; | 223 | atomic_t num_writes; |
| @@ -257,7 +257,7 @@ struct cifsTconInfo { | |||
| 257 | spinlock_t stat_lock; | 257 | spinlock_t stat_lock; |
| 258 | #endif /* CONFIG_CIFS_STATS */ | 258 | #endif /* CONFIG_CIFS_STATS */ |
| 259 | FILE_SYSTEM_DEVICE_INFO fsDevInfo; | 259 | FILE_SYSTEM_DEVICE_INFO fsDevInfo; |
| 260 | FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if file system name truncated */ | 260 | FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */ |
| 261 | FILE_SYSTEM_UNIX_INFO fsUnixInfo; | 261 | FILE_SYSTEM_UNIX_INFO fsUnixInfo; |
| 262 | unsigned retry:1; | 262 | unsigned retry:1; |
| 263 | unsigned nocase:1; | 263 | unsigned nocase:1; |
| @@ -308,7 +308,6 @@ struct cifsFileInfo { | |||
| 308 | atomic_t wrtPending; /* handle in use - defer close */ | 308 | atomic_t wrtPending; /* handle in use - defer close */ |
| 309 | struct semaphore fh_sem; /* prevents reopen race after dead ses*/ | 309 | struct semaphore fh_sem; /* prevents reopen race after dead ses*/ |
| 310 | char * search_resume_name; /* BB removeme BB */ | 310 | char * search_resume_name; /* BB removeme BB */ |
| 311 | unsigned int resume_name_length; /* BB removeme - field renamed and moved BB */ | ||
| 312 | struct cifs_search_info srch_inf; | 311 | struct cifs_search_info srch_inf; |
| 313 | }; | 312 | }; |
| 314 | 313 | ||
| @@ -523,16 +522,16 @@ GLOBAL_EXTERN rwlock_t GlobalSMBSeslock; /* protects list inserts on 3 above */ | |||
| 523 | GLOBAL_EXTERN struct list_head GlobalOplock_Q; | 522 | GLOBAL_EXTERN struct list_head GlobalOplock_Q; |
| 524 | 523 | ||
| 525 | GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; /* Outstanding dir notify requests */ | 524 | GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; /* Outstanding dir notify requests */ |
| 526 | GLOBAL_EXTERN struct list_head GlobalDnotifyRsp_Q; /* Dir notify response queue */ | 525 | GLOBAL_EXTERN struct list_head GlobalDnotifyRsp_Q;/* DirNotify response queue */ |
| 527 | 526 | ||
| 528 | /* | 527 | /* |
| 529 | * Global transaction id (XID) information | 528 | * Global transaction id (XID) information |
| 530 | */ | 529 | */ |
| 531 | GLOBAL_EXTERN unsigned int GlobalCurrentXid; /* protected by GlobalMid_Sem */ | 530 | GLOBAL_EXTERN unsigned int GlobalCurrentXid; /* protected by GlobalMid_Sem */ |
| 532 | GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */ | 531 | GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */ |
| 533 | GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */ | 532 | GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */ |
| 534 | GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above and list operations */ | 533 | GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above & list operations */ |
| 535 | /* on midQ entries */ | 534 | /* on midQ entries */ |
| 536 | GLOBAL_EXTERN char Local_System_Name[15]; | 535 | GLOBAL_EXTERN char Local_System_Name[15]; |
| 537 | 536 | ||
| 538 | /* | 537 | /* |
| @@ -554,7 +553,7 @@ GLOBAL_EXTERN atomic_t smBufAllocCount; | |||
| 554 | GLOBAL_EXTERN atomic_t midCount; | 553 | GLOBAL_EXTERN atomic_t midCount; |
| 555 | 554 | ||
| 556 | /* Misc globals */ | 555 | /* Misc globals */ |
| 557 | GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions | 556 | GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions |
| 558 | to be established on existing mount if we | 557 | to be established on existing mount if we |
| 559 | have the uid/password or Kerberos credential | 558 | have the uid/password or Kerberos credential |
| 560 | or equivalent for current user */ | 559 | or equivalent for current user */ |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 135941738d9d..e714803a52dc 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
| @@ -426,6 +426,10 @@ typedef struct lanman_neg_rsp { | |||
| 426 | unsigned char EncryptionKey[1]; | 426 | unsigned char EncryptionKey[1]; |
| 427 | } __attribute__((packed)) LANMAN_NEG_RSP; | 427 | } __attribute__((packed)) LANMAN_NEG_RSP; |
| 428 | 428 | ||
| 429 | #define READ_RAW_ENABLE 1 | ||
| 430 | #define WRITE_RAW_ENABLE 2 | ||
| 431 | #define RAW_ENABLE (READ_RAW_ENABLE | WRITE_RAW_ENABLE) | ||
| 432 | |||
| 429 | typedef struct negotiate_rsp { | 433 | typedef struct negotiate_rsp { |
| 430 | struct smb_hdr hdr; /* wct = 17 */ | 434 | struct smb_hdr hdr; /* wct = 17 */ |
| 431 | __le16 DialectIndex; | 435 | __le16 DialectIndex; |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 77cca3809467..0442c3b36799 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -411,8 +411,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
| 411 | return rc; | 411 | return rc; |
| 412 | pSMB->hdr.Mid = GetNextMid(server); | 412 | pSMB->hdr.Mid = GetNextMid(server); |
| 413 | pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; | 413 | pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; |
| 414 | /* if (extended_security) | 414 | if((extended_security & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) |
| 415 | pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;*/ | 415 | pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; |
| 416 | 416 | ||
| 417 | count = 0; | 417 | count = 0; |
| 418 | for(i=0;i<CIFS_NUM_PROT;i++) { | 418 | for(i=0;i<CIFS_NUM_PROT;i++) { |
| @@ -425,162 +425,171 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
| 425 | 425 | ||
| 426 | rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, | 426 | rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, |
| 427 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 427 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 428 | if (rc == 0) { | 428 | if (rc != 0) |
| 429 | cFYI(1,("Dialect: %d", pSMBr->DialectIndex)); | 429 | goto neg_err_exit; |
| 430 | /* Check wct = 1 error case */ | 430 | |
| 431 | if((pSMBr->hdr.WordCount < 13) | 431 | cFYI(1,("Dialect: %d", pSMBr->DialectIndex)); |
| 432 | || (pSMBr->DialectIndex == BAD_PROT)) { | 432 | /* Check wct = 1 error case */ |
| 433 | /* core returns wct = 1, but we do not ask for | 433 | if((pSMBr->hdr.WordCount < 13) || (pSMBr->DialectIndex == BAD_PROT)) { |
| 434 | core - otherwise it just comes when dialect | 434 | /* core returns wct = 1, but we do not ask for core - otherwise |
| 435 | index is -1 indicating we could not negotiate | 435 | small wct just comes when dialect index is -1 indicating we |
| 436 | a common dialect */ | 436 | could not negotiate a common dialect */ |
| 437 | rc = -EOPNOTSUPP; | ||
| 438 | goto neg_err_exit; | ||
| 439 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | ||
| 440 | } else if((pSMBr->hdr.WordCount == 13) | ||
| 441 | && (pSMBr->DialectIndex == LANMAN_PROT)) { | ||
| 442 | struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr; | ||
| 443 | |||
| 444 | if((extended_security & CIFSSEC_MAY_LANMAN) || | ||
| 445 | (extended_security & CIFSSEC_MAY_PLNTXT)) | ||
| 446 | server->secType = LANMAN; | ||
| 447 | else { | ||
| 448 | cERROR(1, ("mount failed weak security disabled" | ||
| 449 | " in /proc/fs/cifs/SecurityFlags")); | ||
| 437 | rc = -EOPNOTSUPP; | 450 | rc = -EOPNOTSUPP; |
| 438 | goto neg_err_exit; | 451 | goto neg_err_exit; |
| 439 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | 452 | } |
| 440 | } else if((pSMBr->hdr.WordCount == 13) | 453 | server->secMode = (__u8)le16_to_cpu(rsp->SecurityMode); |
| 441 | && (pSMBr->DialectIndex == LANMAN_PROT)) { | 454 | server->maxReq = le16_to_cpu(rsp->MaxMpxCount); |
| 442 | struct lanman_neg_rsp * rsp = | 455 | server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize), |
| 443 | (struct lanman_neg_rsp *)pSMBr; | ||
| 444 | |||
| 445 | if((extended_security & CIFSSEC_MAY_LANMAN) || | ||
| 446 | (extended_security & CIFSSEC_MAY_PLNTXT)) | ||
| 447 | server->secType = LANMAN; | ||
| 448 | else { | ||
| 449 | cERROR(1, ("mount failed weak security disabled" | ||
| 450 | " in /proc/fs/cifs/SecurityFlags")); | ||
| 451 | rc = -EOPNOTSUPP; | ||
| 452 | goto neg_err_exit; | ||
| 453 | } | ||
| 454 | server->secMode = (__u8)le16_to_cpu(rsp->SecurityMode); | ||
| 455 | server->maxReq = le16_to_cpu(rsp->MaxMpxCount); | ||
| 456 | server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize), | ||
| 457 | (__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); | 456 | (__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); |
| 457 | GETU32(server->sessid) = le32_to_cpu(rsp->SessionKey); | ||
| 458 | /* even though we do not use raw we might as well set this | ||
| 459 | accurately, in case we ever find a need for it */ | ||
| 460 | if((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) { | ||
| 461 | server->maxRw = 0xFF00; | ||
| 462 | server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE; | ||
| 463 | } else { | ||
| 464 | server->maxRw = 0;/* we do not need to use raw anyway */ | ||
| 465 | server->capabilities = CAP_MPX_MODE; | ||
| 466 | } | ||
| 467 | server->timeZone = le16_to_cpu(rsp->ServerTimeZone); | ||
| 458 | 468 | ||
| 459 | /* BB what do we do with raw mode? BB */ | 469 | /* BB get server time for time conversions and add |
| 460 | server->timeZone = le16_to_cpu(rsp->ServerTimeZone); | 470 | code to use it and timezone since this is not UTC */ |
| 461 | /* Do we have to set signing flags? no signing | ||
| 462 | was available LANMAN - default should be ok */ | ||
| 463 | |||
| 464 | /* BB FIXME set default dummy capabilities since | ||
| 465 | they are not returned by the server in this dialect */ | ||
| 466 | |||
| 467 | /* get server time for time conversions and add | ||
| 468 | code to use it and timezone since this is not UTC */ | ||
| 469 | 471 | ||
| 470 | if (rsp->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { | 472 | if (rsp->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { |
| 471 | memcpy(server->cryptKey, rsp->EncryptionKey, | 473 | memcpy(server->cryptKey, rsp->EncryptionKey, |
| 472 | CIFS_CRYPTO_KEY_SIZE); | 474 | CIFS_CRYPTO_KEY_SIZE); |
| 473 | } else { | 475 | } else if (server->secMode & SECMODE_PW_ENCRYPT) { |
| 474 | rc = -EIO; | 476 | rc = -EIO; /* need cryptkey unless plain text */ |
| 475 | goto neg_err_exit; | 477 | goto neg_err_exit; |
| 476 | } | 478 | } |
| 477 | 479 | ||
| 478 | cFYI(1,("LANMAN negotiated")); /* BB removeme BB */ | 480 | cFYI(1,("LANMAN negotiated")); |
| 481 | /* we will not end up setting signing flags - as no signing | ||
| 482 | was in LANMAN and server did not return the flags on */ | ||
| 483 | goto signing_check; | ||
| 479 | #else /* weak security disabled */ | 484 | #else /* weak security disabled */ |
| 480 | } else if(pSMBr->hdr.WordCount == 13) { | 485 | } else if(pSMBr->hdr.WordCount == 13) { |
| 481 | cERROR(1,("mount failed, cifs module not built " | 486 | cERROR(1,("mount failed, cifs module not built " |
| 482 | "with CIFS_WEAK_PW_HASH support")); | 487 | "with CIFS_WEAK_PW_HASH support")); |
| 483 | rc = -EOPNOTSUPP; | 488 | rc = -EOPNOTSUPP; |
| 484 | #endif /* WEAK_PW_HASH */ | 489 | #endif /* WEAK_PW_HASH */ |
| 485 | goto neg_err_exit; | 490 | goto neg_err_exit; |
| 486 | } else if(pSMBr->hdr.WordCount != 17) { | 491 | } else if(pSMBr->hdr.WordCount != 17) { |
| 487 | /* unknown wct */ | 492 | /* unknown wct */ |
| 488 | rc = -EOPNOTSUPP; | 493 | rc = -EOPNOTSUPP; |
| 489 | goto neg_err_exit; | 494 | goto neg_err_exit; |
| 490 | } | 495 | } |
| 491 | 496 | /* else wct == 17 NTLM */ | |
| 492 | server->secMode = pSMBr->SecurityMode; | 497 | server->secMode = pSMBr->SecurityMode; |
| 493 | if((server->secMode & SECMODE_USER) == 0) | 498 | if((server->secMode & SECMODE_USER) == 0) |
| 494 | cFYI(1,("share mode security")); | 499 | cFYI(1,("share mode security")); |
| 495 | 500 | ||
| 496 | if((server->secMode & SECMODE_PW_ENCRYPT) == 0) | 501 | if((server->secMode & SECMODE_PW_ENCRYPT) == 0) |
| 497 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | 502 | #ifdef CONFIG_CIFS_WEAK_PW_HASH |
| 498 | if ((extended_security & CIFSSEC_MAY_PLNTXT) == 0) | 503 | if ((extended_security & CIFSSEC_MAY_PLNTXT) == 0) |
| 499 | #endif /* CIFS_WEAK_PW_HASH */ | 504 | #endif /* CIFS_WEAK_PW_HASH */ |
| 500 | cERROR(1,("Server requests plain text password" | 505 | cERROR(1,("Server requests plain text password" |
| 501 | " but client support disabled")); | 506 | " but client support disabled")); |
| 502 | 507 | ||
| 503 | if(extended_security & CIFSSEC_MUST_NTLMV2) | 508 | if(extended_security & CIFSSEC_MUST_NTLMV2) |
| 504 | server->secType = NTLMv2; | 509 | server->secType = NTLMv2; |
| 505 | else | 510 | else |
| 506 | server->secType = NTLM; | 511 | server->secType = NTLM; |
| 507 | /* else krb5 ... */ | 512 | /* else krb5 ... */ |
| 508 | 513 | ||
| 509 | /* one byte - no need to convert this or EncryptionKeyLen | 514 | /* one byte, so no need to convert this or EncryptionKeyLen from |
| 510 | from little endian */ | 515 | little endian */ |
| 511 | server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount); | 516 | server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount); |
| 512 | /* probably no need to store and check maxvcs */ | 517 | /* probably no need to store and check maxvcs */ |
| 513 | server->maxBuf = | 518 | server->maxBuf = min(le32_to_cpu(pSMBr->MaxBufferSize), |
| 514 | min(le32_to_cpu(pSMBr->MaxBufferSize), | ||
| 515 | (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); | 519 | (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); |
| 516 | server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); | 520 | server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); |
| 517 | cFYI(0, ("Max buf = %d", ses->server->maxBuf)); | 521 | cFYI(0, ("Max buf = %d", ses->server->maxBuf)); |
| 518 | GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); | 522 | GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); |
| 519 | server->capabilities = le32_to_cpu(pSMBr->Capabilities); | 523 | server->capabilities = le32_to_cpu(pSMBr->Capabilities); |
| 520 | server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone); | 524 | server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone); |
| 521 | /* BB with UTC do we ever need to be using srvr timezone? */ | 525 | if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { |
| 522 | if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { | 526 | memcpy(server->cryptKey, pSMBr->u.EncryptionKey, |
| 523 | memcpy(server->cryptKey, pSMBr->u.EncryptionKey, | 527 | CIFS_CRYPTO_KEY_SIZE); |
| 524 | CIFS_CRYPTO_KEY_SIZE); | 528 | } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) |
| 525 | } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) | 529 | && (pSMBr->EncryptionKeyLength == 0)) { |
| 526 | && (pSMBr->EncryptionKeyLength == 0)) { | 530 | /* decode security blob */ |
| 527 | /* decode security blob */ | 531 | } else if (server->secMode & SECMODE_PW_ENCRYPT) { |
| 528 | } else | 532 | rc = -EIO; /* no crypt key only if plain text pwd */ |
| 529 | rc = -EIO; | 533 | goto neg_err_exit; |
| 534 | } | ||
| 530 | 535 | ||
| 531 | /* BB might be helpful to save off the domain of server here */ | 536 | /* BB might be helpful to save off the domain of server here */ |
| 532 | 537 | ||
| 533 | if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) && | 538 | if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) && |
| 534 | (server->capabilities & CAP_EXTENDED_SECURITY)) { | 539 | (server->capabilities & CAP_EXTENDED_SECURITY)) { |
| 535 | count = pSMBr->ByteCount; | 540 | count = pSMBr->ByteCount; |
| 536 | if (count < 16) | 541 | if (count < 16) |
| 537 | rc = -EIO; | 542 | rc = -EIO; |
| 538 | else if (count == 16) { | 543 | else if (count == 16) { |
| 539 | server->secType = RawNTLMSSP; | 544 | server->secType = RawNTLMSSP; |
| 540 | if (server->socketUseCount.counter > 1) { | 545 | if (server->socketUseCount.counter > 1) { |
| 541 | if (memcmp | 546 | if (memcmp(server->server_GUID, |
| 542 | (server->server_GUID, | 547 | pSMBr->u.extended_response. |
| 543 | pSMBr->u.extended_response. | 548 | GUID, 16) != 0) { |
| 544 | GUID, 16) != 0) { | 549 | cFYI(1, ("server UID changed")); |
| 545 | cFYI(1, ("server UID changed")); | ||
| 546 | memcpy(server-> | ||
| 547 | server_GUID, | ||
| 548 | pSMBr->u. | ||
| 549 | extended_response. | ||
| 550 | GUID, 16); | ||
| 551 | } | ||
| 552 | } else | ||
| 553 | memcpy(server->server_GUID, | 550 | memcpy(server->server_GUID, |
| 554 | pSMBr->u.extended_response. | 551 | pSMBr->u.extended_response.GUID, |
| 555 | GUID, 16); | 552 | 16); |
| 556 | } else { | ||
| 557 | rc = decode_negTokenInit(pSMBr->u. | ||
| 558 | extended_response. | ||
| 559 | SecurityBlob, | ||
| 560 | count - 16, | ||
| 561 | &server->secType); | ||
| 562 | if(rc == 1) { | ||
| 563 | /* BB Need to fill struct for sessetup here */ | ||
| 564 | rc = -EOPNOTSUPP; | ||
| 565 | } else { | ||
| 566 | rc = -EINVAL; | ||
| 567 | } | 553 | } |
| 554 | } else | ||
| 555 | memcpy(server->server_GUID, | ||
| 556 | pSMBr->u.extended_response.GUID, 16); | ||
| 557 | } else { | ||
| 558 | rc = decode_negTokenInit(pSMBr->u.extended_response. | ||
| 559 | SecurityBlob, | ||
| 560 | count - 16, | ||
| 561 | &server->secType); | ||
| 562 | if(rc == 1) { | ||
| 563 | /* BB Need to fill struct for sessetup here */ | ||
| 564 | rc = -EOPNOTSUPP; | ||
| 565 | } else { | ||
| 566 | rc = -EINVAL; | ||
| 568 | } | 567 | } |
| 569 | } else | ||
| 570 | server->capabilities &= ~CAP_EXTENDED_SECURITY; | ||
| 571 | if(sign_CIFS_PDUs == FALSE) { | ||
| 572 | if(server->secMode & SECMODE_SIGN_REQUIRED) | ||
| 573 | cERROR(1, | ||
| 574 | ("Server requires /proc/fs/cifs/PacketSigningEnabled")); | ||
| 575 | server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); | ||
| 576 | } else if(sign_CIFS_PDUs == 1) { | ||
| 577 | if((server->secMode & SECMODE_SIGN_REQUIRED) == 0) | ||
| 578 | server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); | ||
| 579 | } | 568 | } |
| 580 | 569 | } else | |
| 570 | server->capabilities &= ~CAP_EXTENDED_SECURITY; | ||
| 571 | |||
| 572 | signing_check: | ||
| 573 | if(sign_CIFS_PDUs == FALSE) { | ||
| 574 | if(server->secMode & SECMODE_SIGN_REQUIRED) | ||
| 575 | cERROR(1,("Server requires " | ||
| 576 | "/proc/fs/cifs/PacketSigningEnabled to be on")); | ||
| 577 | server->secMode &= | ||
| 578 | ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); | ||
| 579 | } else if(sign_CIFS_PDUs == 1) { | ||
| 580 | if((server->secMode & SECMODE_SIGN_REQUIRED) == 0) | ||
| 581 | server->secMode &= | ||
| 582 | ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); | ||
| 583 | } else if(sign_CIFS_PDUs == 2) { | ||
| 584 | if((server->secMode & | ||
| 585 | (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) { | ||
| 586 | cERROR(1,("signing required but server lacks support")); | ||
| 587 | } | ||
| 581 | } | 588 | } |
| 582 | neg_err_exit: | 589 | neg_err_exit: |
| 583 | cifs_buf_release(pSMB); | 590 | cifs_buf_release(pSMB); |
| 591 | |||
| 592 | cFYI(1,("negprot rc %d",rc)); | ||
| 584 | return rc; | 593 | return rc; |
| 585 | } | 594 | } |
| 586 | 595 | ||
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index a52aacb3feff..76a09f5f804f 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
| @@ -323,7 +323,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
| 323 | enum securityEnum type; | 323 | enum securityEnum type; |
| 324 | __u16 action; | 324 | __u16 action; |
| 325 | int bytes_remaining; | 325 | int bytes_remaining; |
| 326 | 326 | ||
| 327 | cFYI(1,("new sess setup")); | ||
| 327 | if(ses == NULL) | 328 | if(ses == NULL) |
| 328 | return -EINVAL; | 329 | return -EINVAL; |
| 329 | 330 | ||
