]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2020-25717: s3:auth: remove fallbacks in smb_getpwnam()
authorRalph Boehme <slow@samba.org>
Fri, 8 Oct 2021 10:33:16 +0000 (12:33 +0200)
committerJule Anger <janger@samba.org>
Mon, 8 Nov 2021 09:52:10 +0000 (10:52 +0100)
So far we tried getpwnam("DOMAIN\account") first and
always did a fallback to getpwnam("account") completely
ignoring the domain part, this just causes problems
as we mix "DOMAIN1\account", "DOMAIN2\account",
and "account"!

As we require a running winbindd for domain member setups
we should no longer do a fallback to just "account" for
users served by winbindd!

For users of the local SAM don't use this code path,
as check_sam_security() doesn't call check_account().

The only case where smb_getpwnam("account") happens is
when map_username() via ("username map [script]")  mapped
"DOMAIN\account" to something without '\', but that is
explicitly desired by the admin.

Note: use 'git show -w'

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556

Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>

Signed-off-by: Ralph Boehme <slow@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
selftest/knownfail.d/ktest [new file with mode: 0644]
source3/auth/auth_util.c

diff --git a/selftest/knownfail.d/ktest b/selftest/knownfail.d/ktest
new file mode 100644 (file)
index 0000000..809612b
--- /dev/null
@@ -0,0 +1,26 @@
+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2...lsa.LookupSidsReply.ktest
+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2...lsa.LookupSidsReply.ktest
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5...rpcclient.ktest:local
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5...rpcclient.ktest:local
+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,connect...lsa.LookupSidsReply.ktest
+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,connect...lsa.LookupSidsReply.ktest
+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,packet...lsa.LookupSidsReply.ktest
+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,packet...lsa.LookupSidsReply.ktest
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,packet...rpcclient.ktest:local
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,packet...rpcclient.ktest:local
+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,sign...lsa.LookupSidsReply.ktest
+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,sign...lsa.LookupSidsReply.ktest
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,sign...rpcclient.ktest:local
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,sign...rpcclient.ktest:local
+^samba3.rpc.lsa.lookupsids.krb5.with.old.ccache.ncacn_np.with..smb2,seal...lsa.LookupSidsReply.ktest
+^samba3.rpc.lsa.lookupsids.krb5.ncacn_np.with..smb2,seal...lsa.LookupSidsReply.ktest
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..krb5,seal...rpcclient.ktest:local
+^samba3.blackbox.rpcclient.krb5.ncacn_np.with..spnego,krb5,seal...rpcclient.ktest:local
+^samba3.blackbox.smbclient_krb5.old.ccache..smbclient.ktest:local
+^samba3.blackbox.smbclient_krb5.new.ccache..smbclient.ktest:local
+^samba3.blackbox.smbclient_large_file..krb5.smbclient.large.posix.write.read.ktest:local
+^samba3.blackbox.smbclient_large_file..krb5.cmp.of.read.and.written.files.ktest:local
+^samba3.blackbox.smbclient_krb5.old.ccache.--client-protection=encrypt.smbclient.ktest:local
+^samba3.blackbox.smbclient_krb5.new.ccache.--client-protection=encrypt.smbclient.ktest:local
+^samba3.blackbox.smbclient_large_file.--client-protection=encrypt.krb5.smbclient.large.posix.write.read.ktest:local
+^samba3.blackbox.smbclient_large_file.--client-protection=encrypt.krb5.cmp.of.read.and.written.files.ktest:local
index 99b85d47a5f0ebbd6ec3463be0335e1bc12213e0..d81313a0495e1c7f5d5e17f0fc88bef34f4a6afc 100644 (file)
@@ -1933,7 +1933,7 @@ struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
 {
        struct passwd *pw = NULL;
        char *p = NULL;
-       char *username = NULL;
+       const char *username = NULL;
 
        /* we only save a copy of the username it has been mangled 
           by winbindd use default domain */
@@ -1952,48 +1952,55 @@ struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
        /* code for a DOMAIN\user string */
 
        if ( p ) {
-               pw = Get_Pwnam_alloc( mem_ctx, domuser );
-               if ( pw ) {
-                       /* make sure we get the case of the username correct */
-                       /* work around 'winbind use default domain = yes' */
-
-                       if ( lp_winbind_use_default_domain() &&
-                            !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
-                               char *domain;
-
-                               /* split the domain and username into 2 strings */
-                               *p = '\0';
-                               domain = username;
-
-                               *p_save_username = talloc_asprintf(mem_ctx,
-                                                               "%s%c%s",
-                                                               domain,
-                                                               *lp_winbind_separator(),
-                                                               pw->pw_name);
-                               if (!*p_save_username) {
-                                       TALLOC_FREE(pw);
-                                       return NULL;
-                               }
-                       } else {
-                               *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
-                       }
+               const char *domain = NULL;
 
-                       /* whew -- done! */
-                       return pw;
+               /* split the domain and username into 2 strings */
+               *p = '\0';
+               domain = username;
+               p++;
+               username = p;
+
+               if (strequal(domain, get_global_sam_name())) {
+                       /*
+                        * This typically don't happen
+                        * as check_sam_Security()
+                        * don't call make_server_info_info3()
+                        * and thus check_account().
+                        *
+                        * But we better keep this.
+                        */
+                       goto username_only;
                }
 
-               /* setup for lookup of just the username */
-               /* remember that p and username are overlapping memory */
-
-               p++;
-               username = talloc_strdup(mem_ctx, p);
-               if (!username) {
+               pw = Get_Pwnam_alloc( mem_ctx, domuser );
+               if (pw == NULL) {
                        return NULL;
                }
+               /* make sure we get the case of the username correct */
+               /* work around 'winbind use default domain = yes' */
+
+               if ( lp_winbind_use_default_domain() &&
+                    !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
+                       *p_save_username = talloc_asprintf(mem_ctx,
+                                                       "%s%c%s",
+                                                       domain,
+                                                       *lp_winbind_separator(),
+                                                       pw->pw_name);
+                       if (!*p_save_username) {
+                               TALLOC_FREE(pw);
+                               return NULL;
+                       }
+               } else {
+                       *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
+               }
+
+               /* whew -- done! */
+               return pw;
+
        }
 
        /* just lookup a plain username */
-
+username_only:
        pw = Get_Pwnam_alloc(mem_ctx, username);
 
        /* Create local user if requested but only if winbindd