>From 90889c1cd78550c106af2f473850e3581625ffae Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Mon, 14 Jan 2013 11:56:03 -0500
Subject: [PATCH 02/12] Avoid sysdb_subdom in sysdb_get_subdomains()

---
 src/db/sysdb.h                               |  6 +-
 src/db/sysdb_subdomains.c                    | 92 +++++++++++-----------------
 src/providers/ipa/ipa_subdomains.c           |  4 +-
 src/responder/common/responder_get_domains.c | 37 +++--------
 src/tests/sysdb-tests.c                      | 22 +++----
 src/util/domain_info_utils.c                 |  3 +
 6 files changed, 61 insertions(+), 103 deletions(-)

diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index d4af5fa6bb46dfb2656924f319369d495d52a004..a5b037c6efddc975511411dcb4ab47b33b031962 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -363,13 +363,13 @@ int sysdb_transaction_cancel(struct sysdb_ctx *sysdb);
 
 /* functions related to subdomains */
 errno_t sysdb_get_subdomains(TALLOC_CTX *mem_ctx,
-                             struct sysdb_ctx *sysdb,
+                             struct sss_domain_info *domain,
                              size_t *subdomain_count,
-                             struct sysdb_subdom ***subdomain_list);
+                             struct sss_domain_info ***subdomain_list);
 
 errno_t sysdb_domain_create(struct sysdb_ctx *sysdb, const char *domain_name);
 
