|
@@ -364,19 +364,43 @@ void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
|
|
|
sec_blob->DomainName.MaximumLength = 0;
|
|
|
}
|
|
|
|
|
|
-/* We do not malloc the blob, it is passed in pbuffer, because its
|
|
|
- maximum possible size is fixed and small, making this approach cleaner.
|
|
|
- This function returns the length of the data in the blob */
|
|
|
-int build_ntlmssp_auth_blob(unsigned char *pbuffer,
|
|
|
+static int size_of_ntlmssp_blob(struct cifs_ses *ses)
|
|
|
+{
|
|
|
+ int sz = sizeof(AUTHENTICATE_MESSAGE) + ses->auth_key.len
|
|
|
+ - CIFS_SESS_KEY_SIZE + CIFS_CPHTXT_SIZE + 2;
|
|
|
+
|
|
|
+ if (ses->domainName)
|
|
|
+ sz += 2 * strnlen(ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
|
|
|
+ else
|
|
|
+ sz += 2;
|
|
|
+
|
|
|
+ if (ses->user_name)
|
|
|
+ sz += 2 * strnlen(ses->user_name, CIFS_MAX_USERNAME_LEN);
|
|
|
+ else
|
|
|
+ sz += 2;
|
|
|
+
|
|
|
+ return sz;
|
|
|
+}
|
|
|
+
|
|
|
+int build_ntlmssp_auth_blob(unsigned char **pbuffer,
|
|
|
u16 *buflen,
|
|
|
struct cifs_ses *ses,
|
|
|
const struct nls_table *nls_cp)
|
|
|
{
|
|
|
int rc;
|
|
|
- AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
|
|
|
+ AUTHENTICATE_MESSAGE *sec_blob;
|
|
|
__u32 flags;
|
|
|
unsigned char *tmp;
|
|
|
|
|
|
+ rc = setup_ntlmv2_rsp(ses, nls_cp);
|
|
|
+ if (rc) {
|
|
|
+ cifs_dbg(VFS, "Error %d during NTLMSSP authentication\n", rc);
|
|
|
+ *buflen = 0;
|
|
|
+ goto setup_ntlmv2_ret;
|
|
|
+ }
|
|
|
+ *pbuffer = kmalloc(size_of_ntlmssp_blob(ses), GFP_KERNEL);
|
|
|
+ sec_blob = (AUTHENTICATE_MESSAGE *)*pbuffer;
|
|
|
+
|
|
|
memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
|
|
|
sec_blob->MessageType = NtLmAuthenticate;
|
|
|
|
|
@@ -391,7 +415,7 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer,
|
|
|
flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
|
|
|
}
|
|
|
|
|
|
- tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
|
|
|
+ tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE);
|
|
|
sec_blob->NegotiateFlags = cpu_to_le32(flags);
|
|
|
|
|
|
sec_blob->LmChallengeResponse.BufferOffset =
|
|
@@ -399,13 +423,9 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer,
|
|
|
sec_blob->LmChallengeResponse.Length = 0;
|
|
|
sec_blob->LmChallengeResponse.MaximumLength = 0;
|
|
|
|
|
|
- sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
|
|
|
+ sec_blob->NtChallengeResponse.BufferOffset =
|
|
|
+ cpu_to_le32(tmp - *pbuffer);
|
|
|
if (ses->user_name != NULL) {
|
|
|
- rc = setup_ntlmv2_rsp(ses, nls_cp);
|
|
|
- if (rc) {
|
|
|
- cifs_dbg(VFS, "Error %d during NTLMSSP authentication\n", rc);
|
|
|
- goto setup_ntlmv2_ret;
|
|
|
- }
|
|
|
memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
|
|
|
ses->auth_key.len - CIFS_SESS_KEY_SIZE);
|
|
|
tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
|
|
@@ -423,23 +443,23 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer,
|
|
|
}
|
|
|
|
|
|
if (ses->domainName == NULL) {
|
|
|
- sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
|
|
|
+ sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
|
|
|
sec_blob->DomainName.Length = 0;
|
|
|
sec_blob->DomainName.MaximumLength = 0;
|
|
|
tmp += 2;
|
|
|
} else {
|
|
|
int len;
|
|
|
len = cifs_strtoUTF16((__le16 *)tmp, ses->domainName,
|
|
|
- CIFS_MAX_USERNAME_LEN, nls_cp);
|
|
|
+ CIFS_MAX_DOMAINNAME_LEN, nls_cp);
|
|
|
len *= 2; /* unicode is 2 bytes each */
|
|
|
- sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
|
|
|
+ sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
|
|
|
sec_blob->DomainName.Length = cpu_to_le16(len);
|
|
|
sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
|
|
|
tmp += len;
|
|
|
}
|
|
|
|
|
|
if (ses->user_name == NULL) {
|
|
|
- sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
|
|
|
+ sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
|
|
|
sec_blob->UserName.Length = 0;
|
|
|
sec_blob->UserName.MaximumLength = 0;
|
|
|
tmp += 2;
|
|
@@ -448,13 +468,13 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer,
|
|
|
len = cifs_strtoUTF16((__le16 *)tmp, ses->user_name,
|
|
|
CIFS_MAX_USERNAME_LEN, nls_cp);
|
|
|
len *= 2; /* unicode is 2 bytes each */
|
|
|
- sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
|
|
|
+ sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
|
|
|
sec_blob->UserName.Length = cpu_to_le16(len);
|
|
|
sec_blob->UserName.MaximumLength = cpu_to_le16(len);
|
|
|
tmp += len;
|
|
|
}
|
|
|
|
|
|
- sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - pbuffer);
|
|
|
+ sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
|
|
|
sec_blob->WorkstationName.Length = 0;
|
|
|
sec_blob->WorkstationName.MaximumLength = 0;
|
|
|
tmp += 2;
|
|
@@ -463,19 +483,19 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer,
|
|
|
(ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
|
|
|
&& !calc_seckey(ses)) {
|
|
|
memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
|
|
|
- sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
|
|
|
+ sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
|
|
|
sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
|
|
|
sec_blob->SessionKey.MaximumLength =
|
|
|
cpu_to_le16(CIFS_CPHTXT_SIZE);
|
|
|
tmp += CIFS_CPHTXT_SIZE;
|
|
|
} else {
|
|
|
- sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
|
|
|
+ sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
|
|
|
sec_blob->SessionKey.Length = 0;
|
|
|
sec_blob->SessionKey.MaximumLength = 0;
|
|
|
}
|
|
|
|
|
|
+ *buflen = tmp - *pbuffer;
|
|
|
setup_ntlmv2_ret:
|
|
|
- *buflen = tmp - pbuffer;
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
@@ -690,6 +710,8 @@ sess_auth_lanman(struct sess_data *sess_data)
|
|
|
rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
|
|
|
ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
|
|
|
true : false, lnm_session_key);
|
|
|
+ if (rc)
|
|
|
+ goto out;
|
|
|
|
|
|
memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE);
|
|
|
bcc_ptr += CIFS_AUTH_RESP_SIZE;
|
|
@@ -1266,7 +1288,7 @@ sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
|
|
|
struct cifs_ses *ses = sess_data->ses;
|
|
|
__u16 bytes_remaining;
|
|
|
char *bcc_ptr;
|
|
|
- char *ntlmsspblob = NULL;
|
|
|
+ unsigned char *ntlmsspblob = NULL;
|
|
|
u16 blob_len;
|
|
|
|
|
|
cifs_dbg(FYI, "rawntlmssp session setup authenticate phase\n");
|
|
@@ -1279,19 +1301,7 @@ sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
|
|
|
/* Build security blob before we assemble the request */
|
|
|
pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
|
|
|
smb_buf = (struct smb_hdr *)pSMB;
|
|
|
- /*
|
|
|
- * 5 is an empirical value, large enough to hold
|
|
|
- * authenticate message plus max 10 of av paris,
|
|
|
- * domain, user, workstation names, flags, etc.
|
|
|
- */
|
|
|
- ntlmsspblob = kzalloc(5*sizeof(struct _AUTHENTICATE_MESSAGE),
|
|
|
- GFP_KERNEL);
|
|
|
- if (!ntlmsspblob) {
|
|
|
- rc = -ENOMEM;
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- rc = build_ntlmssp_auth_blob(ntlmsspblob,
|
|
|
+ rc = build_ntlmssp_auth_blob(&ntlmsspblob,
|
|
|
&blob_len, ses, sess_data->nls_cp);
|
|
|
if (rc)
|
|
|
goto out_free_ntlmsspblob;
|