Skip to content

Commit de3a9e9

Browse files
Paulo Alcantarasmfrench
authored andcommitted
cifs: fix ntlmssp on old servers
Some older servers seem to require the workstation name during ntlmssp to be at most 15 chars (RFC1001 name length), so truncate it before sending when using insecure dialects. Link: https://lore.kernel.org/r/[email protected] Reported-by: Byron Stanoszek <[email protected]> Tested-by: Byron Stanoszek <[email protected]> Fixes: 49bd49f ("cifs: send workstation name during ntlmssp session setup") Cc: [email protected] Signed-off-by: Paulo Alcantara (SUSE) <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent d87c48c commit de3a9e9

File tree

6 files changed

+26
-49
lines changed

6 files changed

+26
-49
lines changed

fs/cifs/cifsglob.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,7 @@ struct cifs_ses {
952952
and after mount option parsing we fill it */
953953
char *domainName;
954954
char *password;
955-
char *workstation_name;
955+
char workstation_name[CIFS_MAX_WORKSTATION_LEN];
956956
struct session_key auth_key;
957957
struct ntlmssp_auth *ntlmssp; /* ciphertext, flags, server challenge */
958958
enum securityEnum sectype; /* what security flavor was specified? */
@@ -2018,4 +2018,17 @@ static inline u64 cifs_flock_len(struct file_lock *fl)
20182018
return fl->fl_end == OFFSET_MAX ? 0 : fl->fl_end - fl->fl_start + 1;
20192019
}
20202020

2021+
static inline size_t ntlmssp_workstation_name_size(const struct cifs_ses *ses)
2022+
{
2023+
if (WARN_ON_ONCE(!ses || !ses->server))
2024+
return 0;
2025+
/*
2026+
* Make workstation name no more than 15 chars when using insecure dialects as some legacy
2027+
* servers do require it during NTLMSSP.
2028+
*/
2029+
if (ses->server->dialect <= SMB20_PROT_ID)
2030+
return min_t(size_t, sizeof(ses->workstation_name), RFC1001_NAME_LEN_WITH_NULL);
2031+
return sizeof(ses->workstation_name);
2032+
}
2033+
20212034
#endif /* _CIFS_GLOB_H */

fs/cifs/connect.c

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,18 +2037,7 @@ cifs_set_cifscreds(struct smb3_fs_context *ctx, struct cifs_ses *ses)
20372037
}
20382038
}
20392039

2040-
ctx->workstation_name = kstrdup(ses->workstation_name, GFP_KERNEL);
2041-
if (!ctx->workstation_name) {
2042-
cifs_dbg(FYI, "Unable to allocate memory for workstation_name\n");
2043-
rc = -ENOMEM;
2044-
kfree(ctx->username);
2045-
ctx->username = NULL;
2046-
kfree_sensitive(ctx->password);
2047-
ctx->password = NULL;
2048-
kfree(ctx->domainname);
2049-
ctx->domainname = NULL;
2050-
goto out_key_put;
2051-
}
2040+
strscpy(ctx->workstation_name, ses->workstation_name, sizeof(ctx->workstation_name));
20522041

20532042
out_key_put:
20542043
up_read(&key->sem);
@@ -2157,12 +2146,9 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
21572146
if (!ses->domainName)
21582147
goto get_ses_fail;
21592148
}
2160-
if (ctx->workstation_name) {
2161-
ses->workstation_name = kstrdup(ctx->workstation_name,
2162-
GFP_KERNEL);
2163-
if (!ses->workstation_name)
2164-
goto get_ses_fail;
2165-
}
2149+
2150+
strscpy(ses->workstation_name, ctx->workstation_name, sizeof(ses->workstation_name));
2151+
21662152
if (ctx->domainauto)
21672153
ses->domainAuto = ctx->domainauto;
21682154
ses->cred_uid = ctx->cred_uid;

fs/cifs/fs_context.c

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,6 @@ smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx
313313
new_ctx->password = NULL;
314314
new_ctx->server_hostname = NULL;
315315
new_ctx->domainname = NULL;
316-
new_ctx->workstation_name = NULL;
317316
new_ctx->UNC = NULL;
318317
new_ctx->source = NULL;
319318
new_ctx->iocharset = NULL;
@@ -328,7 +327,6 @@ smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx
328327
DUP_CTX_STR(UNC);
329328
DUP_CTX_STR(source);
330329
DUP_CTX_STR(domainname);
331-
DUP_CTX_STR(workstation_name);
332330
DUP_CTX_STR(nodename);
333331
DUP_CTX_STR(iocharset);
334332

