summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/providers/ipa/ipa_idmap.c137
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: