Blame SOURCES/0095-IPA-check-ranges-for-collisions-before-saving-them.patch

2fc102
From 841fef45aef0a1424d4afbf3ea2bb40566155af9 Mon Sep 17 00:00:00 2001
2fc102
From: Sumit Bose <sbose@redhat.com>
2fc102
Date: Fri, 7 Feb 2014 18:17:09 +0100
2fc102
Subject: [PATCH 95/97] IPA: check ranges for collisions before saving them
2fc102
2fc102
Fixes https://fedorahosted.org/sssd/ticket/2253
2fc102
---
2fc102
 src/providers/ipa/ipa_subdomains.c | 83 +++++++++++++++++++++++++++++---------
2fc102
 1 file changed, 63 insertions(+), 20 deletions(-)
2fc102
2fc102
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
2fc102
index 88b6ba52538be83417e98c9a5dd033bea87ebe4b..07ae03b6ab0325b011a26f36f4fdc9a5766b8445 100644
2fc102
--- a/src/providers/ipa/ipa_subdomains.c
2fc102
+++ b/src/providers/ipa/ipa_subdomains.c
2fc102
@@ -351,14 +351,28 @@ const char *get_flat_name_from_subdomain_name(struct be_ctx *be_ctx,
2fc102
 }
2fc102
 
2fc102
 static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx,
2fc102
+                                        char *domain_name,
2fc102
                                         size_t count,
2fc102
                                         struct sysdb_attrs **reply,
2fc102
                                         struct range_info ***_range_list)
