f4a605
From 0e179b5f06988c576a1fff505c06920d51fe8ed4 Mon Sep 17 00:00:00 2001
f4a605
From: Stefan Metzmacher <metze@samba.org>
f4a605
Date: Fri, 12 Nov 2021 15:27:58 +0100
f4a605
Subject: [PATCH 1/3] CVE-2020-25727: idmap_nss: verify that the name of the
f4a605
 sid belongs to the configured domain
f4a605
f4a605
We already check the sid belongs to the domain, but checking the name
f4a605
too feels better and make it easier to understand.
f4a605
f4a605
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14901
f4a605
f4a605
Signed-off-by: Stefan Metzmacher <metze@samba.org>
f4a605
Reviewed-by: Ralph Boehme <slow@samba.org>
f4a605
(cherry picked from commit bfd093648b4af51d104096c0cb3535e8706671e5)
f4a605
---
f4a605
 source3/winbindd/idmap_nss.c | 26 +++++++++++++++++++++-----
f4a605
 1 file changed, 21 insertions(+), 5 deletions(-)
f4a605
f4a605
diff --git a/source3/winbindd/idmap_nss.c b/source3/winbindd/idmap_nss.c
f4a605
index da50e2b4aa7..2729a0de3f3 100644
f4a605
--- a/source3/winbindd/idmap_nss.c
f4a605
+++ b/source3/winbindd/idmap_nss.c
f4a605
@@ -139,18 +139,21 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
f4a605
 	for (i = 0; ids[i]; i++) {
f4a605
 		struct group *gr;
f4a605
 		enum lsa_SidType type;
f4a605
-		const char *p = NULL;
f4a605
+		const char *_domain = NULL;
f4a605
+		const char *_name = NULL;
f4a605
+		char *domain = NULL;
f4a605
 		char *name = NULL;
f4a605
 		bool ret;
f4a605
 
f4a605
 		/* by default calls to winbindd are disabled
f4a605
 		   the following call will not recurse so this is safe */
f4a605
 		(void)winbind_on();
f4a605
-		ret = winbind_lookup_sid(talloc_tos(), ids[i]->sid, NULL,
f4a605
-					 &p, &type);
f4a605
+		ret = winbind_lookup_sid(talloc_tos(),
f4a605
+					 ids[i]->sid,
f4a605
+					 &_domain,
f4a605
+					 &_name,
f4a605
+					 &type);
f4a605
 		(void)winbind_off();
f4a605
-		name = discard_const_p(char, p);
f4a605
-
f4a605
 		if (!ret) {
f4a605
 			/* TODO: how do we know if the name is really not mapped,
f4a605
 			 * or something just failed ? */
f4a605
@@ -158,6 +161,18 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
f4a605
 			continue;
f4a605
 		}
f4a605
 
f4a605
+		domain = discard_const_p(char, _domain);
f4a605
+		name = discard_const_p(char, _name);
f4a605
+
f4a605
+		if (!strequal(domain, dom->name)) {
f4a605
+			struct dom_sid_buf buf;
f4a605
+			DBG_ERR("DOMAIN[%s] ignoring SID[%s] belongs to %s [%s\\%s]\n",
f4a605
+			        dom->name, dom_sid_str_buf(ids[i]->sid, &buf),
f4a605
+				sid_type_lookup(type), domain, name);
f4a605
+			ids[i]->status = ID_UNMAPPED;
f4a605
+			continue;
f4a605
+		}
f4a605
+
f4a605
 		switch (type) {
f4a605
 		case SID_NAME_USER: {
f4a605
 			struct passwd *pw;
f4a605
@@ -190,6 +205,7 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
f4a605
 			ids[i]->status = ID_UNKNOWN;
f4a605
 			break;
f4a605
 		}
f4a605
+		TALLOC_FREE(domain);
f4a605
 		TALLOC_FREE(name);
f4a605
 	}
f4a605
 	return NT_STATUS_OK;
f4a605
-- 
f4a605
2.34.1
f4a605
f4a605
f4a605
From 704ae4b8308e9ae6c50e3548f98de65e97ab6aa6 Mon Sep 17 00:00:00 2001
f4a605
From: Joseph Sutton <josephsutton@catalyst.net.nz>
f4a605
Date: Fri, 12 Nov 2021 20:53:30 +1300
f4a605
Subject: [PATCH 2/3] CVE-2020-25717: nsswitch/nsstest.c: Lower 'non existent
f4a605
 uid' to make room for new accounts
f4a605
f4a605
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14901
f4a605
f4a605
Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
f4a605
Reviewed-by: Stefan Metzmacher <metze@samba.org>
f4a605
Reviewed-by: Ralph Boehme <slow@samba.org>
f4a605
(cherry picked from commit fdbee5e074ebd76d659613b8b7114d70f938c38a)
f4a605
---
f4a605
 nsswitch/nsstest.c | 2 +-
f4a605
 1 file changed, 1 insertion(+), 1 deletion(-)
f4a605
f4a605
diff --git a/nsswitch/nsstest.c b/nsswitch/nsstest.c
f4a605
index e2ee9fbf3af..45270cdc459 100644
f4a605
--- a/nsswitch/nsstest.c
f4a605
+++ b/nsswitch/nsstest.c
f4a605
@@ -466,7 +466,7 @@ static void nss_test_errors(void)
f4a605
 		printf("ERROR Non existent user gave error %d\n", last_error);
f4a605
 	}
