diff options
-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 | ||