2fc102
 {
2fc102
     struct range_info **range_list = NULL;
2fc102
+    struct range_info *r;
2fc102
     const char *value;
2fc102
     size_t c;
2fc102
+    size_t d;
2fc102
     int ret;
2fc102
+    enum idmap_error_code err;
2fc102
+    char *name1;
2fc102
+    char *name2;
2fc102
+    char *sid1;
2fc102
+    char *sid2;
2fc102
+    uint32_t rid1;
2fc102
+    uint32_t rid2;
2fc102
+    struct sss_idmap_range range1;
2fc102
+    struct sss_idmap_range range2;
2fc102
+    bool mapping1;
2fc102
+    bool mapping2;
2fc102
 
2fc102
     range_list = talloc_array(mem_ctx, struct range_info *, count + 1);
2fc102
     if (range_list == NULL) {
2fc102
@@ -367,8 +381,8 @@ static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx,
2fc102
     }
2fc102
 
2fc102
     for (c = 0; c < count; c++) {
2fc102
-        range_list[c] = talloc_zero(range_list, struct range_info);
2fc102
-        if (range_list[c] == NULL) {
2fc102
+        r = talloc_zero(range_list, struct range_info);
2fc102
+        if (r == NULL) {
2fc102
             DEBUG(SSSDBG_OP_FAILURE, ("talloc_zero failed.\n"));
2fc102
             ret = ENOMEM;
2fc102
             goto done;
2fc102
@@ -379,8 +393,8 @@ static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx,
2fc102
             DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
2fc102
             goto done;
2fc102
         }
2fc102
-        range_list[c]->name = talloc_strdup(range_list[c], value);
2fc102
-        if (range_list[c]->name == NULL) {
2fc102
+        r->name = talloc_strdup(r, value);
2fc102
+        if (r->name == NULL) {
2fc102
             DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
2fc102
             ret = ENOMEM;
2fc102
             goto done;
2fc102
@@ -388,9 +402,8 @@ static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx,
2fc102
 
2fc102
         ret = sysdb_attrs_get_string(reply[c], IPA_TRUSTED_DOMAIN_SID, &value);
2fc102
         if (ret == EOK) {
2fc102
-            range_list[c]->trusted_dom_sid = talloc_strdup(range_list[c],
2fc102
-                                                           value);
2fc102
-            if (range_list[c]->trusted_dom_sid == NULL) {
2fc102
+            r->trusted_dom_sid = talloc_strdup(r, value);
2fc102
+            if (r->trusted_dom_sid == NULL) {
2fc102
                 DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
2fc102
                 ret = ENOMEM;
2fc102
                 goto done;
2fc102
@@ -401,28 +414,28 @@ static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx,
2fc102
         }
2fc102
 
2fc102
         ret = sysdb_attrs_get_uint32_t(reply[c], IPA_BASE_ID,
2fc102
-                                       &range_list[c]->base_id);
2fc102
+                                       &r->base_id);
2fc102
         if (ret != EOK && ret != ENOENT) {
2fc102
             DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
2fc102
             goto done;
2fc102
         }
2fc102
 
2fc102
         ret = sysdb_attrs_get_uint32_t(reply[c], IPA_ID_RANGE_SIZE,
2fc102
-                                       &range_list[c]->id_range_size);
2fc102
+                                       &r->id_range_size);
2fc102
         if (ret != EOK && ret != ENOENT) {
2fc102
             DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
2fc102
             goto done;
2fc102
         }
2fc102
 
2fc102
         ret = sysdb_attrs_get_uint32_t(reply[c], IPA_BASE_RID,
2fc102
-                                       &range_list[c]->base_rid);
2fc102
+                                       &r->base_rid);
2fc102
         if (ret != EOK && ret != ENOENT) {
2fc102
             DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
2fc102
             goto done;
2fc102
         }
2fc102
 
2fc102
         ret = sysdb_attrs_get_uint32_t(reply[c], IPA_SECONDARY_BASE_RID,
2fc102
-                                       &range_list[c]->secondary_base_rid);
2fc102
+                                       &r->secondary_base_rid);
2fc102
         if (ret != EOK && ret != ENOENT) {
2fc102
             DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
2fc102
             goto done;
2fc102
@@ -430,8 +443,8 @@ static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx,
2fc102
 
2fc102
         ret = sysdb_attrs_get_string(reply[c], IPA_RANGE_TYPE, &value);
2fc102
         if (ret == EOK) {
2fc102
-            range_list[c]->range_type = talloc_strdup(range_list[c], value);
2fc102
-            if (range_list[c]->range_type == NULL) {
2fc102
+            r->range_type = talloc_strdup(r, value);
2fc102
+            if (r->range_type == NULL) {
2fc102
                 DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
2fc102
                 ret = ENOMEM;
2fc102
                 goto done;
2fc102
@@ -439,23 +452,52 @@ static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx,
2fc102
         } else if (ret == ENOENT) {
2fc102
             /* Older IPA servers might not have the range_type attribute, but
2fc102
              * only support local ranges and trusts with algorithmic mapping. */
2fc102
-            if (range_list[c]->trusted_dom_sid == NULL) {
2fc102
-                range_list[c]->range_type = talloc_strdup(range_list[c],
2fc102
-                                                          IPA_RANGE_LOCAL);
2fc102
+            if (r->trusted_dom_sid == NULL) {
2fc102
+                r->range_type = talloc_strdup(r, IPA_RANGE_LOCAL);
2fc102
             } else {
2fc102
-                range_list[c]->range_type = talloc_strdup(range_list[c],
2fc102
-                                                          IPA_RANGE_AD_TRUST);
2fc102
+                r->range_type = talloc_strdup(r, IPA_RANGE_AD_TRUST);
2fc102
             }
2fc102
         } else {
2fc102
             DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
2fc102
             goto done;
2fc102
         }
2fc102
-        if (range_list[c]->range_type == NULL) {
2fc102
+        if (r->range_type == NULL) {
2fc102
             DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
2fc102
             ret = ENOMEM;
2fc102
             goto done;
2fc102
         }
2fc102
+
2fc102
+        ret = get_idmap_data_from_range(r, domain_name, &name1, &sid1, &rid1,
2fc102
+                                        &range1, &mapping1);
2fc102
+        if (ret != EOK) {
2fc102
+            DEBUG(SSSDBG_OP_FAILURE, ("get_idmap_data_from_range failed.\n"));
2fc102
+            goto done;
2fc102
+        }
2fc102
+        for (d = 0; d < c; d++) {
2fc102
+            ret = get_idmap_data_from_range(range_list[d], domain_name, &name2,
2fc102
+                                            &sid2, &rid2, &range2, &mapping2);
2fc102
+            if (ret != EOK) {
2fc102
+                DEBUG(SSSDBG_OP_FAILURE,
2fc102
+                      ("get_idmap_data_from_range failed.\n"));
2fc102
+                goto done;
2fc102
+            }
2fc102
+
2fc102
+            err = sss_idmap_check_collision_ex(name1, sid1, &range1, rid1,
2fc102
+                                               r->name, mapping1,
2fc102
+                                               name2, sid2, &range2, rid2,
2fc102
+                                               range_list[d]->name, mapping2);
2fc102
+            if (err != IDMAP_SUCCESS) {
2fc102
+                DEBUG(SSSDBG_CRIT_FAILURE,
2fc102
+                      ("Collision of ranges [%s] and [%s] detected.\n",
2fc102
+                      r->name, range_list[d]->name));
2fc102
+                ret = EINVAL;
2fc102
+                goto done;
2fc102
+            }
2fc102
+        }
2fc102
+
2fc102
+        range_list[c] = r;
2fc102
     }
2fc102
+
2fc102
     range_list[c] = NULL;
2fc102
 
2fc102
     *_range_list = range_list;
2fc102
@@ -1013,7 +1055,8 @@ static void ipa_subdomains_handler_ranges_done(struct tevent_req *req)
2fc102
         goto done;
2fc102
     }
2fc102
 
2fc102
-    ret = ipa_ranges_parse_results(ctx, reply_count, reply, &range_list);
2fc102
+    ret = ipa_ranges_parse_results(ctx, domain->name,
2fc102
+                                   reply_count, reply, &range_list);
2fc102
     if (ret != EOK) {
2fc102
         DEBUG(SSSDBG_OP_FAILURE,
2fc102
               ("ipa_ranges_parse_results request failed.\n"));
2fc102
-- 
2fc102
1.8.5.3
2fc102