diff options
-rw-r--r-- | source3/winbindd/idmap_hash/idmap_hash.c | 135 |
1 files changed, 84 insertions, 51 deletions
diff --git a/source3/winbindd/idmap_hash/idmap_hash.c b/source3/winbindd/idmap_hash/idmap_hash.c index 1f353c331d5..726338473ea 100644 --- a/source3/winbindd/idmap_hash/idmap_hash.c +++ b/source3/winbindd/idmap_hash/idmap_hash.c @@ -253,9 +253,78 @@ static NTSTATUS unixids_to_sids(struct idmap_domain *dom, /********************************************************************* ********************************************************************/ +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 (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; + } + + id->status = ID_UNMAPPED; + + 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; + } + + /* + * 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. + */ + 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) { + 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; @@ -268,61 +337,25 @@ static NTSTATUS sids_to_unixids(struct idmap_domain *dom, } 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; - num_required++; - 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++; + } } if (num_tomap == num_mapped) { |