From 1f8c231eee77cf7822bee11d210e1b2a432a409c Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgallagh@redhat.com>
Date: Fri, 15 Oct 2010 15:09:58 -0400
Subject: [PATCH 4/5] Modify sysdb_[add|remove]_group_member to accept users and groups

Previously, it assumed that all members were users. This changes
the interface so that either a user or a group can be specified.

Also, it eliminates the need for a memory context to be passed,
since the internal memory should be self-contained.
---
 src/db/sysdb.h                           |   21 ++++--
 src/db/sysdb_ops.c                       |  109 +++++++++++++++++++++---------
 src/providers/ldap/sdap_async_accounts.c |    1 +
 src/tests/sysdb-tests.c                  |   15 +++--
 4 files changed, 102 insertions(+), 44 deletions(-)

diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index a1baa20d9f6e0024f59470b004a937c3a8b97d8f..2ca9527dc089c459b86404fde71b6d1beae95a3a 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -527,20 +527,27 @@ int sysdb_store_group(TALLOC_CTX *mem_ctx,
                       struct sysdb_attrs *attrs,
                       uint64_t cache_timeout);
 
-int sysdb_add_group_member(TALLOC_CTX *mem_ctx,
-                           struct sysdb_ctx *ctx,
+enum sysdb_member_type {
+    SYSDB_MEMBER_USER,
+    SYSDB_MEMBER_GROUP
+};
+
+int sysdb_add_group_member(struct sysdb_ctx *ctx,
                            struct sss_domain_info *domain,
                            const char *group,
-                           const char *user);
+                           const char *member,
+                           enum sysdb_member_type type);
 
-int sysdb_remove_group_member(TALLOC_CTX *mem_ctx,
-                              struct sysdb_ctx *ctx,
+int sysdb_remove_group_member(struct sysdb_ctx *ctx,
                               struct sss_domain_info *domain,
                               const char *group,
-                              const char *user);
+                              const char *member,
+                              enum sysdb_member_type type);
+
 errno_t sysdb_update_members(struct sysdb_ctx *sysdb,
                              struct sss_domain_info *domain,
-                             const char *user,
+                             const char *member,
+                             enum sysdb_member_type type,
                              const char **add_groups,
                              const char **del_groups);
 
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index 7ae22f7d142efc1a3d5d533854d920985169a059..7158da3770af84c19a5267db24d26fcee58a56da 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -1529,54 +1529,96 @@ done:
 /* =Add-User-to-Group(Native/Legacy)====================================== */
 
 
