CVE-2020-25717: s3:auth: Fallback to a SID/UID based mapping if the named based looku...
authorAndrew Bartlett <abartlet@samba.org>
Fri, 12 Nov 2021 03:10:31 +0000 (16:10 +1300)
committerRalph Boehme <slow@samba.org>
Mon, 15 Nov 2021 19:01:56 +0000 (19:01 +0000)
Before the CVE-2020-25717 fixes we had a fallback from
getpwnam('DOMAIN\user') to getpwnam('user') which was very dangerous and
unpredictable.

Now we do the fallback based on sid_to_uid() followed by
getpwuid() on the returned uid.

This obsoletes 'username map [script]' based workaround adviced
for CVE-2020-25717, when nss_winbindd is not used or
idmap_nss is actually used.

In future we may decide to prefer or only do the SID/UID based
lookup, but for now we want to keep this unchanged as much as possible.

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

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

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
[metze@samba.org moved the new logic into the fallback codepath only
 in order to avoid behavior changes as much as possible]
Reviewed-by: Ralph Boehme <slow@samba.org>
Autobuild-User(master): Ralph Böhme <slow@samba.org>
Autobuild-Date(master): Mon Nov 15 19:01:56 UTC 2021 on sn-devel-184

selftest/knownfail.d/idmap_nss_sid_mapping [deleted file]
source3/auth/auth_util.c

diff --git a/selftest/knownfail.d/idmap_nss_sid_mapping b/selftest/knownfail.d/idmap_nss_sid_mapping
deleted file mode 100644 (file)
index 7e1913f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-^samba.tests.krb5.test_idmap_nss.samba.tests.krb5.test_idmap_nss.IdmapNssTests.test_unmapped_user_kerberos
-^samba.tests.krb5.test_idmap_nss.samba.tests.krb5.test_idmap_nss.IdmapNssTests.test_unmapped_user_ntlm
index 4527dedc49d9d8c802fe175dce842b1aa2796bd1..28850cd85201e0fe5a0b04c3b0e008051c87f5ba 100644 (file)
@@ -1877,7 +1877,9 @@ const struct auth_session_info *get_session_info_system(void)
 ***************************************************************************/
 
 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
-                             const char *username, char **found_username,
+                             const char *username,
+                             const struct dom_sid *sid,
+                             char **found_username,
                              struct passwd **pwd,
                              bool *username_was_mapped)
 {
@@ -1912,6 +1914,31 @@ static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
        }
 
        passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, false);
+       if (!passwd && !*username_was_mapped) {
+               struct dom_sid_buf buf;
+               uid_t uid;
+               bool ok;
+
+               DBG_DEBUG("Failed to find authenticated user %s via "
+                         "getpwnam(), fallback to sid_to_uid(%s).\n",
+                         dom_user, dom_sid_str_buf(sid, &buf));
+
+               ok = sid_to_uid(sid, &uid);
+               if (!ok) {
+                       DBG_ERR("Failed to convert SID %s to a UID (dom_user[%s])\n",
+                               dom_sid_str_buf(sid, &buf), dom_user);
+                       return NT_STATUS_NO_SUCH_USER;
+               }
+               passwd = getpwuid_alloc(mem_ctx, uid);
+               if (!passwd) {
+                       DBG_ERR("Failed to find local account with UID %lld for SID %s (dom_user[%s])\n",
+                               (long long)uid,
+                               dom_sid_str_buf(sid, &buf),
+                               dom_user);
+                       return NT_STATUS_NO_SUCH_USER;
+               }
+               real_username = talloc_strdup(mem_ctx, passwd->pw_name);
+       }
        if (!passwd) {
                DEBUG(3, ("Failed to find authenticated user %s via "
                          "getpwnam(), denying access.\n", dom_user));
@@ -2057,6 +2084,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
        bool username_was_mapped;
        struct passwd *pwd;
        struct auth_serversupplied_info *result;
+       struct dom_sid sid;
        TALLOC_CTX *tmp_ctx = talloc_stackframe();
 
        /* 
@@ -2103,9 +2131,13 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
 
        /* this call will try to create the user if necessary */
 
+       sid_copy(&sid, info3->base.domain_sid);
+       sid_append_rid(&sid, info3->base.rid);
+
        nt_status = check_account(tmp_ctx,
                                  nt_domain,
                                  nt_username,
+                                 &sid,
                                  &found_username,
                                  &pwd,
                                  &username_was_mapped);