summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/db/sysdb.h5
-rw-r--r--src/db/sysdb_ops.c56
-rw-r--r--src/tests/sysdb-tests.c56
3 files changed, 117 insertions, 0 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 5c0b744ff..e199ed94b 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -453,6 +453,11 @@ int sysdb_remove_group_member(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *group,
const char *user);
+errno_t sysdb_update_members(struct sysdb_ctx *sysdb,
+ struct sss_domain_info *domain,
+ const char *user,
+ const char **add_groups,
+ const char **del_groups);
/* Password caching function.
* If you are in a transaction ignore sysdb and pass in the handle.
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index 7f454311e..d86c35d6c 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -2199,3 +2199,59 @@ done:
}
return ret;
}
+
+errno_t sysdb_update_members(struct sysdb_ctx *sysdb,
+ struct sss_domain_info *domain,
+ const char *user,
+ const char **add_groups,
+ const char **del_groups)
+{
+ errno_t ret;
+ int i;
+
+ TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+ if(!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ ret = sysdb_transaction_start(sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Failed to start update transaction\n"));
+ goto done;
+ }
+
+ 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);
+ if (ret != EOK) {
+ DEBUG(1, ("Could not add user [%s] to group [%s]. "
+ "Skipping.\n"));
+ /* Continue on, we should try to finish the rest */
+ }
+ }
+ }
+
+ 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);
+ if (ret != EOK) {
+ DEBUG(1, ("Could not remove user [%s] from group [%s]. "
+ "Skipping\n"));
+ /* Continue on, we should try to finish the rest */
+ }
+ }
+ }
+
+ ret = sysdb_transaction_commit(sysdb);
+
+done:
+ if (ret != EOK) {
+ sysdb_transaction_cancel(sysdb);
+ }
+ talloc_free(tmp_ctx);
+ return ret;
+}
diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c
index ee1795033..dac5a0b77 100644
--- a/src/tests/sysdb-tests.c
+++ b/src/tests/sysdb-tests.c
@@ -2105,6 +2105,59 @@ START_TEST (test_sysdb_attrs_to_list)
}
END_TEST
+START_TEST (test_sysdb_update_members)
+{
+ struct sysdb_test_ctx *test_ctx;
+ char **add_groups;
+ char **del_groups;
+ const char *user = "testuser27000";
+ errno_t ret;
+
+ /* Setup */
+ ret = setup_sysdb_tests(&test_ctx);
+ fail_unless(ret == EOK, "Could not set up the test");
+
+ /* Add a user to two groups */
+ add_groups = talloc_array(test_ctx, char *, 3);
+ add_groups[0] = talloc_strdup(add_groups, "testgroup28001");
+ add_groups[1] = talloc_strdup(add_groups, "testgroup28002");
+ add_groups[2] = NULL;
+
+ ret = sysdb_update_members(test_ctx->sysdb, test_ctx->domain, user,
+ (const char **)add_groups, NULL);
+ fail_unless(ret == EOK, "Could not add groups");
+ talloc_zfree(add_groups);
+
+ /* Remove a user from one group and add to another */
+ del_groups = talloc_array(test_ctx, char *, 2);
+ del_groups[0] = talloc_strdup(del_groups, "testgroup28001");
+ del_groups[1] = NULL;
+ add_groups = talloc_array(test_ctx, char *, 2);
+ add_groups[0] = talloc_strdup(add_groups, "testgroup28003");
+ add_groups[1] = NULL;
+
+ ret = sysdb_update_members(test_ctx->sysdb, test_ctx->domain, user,
+ (const char **)add_groups,
+ (const char **)del_groups);
+ fail_unless(ret == EOK, "Group replace failed");
+ talloc_zfree(add_groups);
+ talloc_zfree(del_groups);
+
+ /* Remove a user from two groups */
+ del_groups = talloc_array(test_ctx, char *, 3);
+ del_groups[0] = talloc_strdup(del_groups, "testgroup28002");
+ del_groups[1] = talloc_strdup(del_groups, "testgroup28003");
+ del_groups[2] = NULL;
+
+ ret = sysdb_update_members(test_ctx->sysdb, test_ctx->domain,
+ user, NULL,
+ (const char **)del_groups);
+ fail_unless(ret == EOK, "Could not remove groups");
+
+ talloc_zfree(test_ctx);
+}
+END_TEST
+
Suite *create_sysdb_suite(void)
{
Suite *s = suite_create("sysdb");
@@ -2129,6 +2182,9 @@ Suite *create_sysdb_suite(void)
/* test the change */
tcase_add_loop_test(tc_sysdb, test_sysdb_get_user_attr, 27000, 27010);
+ /* Add and remove users in a group with sysdb_update_members */
+ tcase_add_test(tc_sysdb, test_sysdb_update_members);
+
/* Remove the other half by gid */
tcase_add_loop_test(tc_sysdb, test_sysdb_remove_local_group_by_gid, 28000, 28010);