f4a605
 
f4a605
-	pwd = getpwuid(0xFFF0);
f4a605
+	pwd = getpwuid(0xFF00);
f4a605
 	if (pwd || last_error != NSS_STATUS_NOTFOUND) {
f4a605
 		total_errors++;
f4a605
 		printf("ERROR Non existent uid gave error %d\n", last_error);
f4a605
-- 
f4a605
2.34.1
f4a605
f4a605
f4a605
From 844723aa82cec67fd863fc327bde9fb04eab438d Mon Sep 17 00:00:00 2001
f4a605
From: Andrew Bartlett <abartlet@samba.org>
f4a605
Date: Fri, 12 Nov 2021 16:10:31 +1300
f4a605
Subject: [PATCH 3/3] CVE-2020-25717: s3:auth: Fallback to a SID/UID based
f4a605
 mapping if the named based lookup fails
f4a605
MIME-Version: 1.0
f4a605
Content-Type: text/plain; charset=UTF-8
f4a605
Content-Transfer-Encoding: 8bit
f4a605
f4a605
Before the CVE-2020-25717 fixes we had a fallback from
f4a605
getpwnam('DOMAIN\user') to getpwnam('user') which was very dangerous and
f4a605
unpredictable.
f4a605
f4a605
Now we do the fallback based on sid_to_uid() followed by
f4a605
getpwuid() on the returned uid.
f4a605
f4a605
This obsoletes 'username map [script]' based workaround adviced
f4a605
for CVE-2020-25717, when nss_winbindd is not used or
f4a605
idmap_nss is actually used.
f4a605
f4a605
In future we may decide to prefer or only do the SID/UID based
f4a605
lookup, but for now we want to keep this unchanged as much as possible.
f4a605
f4a605
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14901
f4a605
f4a605
Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
f4a605
f4a605
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
f4a605
Signed-off-by: Stefan Metzmacher <metze@samba.org>
f4a605
f4a605
[metze@samba.org moved the new logic into the fallback codepath only
f4a605
 in order to avoid behavior changes as much as possible]
f4a605
Reviewed-by: Ralph Boehme <slow@samba.org>
f4a605
f4a605
Autobuild-User(master): Ralph Böhme <slow@samba.org>
f4a605
Autobuild-Date(master): Mon Nov 15 19:01:56 UTC 2021 on sn-devel-184
f4a605
f4a605
(cherry picked from commit 0a546be05295a7e4a552f9f4f0c74aeb2e9a0d6e)
f4a605
---
f4a605
 source3/auth/auth_util.c | 34 +++++++++++++++++++++++++++++++++-
f4a605
 1 file changed, 33 insertions(+), 1 deletion(-)
f4a605
f4a605
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
f4a605
index 065b525500f..7a97dd45f11 100644
f4a605
--- a/source3/auth/auth_util.c
f4a605
+++ b/source3/auth/auth_util.c
f4a605
@@ -1862,7 +1862,9 @@ const struct auth_session_info *get_session_info_system(void)
f4a605
 ***************************************************************************/
f4a605
 
f4a605
 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
f4a605
-			      const char *username, char **found_username,
f4a605
+			      const char *username,
f4a605
+			      const struct dom_sid *sid,
f4a605
+			      char **found_username,
f4a605
 			      struct passwd **pwd,
f4a605
 			      bool *username_was_mapped)