@@ -767,8 +765,7 @@ static int smb3_verify_reconfigure_ctx(struct fs_context *fc,
767765
cifs_errorf(fc, "can not change domainname during remount\n");
768766
return -EINVAL;
769767
}
770-
if (new_ctx->workstation_name &&
771-
(!old_ctx->workstation_name || strcmp(new_ctx->workstation_name, old_ctx->workstation_name))) {
768+
if (strcmp(new_ctx->workstation_name, old_ctx->workstation_name)) {
772769
cifs_errorf(fc, "can not change workstation_name during remount\n");
773770
return -EINVAL;
774771
}
@@ -815,7 +812,6 @@ static int smb3_reconfigure(struct fs_context *fc)
815812
STEAL_STRING(cifs_sb, ctx, username);
816813
STEAL_STRING(cifs_sb, ctx, password);
817814
STEAL_STRING(cifs_sb, ctx, domainname);
818-
STEAL_STRING(cifs_sb, ctx, workstation_name);
819815
STEAL_STRING(cifs_sb, ctx, nodename);
820816
STEAL_STRING(cifs_sb, ctx, iocharset);
821817

@@ -1471,22 +1467,15 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
14711467

14721468
int smb3_init_fs_context(struct fs_context *fc)
14731469
{
1474-
int rc;
14751470
struct smb3_fs_context *ctx;
14761471
char *nodename = utsname()->nodename;
14771472
int i;
14781473

14791474
ctx = kzalloc(sizeof(struct smb3_fs_context), GFP_KERNEL);
1480-
if (unlikely(!ctx)) {
1481-
rc = -ENOMEM;
1482-
goto err_exit;
1483-
}
1475+
if (unlikely(!ctx))
1476+
return -ENOMEM;
14841477

1485-
ctx->workstation_name = kstrdup(nodename, GFP_KERNEL);
1486-
if (unlikely(!ctx->workstation_name)) {
1487-
rc = -ENOMEM;
1488-
goto err_exit;
1489-
}
1478+
strscpy(ctx->workstation_name, nodename, sizeof(ctx->workstation_name));
14901479

14911480
/*
14921481
* does not have to be perfect mapping since field is
@@ -1559,14 +1548,6 @@ int smb3_init_fs_context(struct fs_context *fc)
15591548
fc->fs_private = ctx;
15601549
fc->ops = &smb3_fs_context_ops;
15611550
return 0;
1562-
1563-
err_exit:
1564-
if (ctx) {
1565-
kfree(ctx->workstation_name);
1566-
kfree(ctx);
1567-
}
1568-
1569-
return rc;
15701551
}
15711552

15721553
void
@@ -1592,8 +1573,6 @@ smb3_cleanup_fs_context_contents(struct smb3_fs_context *ctx)
15921573
ctx->source = NULL;
15931574
kfree(ctx->domainname);
15941575
ctx->domainname = NULL;
1595-
kfree(ctx->workstation_name);
1596-
ctx->workstation_name = NULL;
15971576
kfree(ctx->nodename);
15981577
ctx->nodename = NULL;
15991578
kfree(ctx->iocharset);

fs/cifs/fs_context.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ struct smb3_fs_context {
171171
char *server_hostname;
172172
char *UNC;
173173
char *nodename;
174-
char *workstation_name;
174+
char workstation_name[CIFS_MAX_WORKSTATION_LEN];
175175
char *iocharset; /* local code page for mapping to and from Unicode */
176176
char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
177177
char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */

fs/cifs/misc.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ sesInfoFree(struct cifs_ses *buf_to_free)
9595
kfree_sensitive(buf_to_free->password);
9696
kfree(buf_to_free->user_name);
9797
kfree(buf_to_free->domainName);
98-
kfree(buf_to_free->workstation_name);
9998
kfree_sensitive(buf_to_free->auth_key.response);
10099
kfree(buf_to_free->iface_list);
101100
kfree_sensitive(buf_to_free);

fs/cifs/sess.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -741,9 +741,9 @@ static int size_of_ntlmssp_blob(struct cifs_ses *ses, int base_size)
741741
else
742742
sz += sizeof(__le16);
743743

744-
if (ses->workstation_name)
744+
if (ses->workstation_name[0])
745745
sz += sizeof(__le16) * strnlen(ses->workstation_name,
746-
CIFS_MAX_WORKSTATION_LEN);
746+
ntlmssp_workstation_name_size(ses));
747747
else
748748
sz += sizeof(__le16);
749749

@@ -987,7 +987,7 @@ int build_ntlmssp_auth_blob(unsigned char **pbuffer,
987987

988988
cifs_security_buffer_from_str(&sec_blob->WorkstationName,
989989
ses->workstation_name,
990-
CIFS_MAX_WORKSTATION_LEN,
990+
ntlmssp_workstation_name_size(ses),
991991
*pbuffer, &tmp,
992992
nls_cp);
993993

0 commit comments

Comments
 (0)