cifs: Fix encoding of SMB1 Session Setup Kerberos Request in non-UNICODE mode
[ Upstream commit 16cb6b0509b65ac89187e9402e0b7a9ddf1765ef ] Like in UNICODE mode, SMB1 Session Setup Kerberos Request contains oslm and domain strings. Extract common code into ascii_oslm_strings() and ascii_domain_string() functions (similar to unicode variants) and use these functions in non-UNICODE code path in sess_auth_kerberos(). Decision if non-UNICODE or UNICODE mode is used is based on the SMBFLG2_UNICODE flag in Flags2 packed field, and not based on the capabilities of server. Fix this check too. Signed-off-by: Pali Rohár <pali@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
f444c139e8
commit
e5208da739
@@ -732,6 +732,22 @@ unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
|
|||||||
*pbcc_area = bcc_ptr;
|
*pbcc_area = bcc_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ascii_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
|
||||||
|
{
|
||||||
|
char *bcc_ptr = *pbcc_area;
|
||||||
|
|
||||||
|
strcpy(bcc_ptr, "Linux version ");
|
||||||
|
bcc_ptr += strlen("Linux version ");
|
||||||
|
strcpy(bcc_ptr, init_utsname()->release);
|
||||||
|
bcc_ptr += strlen(init_utsname()->release) + 1;
|
||||||
|
|
||||||
|
strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
|
||||||
|
bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
|
||||||
|
|
||||||
|
*pbcc_area = bcc_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
|
static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
|
||||||
const struct nls_table *nls_cp)
|
const struct nls_table *nls_cp)
|
||||||
{
|
{
|
||||||
@@ -756,6 +772,25 @@ static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
|
|||||||
*pbcc_area = bcc_ptr;
|
*pbcc_area = bcc_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ascii_domain_string(char **pbcc_area, struct cifs_ses *ses,
|
||||||
|
const struct nls_table *nls_cp)
|
||||||
|
{
|
||||||
|
char *bcc_ptr = *pbcc_area;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
/* copy domain */
|
||||||
|
if (ses->domainName != NULL) {
|
||||||
|
len = strscpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
|
||||||
|
if (WARN_ON_ONCE(len < 0))
|
||||||
|
len = CIFS_MAX_DOMAINNAME_LEN - 1;
|
||||||
|
bcc_ptr += len;
|
||||||
|
} /* else we send a null domain name so server will default to its own domain */
|
||||||
|
*bcc_ptr = 0;
|
||||||
|
bcc_ptr++;
|
||||||
|
|
||||||
|
*pbcc_area = bcc_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
|
static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
|
||||||
const struct nls_table *nls_cp)
|
const struct nls_table *nls_cp)
|
||||||
{
|
{
|
||||||
@@ -801,25 +836,10 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
|
|||||||
*bcc_ptr = 0;
|
*bcc_ptr = 0;
|
||||||
bcc_ptr++; /* account for null termination */
|
bcc_ptr++; /* account for null termination */
|
||||||
|
|
||||||
/* copy domain */
|
|
||||||
if (ses->domainName != NULL) {
|
|
||||||
len = strscpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
|
|
||||||
if (WARN_ON_ONCE(len < 0))
|
|
||||||
len = CIFS_MAX_DOMAINNAME_LEN - 1;
|
|
||||||
bcc_ptr += len;
|
|
||||||
} /* else we send a null domain name so server will default to its own domain */
|
|
||||||
*bcc_ptr = 0;
|
|
||||||
bcc_ptr++;
|
|
||||||
|
|
||||||
/* BB check for overflow here */
|
/* BB check for overflow here */
|
||||||
|
|
||||||
strcpy(bcc_ptr, "Linux version ");
|
ascii_domain_string(&bcc_ptr, ses, nls_cp);
|
||||||
bcc_ptr += strlen("Linux version ");
|
ascii_oslm_strings(&bcc_ptr, nls_cp);
|
||||||
strcpy(bcc_ptr, init_utsname()->release);
|
|
||||||
bcc_ptr += strlen(init_utsname()->release) + 1;
|
|
||||||
|
|
||||||
strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
|
|
||||||
bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
|
|
||||||
|
|
||||||
*pbcc_area = bcc_ptr;
|
*pbcc_area = bcc_ptr;
|
||||||
}
|
}
|
||||||
@@ -1622,7 +1642,7 @@ sess_auth_kerberos(struct sess_data *sess_data)
|
|||||||
sess_data->iov[1].iov_len = msg->secblob_len;
|
sess_data->iov[1].iov_len = msg->secblob_len;
|
||||||
pSMB->req.SecurityBlobLength = cpu_to_le16(sess_data->iov[1].iov_len);
|
pSMB->req.SecurityBlobLength = cpu_to_le16(sess_data->iov[1].iov_len);
|
||||||
|
|
||||||
if (ses->capabilities & CAP_UNICODE) {
|
if (pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) {
|
||||||
/* unicode strings must be word aligned */
|
/* unicode strings must be word aligned */
|
||||||
if (!IS_ALIGNED(sess_data->iov[0].iov_len + sess_data->iov[1].iov_len, 2)) {
|
if (!IS_ALIGNED(sess_data->iov[0].iov_len + sess_data->iov[1].iov_len, 2)) {
|
||||||
*bcc_ptr = 0;
|
*bcc_ptr = 0;
|
||||||
@@ -1631,8 +1651,8 @@ sess_auth_kerberos(struct sess_data *sess_data)
|
|||||||
unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp);
|
unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp);
|
||||||
unicode_domain_string(&bcc_ptr, ses, sess_data->nls_cp);
|
unicode_domain_string(&bcc_ptr, ses, sess_data->nls_cp);
|
||||||
} else {
|
} else {
|
||||||
/* BB: is this right? */
|
ascii_oslm_strings(&bcc_ptr, sess_data->nls_cp);
|
||||||
ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
|
ascii_domain_string(&bcc_ptr, ses, sess_data->nls_cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
sess_data->iov[2].iov_len = (long) bcc_ptr -
|
sess_data->iov[2].iov_len = (long) bcc_ptr -
|
||||||
|
|||||||
Reference in New Issue
Block a user