static int setup_ranges(struct test_ctx *test_ctx, bool external_mapping, bool second_domain) { struct sss_idmap_range range; enum idmap_error_code err; const char *name; const char *sid; assert_non_null(test_ctx); if (second_domain) { range.min = TEST_2_RANGE_MIN; range.max = TEST_2_RANGE_MAX; name = TEST_2_DOM_NAME; sid = TEST_2_DOM_SID; } else { range.min = TEST_RANGE_MIN; range.max = TEST_RANGE_MAX; name = TEST_DOM_NAME; sid = TEST_DOM_SID; } err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, name, sid, &range, NULL, 0, external_mapping); assert_int_equal(err, IDMAP_SUCCESS); range.min += TEST_OFFSET; range.max += TEST_OFFSET; err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, name, sid, &range, NULL, TEST_OFFSET, external_mapping); assert_int_equal(err, IDMAP_SUCCESS); return 0; }
static errno_t sdap_idmap_add_configured_external_range(struct sdap_idmap_ctx *idmap_ctx) { int ret; struct sss_idmap_range range; struct sdap_id_ctx *id_ctx; enum idmap_error_code err; ret = sdap_idmap_get_configured_external_range(idmap_ctx, &range); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_idmap_get_configured_external_range failed.\n"); return ret; } id_ctx = idmap_ctx->id_ctx; err = sss_idmap_add_domain_ex(idmap_ctx->map, id_ctx->be->domain->name, id_ctx->be->domain->domain_id, &range, NULL, 0, true); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not add domain [%s] to the map: [%d]\n", id_ctx->be->domain->name, err); return EIO; } return EOK; }
static int setup_ranges_2922(struct test_ctx *test_ctx) { const int TEST_2922_DFL_SLIDE = 9212; struct sss_idmap_range range; enum idmap_error_code err; const char *name; const char *sid; /* Pick a new slice. */ id_t slice_num = -1; assert_non_null(test_ctx); name = TEST_DOM_NAME; sid = TEST_DOM_SID; err = sss_idmap_calculate_range(test_ctx->idmap_ctx, sid, &slice_num, &range); assert_int_equal(err, IDMAP_SUCCESS); /* Range computation should be deterministic. Lets validate that. */ assert_int_equal(range.min, TEST_2922_MIN_ID); assert_int_equal(range.max, TEST_2922_MAX_ID); assert_int_equal(slice_num, TEST_2922_DFL_SLIDE); err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, name, sid, &range, NULL, 0, false /* No external mapping */); assert_int_equal(err, IDMAP_SUCCESS); return 0; }
void test_sss_idmap_calculate_range_slice_collision(void **state) { struct test_ctx *test_ctx; enum idmap_error_code err; struct sss_idmap_range range; id_t slice_num = 123; test_ctx = talloc_get_type(*state, struct test_ctx); assert_non_null(test_ctx); err = sss_idmap_calculate_range(test_ctx->idmap_ctx, NULL, &slice_num, &range); assert_int_equal(err, IDMAP_SUCCESS); err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, TEST_DOM_NAME, TEST_DOM_SID, &range, NULL, 0, false); assert_int_equal(err, IDMAP_SUCCESS); err = sss_idmap_calculate_range(test_ctx->idmap_ctx, NULL, &slice_num, &range); assert_int_equal(err, IDMAP_COLLISION); slice_num++; err = sss_idmap_calculate_range(test_ctx->idmap_ctx, NULL, &slice_num, &range); assert_int_equal(err, IDMAP_SUCCESS); }
errno_t sdap_idmap_add_domain(struct sdap_idmap_ctx *idmap_ctx, const char *dom_name, const char *dom_sid, id_t slice) { errno_t ret; struct sss_idmap_range range; enum idmap_error_code err; id_t idmap_upper; bool external_mapping = true; ret = sss_idmap_ctx_get_upper(idmap_ctx->map, &idmap_upper); if (ret != IDMAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get upper bound of available ID range.\n"); ret = EIO; goto done; } if (dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_ID_MAPPING)) { external_mapping = false; ret = sss_idmap_calculate_range(idmap_ctx->map, dom_sid, &slice, &range); if (ret != IDMAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to calculate range for domain [%s]: [%d]\n", dom_name, ret); ret = EIO; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Adding domain [%s] as slice [%"SPRIid"]\n", dom_sid, slice); if (range.max > idmap_upper) { /* This should never happen */ DEBUG(SSSDBG_CRIT_FAILURE, "BUG: Range maximum exceeds the global maximum: " "%u > %"SPRIid"\n", range.max, idmap_upper); ret = EINVAL; goto done; } } else { ret = sdap_idmap_get_configured_external_range(idmap_ctx, &range); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_idmap_get_configured_external_range failed.\n"); return ret; } } /* Add this domain to the map */ err = sss_idmap_add_domain_ex(idmap_ctx->map, dom_name, dom_sid, &range, NULL, 0, external_mapping); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not add domain [%s] to the map: [%d]\n", dom_name, err); ret = EIO; goto done; } /* If algorithmic mapping is used add this domain to the SYSDB cache so it * will survive reboot */ if (!external_mapping) { ret = sysdb_idmap_store_mapping(idmap_ctx->id_ctx->be->domain, dom_name, dom_sid, slice); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_idmap_store_mapping failed.\n"); goto done; } } done: return ret; }
void test_add_domain(void **state) { struct test_ctx *test_ctx; enum idmap_error_code err; struct sss_idmap_range range; test_ctx = talloc_get_type(*state, struct test_ctx); assert_non_null(test_ctx); range.min = TEST_RANGE_MIN; range.max = TEST_RANGE_MAX; err = sss_idmap_add_domain(test_ctx->idmap_ctx, TEST_DOM_NAME, TEST_DOM_SID, &range); assert_int_equal(err, IDMAP_SUCCESS); err = sss_idmap_add_domain(test_ctx->idmap_ctx, TEST_DOM_NAME, TEST_DOM_SID, &range); assert_int_equal(err, IDMAP_COLLISION); err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, TEST_DOM_NAME, TEST_DOM_SID, &range, NULL, 0, false); assert_int_equal(err, IDMAP_COLLISION); range.min = TEST_RANGE_MIN + TEST_OFFSET; range.max = TEST_RANGE_MAX + TEST_OFFSET; err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, TEST_DOM_NAME, TEST_DOM_SID, &range, NULL, 0, false); assert_int_equal(err, IDMAP_COLLISION); err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, TEST_DOM_NAME"X", TEST_DOM_SID, &range, NULL, TEST_OFFSET, false); assert_int_equal(err, IDMAP_COLLISION); err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, TEST_DOM_NAME, TEST_DOM_SID"1", &range, NULL, TEST_OFFSET, false); assert_int_equal(err, IDMAP_COLLISION); err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, TEST_DOM_NAME, TEST_DOM_SID, &range, NULL, TEST_OFFSET, true); assert_int_equal(err, IDMAP_COLLISION); err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, TEST_DOM_NAME, TEST_DOM_SID, &range, NULL, TEST_OFFSET, false); assert_int_equal(err, IDMAP_SUCCESS); range.min = TEST_RANGE_MIN + 2 * TEST_OFFSET; range.max = TEST_RANGE_MAX + 2 * TEST_OFFSET; err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, TEST_DOM_NAME"-nosid", NULL, &range, NULL, TEST_OFFSET, false); assert_int_equal(err, IDMAP_SID_INVALID); err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, TEST_DOM_NAME"-nosid", NULL, &range, NULL, TEST_OFFSET, true); assert_int_equal(err, IDMAP_SUCCESS); }
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_get_ranges_from_sysdb(struct sdap_idmap_ctx *idmap_ctx, const char *dom_name, const char *dom_sid_str, bool allow_collisions) { int ret; size_t range_count; struct range_info **range_list; TALLOC_CTX *tmp_ctx; size_t c; enum idmap_error_code err; struct sss_idmap_range range; uint32_t rid; bool external_mapping; char *name; char *sid; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } ret = sysdb_get_ranges(tmp_ctx, idmap_ctx->id_ctx->be->domain->sysdb, &range_count, &range_list); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_ranges failed.\n"); goto done; } for (c = 0; c < range_count; c++) { ret = get_idmap_data_from_range(range_list[c], idmap_ctx->id_ctx->be->domain->name, &name, &sid, &rid, &range, &external_mapping); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_idmap_data_from_range failed for " \ "id range [%s], skipping.\n", range_list[c]->name); continue; } err = sss_idmap_add_domain_ex(idmap_ctx->map, name, sid, &range, range_list[c]->name, rid, external_mapping); if (err != IDMAP_SUCCESS) { if (!allow_collisions || err != IDMAP_COLLISION) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not add range [%s] to ID map\n", range_list[c]->name); ret = EIO; goto done; } } } if (dom_name != NULL || dom_sid_str != NULL) { 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: talloc_free(tmp_ctx); return ret; }