CVE-2020-25717: idmap_nss: verify that the name of the sid belongs to the configured...
authorStefan Metzmacher <metze@samba.org>
Fri, 12 Nov 2021 14:27:58 +0000 (15:27 +0100)
committerAndreas Schneider <asn@samba.org>
Mon, 10 Jan 2022 13:34:53 +0000 (14:34 +0100)
We already check the sid belongs to the domain, but checking the name
too feels better and make it easier to understand.

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

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
[abartlet@samba.org backorted from commit bfd093648b4af51d104096c0cb3535e8706671e5
 as header libcli/security/dom_sid.h was not present for struct dom_sid_buf]

[abartlet@samba.org fix CVE marker]

source3/winbindd/idmap_nss.c

index 3fe98cbc729666e4442565febede3132e922ee06..243b67ccafd77bf5416238b37571484689dc2d8b 100644 (file)
@@ -25,6 +25,7 @@
 #include "nsswitch/winbind_client.h"
 #include "idmap.h"
 #include "lib/winbind_util.h"
+#include "libcli/security/dom_sid.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_IDMAP
@@ -135,18 +136,21 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
        for (i = 0; ids[i]; i++) {
                struct group *gr;
                enum lsa_SidType type;
-               const char *p = NULL;
+               const char *_domain = NULL;
+               const char *_name = NULL;
+               char *domain = NULL;
                char *name = NULL;
                bool ret;
 
                /* by default calls to winbindd are disabled
                   the following call will not recurse so this is safe */
                (void)winbind_on();
-               ret = winbind_lookup_sid(talloc_tos(), ids[i]->sid, NULL,
-                                        &p, &type);
+               ret = winbind_lookup_sid(talloc_tos(),
+                                        ids[i]->sid,
+                                        &_domain,
+                                        &_name,
+                                        &type);
                (void)winbind_off();
-               name = discard_const_p(char, p);
-
                if (!ret) {
                        /* TODO: how do we know if the name is really not mapped,
                         * or something just failed ? */
@@ -154,6 +158,18 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
                        continue;
                }
 
+               domain = discard_const_p(char, _domain);
+               name = discard_const_p(char, _name);
+
+               if (!strequal(domain, dom->name)) {
+                       struct dom_sid_buf buf;
+                       DBG_ERR("DOMAIN[%s] ignoring SID[%s] belongs to %s [%s\\%s]\n",
+                               dom->name, dom_sid_str_buf(ids[i]->sid, &buf),
+                               sid_type_lookup(type), domain, name);
+                       ids[i]->status = ID_UNMAPPED;
+                       continue;
+               }
+
                switch (type) {
                case SID_NAME_USER: {
                        struct passwd *pw;
@@ -186,6 +202,7 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
                        ids[i]->status = ID_UNKNOWN;
                        break;
                }
+               TALLOC_FREE(domain);
                TALLOC_FREE(name);
        }
        return NT_STATUS_OK;