From 786b665d4906283a70ddf2e7c040a97f43a57aad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Fri, 6 Sep 2013 13:44:46 +0200
Subject: [PATCH 3/4] sysdb: sysdb_update_members can take either name or dn

We need to work with distinguish names when processing
cross-domain membership, because groups and users may
be stored in different sysdb tree.

Resolves:
https://fedorahosted.org/sssd/ticket/2066
---
 src/db/sysdb.h                  | 13 ++++++--
 src/db/sysdb_ops.c              | 67 ++++++++++++++++++++++++++++++-----------
 src/tests/simple_access-tests.c |  4 +--
 src/tests/sysdb-tests.c         |  6 ++--
 4 files changed, 65 insertions(+), 25 deletions(-)

diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index c352f89834f18f77196b861fd74096ceac5e3789..ef12d696160ad6fae762d768ff8a45f75bd9b75c 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -673,13 +673,15 @@ int sysdb_add_group_member(struct sysdb_ctx *sysdb,
                            struct sss_domain_info *domain,
                            const char *group,
                            const char *member,
-                           enum sysdb_member_type type);
+                           enum sysdb_member_type type,
+                           bool is_dn);
 
 int sysdb_remove_group_member(struct sysdb_ctx *sysdb,
                               struct sss_domain_info *domain,
                               const char *group,
                               const char *member,
-                              enum sysdb_member_type type);
+                              enum sysdb_member_type type,
+                              bool is_dn);
 
 errno_t sysdb_update_members(struct sysdb_ctx *sysdb,
                              struct sss_domain_info *domain,
@@ -688,6 +690,13 @@ errno_t sysdb_update_members(struct sysdb_ctx *sysdb,
                              const char *const *add_groups,
                              const char *const *del_groups);
 
+errno_t sysdb_update_members_dn(struct sysdb_ctx *sysdb,
+                                struct sss_domain_info *member_domain,
+                                const char *member,
+                                enum sysdb_member_type type,
+                                const char *const *add_groups,
+                                const char *const *del_groups);
+
 /* Password caching function.
  * If you are in a transaction ignore sysdb and pass in the handle.
  * If you are not in a transaction pass NULL in handle and provide sysdb,
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index 75d86b585951b8b07bf3318f8ad286c6dad82afa..677441d3cbc5f8216f76f298a3915df205cf8c72 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -1912,7 +1912,8 @@ sysdb_group_membership_mod(struct sysdb_ctx *sysdb,
                            const char *group,
                            const char *member,
                            enum sysdb_member_type type,
-                           int modify_op)
+                           int modify_op,
+                           bool is_dn)
 {
     struct ldb_dn *group_dn;
     struct ldb_dn *member_dn;
@@ -1936,7 +1937,12 @@ sysdb_group_membership_mod(struct sysdb_ctx *sysdb,
         goto done;
     }
 
-    group_dn = sysdb_group_dn(sysdb, tmp_ctx, domain, group);
+    if (!is_dn) {
+        group_dn = sysdb_group_dn(sysdb, tmp_ctx, domain, group);
+    } else {
+        group_dn = ldb_dn_new(tmp_ctx, sysdb->ldb, group);
+    }
+
     if (!group_dn) {
         ret = ENOMEM;
         goto done;
@@ -1953,10 +1959,11 @@ int sysdb_add_group_member(struct sysdb_ctx *sysdb,
                            struct sss_domain_info *domain,
                            const char *group,
                            const char *member,
-                           enum sysdb_member_type type)
+                           enum sysdb_member_type type,
+                           bool is_dn)
 {
-    return sysdb_group_membership_mod(sysdb, domain, group,
-                                      member, type, SYSDB_MOD_ADD);
+    return sysdb_group_membership_mod(sysdb, domain, group, member,
+                                      type, SYSDB_MOD_ADD, is_dn);
 }
 
 /* =Remove-member-from-Group(Native/Legacy)=============================== */
@@ -1966,10 +1973,11 @@ int sysdb_remove_group_member(struct sysdb_ctx *sysdb,
                               struct sss_domain_info *domain,
                               const char *group,
                               const char *member,
-                              enum sysdb_member_type type)
+                              enum sysdb_member_type type,
+                              bool is_dn)
 {
-    return sysdb_group_membership_mod(sysdb, domain, group,
-                                      member, type, SYSDB_MOD_DEL);
+    return sysdb_group_membership_mod(sysdb, domain, group, member,
+                                      type, SYSDB_MOD_DEL, is_dn);
 }
 
 
@@ -3031,12 +3039,13 @@ done:
     return ret;
 }
 
