Skip to content

Commit

Permalink
CIFS ntlm authentication and signing - Build a proper av/ti pair blob…
Browse files Browse the repository at this point in the history
… for ntlmv2 without extended security authentication

Build an av pair blob as part of ntlmv2 (without extended security) auth
request.  Include netbios and dns names for domain and server and
a timestamp in the blob.

Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
Reviewed-by: Jeff Layton <jlayton@samba.org>
Signed-off-by: Steve French <sfrench@us.ibm.com>
  • Loading branch information
Shirish Pargaonkar authored and Steve French committed Oct 12, 2010
1 parent 0dd12c2 commit 9daa42e
Showing 1 changed file with 69 additions and 11 deletions.
80 changes: 69 additions & 11 deletions fs/cifs/cifsencrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,27 +263,85 @@ void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
}
#endif /* CIFS_WEAK_PW_HASH */

/* This is just a filler for ntlmv2 type of security mechanisms.
* Older servers are not very particular about the contents of av pairs
* in the blob and for sec mechs like ntlmv2, there is no negotiation
* as in ntlmssp, so unless domain and server netbios and dns names
* are specified, there is no way to obtain name. In case of ntlmssp,
* server provides that info in type 2 challenge packet
/* Build a proper attribute value/target info pairs blob.
* Fill in netbios and dns domain name and workstation name
* and client time (total five av pairs and + one end of fields indicator.
* Allocate domain name which gets freed when session struct is deallocated.
*/
static int
build_avpair_blob(struct cifsSesInfo *ses)
build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
{
unsigned int dlen;
unsigned int wlen;
unsigned int size = 6 * sizeof(struct ntlmssp2_name);
__le64 curtime;
char *defdmname = "WORKGROUP";
unsigned char *blobptr;
struct ntlmssp2_name *attrptr;

ses->tilen = 2 * sizeof(struct ntlmssp2_name);
if (!ses->domainName) {
ses->domainName = kstrdup(defdmname, GFP_KERNEL);
if (!ses->domainName)
return -ENOMEM;
}

dlen = strlen(ses->domainName);
wlen = strlen(ses->server->hostname);

/* The length of this blob is a size which is
* six times the size of a structure which holds name/size +
* two times the unicode length of a domain name +
* two times the unicode length of a server name +
* size of a timestamp (which is 8 bytes).
*/
ses->tilen = size + 2 * (2 * dlen) + 2 * (2 * wlen) + 8;
ses->tiblob = kzalloc(ses->tilen, GFP_KERNEL);
if (!ses->tiblob) {
ses->tilen = 0;
cERROR(1, "Challenge target info allocation failure");
return -ENOMEM;
}
attrptr = (struct ntlmssp2_name *) ses->tiblob;
attrptr->type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE);

blobptr = ses->tiblob;
attrptr = (struct ntlmssp2_name *) blobptr;

attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME);
attrptr->length = cpu_to_le16(2 * dlen);
blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp);

blobptr += 2 * dlen;
attrptr = (struct ntlmssp2_name *) blobptr;

attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_COMPUTER_NAME);
attrptr->length = cpu_to_le16(2 * wlen);
blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
cifs_strtoUCS((__le16 *)blobptr, ses->server->hostname, wlen, nls_cp);

blobptr += 2 * wlen;
attrptr = (struct ntlmssp2_name *) blobptr;

attrptr->type = cpu_to_le16(NTLMSSP_AV_DNS_DOMAIN_NAME);
attrptr->length = cpu_to_le16(2 * dlen);
blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp);

blobptr += 2 * dlen;
attrptr = (struct ntlmssp2_name *) blobptr;

attrptr->type = cpu_to_le16(NTLMSSP_AV_DNS_COMPUTER_NAME);
attrptr->length = cpu_to_le16(2 * wlen);
blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
cifs_strtoUCS((__le16 *)blobptr, ses->server->hostname, wlen, nls_cp);

blobptr += 2 * wlen;
attrptr = (struct ntlmssp2_name *) blobptr;

attrptr->type = cpu_to_le16(NTLMSSP_AV_TIMESTAMP);
attrptr->length = cpu_to_le16(sizeof(__le64));
blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
curtime = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
memcpy(blobptr, &curtime, sizeof(__le64));

return 0;
}
Expand Down Expand Up @@ -429,7 +487,7 @@ setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
}
}
} else {
rc = build_avpair_blob(ses);
rc = build_avpair_blob(ses, nls_cp);
if (rc) {
cERROR(1, "error %d building av pair blob", rc);
return rc;
Expand Down

0 comments on commit 9daa42e

Please sign in to comment.