-int sysdb_add_group_member(TALLOC_CTX *mem_ctx,
-                           struct sysdb_ctx *ctx,
+int sysdb_add_group_member(struct sysdb_ctx *ctx,
                            struct sss_domain_info *domain,
                            const char *group,
-                           const char *user)
+                           const char *member,
+                           enum sysdb_member_type type)
 {
-    struct ldb_dn *group_dn, *user_dn;
+    struct ldb_dn *group_dn;
+    struct ldb_dn *member_dn;
     int ret;
+    TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+    if (!tmp_ctx) {
+        return ENOMEM;
+    }
 
-    group_dn = sysdb_group_dn(ctx, mem_ctx, domain->name, group);
+    group_dn = sysdb_group_dn(ctx, tmp_ctx, domain->name, group);
     if (!group_dn) {
-        return ENOMEM;
+        ret = ENOMEM;
+        goto done;
     }
 
-    user_dn = sysdb_user_dn(ctx, mem_ctx, domain->name, user);
-    if (!user_dn) {
-        return ENOMEM;
+    if (type == SYSDB_MEMBER_USER) {
+        member_dn = sysdb_user_dn(ctx, tmp_ctx, domain->name, member);
+        if (!member_dn) {
+            ret = ENOMEM;
+            goto done;
+        }
+    } else if (type == SYSDB_MEMBER_GROUP) {
+        member_dn = sysdb_group_dn(ctx, tmp_ctx, domain->name, member);
+        if (!member_dn) {
+            ret = ENOMEM;
+            goto done;
+        }
+    } else {
+        ret = EINVAL;
+        goto done;
     }
 
-    ret = sysdb_mod_group_member(mem_ctx, ctx,
-                                 user_dn, group_dn, SYSDB_MOD_ADD);
+    ret = sysdb_mod_group_member(tmp_ctx, ctx,
+                                 member_dn, group_dn,
+                                 SYSDB_MOD_ADD);
+
+done:
+    talloc_free(tmp_ctx);
     return ret;
 }
 
 /* =Remove-member-from-Group(Native/Legacy)=============================== */
 
 
-int sysdb_remove_group_member(TALLOC_CTX *mem_ctx,
-                              struct sysdb_ctx *ctx,
+int sysdb_remove_group_member(struct sysdb_ctx *ctx,
                               struct sss_domain_info *domain,
                               const char *group,
-                              const char *user)
+                              const char *member,
+                              enum sysdb_member_type type)
 {
-    struct ldb_dn *group_dn, *user_dn;
+    struct ldb_dn *group_dn;
+    struct ldb_dn *member_dn;
     int ret;
+    TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+    if (!tmp_ctx) {
+        return ENOMEM;
+    }
 
-    group_dn = sysdb_group_dn(ctx, mem_ctx, domain->name, group);
+    group_dn = sysdb_group_dn(ctx, tmp_ctx, domain->name, group);
     if (!group_dn) {
-        return ENOMEM;
+        ret = ENOMEM;
+        goto done;
     }
 
-    user_dn = sysdb_user_dn(ctx, mem_ctx, domain->name, user);
-    if (!user_dn) {
-        return ENOMEM;
+    if (type == SYSDB_MEMBER_USER) {
+        member_dn = sysdb_user_dn(ctx, tmp_ctx, domain->name, member);
+        if (!member_dn) {
+            ret = ENOMEM;
+            goto done;
+        }
+    } else if (type == SYSDB_MEMBER_GROUP) {
+        member_dn = sysdb_group_dn(ctx, tmp_ctx, domain->name, member);
+        if (!member_dn) {
+            ret = ENOMEM;
+            goto done;
+        }
+    } else {
+        ret = EINVAL;
+        goto done;
     }
-
-    ret = sysdb_mod_group_member(mem_ctx, ctx,
-                                 user_dn, group_dn, SYSDB_MOD_DEL);
+    ret = sysdb_mod_group_member(tmp_ctx, ctx,
+                                 member_dn, group_dn,
+                                 SYSDB_MOD_DEL);
+done:
+    talloc_free(tmp_ctx);
     return ret;
 }
 
@@ -2529,7 +2571,8 @@ done:
 
 errno_t sysdb_update_members(struct sysdb_ctx *sysdb,
                              struct sss_domain_info *domain,
-                             const char *user,
+                             const char *member,
+                             enum sysdb_member_type type,
                              const char **add_groups,
                              const char **del_groups)
 {
@@ -2550,11 +2593,12 @@ errno_t sysdb_update_members(struct sysdb_ctx *sysdb,
     if (add_groups) {
         /* Add the user to all add_groups */
         for (i = 0; add_groups[i]; i++) {
-            ret = sysdb_add_group_member(tmp_ctx, sysdb, domain,
-                                         add_groups[i], user);
+            ret = sysdb_add_group_member(sysdb, domain,
+                                         add_groups[i], member,
+                                         type);
             if (ret != EOK) {
-                DEBUG(1, ("Could not add user [%s] to group [%s]. "
-                          "Skipping.\n", user, add_groups[i]));
+                DEBUG(1, ("Could not add member [%s] to group [%s]. "
+                          "Skipping.\n", member, add_groups[i]));
                 /* Continue on, we should try to finish the rest */
             }
         }
@@ -2563,11 +2607,12 @@ errno_t sysdb_update_members(struct sysdb_ctx *sysdb,
     if (del_groups) {
         /* Remove the user from all del_groups */
         for (i = 0; del_groups[i]; i++) {
-            ret = sysdb_remove_group_member(tmp_ctx, sysdb, domain,
-                                            del_groups[i], user);
+            ret = sysdb_remove_group_member(sysdb, domain,
+                                            del_groups[i], member,
+                                            type);
             if (ret != EOK) {
-                DEBUG(1, ("Could not remove user [%s] from group [%s]. "
-                          "Skipping\n", user, del_groups[i]));
+                DEBUG(1, ("Could not remove member [%s] from group [%s]. "
+                          "Skipping\n", member, del_groups[i]));
                 /* Continue on, we should try to finish the rest */
             }
         }
diff --git a/src/providers/ldap/sdap_async_accounts.c b/src/providers/ldap/sdap_async_accounts.c
index 3ee8a4eacb57b63d341b5538bfac074bbf0c4b24..7b2b3e007b3259e31b959b2c27b6629fbc357db6 100644
--- a/src/providers/ldap/sdap_async_accounts.c
+++ b/src/providers/ldap/sdap_async_accounts.c
@@ -2023,6 +2023,7 @@ static void sdap_initgr_rfc2307_process(struct tevent_req *subreq)
     }
 
     ret = sysdb_update_members(state->sysdb, state->dom, state->name,
+                               SYSDB_MEMBER_USER,
                                (const char **)add_groups,
                                (const char **)del_groups);
     if (ret != EOK) {
diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c
index b874544c0bb491cc845d598c07b59b06d29c5584..dd76d97afeddfeee47313f8015f42071bfea3035 100644
--- a/src/tests/sysdb-tests.c
+++ b/src/tests/sysdb-tests.c
@@ -326,9 +326,10 @@ static int test_add_group_member(struct test_data *data)
         return ENOMEM;
     }
 
-    ret = sysdb_add_group_member(data, data->ctx->sysdb,
+    ret = sysdb_add_group_member(data->ctx->sysdb,
                                  data->ctx->domain,
-                                 data->groupname, username);
+                                 data->groupname, username,
+                                 SYSDB_MEMBER_USER);
     return ret;
 }
 
@@ -342,9 +343,10 @@ static int test_remove_group_member(struct test_data *data)
         return ENOMEM;
     }
 
-    ret = sysdb_remove_group_member(data, data->ctx->sysdb,
+    ret = sysdb_remove_group_member(data->ctx->sysdb,
                                     data->ctx->domain,
-                                    data->groupname, username);
+                                    data->groupname, username,
+                                    SYSDB_MEMBER_USER);
     return ret;
 }
 
@@ -2217,6 +2219,7 @@ START_TEST (test_sysdb_update_members)
     add_groups[2] = NULL;
 
     ret = sysdb_update_members(test_ctx->sysdb, test_ctx->domain, user,
+                               SYSDB_MEMBER_USER,
                                (const char **)add_groups, NULL);
     fail_unless(ret == EOK, "Could not add groups");
     talloc_zfree(add_groups);
@@ -2230,6 +2233,7 @@ START_TEST (test_sysdb_update_members)
     add_groups[1] = NULL;
 
     ret = sysdb_update_members(test_ctx->sysdb, test_ctx->domain, user,
+                               SYSDB_MEMBER_USER,
                                (const char **)add_groups,
                                (const char **)del_groups);
     fail_unless(ret == EOK, "Group replace failed");
@@ -2243,7 +2247,8 @@ START_TEST (test_sysdb_update_members)
     del_groups[2] = NULL;
 
     ret = sysdb_update_members(test_ctx->sysdb, test_ctx->domain,
-                               user, NULL,
+                               user, SYSDB_MEMBER_USER,
+                               NULL,
                                (const char **)del_groups);
     fail_unless(ret == EOK, "Could not remove groups");
 
-- 
1.7.2.3

