The branch, master has been updated via 7ee725f2860 idmap_hash: remember new domain sids in idmap_hash_sid_to_id() via ee820553fd2 idmap_hash: don't return ID_REQUIRE_TYPE if the domain is known in the netsamlogon cache via ede88d9f83f idmap_hash: only return ID_REQUIRE_TYPE if we don't know about the domain yet via 42dcb3db055 idmap_hash: return ID_REQUIRE_TYPE only if there's a chance to get a mapping later via c158b075b0b idmap_hash: split out a idmap_hash_sid_to_id() helper function via 57150b463fb idmap_hash: split out a idmap_hash_id_to_sid() helper function via 14102b05f37 idmap_hash: mirror the NT_STATUS_NONE_MAPPED/STATUS_SOME_UNMAPPED logic from idmap_autorid via 0da13ab3ad7 idmap_hash: we don't need to call idmap_hash_initialize() over an over again via 2cfcff3101f idmap_hash: remove unused error checks via 0f96c4b419a idmap_hash: fix comments about the algorithm via 9a24570d3d6 idmap_hash: provide ID_TYPE_BOTH mappings also for unixids_to_sids via a9583b5f96f idmap_autorid: fix ID_REQUIRE_TYPE for more than one SID for an unknown domain via ad242a20643 winbindd: don't call set_domain_online_request() in the idmap child from 78635d55fb8 audit_logging: Use `json_int_t` instead of `int` for `json_add_int` value type
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 7ee725f2860d835e9619fa594a2ee6faedbc6d21 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Mar 21 16:54:31 2019 +0100 idmap_hash: remember new domain sids in idmap_hash_sid_to_id() This change means that idmap_hash_id_to_sid() can return mappings for new domains learned in idmap_hash_sid_to_id(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Stefan Metzmacher <me...@samba.org> Autobuild-Date(master): Fri Mar 10 11:35:06 UTC 2023 on atb-devel-224 commit ee820553fd2c6ada966a0160cbb0240049f9d9f7 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Mar 21 16:54:31 2019 +0100 idmap_hash: don't return ID_REQUIRE_TYPE if the domain is known in the netsamlogon cache BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit ede88d9f83fb77fa8eff226fb6a85ac71e415098 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Mar 21 16:54:31 2019 +0100 idmap_hash: only return ID_REQUIRE_TYPE if we don't know about the domain yet BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 42dcb3db05530179a991fe58e7b96b52bbbcc607 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Mar 21 16:54:31 2019 +0100 idmap_hash: return ID_REQUIRE_TYPE only if there's a chance to get a mapping later If we are going to return ID_UNMAPPED later anyway, there's no need to defer that decision by returning ID_REQUIRE_TYPE first. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit c158b075b0b5035615fa8848f1f3d8ef27696861 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Mar 21 14:05:13 2019 +0100 idmap_hash: split out a idmap_hash_sid_to_id() helper function BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 57150b463fb8e27c048670f7b4902bd091ee3ae9 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Mar 21 14:05:13 2019 +0100 idmap_hash: split out a idmap_hash_id_to_sid() helper function BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 14102b05f3744c67178bd719d41e67fc3e049ee4 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Mar 21 14:00:16 2019 +0100 idmap_hash: mirror the NT_STATUS_NONE_MAPPED/STATUS_SOME_UNMAPPED logic from idmap_autorid BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 0da13ab3ad7278eafdcd988f39e891242eb46d37 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Mar 21 10:54:49 2019 +0100 idmap_hash: we don't need to call idmap_hash_initialize() over an over again It's always the first function that's called from idmap_methods. This also demonstrates that we currently always return NT_STATUS_OK, even if we haven't mapped all map entries. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 2cfcff3101fce94b365eccde114432dfa980bbd0 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Mar 21 13:54:10 2019 +0100 idmap_hash: remove unused error checks id_map_ptrs_init() is used in the callers in order to set everything up as expected. Other backends also just trust the caller. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 0f96c4b419a59ea884e68a460910e5c8a45bfcec Author: Stefan Metzmacher <me...@samba.org> Date: Thu Mar 21 13:37:16 2019 +0100 idmap_hash: fix comments about the algorithm Only support ~ 50k users per domain. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 9a24570d3d69f51b6d50bb04b739815ec67c1a3d Author: Stefan Metzmacher <me...@samba.org> Date: Thu Mar 21 16:38:35 2019 +0100 idmap_hash: provide ID_TYPE_BOTH mappings also for unixids_to_sids While sids_to_unixids returns ID_TYPE_BOTH mappings, unixids_to_sids() returns the callers asked for, which fills gencache with the non ID_TYPE_BOTH mappings. As a result also the sids_to_unixids fast path via gencache won't return ID_TYPE_BOTH mappings. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit a9583b5f96fe3fbf9c1ee545fa868fd705aef3e0 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Feb 17 16:51:42 2023 +0100 idmap_autorid: fix ID_REQUIRE_TYPE for more than one SID for an unknown domain When we see a trusted domain SID for the first time, idmap_autorid returns ID_REQUIRE_TYPE only for the first sid and leaves the others with ID_TYPE_NOT_SPECIFIED. It means the winbindd parent only retries the first sid. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15318 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit ad242a20643c930eb00a8b700f7bd9638f8821a8 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Feb 16 16:31:34 2023 +0100 winbindd: don't call set_domain_online_request() in the idmap child Most idmap backends don't need access to the domain controllers. And the related code is not needed for the backends. Commit 17c86a2c5a5a5e2b194362e5f36f0f99910222c5 changed the logic of set_domain_online_request() completely! Instead of triggering a dc probe in the background, it is now doing a blocking connection. And doing this in the idmap child is completely useless. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15317 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: source3/winbindd/idmap_autorid.c | 15 +- source3/winbindd/idmap_hash/idmap_hash.c | 302 ++++++++++++++++++++----------- source3/winbindd/winbindd_dual.c | 7 - 3 files changed, 208 insertions(+), 116 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c index c7d56a37684..bf5947a9b43 100644 --- a/source3/winbindd/idmap_autorid.c +++ b/source3/winbindd/idmap_autorid.c @@ -697,9 +697,10 @@ static NTSTATUS idmap_autorid_sids_to_unixids(struct idmap_domain *dom, { struct idmap_tdb_common_context *commoncfg; NTSTATUS ret; - int i; - int num_tomap = 0; - int num_mapped = 0; + size_t i; + size_t num_tomap = 0; + size_t num_mapped = 0; + size_t num_required = 0; /* initialize the status to avoid surprise */ for (i = 0; ids[i]; i++) { @@ -713,6 +714,12 @@ static NTSTATUS idmap_autorid_sids_to_unixids(struct idmap_domain *dom, for (i = 0; ids[i]; i++) { ret = idmap_autorid_sid_to_id(commoncfg, dom, ids[i]); + if (NT_STATUS_EQUAL(ret, NT_STATUS_SOME_NOT_MAPPED) && + ids[i]->status == ID_REQUIRE_TYPE) + { + num_required++; + continue; + } if ((!NT_STATUS_IS_OK(ret)) && (!NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED))) { struct dom_sid_buf buf; @@ -729,6 +736,8 @@ static NTSTATUS idmap_autorid_sids_to_unixids(struct idmap_domain *dom, if (num_tomap == num_mapped) { return NT_STATUS_OK; + } else if (num_required > 0) { + return STATUS_SOME_UNMAPPED; } else if (num_mapped == 0) { return NT_STATUS_NONE_MAPPED; } diff --git a/source3/winbindd/idmap_hash/idmap_hash.c b/source3/winbindd/idmap_hash/idmap_hash.c index d0bed7631a6..e9d90e3d02b 100644 --- a/source3/winbindd/idmap_hash/idmap_hash.c +++ b/source3/winbindd/idmap_hash/idmap_hash.c @@ -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 @@ -60,13 +61,16 @@ static uint32_t hash_domain_sid(const struct dom_sid *sid) } /********************************************************************* - Hash a Relative ID to a 20 bit number + Hash a Relative ID to a 19 bit number ********************************************************************/ static uint32_t hash_rid(uint32_t rid) { - /* 20 bits for the rid which allows us to support - the first 100K users/groups in a domain */ + /* + * 19 bits for the rid which allows us to support + * the first 50K users/groups in a domain + * + */ return (rid & 0x0007FFFF); } @@ -79,8 +83,13 @@ static uint32_t combine_hashes(uint32_t h_domain, { uint32_t return_id = 0; - /* shift the hash_domain 19 bits to the left and OR with the - hash_rid */ + /* + * shift the hash_domain 19 bits to the left and OR with the + * hash_rid + * + * This will generate a 31 bit number out of + * 12 bit domain and 19 bit rid. + */ return_id = ((h_domain<<19) | h_rid); @@ -123,14 +132,6 @@ static NTSTATUS idmap_hash_initialize(struct idmap_domain *dom) return NT_STATUS_INVALID_PARAMETER; } - /* If the domain SID hash table has been initialized, assume - that we completed this function previously */ - - if (dom->private_data != NULL) { - nt_status = NT_STATUS_OK; - goto done; - } - if (!wcache_tdc_fetch_list(&dom_list, &num_domains)) { nt_status = NT_STATUS_TRUSTED_DOMAIN_FAILURE; BAIL_ON_NTSTATUS_ERROR(nt_status); @@ -183,135 +184,224 @@ done: /********************************************************************* ********************************************************************/ +static NTSTATUS idmap_hash_id_to_sid(struct sid_hash_table *hashed_domains, + struct idmap_domain *dom, + struct id_map *id) +{ + uint32_t h_domain = 0, h_rid = 0; + + id->status = ID_UNMAPPED; + + separate_hashes(id->xid.id, &h_domain, &h_rid); + + /* + * If the domain hash doesn't find a SID in the table, + * skip it + */ + if (hashed_domains[h_domain].sid == NULL) { + /* keep ID_UNMAPPED */ + return NT_STATUS_OK; + } + + id->xid.type = ID_TYPE_BOTH; + sid_compose(id->sid, hashed_domains[h_domain].sid, h_rid); + id->status = ID_MAPPED; + + return NT_STATUS_OK; +} + static NTSTATUS unixids_to_sids(struct idmap_domain *dom, struct id_map **ids) { struct sid_hash_table *hashed_domains = talloc_get_type_abort( dom->private_data, struct sid_hash_table); - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - int i; - - if (!ids) { - nt_status = NT_STATUS_INVALID_PARAMETER; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } + size_t i; + size_t num_tomap = 0; + size_t num_mapped = 0; - /* initialize the status to avoid suprise */ + /* initialize the status to avoid surprise */ for (i = 0; ids[i]; i++) { ids[i]->status = ID_UNKNOWN; + num_tomap++; } - nt_status = idmap_hash_initialize(dom); - BAIL_ON_NTSTATUS_ERROR(nt_status); - for (i=0; ids[i]; i++) { - uint32_t h_domain, h_rid; + NTSTATUS ret; + + ret = idmap_hash_id_to_sid(hashed_domains, dom, ids[i]); + if (!NT_STATUS_IS_OK(ret)) { + /* some fatal error occurred, log it */ + DBG_NOTICE("Unexpected error resolving an ID " + "(%d): %s\n", ids[i]->xid.id, + nt_errstr(ret)); + return ret; + } - ids[i]->status = ID_UNMAPPED; + if (ids[i]->status == ID_MAPPED) { + num_mapped++; + } + } - separate_hashes(ids[i]->xid.id, &h_domain, &h_rid); + if (num_tomap == num_mapped) { + return NT_STATUS_OK; + } else if (num_mapped == 0) { + return NT_STATUS_NONE_MAPPED; + } - /* Make sure the caller allocated memor for us */ + return STATUS_SOME_UNMAPPED; +} - if (!ids[i]->sid) { - nt_status = NT_STATUS_INVALID_PARAMETER; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } +/********************************************************************* + ********************************************************************/ - /* If the domain hash doesn't find a SID in the table, - skip it */ +static NTSTATUS idmap_hash_sid_to_id(struct sid_hash_table *hashed_domains, + struct idmap_domain *dom, + struct id_map *id) +{ + struct dom_sid sid; + uint32_t rid; + uint32_t h_domain, h_rid; - if (!hashed_domains[h_domain].sid) - continue; + id->status = ID_UNMAPPED; - sid_compose(ids[i]->sid, hashed_domains[h_domain].sid, h_rid); - ids[i]->status = ID_MAPPED; + sid_copy(&sid, id->sid); + sid_split_rid(&sid, &rid); + + h_domain = hash_domain_sid(&sid); + h_rid = hash_rid(rid); + + /* Check that both hashes are non-zero*/ + if (h_domain == 0) { + /* keep ID_UNMAPPED */ + return NT_STATUS_OK; + } + if (h_rid == 0) { + /* keep ID_UNMAPPED */ + return NT_STATUS_OK; } -done: - return nt_status; -} + /* + * 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; + } -/********************************************************************* - ********************************************************************/ + /* + * 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. + */ + if (netsamlogon_cache_have(&sid)) { + /* + * The domain is valid, so we'll + * remember it in order to + * allow reverse mappings to work. + */ + goto remember_domain; + } + + if (id->xid.type == ID_TYPE_NOT_SPECIFIED) { + /* + * idmap_hash used to bounce back the requested type, + * which was ID_TYPE_UID, ID_TYPE_GID or + * ID_TYPE_NOT_SPECIFIED before as the winbindd parent + * always used a lookupsids. When the lookupsids + * failed because of an unknown domain, the idmap child + * weren't requested at all and the caller sees + * ID_TYPE_NOT_SPECIFIED. + * + * Now that the winbindd parent will pass ID_TYPE_BOTH + * in order to indicate that the domain exists. + * We should ask the parent to fallback to lookupsids + * if the domain is not known yet. + */ + id->status = ID_REQUIRE_TYPE; + return NT_STATUS_OK; + } + + /* + * Now we're sure the domain exist, remember + * the domain in order to return reverse mappings + * in future. + */ +remember_domain: + hashed_domains[h_domain].sid = dom_sid_dup(hashed_domains, &sid); + if (hashed_domains[h_domain].sid == NULL) { + return NT_STATUS_NO_MEMORY; + } + + /* + * idmap_hash used to bounce back the requested type, + * which was ID_TYPE_UID, ID_TYPE_GID or + * ID_TYPE_NOT_SPECIFIED before as the winbindd parent + * always used a lookupsids. + * + * This module should have supported ID_TYPE_BOTH since + * samba-4.1.0, similar to idmap_rid and idmap_autorid. + * + * Now that the winbindd parent will pass ID_TYPE_BOTH + * in order to indicate that the domain exists, it's + * better to always return ID_TYPE_BOTH instead of a + * random mix of ID_TYPE_UID, ID_TYPE_GID or + * ID_TYPE_BOTH. + */ +return_mapping: + id->xid.type = ID_TYPE_BOTH; + id->xid.id = combine_hashes(h_domain, h_rid); + id->status = ID_MAPPED; + + return NT_STATUS_OK; +} static NTSTATUS sids_to_unixids(struct idmap_domain *dom, struct id_map **ids) { - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - int i; - - if (!ids) { - nt_status = NT_STATUS_INVALID_PARAMETER; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } + struct sid_hash_table *hashed_domains = talloc_get_type_abort( + dom->private_data, struct sid_hash_table); + size_t i; + size_t num_tomap = 0; + size_t num_mapped = 0; + size_t num_required = 0; - /* initialize the status to avoid suprise */ + /* initialize the status to avoid surprise */ for (i = 0; ids[i]; i++) { ids[i]->status = ID_UNKNOWN; + num_tomap++; } - nt_status = idmap_hash_initialize(dom); - BAIL_ON_NTSTATUS_ERROR(nt_status); - for (i=0; ids[i]; i++) { - struct dom_sid sid; - uint32_t rid; - uint32_t h_domain, h_rid; - - ids[i]->status = ID_UNMAPPED; - - if (ids[i]->xid.type == ID_TYPE_NOT_SPECIFIED) { - /* - * idmap_hash used to bounce back the requested type, - * which was ID_TYPE_UID, ID_TYPE_GID or - * ID_TYPE_NOT_SPECIFIED before as the winbindd parent - * always used a lookupsids. When the lookupsids - * failed because of an unknown domain, the idmap child - * weren't requested at all and the caller sees - * ID_TYPE_NOT_SPECIFIED. - * - * Now that the winbindd parent will pass ID_TYPE_BOTH - * in order to indicate that the domain exists. - * We should ask the parent to fallback to lookupsids - * if the domain is not known yet. - */ - ids[i]->status = ID_REQUIRE_TYPE; - continue; + NTSTATUS ret; + + ret = idmap_hash_sid_to_id(hashed_domains, dom, ids[i]); + if (!NT_STATUS_IS_OK(ret)) { + struct dom_sid_buf buf; + /* some fatal error occurred, log it */ + DBG_NOTICE("Unexpected error resolving a SID " + "(%s): %s\n", + dom_sid_str_buf(ids[i]->sid, &buf), + nt_errstr(ret)); + return ret; } - sid_copy(&sid, ids[i]->sid); - sid_split_rid(&sid, &rid); - - h_domain = hash_domain_sid(&sid); - h_rid = hash_rid(rid); - - /* Check that both hashes are non-zero*/ - - if (h_domain && h_rid) { - /* - * idmap_hash used to bounce back the requested type, - * which was ID_TYPE_UID, ID_TYPE_GID or - * ID_TYPE_NOT_SPECIFIED before as the winbindd parent - * always used a lookupsids. - * - * This module should have supported ID_TYPE_BOTH since - * samba-4.1.0, similar to idmap_rid and idmap_autorid. - * - * Now that the winbindd parent will pass ID_TYPE_BOTH - * in order to indicate that the domain exists, it's - * better to always return ID_TYPE_BOTH instead of a - * random mix of ID_TYPE_UID, ID_TYPE_GID or - * ID_TYPE_BOTH. - */ - ids[i]->xid.type = ID_TYPE_BOTH; - ids[i]->xid.id = combine_hashes(h_domain, h_rid); - ids[i]->status = ID_MAPPED; + if (ids[i]->status == ID_MAPPED) { + num_mapped++; + } + if (ids[i]->status == ID_REQUIRE_TYPE) { + num_required++; } } -done: - return nt_status; + if (num_tomap == num_mapped) { + return NT_STATUS_OK; + } else if (num_required > 0) { + return STATUS_SOME_UNMAPPED; + } else if (num_mapped == 0) { + return NT_STATUS_NONE_MAPPED; + } + + return STATUS_SOME_UNMAPPED; } /********************************************************************* diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index d9c32b10072..239a31f7de3 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -1817,13 +1817,6 @@ static bool fork_domain_child(struct winbindd_child *child) } } - /* - * We are in idmap child, bring primary domain online. - */ - if (is_idmap_child(child)) { - set_domain_online_request(primary_domain); - } - /* We might be in the idmap child...*/ if (child->domain && !(child->domain->internal) && lp_winbind_offline_logon()) { -- Samba Shared Repository