]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2020-25717 lookup_name: allow lookup names prefixed with DNS forest root for...
authorAlexander Bokovoy <ab@samba.org>
Tue, 10 Nov 2020 15:35:24 +0000 (17:35 +0200)
committerJule Anger <janger@samba.org>
Mon, 8 Nov 2021 09:52:09 +0000 (10:52 +0100)
In FreeIPA deployment with active Global Catalog service, when a two-way
trust to Active Directory forest is established, Windows systems can
look up FreeIPA users and groups. When using a security tab in Windows
Explorer on AD side, a lookup over a trusted forest might come as
realm\name instead of NetBIOS domain name:

--------------------------------------------------------------------
[2020/01/13 11:12:39.859134,  1, pid=33253, effective(17324010041732401004), real(1732401004, 0), class=rpc_parse] ../../librpc/ndr/ndr.c:471(ndr_print_function_debug)
       lsa_LookupNames3: struct lsa_LookupNames3
          in: struct lsa_LookupNames3
              handle                   : *
                  handle: struct policy_handle
                      handle_type              : 0x00000000 (0)
                      uuid                     : 0000000e-0000-0000-1c5e-a750e5810000
              num_names                : 0x00000001 (1)
              names: ARRAY(1)
                  names: struct lsa_String
                      length                   : 0x001e (30)
                      size                     : 0x0020 (32)
                      string                   : *
                          string                   : 'ipa.test\admins'
              sids                     : *
                  sids: struct lsa_TransSidArray3
                      count                    : 0x00000000 (0)
                      sids                     : NULL
              level                    : LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 (6)
              count                    : *
                  count                    : 0x00000000 (0)
              lookup_options           : LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES (0)
              client_revision          : LSA_CLIENT_REVISION_2 (2)
--------------------------------------------------------------------

If we are running as a DC and PASSDB supports returning domain info
(pdb_get_domain_info() returns a valid structure), check domain of the
name in lookup_name() against DNS forest name and allow the request to
be done against the primary domain. This corresponds to FreeIPA's use of
Samba as a DC. For normal domain members a realm-based lookup falls back
to a lookup over to its own domain controller with the help of winbindd.

Signed-off-by: Alexander Bokovoy <ab@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Autobuild-User(master): Alexander Bokovoy <ab@samba.org>
Autobuild-Date(master): Wed Nov 11 10:59:01 UTC 2020 on sn-devel-184

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

(cherry picked from commit 31c703766fd2b89737826fb7e9a707f0622bb8cd)

source3/passdb/lookup_sid.c

index 39b81f3147add183779009bb0fa3740e717ae1ea..0e01467b3cb44d1dd0bcb9f7d51b7268f10ae97b 100644 (file)
@@ -114,17 +114,36 @@ bool lookup_name(TALLOC_CTX *mem_ctx,
                full_name, domain, name));
        DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags));
 
-       if (((flags & LOOKUP_NAME_DOMAIN) || (flags == 0)) &&
-           strequal(domain, get_global_sam_name()))
-       {
+       if ((flags & LOOKUP_NAME_DOMAIN) || (flags == 0)) {
+               bool check_global_sam = false;
+
+               check_global_sam = strequal(domain, get_global_sam_name());
+
+               /* If we are running on a DC that has PASSDB module with domain
+                * information, check if DNS forest name is matching the domain
+                * name. This is the case of FreeIPA domain controller when
+                * trusted AD DC looks up users found in a Global Catalog of
+                * the forest root domain. */
+               if (!check_global_sam && (IS_DC)) {
+                       struct pdb_domain_info *dom_info = NULL;
+                       dom_info = pdb_get_domain_info(tmp_ctx);
+
+                       if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) {
+                               check_global_sam = strequal(domain, dom_info->dns_forest);
+                       }
 
-               /* It's our own domain, lookup the name in passdb */
-               if (lookup_global_sam_name(name, flags, &rid, &type)) {
-                       sid_compose(&sid, get_global_sam_sid(), rid);
-                       goto ok;
+                       TALLOC_FREE(dom_info);
+               }
+
+               if (check_global_sam) {
+                       /* It's our own domain, lookup the name in passdb */
+                       if (lookup_global_sam_name(name, flags, &rid, &type)) {
+                               sid_compose(&sid, get_global_sam_sid(), rid);
+                               goto ok;
+                       }
+                       TALLOC_FREE(tmp_ctx);
+                       return false;
                }
-               TALLOC_FREE(tmp_ctx);
-               return false;
        }
 
        if ((flags & LOOKUP_NAME_BUILTIN) &&