diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/providers/ipa/ipa_idmap.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/providers/ipa/ipa_idmap.c b/src/providers/ipa/ipa_idmap.c index 2f141f8ea..eaca0ed3c 100644 --- a/src/providers/ipa/ipa_idmap.c +++ b/src/providers/ipa/ipa_idmap.c @@ -26,6 +26,136 @@ #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)); + ret = EINVAL; + goto done; + } + + 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 +248,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: |