Skip to content

Commit 3956644

Browse files
germanopsmfrench
authored andcommitted
Fix default behaviour for empty domains and add domainauto option
With commit 2b149f1 many things have been fixed/introduced. However, the default behaviour for RawNTLMSSP authentication seems to be wrong in case the domain is not passed on the command line. The main points (see below) of the patch are: - It alignes behaviour with Windows clients - It fixes backward compatibility - It fixes UPN I compared this behavour with the one from a Windows 10 command line client. When no domains are specified on the command line, I traced the packets and observed that the client does send an empty domain to the server. In the linux kernel case, the empty domain is replaced by the primary domain communicated by the SMB server. This means that, if the credentials are valid against the local server but that server is part of a domain, then the kernel module will ask to authenticate against that domain and we will get LOGON failure. I compared the packet trace from the smbclient when no domain is passed and, in that case, a default domain from the client smb.conf is taken. Apparently, connection succeeds anyway, because when the domain passed is not valid (in my case WORKGROUP), then the local one is tried and authentication succeeds. I tried with any kind of invalid domain and the result was always a connection. So, trying to interpret what to do and picking a valid domain if none is passed, seems the wrong thing to do. To this end, a new option "domainauto" has been added in case the user wants a mechanism for guessing. Without this patch, backward compatibility also is broken. With kernel 3.10, the default auth mechanism was NTLM. One of our testing servers accepted NTLM and, because no domains are passed, authentication was local. Moving to RawNTLMSSP forced us to change our command line to add a fake domain to pass to prevent this mechanism to kick in. For the same reasons, UPN is broken because the domain is specified in the username. The SMB server will work out the domain from the UPN and authenticate against the right server. Without the patch, though, given the domain is empty, it gets replaced with another domain that could be the wrong one for the authentication. Signed-off-by: Germano Percossi <germano.percossi@citrix.com> Acked-by: Pavel Shilovsky <pshilov@microsoft.com> Signed-off-by: Steve French <smfrench@gmail.com>
1 parent c6fc663 commit 3956644

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

fs/cifs/cifsencrypt.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -699,11 +699,15 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
699699

700700
if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) {
701701
if (!ses->domainName) {
702-
rc = find_domain_name(ses, nls_cp);
703-
if (rc) {
704-
cifs_dbg(VFS, "error %d finding domain name\n",
705-
rc);
706-
goto setup_ntlmv2_rsp_ret;
702+
if (ses->domainAuto) {
703+
rc = find_domain_name(ses, nls_cp);
704+
if (rc) {
705+
cifs_dbg(VFS, "error %d finding domain name\n",
706+
rc);
707+
goto setup_ntlmv2_rsp_ret;
708+
}
709+
} else {
710+
ses->domainName = kstrdup("", GFP_KERNEL);
707711
}
708712
}
709713
} else {

fs/cifs/cifsglob.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,7 @@ struct smb_vol {
514514
bool persistent:1;
515515
bool nopersistent:1;
516516
bool resilient:1; /* noresilient not required since not fored for CA */
517+
bool domainauto:1;
517518
unsigned int rsize;
518519
unsigned int wsize;
519520
bool sockopt_tcp_nodelay:1;
@@ -830,6 +831,7 @@ struct cifs_ses {
830831
enum securityEnum sectype; /* what security flavor was specified? */
831832
bool sign; /* is signing required? */
832833
bool need_reconnect:1; /* connection reset, uid now invalid */
834+
bool domainAuto:1;
833835
#ifdef CONFIG_CIFS_SMB2
834836
__u16 session_flags;
835837
__u8 smb3signingkey[SMB3_SIGN_KEY_SIZE];

fs/cifs/connect.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ enum {
9191
Opt_multiuser, Opt_sloppy, Opt_nosharesock,
9292
Opt_persistent, Opt_nopersistent,
9393
Opt_resilient, Opt_noresilient,
94+
Opt_domainauto,
9495

9596
/* Mount options which take numeric value */
9697
Opt_backupuid, Opt_backupgid, Opt_uid,
@@ -180,6 +181,7 @@ static const match_table_t cifs_mount_option_tokens = {
180181
{ Opt_nopersistent, "nopersistenthandles"},
181182
{ Opt_resilient, "resilienthandles"},
182183
{ Opt_noresilient, "noresilienthandles"},
184+
{ Opt_domainauto, "domainauto"},
183185

184186
{ Opt_backupuid, "backupuid=%s" },
185187
{ Opt_backupgid, "backupgid=%s" },
@@ -1504,6 +1506,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
15041506
case Opt_noresilient:
15051507
vol->resilient = false; /* already the default */
15061508
break;
1509+
case Opt_domainauto:
1510+
vol->domainauto = true;
1511+
break;
15071512

15081513
/* Numeric Values */
15091514
case Opt_backupuid:
@@ -2578,6 +2583,8 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
25782583
if (!ses->domainName)
25792584
goto get_ses_fail;
25802585
}
2586+
if (volume_info->domainauto)
2587+
ses->domainAuto = volume_info->domainauto;
25812588
ses->cred_uid = volume_info->cred_uid;
25822589
ses->linux_uid = volume_info->linux_uid;
25832590

0 commit comments

Comments
 (0)