>From 54200eb2d8266dc2e931f45c86e7b2e60f458da4 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Mon, 14 Jan 2013 14:55:05 -0500
Subject: [PATCH 05/12] Add sysdb_subdomain_store() function

Replaces sysdb_add_subdomain_attributes and is a public sysdb interface.
---
 src/db/sysdb.h            |   5 ++
 src/db/sysdb_subdomains.c | 139 +++++++++++++++++++++++++++++++++-------------
 2 files changed, 105 insertions(+), 39 deletions(-)

diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 9134b777812df9025b0cc893531cb05fec6790a0..ab960cc449200b2796c87b17dd5c01cf8df468af 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -369,10 +369,15 @@ errno_t sysdb_get_subdomains(TALLOC_CTX *mem_ctx,
 
 errno_t sysdb_domain_create(struct sysdb_ctx *sysdb, const char *domain_name);
 
+errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb,
+                              const char *name, const char *realm,
+                              const char *flat_name, const char *domain_id);
+
 errno_t sysdb_update_subdomains(struct sss_domain_info *domain,
                                 int num_subdoms,
                                 struct sysdb_subdom *subdoms);
 
+
 errno_t sysdb_master_domain_update(struct sss_domain_info *domain);
 
 errno_t sysdb_master_domain_add_info(struct sss_domain_info *domain,
diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
index 2b1de12659c2c7f781a91e165b91d2141dd83466..d6692b6decf8a418886bc69508a80e1b0b8fa761 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -302,11 +302,24 @@ done:
     return ret;
 }
 
-static errno_t sysdb_add_subdomain_attributes(struct sysdb_ctx *sysdb,
-                                             struct sysdb_subdom *domain_info)
+errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb,
+                              const char *name, const char *realm,
+                              const char *flat_name, const char *domain_id)
 {
     TALLOC_CTX *tmp_ctx;
     struct ldb_message *msg;
+    struct ldb_dn *dn;
+    struct ldb_result *res;
+    const char *attrs[] = {"cn",
+                           SYSDB_SUBDOMAIN_REALM,
+                           SYSDB_SUBDOMAIN_FLAT,
+                           SYSDB_SUBDOMAIN_ID,
+                           NULL};
+    const char *tmp_str;
+    bool store = false;
+    int realm_flags = 0;
+    int flat_flags = 0;
+    int id_flags = 0;
     int ret;
 
     tmp_ctx = talloc_new(NULL);
@@ -314,72 +327,117 @@ static errno_t sysdb_add_subdomain_attributes(struct sysdb_ctx *sysdb,
         return ENOMEM;
     }
 
+    dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_DOM_BASE, name);
+    if (dn == NULL) {
+        ret = EIO;
+        goto done;
+    }
+    ret = ldb_search(sysdb->ldb, tmp_ctx, &res,
+                     dn, LDB_SCOPE_BASE, attrs, NULL);
+    if (ret != LDB_SUCCESS) {
+        ret = EIO;
+        goto done;
+    }
+
+    if (res->count == 0) {
+        ret = sysdb_domain_create(sysdb, name);
+        if (ret) {
+            goto done;
+        }
+        store = true;
+        if (realm) realm_flags = LDB_FLAG_MOD_ADD;
+        if (flat_name) flat_flags = LDB_FLAG_MOD_ADD;
+        if (domain_id) id_flags = LDB_FLAG_MOD_ADD;
+    } else if (res->count != 1) {
+        ret = EINVAL;
+        goto done;
+    } else { /* 1 found */
+        if (realm) {
+            tmp_str = ldb_msg_find_attr_as_string(res->msgs[0],
+                                                  SYSDB_SUBDOMAIN_REALM, NULL);
+            if (!tmp_str || strcasecmp(tmp_str, realm) != 0) {
+                realm_flags = LDB_FLAG_MOD_REPLACE;
+            }
+        }
+        if (flat_name) {
+            tmp_str = ldb_msg_find_attr_as_string(res->msgs[0],
+                                                  SYSDB_SUBDOMAIN_FLAT, NULL);
+            if (!tmp_str || strcasecmp(tmp_str, flat_name) != 0) {
+                flat_flags = LDB_FLAG_MOD_REPLACE;
+            }
+        }
+        if (domain_id) {
+            tmp_str = ldb_msg_find_attr_as_string(res->msgs[0],
+                                                  SYSDB_SUBDOMAIN_ID, NULL);
+            if (!tmp_str || strcasecmp(tmp_str, domain_id) != 0) {
+                id_flags = LDB_FLAG_MOD_REPLACE;
+            }
+        }
+    }
+
+    if (!store && realm_flags == 0 && flat_flags == 0 && id_flags == 0) {
+        ret = EOK;
+        goto done;
+    }
+
     msg = ldb_msg_new(tmp_ctx);
     if (msg == NULL) {
         ret = ENOMEM;
         goto done;
     }
+    msg->dn = dn;
 
