diff options
author | Sumit Bose <sbose@redhat.com> | 2014-02-07 18:17:09 +0100 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2014-02-26 15:11:31 +0100 |
commit | 096a9678919fae460342469989b97fd47d812823 (patch) | |
tree | e9e0b4c047ac09553d04a40c7365addc29186766 /src | |
parent | f69f3581658351003a6d9245045e41d0efb85022 (diff) | |
download | sssd-096a9678919fae460342469989b97fd47d812823.tar.gz sssd-096a9678919fae460342469989b97fd47d812823.tar.xz sssd-096a9678919fae460342469989b97fd47d812823.zip |
IPA: check ranges for collisions before saving them
Fixes https://fedorahosted.org/sssd/ticket/2253
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/providers/ipa/ipa_subdomains.c | 84 |
1 files changed, 64 insertions, 20 deletions
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c index b9d9ceb6f..7103ba28a 100644 --- a/src/providers/ipa/ipa_subdomains.c +++ b/src/providers/ipa/ipa_subdomains.c @@ -351,14 +351,28 @@ const char *get_flat_name_from_subdomain_name(struct be_ctx *be_ctx, } static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx, + char *domain_name, size_t count, struct sysdb_attrs **reply, struct range_info ***_range_list) { struct range_info **range_list = NULL; + struct range_info *r; const char *value; size_t c; + size_t d; int ret; + enum idmap_error_code err; + char *name1; + char *name2; + char *sid1; + char *sid2; + uint32_t rid1; + uint32_t rid2; + struct sss_idmap_range range1; + struct sss_idmap_range range2; + bool mapping1; + bool mapping2; range_list = talloc_array(mem_ctx, struct range_info *, count + 1); if (range_list == NULL) { @@ -367,8 +381,8 @@ static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx, } for (c = 0; c < count; c++) { - range_list[c] = talloc_zero(range_list, struct range_info); - if (range_list[c] == NULL) { + r = talloc_zero(range_list, struct range_info); + if (r == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); ret = ENOMEM; goto done; @@ -379,8 +393,9 @@ static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx, DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } - range_list[c]->name = talloc_strdup(range_list[c], value); - if (range_list[c]->name == NULL) { + + r->name = talloc_strdup(r, value); + if (r->name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; @@ -388,9 +403,8 @@ static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx, ret = sysdb_attrs_get_string(reply[c], IPA_TRUSTED_DOMAIN_SID, &value); if (ret == EOK) { - range_list[c]->trusted_dom_sid = talloc_strdup(range_list[c], - value); - if (range_list[c]->trusted_dom_sid == NULL) { + r->trusted_dom_sid = talloc_strdup(r, value); + if (r->trusted_dom_sid == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; @@ -401,28 +415,28 @@ static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx, } ret = sysdb_attrs_get_uint32_t(reply[c], IPA_BASE_ID, - &range_list[c]->base_id); + &r->base_id); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } ret = sysdb_attrs_get_uint32_t(reply[c], IPA_ID_RANGE_SIZE, - &range_list[c]->id_range_size); + &r->id_range_size); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } ret = sysdb_attrs_get_uint32_t(reply[c], IPA_BASE_RID, - &range_list[c]->base_rid); + &r->base_rid); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } ret = sysdb_attrs_get_uint32_t(reply[c], IPA_SECONDARY_BASE_RID, - &range_list[c]->secondary_base_rid); + &r->secondary_base_rid); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; @@ -430,8 +444,8 @@ static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx, ret = sysdb_attrs_get_string(reply[c], IPA_RANGE_TYPE, &value); if (ret == EOK) { - range_list[c]->range_type = talloc_strdup(range_list[c], value); - if (range_list[c]->range_type == NULL) { + r->range_type = talloc_strdup(r, value); + if (r->range_type == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; @@ -439,23 +453,52 @@ static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx, } else if (ret == ENOENT) { /* Older IPA servers might not have the range_type attribute, but * only support local ranges and trusts with algorithmic mapping. */ - if (range_list[c]->trusted_dom_sid == NULL) { - range_list[c]->range_type = talloc_strdup(range_list[c], - IPA_RANGE_LOCAL); + if (r->trusted_dom_sid == NULL) { + r->range_type = talloc_strdup(r, IPA_RANGE_LOCAL); } else { - range_list[c]->range_type = talloc_strdup(range_list[c], - IPA_RANGE_AD_TRUST); + r->range_type = talloc_strdup(r, IPA_RANGE_AD_TRUST); } } else { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } - if (range_list[c]->range_type == NULL) { + if (r->range_type == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } + + ret = get_idmap_data_from_range(r, domain_name, &name1, &sid1, &rid1, + &range1, &mapping1); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("get_idmap_data_from_range failed.\n")); + goto done; + } + for (d = 0; d < c; d++) { + ret = get_idmap_data_from_range(range_list[d], domain_name, &name2, + &sid2, &rid2, &range2, &mapping2); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + ("get_idmap_data_from_range failed.\n")); + goto done; + } + + err = sss_idmap_check_collision_ex(name1, sid1, &range1, rid1, + r->name, mapping1, + name2, sid2, &range2, rid2, + range_list[d]->name, mapping2); + if (err != IDMAP_SUCCESS) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Collision of ranges [%s] and [%s] detected.\n", + r->name, range_list[d]->name); + ret = EINVAL; + goto done; + } + } + + range_list[c] = r; } + range_list[c] = NULL; *_range_list = range_list; @@ -1013,7 +1056,8 @@ static void ipa_subdomains_handler_ranges_done(struct tevent_req *req) goto done; } - ret = ipa_ranges_parse_results(ctx, reply_count, reply, &range_list); + ret = ipa_ranges_parse_results(ctx, domain->name, + reply_count, reply, &range_list); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_ranges_parse_results request failed.\n"); |