summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/connect.c730
1 files changed, 0 insertions, 730 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 9dcdb0c707ea..3a934dd84225 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2605,736 +2605,6 @@ out:
return rc;
}
-static int
-CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
- struct cifsSesInfo *ses, bool *pNTLMv2_flag,
- const struct nls_table *nls_codepage)
-{
- struct smb_hdr *smb_buffer;
- struct smb_hdr *smb_buffer_response;
- SESSION_SETUP_ANDX *pSMB;
- SESSION_SETUP_ANDX *pSMBr;
- char *bcc_ptr;
- char *domain;
- int rc = 0;
- int remaining_words = 0;
- int bytes_returned = 0;
- int len;
- int SecurityBlobLength = sizeof(NEGOTIATE_MESSAGE);
- PNEGOTIATE_MESSAGE SecurityBlob;
- PCHALLENGE_MESSAGE SecurityBlob2;
- __u32 negotiate_flags, capabilities;
- __u16 count;
-
- cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
- if (ses == NULL)
- return -EINVAL;
- domain = ses->domainName;
- *pNTLMv2_flag = false;
- smb_buffer = cifs_buf_get();
- if (smb_buffer == NULL) {
- return -ENOMEM;
- }
- smb_buffer_response = smb_buffer;
- pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
- pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
-
- /* send SMBsessionSetup here */
- header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
- NULL /* no tCon exists yet */ , 12 /* wct */ );
-
- smb_buffer->Mid = GetNextMid(ses->server);
- pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
- pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
-
- pSMB->req.AndXCommand = 0xFF;
- pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
- pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
-
- if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
- smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-
- capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
- CAP_EXTENDED_SECURITY;
- if (ses->capabilities & CAP_UNICODE) {
- smb_buffer->Flags2 |= SMBFLG2_UNICODE;
- capabilities |= CAP_UNICODE;
- }
- if (ses->capabilities & CAP_STATUS32) {
- smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
- capabilities |= CAP_STATUS32;
- }
- if (ses->capabilities & CAP_DFS) {
- smb_buffer->Flags2 |= SMBFLG2_DFS;
- capabilities |= CAP_DFS;
- }
- pSMB->req.Capabilities = cpu_to_le32(capabilities);
-
- bcc_ptr = (char *) &pSMB->req.SecurityBlob;
- SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
- strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
- SecurityBlob->MessageType = NtLmNegotiate;
- negotiate_flags =
- NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
- NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
- NTLMSSP_NEGOTIATE_56 |
- /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
- if (sign_CIFS_PDUs)
- negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
- /* setup pointers to domain name and workstation name */
- bcc_ptr += SecurityBlobLength;
-
- SecurityBlob->WorkstationName.BufferOffset = 0;
- SecurityBlob->WorkstationName.Length = 0;
- SecurityBlob->WorkstationName.MaximumLength = 0;
-
- /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
- along with username on auth request (ie the response to challenge) */
- SecurityBlob->DomainName.BufferOffset = 0;
- SecurityBlob->DomainName.Length = 0;
- SecurityBlob->DomainName.MaximumLength = 0;
- if (ses->capabilities & CAP_UNICODE) {
- if ((long) bcc_ptr % 2) {
- *bcc_ptr = 0;
- bcc_ptr++;
- }
-
- bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
- 32, nls_codepage);
- bcc_ptr += 2 * bytes_returned;
- bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
- nls_codepage);
- bcc_ptr += 2 * bytes_returned;
- bcc_ptr += 2; /* null terminate Linux version */
- bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
- 64, nls_codepage);
- bcc_ptr += 2 * bytes_returned;
- *(bcc_ptr + 1) = 0;
- *(bcc_ptr + 2) = 0;
- bcc_ptr += 2; /* null terminate network opsys string */
- *(bcc_ptr + 1) = 0;
- *(bcc_ptr + 2) = 0;
- bcc_ptr += 2; /* null domain */
- } else { /* ASCII */
- strcpy(bcc_ptr, "Linux version ");
- bcc_ptr += strlen("Linux version ");
- strcpy(bcc_ptr, utsname()->release);
- bcc_ptr += strlen(utsname()->release) + 1;
- strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
- bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
- bcc_ptr++; /* empty domain field */
- *bcc_ptr = 0;
- }
- SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
- pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
- count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
- smb_buffer->smb_buf_length += count;
- pSMB->req.ByteCount = cpu_to_le16(count);
-
- rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
- &bytes_returned, CIFS_LONG_OP);
-
- if (smb_buffer_response->Status.CifsError ==
- cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
- rc = 0;
-
- if (rc) {
-/* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
- } else if ((smb_buffer_response->WordCount == 3)
- || (smb_buffer_response->WordCount == 4)) {
- __u16 action = le16_to_cpu(pSMBr->resp.Action);
- __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
-
- if (action & GUEST_LOGIN)
- cFYI(1, ("Guest login"));
- /* Do we want to set anything in SesInfo struct when guest login? */
-
- bcc_ptr = pByteArea(smb_buffer_response);
- /* response can have either 3 or 4 word count - Samba sends 3 */
-
- SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
- if (SecurityBlob2->MessageType != NtLmChallenge) {
- cFYI(1, ("Unexpected NTLMSSP message type received %d",
- SecurityBlob2->MessageType));
- } else if (ses) {
- ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
- cFYI(1, ("UID = %d", ses->Suid));
- if ((pSMBr->resp.hdr.WordCount == 3)
- || ((pSMBr->resp.hdr.WordCount == 4)
- && (blob_len <
- pSMBr->resp.ByteCount))) {
-
- if (pSMBr->resp.hdr.WordCount == 4) {
- bcc_ptr += blob_len;
- cFYI(1, ("Security Blob Length %d",
- blob_len));
- }
-
- cFYI(1, ("NTLMSSP Challenge rcvd"));
-
- memcpy(ses->server->cryptKey,
- SecurityBlob2->Challenge,
- CIFS_CRYPTO_KEY_SIZE);
-/* NTLMV2 flag is not for NTLMv2 password hash */
-/* if (SecurityBlob2->NegotiateFlags &
- cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
- *pNTLMv2_flag = true; */ /* BB wrong */
-
- if ((SecurityBlob2->NegotiateFlags &
- cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
- || (sign_CIFS_PDUs > 1))
- ses->server->secMode |=
- SECMODE_SIGN_REQUIRED;
- if ((SecurityBlob2->NegotiateFlags &
- cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
- ses->server->secMode |=
- SECMODE_SIGN_ENABLED;
-
- if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
- if ((long) (bcc_ptr) % 2) {
- remaining_words =
- (BCC(smb_buffer_response)
- - 1) / 2;
- /* Must word align unicode strings */
- bcc_ptr++;
- } else {
- remaining_words =
- BCC
- (smb_buffer_response) / 2;
- }
- len =
- UniStrnlen((wchar_t *) bcc_ptr,
- remaining_words - 1);
-/* We look for obvious messed up bcc or strings in response so we do not go off
- the end since (at least) WIN2K and Windows XP have a major bug in not null
- terminating last Unicode string in response */
- kfree(ses->serverOS);
- ses->serverOS =
- kzalloc(2 * (len + 1), GFP_KERNEL);
- cifs_strfromUCS_le(ses->serverOS,
- (__le16 *)
- bcc_ptr, len,
- nls_codepage);
- bcc_ptr += 2 * (len + 1);
- remaining_words -= len + 1;
- ses->serverOS[2 * len] = 0;
- ses->serverOS[1 + (2 * len)] = 0;
- if (remaining_words > 0) {
- len = UniStrnlen((wchar_t *)
- bcc_ptr,
- remaining_words
- - 1);
- kfree(ses->serverNOS);
- ses->serverNOS =
- kzalloc(2 * (len + 1),
- GFP_KERNEL);
- cifs_strfromUCS_le(ses->
- serverNOS,
- (__le16 *)
- bcc_ptr,
- len,
- nls_codepage);
- bcc_ptr += 2 * (len + 1);
- ses->serverNOS[2 * len] = 0;
- ses->serverNOS[1 +
- (2 * len)] = 0;
- remaining_words -= len + 1;
- if (remaining_words > 0) {
- len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
- /* last string not always null terminated
- (for e.g. for Windows XP & 2000) */
- kfree(ses->serverDomain);
- ses->serverDomain =
- kzalloc(2 *
- (len +
- 1),
- GFP_KERNEL);
- cifs_strfromUCS_le
- (ses->serverDomain,
- (__le16 *)bcc_ptr,
- len, nls_codepage);
- bcc_ptr +=
- 2 * (len + 1);
- ses->serverDomain[2*len]
- = 0;
- ses->serverDomain
- [1 + (2 * len)]
- = 0;
- } /* else no more room so create dummy domain string */
- else {
- kfree(ses->serverDomain);
- ses->serverDomain =
- kzalloc(2,
- GFP_KERNEL);
- }
- } else { /* no room so create dummy domain and NOS string */
- kfree(ses->serverDomain);
- ses->serverDomain =
- kzalloc(2, GFP_KERNEL);
- kfree(ses->serverNOS);
- ses->serverNOS =
- kzalloc(2, GFP_KERNEL);
- }
- } else { /* ASCII */
- len = strnlen(bcc_ptr, 1024);
- if (((long) bcc_ptr + len) - (long)
- pByteArea(smb_buffer_response)
- <= BCC(smb_buffer_response)) {
- kfree(ses->serverOS);
- ses->serverOS =
- kzalloc(len + 1,
- GFP_KERNEL);
- strncpy(ses->serverOS,
- bcc_ptr, len);
-
- bcc_ptr += len;
- bcc_ptr[0] = 0; /* null terminate string */
- bcc_ptr++;
-
- len = strnlen(bcc_ptr, 1024);
- kfree(ses->serverNOS);
- ses->serverNOS =
- kzalloc(len + 1,
- GFP_KERNEL);
- strncpy(ses->serverNOS, bcc_ptr, len);
- bcc_ptr += len;
- bcc_ptr[0] = 0;
- bcc_ptr++;
-
- len = strnlen(bcc_ptr, 1024);
- kfree(ses->serverDomain);
- ses->serverDomain =
- kzalloc(len + 1,
- GFP_KERNEL);
- strncpy(ses->serverDomain,
- bcc_ptr, len);
- bcc_ptr += len;
- bcc_ptr[0] = 0;
- bcc_ptr++;
- } else
- cFYI(1,
- ("field of length %d "
- "extends beyond end of smb",
- len));
- }
- } else {
- cERROR(1, ("Security Blob Length extends beyond"
- " end of SMB"));
- }
- } else {
- cERROR(1, ("No session structure passed in."));
- }
- } else {
- cERROR(1, ("Invalid Word count %d:",
- smb_buffer_response->WordCount));
- rc = -EIO;
- }
-
- cifs_buf_release(smb_buffer);
-
- return rc;
-}
-
-static int
-CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
- char *ntlm_session_key, bool ntlmv2_flag,
- const struct nls_table *nls_codepage)
-{
- struct smb_hdr *smb_buffer;
- struct smb_hdr *smb_buffer_response;
- SESSION_SETUP_ANDX *pSMB;
- SESSION_SETUP_ANDX *pSMBr;
- char *bcc_ptr;
- char *user;
- char *domain;
- int rc = 0;
- int remaining_words = 0;
- int bytes_returned = 0;
- int len;
- int SecurityBlobLength = sizeof(AUTHENTICATE_MESSAGE);
- PAUTHENTICATE_MESSAGE SecurityBlob;
- __u32 negotiate_flags, capabilities;
- __u16 count;
-
- cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
- if (ses == NULL)
- return -EINVAL;
- user = ses->userName;
- domain = ses->domainName;
- smb_buffer = cifs_buf_get();
- if (smb_buffer == NULL) {
- return -ENOMEM;
- }
- smb_buffer_response = smb_buffer;
- pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
- pSMBr = (SESSION_SETUP_ANDX *)smb_buffer_response;
-
- /* send SMBsessionSetup here */
- header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
- NULL /* no tCon exists yet */ , 12 /* wct */ );
-
- smb_buffer->Mid = GetNextMid(ses->server);
- pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
- pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
- pSMB->req.AndXCommand = 0xFF;
- pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
- pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
-
- pSMB->req.hdr.Uid = ses->Suid;
-
- if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
- smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-
- capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
- CAP_EXTENDED_SECURITY;
- if (ses->capabilities & CAP_UNICODE) {
- smb_buffer->Flags2 |= SMBFLG2_UNICODE;
- capabilities |= CAP_UNICODE;
- }
- if (ses->capabilities & CAP_STATUS32) {
- smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
- capabilities |= CAP_STATUS32;
- }
- if (ses->capabilities & CAP_DFS) {
- smb_buffer->Flags2 |= SMBFLG2_DFS;
- capabilities |= CAP_DFS;
- }
- pSMB->req.Capabilities = cpu_to_le32(capabilities);
-
- bcc_ptr = (char *)&pSMB->req.SecurityBlob;
- SecurityBlob = (PAUTHENTICATE_MESSAGE)bcc_ptr;
- strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
- SecurityBlob->MessageType = NtLmAuthenticate;
- bcc_ptr += SecurityBlobLength;
- negotiate_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
- NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
- NTLMSSP_NEGOTIATE_56 | NTLMSSP_NEGOTIATE_128 |
- NTLMSSP_NEGOTIATE_EXTENDED_SEC;
- if (sign_CIFS_PDUs)
- negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
-
-/* setup pointers to domain name and workstation name */
-
- SecurityBlob->WorkstationName.BufferOffset = 0;
- SecurityBlob->WorkstationName.Length = 0;
- SecurityBlob->WorkstationName.MaximumLength = 0;
- SecurityBlob->SessionKey.Length = 0;
- SecurityBlob->SessionKey.MaximumLength = 0;
- SecurityBlob->SessionKey.BufferOffset = 0;
-
- SecurityBlob->LmChallengeResponse.Length = 0;
- SecurityBlob->LmChallengeResponse.MaximumLength = 0;
- SecurityBlob->LmChallengeResponse.BufferOffset = 0;
-
- SecurityBlob->NtChallengeResponse.Length =
- cpu_to_le16(CIFS_SESS_KEY_SIZE);
- SecurityBlob->NtChallengeResponse.MaximumLength =
- cpu_to_le16(CIFS_SESS_KEY_SIZE);
- memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
- SecurityBlob->NtChallengeResponse.BufferOffset =
- cpu_to_le32(SecurityBlobLength);
- SecurityBlobLength += CIFS_SESS_KEY_SIZE;
- bcc_ptr += CIFS_SESS_KEY_SIZE;
-
- if (ses->capabilities & CAP_UNICODE) {
- if (domain == NULL) {
- SecurityBlob->DomainName.BufferOffset = 0;
- SecurityBlob->DomainName.Length = 0;
- SecurityBlob->DomainName.MaximumLength = 0;
- } else {
- __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
- nls_codepage);
- ln *= 2;
- SecurityBlob->DomainName.MaximumLength =
- cpu_to_le16(ln);
- SecurityBlob->DomainName.BufferOffset =
- cpu_to_le32(SecurityBlobLength);
- bcc_ptr += ln;
- SecurityBlobLength += ln;
- SecurityBlob->DomainName.Length = cpu_to_le16(ln);
- }
- if (user == NULL) {
- SecurityBlob->UserName.BufferOffset = 0;
- SecurityBlob->UserName.Length = 0;
- SecurityBlob->UserName.MaximumLength = 0;
- } else {
- __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
- nls_codepage);
- ln *= 2;
- SecurityBlob->UserName.MaximumLength =
- cpu_to_le16(ln);
- SecurityBlob->UserName.BufferOffset =
- cpu_to_le32(SecurityBlobLength);
- bcc_ptr += ln;
- SecurityBlobLength += ln;
- SecurityBlob->UserName.Length = cpu_to_le16(ln);
- }
-
- /* SecurityBlob->WorkstationName.Length =
- cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
- SecurityBlob->WorkstationName.Length *= 2;
- SecurityBlob->WorkstationName.MaximumLength =
- cpu_to_le16(SecurityBlob->WorkstationName.Length);
- SecurityBlob->WorkstationName.BufferOffset =
- cpu_to_le32(SecurityBlobLength);
- bcc_ptr += SecurityBlob->WorkstationName.Length;
- SecurityBlobLength += SecurityBlob->WorkstationName.Length;
- SecurityBlob->WorkstationName.Length =
- cpu_to_le16(SecurityBlob->WorkstationName.Length); */
-
- if ((long) bcc_ptr % 2) {
- *bcc_ptr = 0;
- bcc_ptr++;
- }
- bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
- 32, nls_codepage);
- bcc_ptr += 2 * bytes_returned;
- bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
- nls_codepage);
- bcc_ptr += 2 * bytes_returned;
- bcc_ptr += 2; /* null term version string */
- bytes_returned =
- cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
- 64, nls_codepage);
- bcc_ptr += 2 * bytes_returned;
- *(bcc_ptr + 1) = 0;
- *(bcc_ptr + 2) = 0;
- bcc_ptr += 2; /* null terminate network opsys string */
- *(bcc_ptr + 1) = 0;
- *(bcc_ptr + 2) = 0;
- bcc_ptr += 2; /* null domain */
- } else { /* ASCII */
- if (domain == NULL) {
- SecurityBlob->DomainName.BufferOffset = 0;
- SecurityBlob->DomainName.Length = 0;
- SecurityBlob->DomainName.MaximumLength = 0;
- } else {
- __u16 ln;
- negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
- strncpy(bcc_ptr, domain, 63);
- ln = strnlen(domain, 64);
- SecurityBlob->DomainName.MaximumLength =
- cpu_to_le16(ln);
- SecurityBlob->DomainName.BufferOffset =
- cpu_to_le32(SecurityBlobLength);
- bcc_ptr += ln;
- SecurityBlobLength += ln;
- SecurityBlob->DomainName.Length = cpu_to_le16(ln);
- }
- if (user == NULL) {
- SecurityBlob->UserName.BufferOffset = 0;
- SecurityBlob->UserName.Length = 0;
- SecurityBlob->UserName.MaximumLength = 0;
- } else {
- __u16 ln;
- strncpy(bcc_ptr, user, 63);
- ln = strnlen(user, 64);
- SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln);
- SecurityBlob->UserName.BufferOffset =
- cpu_to_le32(SecurityBlobLength);
- bcc_ptr += ln;
- SecurityBlobLength += ln;
- SecurityBlob->UserName.Length = cpu_to_le16(ln);
- }
- /* BB fill in our workstation name if known BB */
-
- strcpy(bcc_ptr, "Linux version ");
- bcc_ptr += strlen("Linux version ");
- strcpy(bcc_ptr, utsname()->release);
- bcc_ptr += strlen(utsname()->release) + 1;
- strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
- bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
- bcc_ptr++; /* null domain */
- *bcc_ptr = 0;
- }
- SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
- pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
- count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
- smb_buffer->smb_buf_length += count;
- pSMB->req.ByteCount = cpu_to_le16(count);
-
- rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
- &bytes_returned, CIFS_LONG_OP);
- if (rc) {
-/* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
- } else if ((smb_buffer_response->WordCount == 3) ||
- (smb_buffer_response->WordCount == 4)) {
- __u16 action = le16_to_cpu(pSMBr->resp.Action);
- __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
- if (action & GUEST_LOGIN)
- cFYI(1, ("Guest login")); /* BB Should we set anything
- in SesInfo struct ? */
-/* if (SecurityBlob2->MessageType != NtLm??) {
- cFYI("Unexpected message type on auth response is %d"));
- } */
-
- if (ses) {
- cFYI(1,
- ("Check challenge UID %d vs auth response UID %d",
- ses->Suid, smb_buffer_response->Uid));
- /* UID left in wire format */
- ses->Suid = smb_buffer_response->Uid;
- bcc_ptr = pByteArea(smb_buffer_response);
- /* response can have either 3 or 4 word count - Samba sends 3 */
- if ((pSMBr->resp.hdr.WordCount == 3)
- || ((pSMBr->resp.hdr.WordCount == 4)
- && (blob_len <
- pSMBr->resp.ByteCount))) {
- if (pSMBr->resp.hdr.WordCount == 4) {
- bcc_ptr +=
- blob_len;
- cFYI(1,
- ("Security Blob Length %d ",
- blob_len));
- }
-
- cFYI(1,
- ("NTLMSSP response to Authenticate "));
-
- if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
- if ((long) (bcc_ptr) % 2) {
- remaining_words =
- (BCC(smb_buffer_response)
- - 1) / 2;
- bcc_ptr++; /* Unicode strings must be word aligned */
- } else {
- remaining_words = BCC(smb_buffer_response) / 2;
- }
- len = UniStrnlen((wchar_t *) bcc_ptr,
- remaining_words - 1);
-/* We look for obvious messed up bcc or strings in response so we do not go off
- the end since (at least) WIN2K and Windows XP have a major bug in not null
- terminating last Unicode string in response */
- kfree(ses->serverOS);
- ses->serverOS =
- kzalloc(2 * (len + 1), GFP_KERNEL);
- cifs_strfromUCS_le(ses->serverOS,
- (__le16 *)
- bcc_ptr, len,
- nls_codepage);
- bcc_ptr += 2 * (len + 1);
- remaining_words -= len + 1;
- ses->serverOS[2 * len] = 0;
- ses->serverOS[1 + (2 * len)] = 0;
- if (remaining_words > 0) {
- len = UniStrnlen((wchar_t *)
- bcc_ptr,
- remaining_words
- - 1);
- kfree(ses->serverNOS);
- ses->serverNOS =
- kzalloc(2 * (len + 1),
- GFP_KERNEL);
- cifs_strfromUCS_le(ses->
- serverNOS,
- (__le16 *)
- bcc_ptr,
- len,
- nls_codepage);
- bcc_ptr += 2 * (len + 1);
- ses->serverNOS[2 * len] = 0;
- ses->serverNOS[1+(2*len)] = 0;
- remaining_words -= len + 1;
- if (remaining_words > 0) {
- len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
- /* last string not always null terminated (e.g. for Windows XP & 2000) */
- kfree(ses->serverDomain);
- ses->serverDomain =
- kzalloc(2 *
- (len +
- 1),
- GFP_KERNEL);
- cifs_strfromUCS_le
- (ses->
- serverDomain,
- (__le16 *)
- bcc_ptr, len,
- nls_codepage);
- bcc_ptr +=
- 2 * (len + 1);
- ses->
- serverDomain[2
- * len]
- = 0;
- ses->
- serverDomain[1
- +
- (2
- *
- len)]
- = 0;
- } /* else no more room so create dummy domain string */
- else {
- kfree(ses->serverDomain);
- ses->serverDomain = kzalloc(2,GFP_KERNEL);
- }
- } else { /* no room so create dummy domain and NOS string */
- kfree(ses->serverDomain);
- ses->serverDomain = kzalloc(2, GFP_KERNEL);
- kfree(ses->serverNOS);
- ses->serverNOS = kzalloc(2, GFP_KERNEL);
- }
- } else { /* ASCII */
- len = strnlen(bcc_ptr, 1024);
- if (((long) bcc_ptr + len) -
- (long) pByteArea(smb_buffer_response)
- <= BCC(smb_buffer_response)) {
- kfree(ses->serverOS);
- ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
- strncpy(ses->serverOS,bcc_ptr, len);
-
- bcc_ptr += len;
- bcc_ptr[0] = 0; /* null terminate the string */
- bcc_ptr++;
-
- len = strnlen(bcc_ptr, 1024);
- kfree(ses->serverNOS);
- ses->serverNOS = kzalloc(len+1,
- GFP_KERNEL);
- strncpy(ses->serverNOS,
- bcc_ptr, len);
- bcc_ptr += len;
- bcc_ptr[0] = 0;
- bcc_ptr++;
-
- len = strnlen(bcc_ptr, 1024);
- kfree(ses->serverDomain);
- ses->serverDomain =
- kzalloc(len+1,
- GFP_KERNEL);
- strncpy(ses->serverDomain,
- bcc_ptr, len);
- bcc_ptr += len;
- bcc_ptr[0] = 0;
- bcc_ptr++;
- } else
- cFYI(1, ("field of length %d "
- "extends beyond end of smb ",
- len));
- }
- } else {
- cERROR(1, ("Security Blob extends beyond end "
- "of SMB"));
- }
- } else {
- cERROR(1, ("No session structure passed in."));
- }
- } else {
- cERROR(1, ("Invalid Word count %d: ",
- smb_buffer_response->WordCount));
- rc = -EIO;
- }
-
- cifs_buf_release(smb_buffer);
-
- return rc;
-}
-
int
CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
const char *tree, struct cifsTconInfo *tcon,
OpenPOWER on IntegriCloud