-errno_t sysdb_update_members(struct sysdb_ctx *sysdb,
-                             struct sss_domain_info *domain,
-                             const char *member,
-                             enum sysdb_member_type type,
-                             const char *const *add_groups,
-                             const char *const *del_groups)
+static errno_t sysdb_update_members_ex(struct sysdb_ctx *sysdb,
+                                       struct sss_domain_info *domain,
+                                       const char *member,
+                                       enum sysdb_member_type type,
+                                       const char *const *add_groups,
+                                       const char *const *del_groups,
+                                       bool is_dn)
 {
     errno_t ret;
     errno_t sret;
@@ -3059,8 +3068,8 @@ 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(sysdb, domain,
-                                         add_groups[i], member, type);
+            ret = sysdb_add_group_member(sysdb, domain, add_groups[i],
+                                         member, type, is_dn);
             if (ret != EOK) {
                 DEBUG(1, ("Could not add member [%s] to group [%s]. "
                           "Skipping.\n", member, add_groups[i]));
@@ -3072,8 +3081,8 @@ 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(sysdb, domain,
-                                            del_groups[i], member, type);
+            ret = sysdb_remove_group_member(sysdb, domain, del_groups[i],
+                                            member, type, is_dn);
             if (ret != EOK) {
                 DEBUG(1, ("Could not remove member [%s] from group [%s]. "
                           "Skipping\n", member, del_groups[i]));
@@ -3101,6 +3110,28 @@ done:
     return ret;
 }
 
+errno_t sysdb_update_members(struct sysdb_ctx *sysdb,
+                             struct sss_domain_info *domain,
+                             const char *member,
+                             enum sysdb_member_type type,
+                             const char *const *add_groups,
+                             const char *const *del_groups)
+{
+    return sysdb_update_members_ex(sysdb, domain, member, type,
+                                   add_groups, del_groups, false);
+}
+
+errno_t sysdb_update_members_dn(struct sysdb_ctx *sysdb,
+                                struct sss_domain_info *member_domain,
+                                const char *member,
+                                enum sysdb_member_type type,
+                                const char *const *add_groups,
+                                const char *const *del_groups)
+{
+    return sysdb_update_members_ex(sysdb, member_domain, member, type,
+                                   add_groups, del_groups, true);
+}
+
 errno_t sysdb_remove_attrs(struct sysdb_ctx *sysdb,
                            struct sss_domain_info *domain,
                            const char *name,
diff --git a/src/tests/simple_access-tests.c b/src/tests/simple_access-tests.c
index d1a6056abd2e226e07b5b6a256d19b94ed1f5650..64c00de938785b30898ed1edc8ea5c64dd453f1e 100644
--- a/src/tests/simple_access-tests.c
+++ b/src/tests/simple_access-tests.c
@@ -174,11 +174,11 @@ void setup_simple_group(void)
     fail_if(ret != EOK, "Could not add g2");
 
     ret = sysdb_add_group_member(test_ctx->sysdb, test_ctx->ctx->domain,
-                                 "g1", "u1", SYSDB_MEMBER_USER);
+                                 "g1", "u1", SYSDB_MEMBER_USER, false);
     fail_if(ret != EOK, "Could not add u1 to g1");
 
     ret = sysdb_add_group_member(test_ctx->sysdb, test_ctx->ctx->domain,
-                                 "g2", "u2", SYSDB_MEMBER_USER);
+                                 "g2", "u2", SYSDB_MEMBER_USER, false);
     fail_if(ret != EOK, "Could not add u2 to g2");
 }
 
diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c
index 6f95d248b65fe832447268e4d9eb94ceb2af7c17..950af27af509163972dc3ba8b944b09530c5417b 100644
--- a/src/tests/sysdb-tests.c
+++ b/src/tests/sysdb-tests.c
@@ -331,7 +331,7 @@ static int test_add_group_member(struct test_data *data)
 
     ret = sysdb_add_group_member(data->ctx->sysdb, data->ctx->domain,
                                  data->groupname, username,
-                                 SYSDB_MEMBER_USER);
+                                 SYSDB_MEMBER_USER, false);
     return ret;
 }
 
@@ -347,7 +347,7 @@ static int test_remove_group_member(struct test_data *data)
 
     ret = sysdb_remove_group_member(data->ctx->sysdb, data->ctx->domain,
                                     data->groupname, username,
-                                    SYSDB_MEMBER_USER);
+                                    SYSDB_MEMBER_USER, false);
     return ret;
 }
 
@@ -3969,7 +3969,7 @@ START_TEST(test_odd_characters)
     /* Add to the group */
     ret = sysdb_add_group_member(test_ctx->sysdb, test_ctx->domain,
                                  odd_groupname, odd_username,
-                                 SYSDB_MEMBER_USER);
+                                 SYSDB_MEMBER_USER, false);
     fail_unless(ret == EOK, "sysdb_add_group_member error [%d][%s]",
                             ret, strerror(ret));
 
-- 
1.7.11.7