f4a605
 {
f4a605
@@ -1897,6 +1899,31 @@ static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
f4a605
 	}
f4a605
 
f4a605
 	passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, false);
f4a605
+	if (!passwd && !*username_was_mapped) {
f4a605
+		struct dom_sid_buf buf;
f4a605
+		uid_t uid;
f4a605
+		bool ok;
f4a605
+
f4a605
+		DBG_DEBUG("Failed to find authenticated user %s via "
f4a605
+			  "getpwnam(), fallback to sid_to_uid(%s).\n",
f4a605
+			  dom_user, dom_sid_str_buf(sid, &buf));
f4a605
+
f4a605
+		ok = sid_to_uid(sid, &uid);
f4a605
+		if (!ok) {
f4a605
+			DBG_ERR("Failed to convert SID %s to a UID (dom_user[%s])\n",
f4a605
+				dom_sid_str_buf(sid, &buf), dom_user);
f4a605
+			return NT_STATUS_NO_SUCH_USER;
f4a605
+		}
f4a605
+		passwd = getpwuid_alloc(mem_ctx, uid);
f4a605
+		if (!passwd) {
f4a605
+			DBG_ERR("Failed to find local account with UID %lld for SID %s (dom_user[%s])\n",
f4a605
+				(long long)uid,
f4a605
+				dom_sid_str_buf(sid, &buf),
f4a605
+				dom_user);
f4a605
+			return NT_STATUS_NO_SUCH_USER;
f4a605
+		}
f4a605
+		real_username = talloc_strdup(mem_ctx, passwd->pw_name);
f4a605
+	}
f4a605
 	if (!passwd) {
f4a605
 		DEBUG(3, ("Failed to find authenticated user %s via "
f4a605
 			  "getpwnam(), denying access.\n", dom_user));
f4a605
@@ -2042,6 +2069,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
f4a605
 	bool username_was_mapped;
f4a605
 	struct passwd *pwd;
f4a605
 	struct auth_serversupplied_info *result;
f4a605
+	struct dom_sid sid;
f4a605
 	TALLOC_CTX *tmp_ctx = talloc_stackframe();
f4a605
 
f4a605
 	/* 
f4a605
@@ -2088,9 +2116,13 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
f4a605
 
f4a605
 	/* this call will try to create the user if necessary */
f4a605
 
f4a605
+	sid_copy(&sid, info3->base.domain_sid);
f4a605
+	sid_append_rid(&sid, info3->base.rid);
f4a605
+
f4a605
 	nt_status = check_account(tmp_ctx,
f4a605
 				  nt_domain,
f4a605
 				  nt_username,
f4a605
+				  &sid,
f4a605
 				  &found_username,
f4a605
 				  &pwd,
f4a605
 				  &username_was_mapped);
f4a605
-- 
f4a605
2.34.1
f4a605