-errno_t sysdb_update_subdomains(struct sysdb_ctx *sysdb,
+errno_t sysdb_update_subdomains(struct sss_domain_info *domain,
                                 int num_subdoms,
                                 struct sysdb_subdom *subdoms);
 
diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
index 9b295d7e5d88c11c46a39eb57b51465aa8fe3dc5..eea27aadfad892dd49a8c81a349f1304029d338c 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -23,9 +23,10 @@
 #include "util/util.h"
 #include "db/sysdb_private.h"
 
-errno_t sysdb_get_subdomains(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
+errno_t sysdb_get_subdomains(TALLOC_CTX *mem_ctx,
+                             struct sss_domain_info *domain,
                              size_t *subdomain_count,
-                             struct sysdb_subdom ***subdomain_list)
+                             struct sss_domain_info ***subdomain_list)
 {
     int i;
     errno_t ret;
@@ -36,9 +37,8 @@ errno_t sysdb_get_subdomains(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
                            SYSDB_SUBDOMAIN_FLAT,
                            SYSDB_SUBDOMAIN_ID,
                            NULL};
-    struct sysdb_subdom **list;
+    struct sss_domain_info **list;
     struct ldb_dn *basedn;
-    const char *tmp_str;
 
     tmp_ctx = talloc_new(NULL);
     if (tmp_ctx == NULL) {
@@ -46,12 +46,12 @@ errno_t sysdb_get_subdomains(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
         goto done;
     }
 
-    basedn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_BASE);
+    basedn = ldb_dn_new(tmp_ctx, domain->sysdb->ldb, SYSDB_BASE);
     if (basedn == NULL) {
         ret = EIO;
         goto done;
     }
-    ret = ldb_search(sysdb->ldb, tmp_ctx, &res,
+    ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res,
                      basedn, LDB_SCOPE_ONELEVEL,
                      attrs, "objectclass=%s", SYSDB_SUBDOMAIN_CLASS);
     if (ret != LDB_SUCCESS) {
@@ -59,20 +59,21 @@ errno_t sysdb_get_subdomains(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
         goto done;
     }
 
-    list = talloc_zero_array(tmp_ctx, struct sysdb_subdom *, res->count + 1);
+    list = talloc_zero_array(tmp_ctx, struct sss_domain_info *,
+                             res->count + 1);
     if (list == NULL) {
         ret = ENOMEM;
         goto done;
     }
 
     for (i = 0; i < res->count; i++) {
-        list[i] = talloc_zero(list, struct sysdb_subdom);
-        if (list[i] == NULL) {
-            ret = ENOMEM;
-            goto done;
-        }
-        tmp_str = ldb_msg_find_attr_as_string(res->msgs[i], "cn", NULL);
-        if (tmp_str == NULL) {
+        const char *name;
+        const char *realm;
+        const char *flat;
+        const char *id;
+
+        name = ldb_msg_find_attr_as_string(res->msgs[i], "cn", NULL);
+        if (name == NULL) {
             DEBUG(SSSDBG_MINOR_FAILURE,
                   ("The object [%s] doesn't have a name\n",
                    ldb_dn_get_linearized(res->msgs[i]->dn)));
@@ -80,41 +81,20 @@ errno_t sysdb_get_subdomains(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
             goto done;
         }
 
-        list[i]->name = talloc_strdup(list, tmp_str);
-        if (list[i]->name == NULL) {
+        realm = ldb_msg_find_attr_as_string(res->msgs[i],
+                                            SYSDB_SUBDOMAIN_REALM, NULL);
+
+        flat = ldb_msg_find_attr_as_string(res->msgs[i],
+                                           SYSDB_SUBDOMAIN_FLAT, NULL);
+
+        id = ldb_msg_find_attr_as_string(res->msgs[i],
+                                         SYSDB_SUBDOMAIN_ID, NULL);
+
+        list[i] = new_subdomain(list, domain, name, realm, flat, id);
+        if (list[i] == NULL) {
             ret = ENOMEM;
             goto done;
         }
-
-        tmp_str = ldb_msg_find_attr_as_string(res->msgs[i],
-                                              SYSDB_SUBDOMAIN_REALM, NULL);
-        if (tmp_str != NULL) {
-            list[i]->realm = talloc_strdup(list, tmp_str);
-            if (list[i]->realm == NULL) {
-                ret = ENOMEM;
-                goto done;
-            }
-        }
-
-        tmp_str = ldb_msg_find_attr_as_string(res->msgs[i],
-                                              SYSDB_SUBDOMAIN_FLAT, NULL);
-        if (tmp_str != NULL) {
-            list[i]->flat_name = talloc_strdup(list, tmp_str);
-            if (list[i]->flat_name == NULL) {
-                ret = ENOMEM;
-                goto done;
-            }
-        }
-
-        tmp_str = ldb_msg_find_attr_as_string(res->msgs[i],
-                                              SYSDB_SUBDOMAIN_ID, NULL);
-        if (tmp_str != NULL) {
-            list[i]->id = talloc_strdup(list, tmp_str);
-            if (list[i]->id == NULL) {
-                ret = ENOMEM;
-                goto done;
-            }
-        }
     }
 
     list[res->count] = NULL;
@@ -432,7 +412,7 @@ done:
     return ret;
 }
 
-errno_t sysdb_update_subdomains(struct sysdb_ctx *sysdb,
+errno_t sysdb_update_subdomains(struct sss_domain_info *domain,
                                 int num_subdoms,
                                 struct sysdb_subdom *subdoms)
 {
@@ -442,7 +422,7 @@ errno_t sysdb_update_subdomains(struct sysdb_ctx *sysdb,
     size_t d;
     TALLOC_CTX *tmp_ctx = NULL;
     size_t cur_subdomains_count;
-    struct sysdb_subdom **cur_subdomains;
+    struct sss_domain_info **cur_subdomains;
     struct ldb_dn *dn;
     bool in_transaction = false;
     bool *keep_subdomain;
@@ -454,7 +434,7 @@ errno_t sysdb_update_subdomains(struct sysdb_ctx *sysdb,
     }
 
     /* Retrieve all subdomains that are currently in sysdb */
-    ret = sysdb_get_subdomains(tmp_ctx, sysdb, &cur_subdomains_count,
+    ret = sysdb_get_subdomains(tmp_ctx, domain, &cur_subdomains_count,
                                &cur_subdomains);
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE, ("sysdb_get_subdomains failed.\n"));
@@ -468,7 +448,7 @@ errno_t sysdb_update_subdomains(struct sysdb_ctx *sysdb,
         goto done;
     }
 
-    ret = sysdb_transaction_start(sysdb);
+    ret = sysdb_transaction_start(domain->sysdb);
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE, ("sysdb_transaction_start failed.\n"));
         goto done;
@@ -492,13 +472,13 @@ errno_t sysdb_update_subdomains(struct sysdb_ctx *sysdb,
         if (d == cur_subdomains_count) {
             DEBUG(SSSDBG_TRACE_FUNC, ("Adding sub-domain [%s].\n",
                                       subdoms[c].name));
-            ret = sysdb_domain_create(sysdb, subdoms[c].name);
+            ret = sysdb_domain_create(domain->sysdb, subdoms[c].name);
             if (ret != EOK) {
                 DEBUG(SSSDBG_OP_FAILURE, ("sysdb_domain_create failed.\n"));
                 goto done;
             }
 
-            ret = sysdb_add_subdomain_attributes(sysdb, &subdoms[c]);
+            ret = sysdb_add_subdomain_attributes(domain->sysdb, &subdoms[c]);
             if (ret != EOK) {
                 DEBUG(SSSDBG_OP_FAILURE,
                       ("sysdb_add_subdomain_attributes failed.\n"));
@@ -515,14 +495,14 @@ errno_t sysdb_update_subdomains(struct sysdb_ctx *sysdb,
         if (!keep_subdomain[d]) {
             DEBUG(SSSDBG_TRACE_FUNC, ("Removing sub-domain [%s].\n",
                                       cur_subdomains[d]->name));
-            dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_DOM_BASE,
+            dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_DOM_BASE,
                                 cur_subdomains[d]->name);
             if (dn == NULL) {
                 ret = ENOMEM;
                 goto done;
             }
 
-            ret = sysdb_delete_recursive(sysdb, dn, true);
+            ret = sysdb_delete_recursive(domain->sysdb, dn, true);
             if (ret != EOK) {
                 DEBUG(SSSDBG_OP_FAILURE, ("sysdb_delete_recursive failed.\n"));
                 goto done;
@@ -530,7 +510,7 @@ errno_t sysdb_update_subdomains(struct sysdb_ctx *sysdb,
         }
     }
 
-    ret = sysdb_transaction_commit(sysdb);
+    ret = sysdb_transaction_commit(domain->sysdb);
     if (ret != EOK) {
         DEBUG(SSSDBG_MINOR_FAILURE, ("Could not commit transaction\n"));
         goto done;
@@ -539,7 +519,7 @@ errno_t sysdb_update_subdomains(struct sysdb_ctx *sysdb,
 
 done:
     if (in_transaction) {
-        sret = sysdb_transaction_cancel(sysdb);
+        sret = sysdb_transaction_cancel(domain->sysdb);
         if (sret != EOK) {
             DEBUG(SSSDBG_CRIT_FAILURE, ("Could not cancel transaction\n"));
         }
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
index c9ab3aadc17e4e92ffb11bce7c2fa8c0b8ed4756..34a3f1be7f9936c2b983855d5abfe2c1aad2a959 100644
--- a/src/providers/ipa/ipa_subdomains.c
+++ b/src/providers/ipa/ipa_subdomains.c
@@ -674,13 +674,11 @@ static void ipa_subdomains_handler_done(struct tevent_req *req)
     size_t reply_count;
     struct sysdb_attrs **reply = NULL;
     struct ipa_subdomains_req_ctx *ctx;
-    struct sysdb_ctx *sysdb;
     struct sss_domain_info *domain;
     bool refresh_has_changes = false;
 
     ctx = tevent_req_callback_data(req, struct ipa_subdomains_req_ctx);
     domain = ctx->sd_ctx->be_ctx->domain;
-    sysdb = domain->sysdb;
 
     ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply);
     talloc_zfree(req);
@@ -717,7 +715,7 @@ static void ipa_subdomains_handler_done(struct tevent_req *req)
     }
 
     if (refresh_has_changes) {
-        ret = sysdb_update_subdomains(sysdb, ctx->sd_ctx->num_subdoms,
+        ret = sysdb_update_subdomains(domain, ctx->sd_ctx->num_subdoms,
                                       ctx->sd_ctx->subdoms);
         if (ret != EOK) {
             DEBUG(SSSDBG_OP_FAILURE, ("sysdb_update_subdomains failed.\n"));
diff --git a/src/responder/common/responder_get_domains.c b/src/responder/common/responder_get_domains.c
index e52d61c28cb3d49dd704d90f124e5bf4ed4fab7e..1ad9fbfaec2033fbe3e8782308d853e8fe6c2d2b 100644
--- a/src/responder/common/responder_get_domains.c
+++ b/src/responder/common/responder_get_domains.c
@@ -281,15 +281,14 @@ process_subdomains(struct sss_domain_info *domain)
 {
     int ret;
     size_t c;
-    struct sss_domain_info **new_sd_list = NULL;
     size_t subdomain_count;
-    struct sysdb_subdom **subdomains;
+    struct sss_domain_info **subdomains;
     struct sysdb_subdom *master_info;
 
     /* Retrieve all subdomains of this domain from sysdb
      * and create their struct sss_domain_info representations
      */
-    ret = sysdb_get_subdomains(domain, domain->sysdb,
+    ret = sysdb_get_subdomains(domain, domain,
                                &subdomain_count, &subdomains);
     if (ret != EOK) {
         DEBUG(SSSDBG_FUNC_DATA, ("sysdb_get_subdomains failed.\n"));
@@ -302,32 +301,11 @@ process_subdomains(struct sss_domain_info *domain)
         goto done;
     }
 
-    new_sd_list = talloc_zero_array(domain, struct sss_domain_info *,
-                                    subdomain_count);
-    if (new_sd_list == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
-    for (c = 0; c < subdomain_count; c++) {
-        DEBUG(SSSDBG_FUNC_DATA, ("Adding subdomain [%s] to the domain [%s]!\n",
-                                 subdomains[c]->name, domain->name));
-        new_sd_list[c] =  new_subdomain(new_sd_list, domain,
-                                        subdomains[c]->name,
-                                        subdomains[c]->realm,
-                                        subdomains[c]->flat_name,
-                                        subdomains[c]->id);
-        if (new_sd_list[c] == NULL) {
-            ret = ENOMEM;
-            goto done;
-        }
-    }
-
     /* Link all subdomains into single-linked list
      * (the list is used when processing all domains)
      */
-    while (c > 1) {
-        new_sd_list[c-1]->next  = new_sd_list[c];
-        --c;
+    for (c = 0; c < subdomain_count - 1; c++) {
+        subdomains[c]->next = subdomains[c + 1];
     }
 
     if (domain->flat_name == NULL || domain->domain_id == NULL) {
@@ -364,10 +342,9 @@ process_subdomains(struct sss_domain_info *domain)
         goto done;
     }
 
-    domain->subdomain_count = subdomain_count;
     talloc_zfree(domain->subdomains);
-    domain->subdomains = new_sd_list;
-    new_sd_list = NULL;
+    domain->subdomain_count = subdomain_count;
+    domain->subdomains = subdomains;
 
     ret = EOK;
 
@@ -375,7 +352,7 @@ done:
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE, ("Failed to update sub-domains "
                                   "of domain [%s].\n", domain->name));
-        talloc_free(new_sd_list);
+        talloc_free(subdomains);
     }
 
     return ret;
diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c
index 588c515b311677f1b380b6da7ed091b397bbc454..609271dc364222f4837cedf791b5d4393ad3198c 100644
--- a/src/tests/sysdb-tests.c
+++ b/src/tests/sysdb-tests.c
@@ -4471,7 +4471,7 @@ START_TEST(test_sysdb_subdomain_create)
 {
     struct sysdb_test_ctx *test_ctx;
     errno_t ret;
-    struct sysdb_subdom **cur_subdomains = NULL;
+    struct sss_domain_info **cur_subdomains = NULL;
     size_t cur_subdomains_count;
     struct sysdb_subdom *new_subdom1 = &dom1;
     struct sysdb_subdom *new_subdom2 = &dom2;
@@ -4481,18 +4481,18 @@ START_TEST(test_sysdb_subdomain_create)
     ret = setup_sysdb_tests(&test_ctx);
     fail_if(ret != EOK, "Could not set up the test");
 
-    ret = sysdb_get_subdomains(test_ctx, test_ctx->sysdb,
+    ret = sysdb_get_subdomains(test_ctx, test_ctx->domain,
                                &cur_subdomains_count, &cur_subdomains);
     fail_unless(ret == EOK, "sysdb_get_subdomains failed with [%d][%s]",
                             ret, strerror(ret));
     fail_unless(cur_subdomains != NULL, "No sub-domains returned.");
     fail_unless(cur_subdomains[0] == NULL, "No empty sub-domain list returned.");
 
-    ret = sysdb_update_subdomains(test_ctx->sysdb, num_subdom1, new_subdom1);
+    ret = sysdb_update_subdomains(test_ctx->domain, num_subdom1, new_subdom1);
     fail_unless(ret == EOK, "sysdb_update_subdomains failed with [%d][%s]",
                             ret, strerror(ret));
 
-    ret = sysdb_get_subdomains(test_ctx, test_ctx->sysdb,
+    ret = sysdb_get_subdomains(test_ctx, test_ctx->domain,
                                &cur_subdomains_count, &cur_subdomains);
     fail_unless(ret == EOK, "sysdb_get_subdomains failed with [%d][%s]",
                             ret, strerror(ret));
@@ -4502,11 +4502,11 @@ START_TEST(test_sysdb_subdomain_create)
                 "Unexpected sub-domain found, expected [%s], got [%s]",
                 new_subdom1[0].name, cur_subdomains[0]->name);
 
-    ret = sysdb_update_subdomains(test_ctx->sysdb, num_subdom2, new_subdom2);
+    ret = sysdb_update_subdomains(test_ctx->domain, num_subdom2, new_subdom2);
     fail_unless(ret == EOK, "sysdb_update_subdomains failed with [%d][%s]",
                             ret, strerror(ret));
 
-    ret = sysdb_get_subdomains(test_ctx, test_ctx->sysdb,
+    ret = sysdb_get_subdomains(test_ctx, test_ctx->domain,
                                &cur_subdomains_count, &cur_subdomains);
     fail_unless(ret == EOK, "sysdb_get_subdomains failed with [%d][%s]",
                             ret, strerror(ret));
@@ -4516,11 +4516,11 @@ START_TEST(test_sysdb_subdomain_create)
                 "Unexpected sub-domain found, expected [%s], got [%s]",
                 new_subdom2[0].name, cur_subdomains[0]->name);
 
-    ret = sysdb_update_subdomains(test_ctx->sysdb, 0, NULL);
+    ret = sysdb_update_subdomains(test_ctx->domain, 0, NULL);
     fail_unless(ret == EOK, "sysdb_update_subdomains failed with [%d][%s]",
                             ret, strerror(ret));
 
-    ret = sysdb_get_subdomains(test_ctx, test_ctx->sysdb,
+    ret = sysdb_get_subdomains(test_ctx, test_ctx->domain,
                                &cur_subdomains_count, &cur_subdomains);
     fail_unless(ret == EOK, "sysdb_get_subdomains failed with [%d][%s]",
                             ret, strerror(ret));
@@ -4543,7 +4543,7 @@ START_TEST(test_sysdb_subdomain_store_user)
     ret = setup_sysdb_tests(&test_ctx);
     fail_if(ret != EOK, "Could not set up the test");
 
-    ret = sysdb_update_subdomains(test_ctx->sysdb, num_subdom, test_subdom);
+    ret = sysdb_update_subdomains(test_ctx->domain, num_subdom, test_subdom);
     fail_unless(ret == EOK, "sysdb_update_subdomains failed with [%d][%s]",
                             ret, strerror(ret));
 
@@ -4599,7 +4599,7 @@ START_TEST(test_sysdb_subdomain_user_ops)
     ret = setup_sysdb_tests(&test_ctx);
     fail_if(ret != EOK, "Could not set up the test");
 
-    ret = sysdb_update_subdomains(test_ctx->sysdb, num_subdom, test_subdom);
+    ret = sysdb_update_subdomains(test_ctx->domain, num_subdom, test_subdom);
     fail_unless(ret == EOK, "sysdb_update_subdomains failed with [%d][%s]",
                             ret, strerror(ret));
 
@@ -4651,7 +4651,7 @@ START_TEST(test_sysdb_subdomain_group_ops)
     ret = setup_sysdb_tests(&test_ctx);
     fail_if(ret != EOK, "Could not set up the test");
 
-    ret = sysdb_update_subdomains(test_ctx->sysdb, num_subdom, test_subdom);
+    ret = sysdb_update_subdomains(test_ctx->domain, num_subdom, test_subdom);
     fail_unless(ret == EOK, "sysdb_update_subdomains failed with [%d][%s]",
                             ret, strerror(ret));
 
diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c
index c45c83d64236f8af6c092f461ebc79fa2e454cb4..1ff7c0c6d0050bb1a9f5e5a0fd1263ffcfe1e913 100644
--- a/src/util/domain_info_utils.c
+++ b/src/util/domain_info_utils.c
@@ -31,6 +31,9 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx,
 {
     struct sss_domain_info *dom;
 
+    DEBUG(SSSDBG_TRACE_FUNC,
+          ("Creating [%s] as subdomain of [%s]!\n", name, parent->name));
+
     dom = talloc_zero(mem_ctx, struct sss_domain_info);
     if (dom == NULL) {
         DEBUG(SSSDBG_OP_FAILURE, ("talloc_zero failed.\n"));
-- 
1.8.0.1

