idmap_hash: remember new domain sids in idmap_hash_sid_to_id()
authorStefan Metzmacher <metze@samba.org>
Thu, 21 Mar 2019 15:54:31 +0000 (16:54 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 15 Oct 2019 07:36:38 +0000 (09:36 +0200)
This is similar to the checks in idmap_autorid_sid_to_id()
to check if a new mapping should be created.

This change means that idmap_hash_id_to_sid() can return mappings
for new domains learned in idmap_hash_sid_to_id().

Signed-off-by: Stefan Metzmacher <metze@samba.org>
source3/winbindd/idmap_hash/idmap_hash.c

index 65526fce4da0e86d5097990d77580af5adc9e59f..23cf917c03025d568af7c5fed84ccd78a6fc37d9 100644 (file)
@@ -25,6 +25,7 @@
 #include "ads.h"
 #include "nss_info.h"
 #include "../libcli/security/dom_sid.h"
+#include "libsmb/samlogon_cache.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_IDMAP
@@ -277,6 +278,68 @@ static NTSTATUS idmap_hash_sid_to_id(struct sid_hash_table *hashed_domains,
                return NT_STATUS_NONE_MAPPED;
        }
 
+       /*
+        * If the domain hash already exists find a SID in the table,
+        * just return the mapping.
+        */
+       if (hashed_domains[h_domain].sid != NULL) {
+               goto return_mapping;
+       }
+
+       /*
+        * If the caller already did a lookup sid and made sure the
+        * domain sid is valid, we can allocate a new range.
+        *
+        * Currently the winbindd parent already does a lookup sids
+        * first, but hopefully changes in future. If the
+        * caller knows the domain sid, ID_TYPE_BOTH should be
+        * passed instead of ID_TYPE_NOT_SPECIFIED.
+        */
+       if (id->xid.type == ID_TYPE_NOT_SPECIFIED) {
+               /*
+                * We keep the legacy behavior and
+                * just return the mapping, but
+                * the reverse mapping would not
+                * still not work.
+                *
+                * Maybe we should return NT_STATUS_NONE_MAPPED,
+                * but for now we keep what we already have.
+                */
+               goto return_mapping;
+       }
+
+       /*
+        * Check of last resort: A domain is valid if a user from that
+        * domain has recently logged in. The samlogon_cache these
+        * days also stores the domain sid.
+        *
+        * We used to check the list of trusted domains we received
+        * from "our" dc, but this is not reliable enough.
+        */
+       if (!netsamlogon_cache_have(&sid)) {
+               /*
+                * We keep the legacy behavior and
+                * just return the mapping, but
+                * the reverse mapping would not
+                * still not work.
+                *
+                * Maybe we should return NT_STATUS_NONE_MAPPED,
+                * but for now we keep what we already have.
+                */
+               goto return_mapping;
+       }
+
+       /*
+        * Now we're sure the domain exist, remember
+        * the domain in order to return reverse mappings
+        * in future.
+        */
+       hashed_domains[h_domain].sid = dom_sid_dup(hashed_domains, &sid);
+       if (hashed_domains[h_domain].sid == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+return_mapping:
        id->xid.id = combine_hashes(h_domain, h_rid);
        id->status = ID_MAPPED;