return av;
}
-/* Server has provided av pairs/target info in the type 2 challenge
- * packet and we have plucked it and stored within smb session.
- * We parse that blob here to find netbios domain name to be used
- * as part of ntlmv2 authentication (in Target String), if not already
- * specified on the command line.
- * If this function returns without any error but without fetching
- * domain name, authentication may fail against some server but
- * may not fail against other (those who are not very particular
- * about target string i.e. for some, just user name might suffice.
+/*
+ * Check if server has provided av pair of @type in the NTLMSSP
+ * CHALLENGE_MESSAGE blob.
*/
-static int find_domain_name(struct cifs_ses *ses)
+static int find_av_name(struct cifs_ses *ses, u16 type, char **name, u16 maxlen)
{
const struct nls_table *nlsc = ses->local_nls;
struct ntlmssp2_name *av;
- u16 len;
+ u16 len, nlen;
+
+ if (*name)
+ return 0;
av_for_each_entry(ses, av) {
len = AV_LEN(av);
- if (AV_TYPE(av) == NTLMSSP_AV_NB_DOMAIN_NAME &&
- len < CIFS_MAX_DOMAINNAME_LEN && !ses->domainName) {
- ses->domainName = kmalloc(len + 1, GFP_KERNEL);
- if (!ses->domainName)
+ if (AV_TYPE(av) != type)
+ continue;
+ if (!IS_ALIGNED(len, sizeof(__le16))) {
+ cifs_dbg(VFS | ONCE, "%s: bad length(%u) for type %u\n",
+ __func__, len, type);
+ continue;
+ }
+ nlen = len / sizeof(__le16);
+ if (nlen <= maxlen) {
+ ++nlen;
+ *name = kmalloc(nlen, GFP_KERNEL);
+ if (!*name)
return -ENOMEM;
- cifs_from_utf16(ses->domainName, AV_DATA_PTR(av),
- len, len, nlsc, NO_MAP_UNI_RSVD);
+ cifs_from_utf16(*name, AV_DATA_PTR(av), nlen,
+ len, nlsc, NO_MAP_UNI_RSVD);
+ break;
}
}
return 0;
if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) {
if (!ses->domainName) {
if (ses->domainAuto) {
- rc = find_domain_name(ses);
- if (rc) {
- cifs_dbg(VFS, "error %d finding domain name\n",
- rc);
+ /*
+ * Domain (workgroup) hasn't been specified in
+ * mount options, so try to find it in
+ * CHALLENGE_MESSAGE message and then use it as
+ * part of NTLMv2 authentication.
+ */
+ rc = find_av_name(ses, NTLMSSP_AV_NB_DOMAIN_NAME,
+ &ses->domainName,
+ CIFS_MAX_DOMAINNAME_LEN);
+ if (rc)
goto setup_ntlmv2_rsp_ret;
- }
} else {
ses->domainName = kstrdup("", GFP_KERNEL);
+ if (!ses->domainName) {
+ rc = -ENOMEM;
+ goto setup_ntlmv2_rsp_ret;
+ }
}
}
+ rc = find_av_name(ses, NTLMSSP_AV_DNS_DOMAIN_NAME,
+ &ses->dns_dom, CIFS_MAX_DOMAINNAME_LEN);
+ if (rc)
+ goto setup_ntlmv2_rsp_ret;
} else {
rc = build_avpair_blob(ses, nls_cp);
if (rc) {