From 6df19847674d59e079782d30ec8a9dbdc77b99e2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 20 Feb 2021 15:50:12 +0100 Subject: [PATCH] passdb: Simplify sids_to_unixids() Best reviewed with "git show -b", there's a "continue" statement that changes subsequent indentation. Decouple lookup status of ids from ID_TYPE_NOT_SPECIFIED Bug: https://bugzilla.samba.org/show_bug.cgi?id=14571 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- source3/passdb/lookup_sid.c | 101 +++++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 6 deletions(-) diff --git source3/passdb/lookup_sid.c source3/passdb/lookup_sid.c index 64a181e..cd59aab 100644 --- source3/passdb/lookup_sid.c +++ source3/passdb/lookup_sid.c @@ -27,6 +27,7 @@ #include "idmap_cache.h" #include "../libcli/security/security.h" #include "lib/winbind_util.h" +#include "lib/util/bitmap.h" /***************************************************************** Dissect a user-provided name into domain, name, sid and type. @@ -1400,7 +1401,9 @@ bool sids_to_unix_ids(const struct dom_sid *sids, uint32_t num_sids, { struct wbcDomainSid *wbc_sids = NULL; struct wbcUnixId *wbc_ids = NULL; + struct bitmap *found = NULL; uint32_t i, num_not_cached; + uint32_t wbc_ids_size = 0; wbcErr err; bool ret = false; @@ -1408,6 +1411,20 @@ bool sids_to_unix_ids(const struct dom_sid *sids, uint32_t num_sids, if (wbc_sids == NULL) { return false; } + found = bitmap_talloc(wbc_sids, num_sids); + if (found == NULL) { + goto fail; + } + + /* + * We go through the requested SID array three times. + * First time to look for global_sid_Unix_Users + * and global_sid_Unix_Groups SIDS, and to look + * for mappings cached in the idmap_cache. + * + * Use bitmap_set() to mark an ids[] array entry as + * being mapped. + */ num_not_cached = 0; @@ -1417,34 +1434,40 @@ bool sids_to_unix_ids(const struct dom_sid *sids, uint32_t num_sids, if (fetch_uid_from_cache(&ids[i].id.uid, &sids[i])) { ids[i].type = WBC_ID_TYPE_UID; + bitmap_set(found, i); continue; } if (fetch_gid_from_cache(&ids[i].id.gid, &sids[i])) { ids[i].type = WBC_ID_TYPE_GID; + bitmap_set(found, i); continue; } if (sid_peek_check_rid(&global_sid_Unix_Users, &sids[i], &rid)) { ids[i].type = WBC_ID_TYPE_UID; ids[i].id.uid = rid; + bitmap_set(found, i); continue; } if (sid_peek_check_rid(&global_sid_Unix_Groups, &sids[i], &rid)) { ids[i].type = WBC_ID_TYPE_GID; ids[i].id.gid = rid; + bitmap_set(found, i); continue; } if (idmap_cache_find_sid2uid(&sids[i], &ids[i].id.uid, &expired) && !expired && ids[i].id.uid != (uid_t)-1) { ids[i].type = WBC_ID_TYPE_UID; + bitmap_set(found, i); continue; } if (idmap_cache_find_sid2gid(&sids[i], &ids[i].id.gid, &expired) && !expired && ids[i].id.gid != (gid_t)-1) { ids[i].type = WBC_ID_TYPE_GID; + bitmap_set(found, i); continue; } ids[i].type = WBC_ID_TYPE_NOT_SPECIFIED; @@ -1455,43 +1478,109 @@ bool sids_to_unix_ids(const struct dom_sid *sids, uint32_t num_sids, if (num_not_cached == 0) { goto done; } - wbc_ids = TALLOC_ARRAY(talloc_tos(), struct wbcUnixId, num_not_cached); + + /* + * For the ones that we couldn't map in the loop above, query winbindd + * via wbcSidsToUnixIds(). + */ + + wbc_ids_size = num_not_cached; + wbc_ids = talloc_array(talloc_tos(), struct wbcUnixId, wbc_ids_size); + if (wbc_ids == NULL) { goto fail; } - for (i=0; i