diff options
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r-- | fs/cifs/connect.c | 99 |
1 files changed, 51 insertions, 48 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 2a0c1f4ca0ae..0b86d5ca9014 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs/connect.c | 2 | * fs/cifs/connect.c |
3 | * | 3 | * |
4 | * Copyright (C) International Business Machines Corp., 2002,2005 | 4 | * Copyright (C) International Business Machines Corp., 2002,2006 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * | 6 | * |
7 | * This library is free software; you can redistribute it and/or modify | 7 | * This library is free software; you can redistribute it and/or modify |
@@ -564,7 +564,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
564 | 564 | ||
565 | 565 | ||
566 | dump_smb(smb_buffer, length); | 566 | dump_smb(smb_buffer, length); |
567 | if (checkSMB (smb_buffer, smb_buffer->Mid, total_read+4)) { | 567 | if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) { |
568 | cifs_dump_mem("Bad SMB: ", smb_buffer, 48); | 568 | cifs_dump_mem("Bad SMB: ", smb_buffer, 48); |
569 | continue; | 569 | continue; |
570 | } | 570 | } |
@@ -1476,6 +1476,14 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, | |||
1476 | rc = smb_send(*csocket, smb_buf, 0x44, | 1476 | rc = smb_send(*csocket, smb_buf, 0x44, |
1477 | (struct sockaddr *)psin_server); | 1477 | (struct sockaddr *)psin_server); |
1478 | kfree(ses_init_buf); | 1478 | kfree(ses_init_buf); |
1479 | msleep(1); /* RFC1001 layer in at least one server | ||
1480 | requires very short break before negprot | ||
1481 | presumably because not expecting negprot | ||
1482 | to follow so fast. This is a simple | ||
1483 | solution that works without | ||
1484 | complicating the code and causes no | ||
1485 | significant slowing down on mount | ||
1486 | for everyone else */ | ||
1479 | } | 1487 | } |
1480 | /* else the negprot may still work without this | 1488 | /* else the negprot may still work without this |
1481 | even though malloc failed */ | 1489 | even though malloc failed */ |
@@ -1920,27 +1928,34 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1920 | cifs_sb->tcon = tcon; | 1928 | cifs_sb->tcon = tcon; |
1921 | tcon->ses = pSesInfo; | 1929 | tcon->ses = pSesInfo; |
1922 | 1930 | ||
1923 | /* do not care if following two calls succeed - informational only */ | 1931 | /* do not care if following two calls succeed - informational */ |
1924 | CIFSSMBQFSDeviceInfo(xid, tcon); | 1932 | CIFSSMBQFSDeviceInfo(xid, tcon); |
1925 | CIFSSMBQFSAttributeInfo(xid, tcon); | 1933 | CIFSSMBQFSAttributeInfo(xid, tcon); |
1934 | |||
1926 | if (tcon->ses->capabilities & CAP_UNIX) { | 1935 | if (tcon->ses->capabilities & CAP_UNIX) { |
1927 | if(!CIFSSMBQFSUnixInfo(xid, tcon)) { | 1936 | if(!CIFSSMBQFSUnixInfo(xid, tcon)) { |
1928 | if(!volume_info.no_psx_acl) { | 1937 | __u64 cap = |
1929 | if(CIFS_UNIX_POSIX_ACL_CAP & | 1938 | le64_to_cpu(tcon->fsUnixInfo.Capability); |
1930 | le64_to_cpu(tcon->fsUnixInfo.Capability)) | 1939 | cap &= CIFS_UNIX_CAP_MASK; |
1931 | cFYI(1,("server negotiated posix acl support")); | 1940 | if(volume_info.no_psx_acl) |
1932 | sb->s_flags |= MS_POSIXACL; | 1941 | cap &= ~CIFS_UNIX_POSIX_ACL_CAP; |
1942 | else if(CIFS_UNIX_POSIX_ACL_CAP & cap) { | ||
1943 | cFYI(1,("negotiated posix acl support")); | ||
1944 | sb->s_flags |= MS_POSIXACL; | ||
1933 | } | 1945 | } |
1934 | 1946 | ||
1935 | /* Try and negotiate POSIX pathnames if we can. */ | 1947 | if(volume_info.posix_paths == 0) |
1936 | if (volume_info.posix_paths && (CIFS_UNIX_POSIX_PATHNAMES_CAP & | 1948 | cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; |
1937 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { | 1949 | else if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) { |
1938 | if (!CIFSSMBSetFSUnixInfo(xid, tcon, CIFS_UNIX_POSIX_PATHNAMES_CAP)) { | 1950 | cFYI(1,("negotiate posix pathnames")); |
1939 | cFYI(1,("negotiated posix pathnames support")); | 1951 | cifs_sb->mnt_cifs_flags |= |
1940 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS; | 1952 | CIFS_MOUNT_POSIX_PATHS; |
1941 | } else { | 1953 | } |
1942 | cFYI(1,("posix pathnames support requested but not supported")); | 1954 | |
1943 | } | 1955 | cFYI(1,("Negotiate caps 0x%x",(int)cap)); |
1956 | |||
1957 | if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { | ||
1958 | cFYI(1,("setting capabilities failed")); | ||
1944 | } | 1959 | } |
1945 | } | 1960 | } |
1946 | } | 1961 | } |
@@ -2278,6 +2293,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2278 | smb_buffer->Mid = GetNextMid(ses->server); | 2293 | smb_buffer->Mid = GetNextMid(ses->server); |
2279 | pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; | 2294 | pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; |
2280 | pSMB->req.AndXCommand = 0xFF; | 2295 | pSMB->req.AndXCommand = 0xFF; |
2296 | if(ses->server->maxBuf > 64*1024) | ||
2297 | ses->server->maxBuf = (64*1023); | ||
2281 | pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); | 2298 | pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); |
2282 | pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); | 2299 | pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); |
2283 | 2300 | ||
@@ -2525,7 +2542,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2525 | __u32 negotiate_flags, capabilities; | 2542 | __u32 negotiate_flags, capabilities; |
2526 | __u16 count; | 2543 | __u16 count; |
2527 | 2544 | ||
2528 | cFYI(1, ("In NTLMSSP sesssetup (negotiate) ")); | 2545 | cFYI(1, ("In NTLMSSP sesssetup (negotiate)")); |
2529 | if(ses == NULL) | 2546 | if(ses == NULL) |
2530 | return -EINVAL; | 2547 | return -EINVAL; |
2531 | domain = ses->domainName; | 2548 | domain = ses->domainName; |
@@ -2575,7 +2592,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2575 | SecurityBlob->MessageType = NtLmNegotiate; | 2592 | SecurityBlob->MessageType = NtLmNegotiate; |
2576 | negotiate_flags = | 2593 | negotiate_flags = |
2577 | NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM | | 2594 | NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM | |
2578 | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | 0x80000000 | | 2595 | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | |
2596 | NTLMSSP_NEGOTIATE_56 | | ||
2579 | /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128; | 2597 | /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128; |
2580 | if(sign_CIFS_PDUs) | 2598 | if(sign_CIFS_PDUs) |
2581 | negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN; | 2599 | negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN; |
@@ -2588,26 +2606,11 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2588 | SecurityBlob->WorkstationName.Length = 0; | 2606 | SecurityBlob->WorkstationName.Length = 0; |
2589 | SecurityBlob->WorkstationName.MaximumLength = 0; | 2607 | SecurityBlob->WorkstationName.MaximumLength = 0; |
2590 | 2608 | ||
2591 | if (domain == NULL) { | 2609 | /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent |
2592 | SecurityBlob->DomainName.Buffer = 0; | 2610 | along with username on auth request (ie the response to challenge) */ |
2593 | SecurityBlob->DomainName.Length = 0; | 2611 | SecurityBlob->DomainName.Buffer = 0; |
2594 | SecurityBlob->DomainName.MaximumLength = 0; | 2612 | SecurityBlob->DomainName.Length = 0; |
2595 | } else { | 2613 | SecurityBlob->DomainName.MaximumLength = 0; |
2596 | __u16 len; | ||
2597 | negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED; | ||
2598 | strncpy(bcc_ptr, domain, 63); | ||
2599 | len = strnlen(domain, 64); | ||
2600 | SecurityBlob->DomainName.MaximumLength = | ||
2601 | cpu_to_le16(len); | ||
2602 | SecurityBlob->DomainName.Buffer = | ||
2603 | cpu_to_le32((long) &SecurityBlob-> | ||
2604 | DomainString - | ||
2605 | (long) &SecurityBlob->Signature); | ||
2606 | bcc_ptr += len; | ||
2607 | SecurityBlobLength += len; | ||
2608 | SecurityBlob->DomainName.Length = | ||
2609 | cpu_to_le16(len); | ||
2610 | } | ||
2611 | if (ses->capabilities & CAP_UNICODE) { | 2614 | if (ses->capabilities & CAP_UNICODE) { |
2612 | if ((long) bcc_ptr % 2) { | 2615 | if ((long) bcc_ptr % 2) { |
2613 | *bcc_ptr = 0; | 2616 | *bcc_ptr = 0; |
@@ -2677,7 +2680,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2677 | SecurityBlob2->MessageType)); | 2680 | SecurityBlob2->MessageType)); |
2678 | } else if (ses) { | 2681 | } else if (ses) { |
2679 | ses->Suid = smb_buffer_response->Uid; /* UID left in le format */ | 2682 | ses->Suid = smb_buffer_response->Uid; /* UID left in le format */ |
2680 | cFYI(1, ("UID = %d ", ses->Suid)); | 2683 | cFYI(1, ("UID = %d", ses->Suid)); |
2681 | if ((pSMBr->resp.hdr.WordCount == 3) | 2684 | if ((pSMBr->resp.hdr.WordCount == 3) |
2682 | || ((pSMBr->resp.hdr.WordCount == 4) | 2685 | || ((pSMBr->resp.hdr.WordCount == 4) |
2683 | && (blob_len < | 2686 | && (blob_len < |
@@ -2685,17 +2688,17 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2685 | 2688 | ||
2686 | if (pSMBr->resp.hdr.WordCount == 4) { | 2689 | if (pSMBr->resp.hdr.WordCount == 4) { |
2687 | bcc_ptr += blob_len; | 2690 | bcc_ptr += blob_len; |
2688 | cFYI(1, | 2691 | cFYI(1, ("Security Blob Length %d", |
2689 | ("Security Blob Length %d ", | ||
2690 | blob_len)); | 2692 | blob_len)); |
2691 | } | 2693 | } |
2692 | 2694 | ||
2693 | cFYI(1, ("NTLMSSP Challenge rcvd ")); | 2695 | cFYI(1, ("NTLMSSP Challenge rcvd")); |
2694 | 2696 | ||
2695 | memcpy(ses->server->cryptKey, | 2697 | memcpy(ses->server->cryptKey, |
2696 | SecurityBlob2->Challenge, | 2698 | SecurityBlob2->Challenge, |
2697 | CIFS_CRYPTO_KEY_SIZE); | 2699 | CIFS_CRYPTO_KEY_SIZE); |
2698 | if(SecurityBlob2->NegotiateFlags & cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2)) | 2700 | if(SecurityBlob2->NegotiateFlags & |
2701 | cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2)) | ||
2699 | *pNTLMv2_flag = TRUE; | 2702 | *pNTLMv2_flag = TRUE; |
2700 | 2703 | ||
2701 | if((SecurityBlob2->NegotiateFlags & | 2704 | if((SecurityBlob2->NegotiateFlags & |
@@ -2818,7 +2821,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2818 | bcc_ptr++; | 2821 | bcc_ptr++; |
2819 | } else | 2822 | } else |
2820 | cFYI(1, | 2823 | cFYI(1, |
2821 | ("Variable field of length %d extends beyond end of smb ", | 2824 | ("Variable field of length %d extends beyond end of smb", |
2822 | len)); | 2825 | len)); |
2823 | } | 2826 | } |
2824 | } else { | 2827 | } else { |
@@ -2830,7 +2833,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2830 | } | 2833 | } |
2831 | } else { | 2834 | } else { |
2832 | cERROR(1, | 2835 | cERROR(1, |
2833 | (" Invalid Word count %d: ", | 2836 | (" Invalid Word count %d:", |
2834 | smb_buffer_response->WordCount)); | 2837 | smb_buffer_response->WordCount)); |
2835 | rc = -EIO; | 2838 | rc = -EIO; |
2836 | } | 2839 | } |
@@ -3447,7 +3450,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, | |||
3447 | if (extended_security | 3450 | if (extended_security |
3448 | && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) | 3451 | && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) |
3449 | && (pSesInfo->server->secType == NTLMSSP)) { | 3452 | && (pSesInfo->server->secType == NTLMSSP)) { |
3450 | cFYI(1, ("New style sesssetup ")); | 3453 | cFYI(1, ("New style sesssetup")); |
3451 | rc = CIFSSpnegoSessSetup(xid, pSesInfo, | 3454 | rc = CIFSSpnegoSessSetup(xid, pSesInfo, |
3452 | NULL /* security blob */, | 3455 | NULL /* security blob */, |
3453 | 0 /* blob length */, | 3456 | 0 /* blob length */, |
@@ -3455,7 +3458,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, | |||
3455 | } else if (extended_security | 3458 | } else if (extended_security |
3456 | && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) | 3459 | && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) |
3457 | && (pSesInfo->server->secType == RawNTLMSSP)) { | 3460 | && (pSesInfo->server->secType == RawNTLMSSP)) { |
3458 | cFYI(1, ("NTLMSSP sesssetup ")); | 3461 | cFYI(1, ("NTLMSSP sesssetup")); |
3459 | rc = CIFSNTLMSSPNegotiateSessSetup(xid, | 3462 | rc = CIFSNTLMSSPNegotiateSessSetup(xid, |
3460 | pSesInfo, | 3463 | pSesInfo, |
3461 | &ntlmv2_flag, | 3464 | &ntlmv2_flag, |