-    msg->dn = ldb_dn_new_fmt(msg, sysdb->ldb, SYSDB_DOM_BASE,
-                             domain_info->name);
-    if (msg->dn == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
+   if (store) {
+        ret = ldb_msg_add_empty(msg, SYSDB_OBJECTCLASS, LDB_FLAG_MOD_ADD, NULL);
+        if (ret != LDB_SUCCESS) {
+            ret = sysdb_error_to_errno(ret);
+            goto done;
+        }
 
-    ret = ldb_msg_add_empty(msg, SYSDB_OBJECTCLASS, LDB_FLAG_MOD_ADD, NULL);
-    if (ret != LDB_SUCCESS) {
-        ret = sysdb_error_to_errno(ret);
-        goto done;
-    }
 
-    ret = ldb_msg_add_string(msg, SYSDB_OBJECTCLASS, SYSDB_SUBDOMAIN_CLASS);
-    if (ret != LDB_SUCCESS) {
-        ret = sysdb_error_to_errno(ret);
-        goto done;
+        ret = ldb_msg_add_string(msg, SYSDB_OBJECTCLASS, SYSDB_SUBDOMAIN_CLASS);
+        if (ret != LDB_SUCCESS) {
+            ret = sysdb_error_to_errno(ret);
+            goto done;
+        }
     }
 
-    if (domain_info->realm != NULL) {
-        ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_REALM, LDB_FLAG_MOD_ADD,
-                                NULL);
+    if (realm_flags) {
+        ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_REALM, realm_flags, NULL);
         if (ret != LDB_SUCCESS) {
             ret = sysdb_error_to_errno(ret);
             goto done;
         }
 
-        ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_REALM,
-                                 domain_info->realm);
+        ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_REALM, realm);
         if (ret != LDB_SUCCESS) {
             ret = sysdb_error_to_errno(ret);
             goto done;
         }
     }
 
-    if (domain_info->flat_name != NULL) {
-        ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_FLAT, LDB_FLAG_MOD_ADD,
-                                NULL);
+    if (flat_flags) {
+        ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_FLAT, flat_flags, NULL);
         if (ret != LDB_SUCCESS) {
             ret = sysdb_error_to_errno(ret);
             goto done;
         }
 
-        ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_FLAT,
-                                 domain_info->flat_name);
+        ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_FLAT, flat_name);
         if (ret != LDB_SUCCESS) {
             ret = sysdb_error_to_errno(ret);
             goto done;
         }
     }
 
-    if (domain_info->id != NULL) {
-        ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_ID, LDB_FLAG_MOD_ADD,
-                                NULL);
+    if (id_flags) {
+        ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_ID, id_flags, NULL);
         if (ret != LDB_SUCCESS) {
             ret = sysdb_error_to_errno(ret);
             goto done;
         }
 
-        ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_ID, domain_info->id);
+        ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_ID, domain_id);
         if (ret != LDB_SUCCESS) {
             ret = sysdb_error_to_errno(ret);
             goto done;
@@ -389,8 +447,7 @@ static errno_t sysdb_add_subdomain_attributes(struct sysdb_ctx *sysdb,
     ret = ldb_modify(sysdb->ldb, msg);
     if (ret != LDB_SUCCESS) {
         DEBUG(SSSDBG_FATAL_FAILURE, ("Failed to add subdomain attributes to "
-                                     "[%s]: [%d][%s]!\n",
-                                     domain_info->name, ret,
+                                     "[%s]: [%d][%s]!\n", name, ret,
                                      ldb_errstring(sysdb->ldb)));
         ret = sysdb_error_to_errno(ret);
         goto done;
@@ -462,18 +519,22 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain,
         }
 
         if (d == cur_subdomains_count) {
+            struct sss_domain_info *ns;
+
             DEBUG(SSSDBG_TRACE_FUNC, ("Adding sub-domain [%s].\n",
                                       subdoms[c].name));
-            ret = sysdb_domain_create(domain->sysdb, subdoms[c].name);
-            if (ret != EOK) {
-                DEBUG(SSSDBG_OP_FAILURE, ("sysdb_domain_create failed.\n"));
+
+            ns = new_subdomain(tmp_ctx, domain,
+                               subdoms[c].name, subdoms[c].realm,
+                               subdoms[c].flat_name, subdoms[c].id);
+            if (!ns) {
+                DEBUG(SSSDBG_OP_FAILURE, ("new_subdomain failed.\n"));
                 goto done;
             }
 
-            ret = sysdb_add_subdomain_attributes(domain->sysdb, &subdoms[c]);
+            ret = sysdb_subdomain_create(ns);
             if (ret != EOK) {
-                DEBUG(SSSDBG_OP_FAILURE,
-                      ("sysdb_add_subdomain_attributes failed.\n"));
+                DEBUG(SSSDBG_OP_FAILURE, ("sysdb_subdomain_create failed.\n"));
                 goto done;
             }
         }
-- 
1.8.0.1

