From d59e1d2397c92a2c9f43eb310d99d81cc835b37e Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Mon, 2 Aug 2010 10:47:10 -0400 Subject: Add sysdb_update_members function This function will take a user, a list of groups that this user should be added to and a list of groups the user should be removed from and will recursively call sysdb_[add|remove]_group_member Includes a unit test --- src/db/sysdb.h | 5 +++++ src/db/sysdb_ops.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ src/tests/sysdb-tests.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+) (limited to 'src') 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); -- cgit