From 3e7283a39994ac24a9ff9dfede0d735cc89b4bb0 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Wed, 23 Oct 2013 13:30:57 +0200 Subject: [PATCH 4/4] IPA: add trusted domains with missing idrange If the forest root of a trusted forest is managing POSIX IDs for its users and groups the same is assumed for all member domains in the forest which do not have explicitly have an idrange set. To reflect this SSSD will create the matching ranges automatically. Fixes https://fedorahosted.org/sssd/ticket/2101 --- src/providers/ipa/ipa_idmap.c | 136 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/src/providers/ipa/ipa_idmap.c b/src/providers/ipa/ipa_idmap.c index 2f141f8..cca0157 100644 --- a/src/providers/ipa/ipa_idmap.c +++ b/src/providers/ipa/ipa_idmap.c @@ -26,6 +26,135 @@ #include "providers/ipa/ipa_common.h" #include "util/util_sss_idmap.h" +static errno_t ipa_idmap_check_posix_child(struct sdap_idmap_ctx *idmap_ctx, + const char *dom_name, + const char *dom_sid_str, + size_t range_count, + struct range_info **range_list) +{ + bool has_algorithmic_mapping; + enum idmap_error_code err; + struct sss_domain_info *dom; + struct sss_domain_info *forest_root; + size_t c; + struct sss_idmap_range range; + struct range_info *r; + char *range_id; + TALLOC_CTX *tmp_ctx; + bool found = false; + int ret; + + err = sss_idmap_domain_has_algorithmic_mapping(idmap_ctx->map, dom_sid_str, + &has_algorithmic_mapping); + if (err == IDMAP_SUCCESS) { + DEBUG(SSSDBG_TRACE_ALL, + ("Idmap of domain [%s] already known, nothing to do.\n", + dom_sid_str)); + return EOK; + } else { + err = sss_idmap_domain_by_name_has_algorithmic_mapping(idmap_ctx->map, + dom_name, + &has_algorithmic_mapping); + if (err == IDMAP_SUCCESS) { + DEBUG(SSSDBG_TRACE_ALL, + ("Idmap of domain [%s] already known, nothing to do.\n", + dom_sid_str)); + return EOK; + } + } + DEBUG(SSSDBG_TRACE_ALL, ("Trying to add idmap for domain [%s].\n", + dom_sid_str)); + + if (err != IDMAP_SID_UNKNOWN && err != IDMAP_NAME_UNKNOWN) { + DEBUG(SSSDBG_OP_FAILURE, + ("sss_idmap_domain_has_algorithmic_mapping failed.\n")); + return EINVAL; + } + + dom = find_subdomain_by_sid(idmap_ctx->id_ctx->be->domain, dom_sid_str); + if (dom == NULL) { + DEBUG(SSSDBG_OP_FAILURE, + ("find_subdomain_by_sid failed with SID [%s].\n", dom_sid_str)); + return EINVAL; + } + + if (dom->forest == NULL) { + DEBUG(SSSDBG_MINOR_FAILURE, ("No forest available for domain [%s].\n", + dom_sid_str)); + return EINVAL; + } + + forest_root = find_subdomain_by_name(idmap_ctx->id_ctx->be->domain, + dom->forest, true); + if (forest_root == NULL) { + DEBUG(SSSDBG_OP_FAILURE, + ("find_subdomain_by_name failed to find forest root [%s].\n", + dom->forest)); + return ENOENT; + } + + if (forest_root->domain_id == NULL) { + DEBUG(SSSDBG_MINOR_FAILURE, ("Forest root [%s] does not have a SID.\n", + dom->forest)); + return EINVAL; + } + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_OP_FAILURE, ("talloc_new failed.\n")); + return ENOMEM; + } + + for (c = 0; c < range_count; c++) { + r = range_list[c]; + if (r->trusted_dom_sid != NULL + && strcmp(r->trusted_dom_sid, forest_root->domain_id) == 0) { + + if (r->range_type == NULL + || strcmp(r->range_type, IPA_RANGE_AD_TRUST_POSIX) != 0) { + DEBUG(SSSDBG_MINOR_FAILURE, + ("Forest root does not have range type [%s].\n", + IPA_RANGE_AD_TRUST_POSIX)); + return EINVAL; + } + + range.min = r->base_id; + range.max = r->base_id + r->id_range_size -1; + range_id = talloc_asprintf(tmp_ctx, "%s-%s", dom_sid_str, r->name); + if (range_id == NULL) { + DEBUG(SSSDBG_OP_FAILURE, ("talloc_asprintf failed.\n")); + ret = ENOMEM; + goto done; + } + + err = sss_idmap_add_domain_ex(idmap_ctx->map, dom_name, dom_sid_str, + &range, range_id, 0, true); + if (err != IDMAP_SUCCESS && err != IDMAP_COLLISION) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Could not add range [%s] to ID map\n", + range_id)); + ret = EIO; + goto done; + } + + found = true; + } + } + + if (!found) { + DEBUG(SSSDBG_MINOR_FAILURE, ("No idrange found for forest root [%s].\n", + forest_root->domain_id)); + ret = ENOENT; + goto done; + } + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + errno_t ipa_idmap_find_new_domain(struct sdap_idmap_ctx *idmap_ctx, const char *dom_name, const char *dom_sid_str) @@ -118,6 +247,13 @@ errno_t ipa_idmap_find_new_domain(struct sdap_idmap_ctx *idmap_ctx, } } + ret = ipa_idmap_check_posix_child(idmap_ctx, dom_name, dom_sid_str, + range_count, range_list); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("ipa_idmap_check_posix_child failed.\n")); + goto done; + } + ret = EOK; done: -- 1.8.3.1