summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2009-02-10 19:29:13 -0500
committerSimo Sorce <idra@samba.org>2009-02-12 17:08:57 -0500
commitb7f8cce6f34cae52260a7eca13e39c2ecd98d77c (patch)
tree61a6f45ffdcdda256bbe3400f2c1be5fed763242 /server
parent02618c33c2389922a69ebad38a9ee4143d1986a6 (diff)
downloadsssd-b7f8cce6f34cae52260a7eca13e39c2ecd98d77c.tar.gz
sssd-b7f8cce6f34cae52260a7eca13e39c2ecd98d77c.tar.bz2
sssd-b7f8cce6f34cae52260a7eca13e39c2ecd98d77c.zip
Adding sysdb_add_acct_to_posix_group and associated unit tests
Diffstat (limited to 'server')
-rw-r--r--server/db/sysdb.c175
-rw-r--r--server/db/sysdb.h14
-rw-r--r--server/tests/sysdb-tests.c300
3 files changed, 462 insertions, 27 deletions
diff --git a/server/db/sysdb.c b/server/db/sysdb.c
index 5e94aab8..175bf545 100644
--- a/server/db/sysdb.c
+++ b/server/db/sysdb.c
@@ -733,9 +733,12 @@ done:
int sysdb_store_account_posix(TALLOC_CTX *memctx,
struct sysdb_ctx *sysdb,
const char *domain,
- char *name, char *pwd,
+ const char *name,
+ const char *pwd,
uid_t uid, gid_t gid,
- char *gecos, char *homedir, char *shell)
+ const char *gecos,
+ const char *homedir,
+ const char *shell)
{
TALLOC_CTX *tmp_ctx;
const char *attrs[] = { SYSDB_PW_NAME, NULL };
@@ -1114,10 +1117,9 @@ int sysdb_store_group_posix(TALLOC_CTX *memctx,
}
group_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
- "gid=%s,"SYSDB_TMPL_GROUP_BASE,
+ SYSDB_GR_NAME"=%s,"SYSDB_TMPL_GROUP_BASE,
name, domain);
if (group_dn == NULL) {
- ret = ENOMEM;
talloc_free(tmp_ctx);
return ENOMEM;
}
@@ -1261,6 +1263,171 @@ done:
return ret;
}
+int sysdb_add_acct_to_posix_group(TALLOC_CTX *mem_ctx,
+ struct sysdb_ctx *sysdb,
+ const char *domain,
+ const char *gname,
+ const char *username)
+{
+ TALLOC_CTX *tmp_ctx;
+ int ret, lret;
+ char *account;
+ struct ldb_dn *acct_dn;
+ struct ldb_dn *group_dn;
+ struct ldb_message *msg;
+ struct ldb_result *res;
+ struct ldb_request *req;
+ const char *acct_attrs[] = { SYSDB_PW_NAME, NULL };
+ const char *group_attrs[] = { SYSDB_GR_MEMBER, NULL };
+
+ if (!sysdb || !domain || !gname || !username) {
+ return EINVAL;
+ }
+
+ tmp_ctx = talloc_new(mem_ctx);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ account = talloc_asprintf(tmp_ctx,
+ SYSDB_PW_NAME"=%s,"SYSDB_TMPL_USER_BASE,
+ username, domain);
+ if (account == NULL) {
+ talloc_free(tmp_ctx);
+ return ENOMEM;
+ }
+ acct_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, account);
+ if (acct_dn == NULL) {
+ talloc_free(tmp_ctx);
+ return ENOMEM;
+ }
+
+ group_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
+ SYSDB_GR_NAME"=%s,"SYSDB_TMPL_GROUP_BASE,
+ gname, domain);
+ if (group_dn == NULL) {
+ talloc_free(tmp_ctx);
+ return ENOMEM;
+ }
+ ret = EOK;
+
+ /* Start LDB Transaction */
+ lret = ldb_transaction_start(sysdb->ldb);
+ if (lret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed ldb transaction start !? (%d)\n", lret));
+ talloc_free(tmp_ctx);
+ return EIO;
+ }
+
+ /* Verify the existence of the user */
+ lret = ldb_search(sysdb->ldb, tmp_ctx, &res, acct_dn,
+ LDB_SCOPE_BASE, acct_attrs, SYSDB_PWENT_FILTER);
+ if (lret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed to make search request: %s(%d)[%s]\b",
+ ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb)));
+ ret = EIO;
+ goto done;
+ }
+
+ switch(res->count) {
+ case 0:
+ DEBUG(1, ("No such user to add to group.\n"));
+ goto done;
+ break;
+
+ case 1:
+ /* Exactly one user returned. Proceed */
+ break;
+
+ default:
+ DEBUG(0, ("Cache DB corrupted, base search returned %d results\n",
+ res->count));
+ ret = EIO;
+ goto done;
+ }
+ talloc_free(res);
+
+ /* Verify the existence of the group */
+ lret = ldb_search(sysdb->ldb, tmp_ctx, &res, group_dn,
+ LDB_SCOPE_BASE, group_attrs, SYSDB_GRENT_FILTER);
+ if (lret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed to make search request: %s(%d)[%s]\b",
+ ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb)));
+ ret = EIO;
+ goto done;
+ }
+
+ switch(res->count) {
+ case 0:
+ DEBUG(1, ("No such group.\n"));
+ goto done;
+ break;
+
+ case 1:
+ /* Exactly one user returned. Proceed */
+ break;
+
+ default:
+ DEBUG(0, ("Cache DB corrupted, base search returned %d results\n",
+ res->count));
+ ret = EIO;
+ goto done;
+ }
+ talloc_free(res);
+
+ /* Add the user as a member of the group */
+ msg = ldb_msg_new(tmp_ctx);
+ if(msg == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ msg->dn = group_dn;
+ lret = ldb_msg_add_empty(msg, SYSDB_GR_MEMBER, LDB_FLAG_MOD_ADD, NULL);
+ if (lret == LDB_SUCCESS) {
+ lret = ldb_msg_add_fmt(msg, SYSDB_GR_MEMBER, "%s", account);
+ }
+ if (lret != LDB_SUCCESS) {
+ ret = errno;
+ goto done;
+ }
+
+ lret = ldb_build_mod_req(&req, sysdb->ldb, tmp_ctx, msg, NULL,
+ NULL, ldb_op_default_callback, NULL);
+ if (lret == LDB_SUCCESS) {
+ lret = ldb_request(sysdb->ldb, req);
+ if (lret == LDB_SUCCESS) {
+ lret = ldb_wait(req->handle, LDB_WAIT_ALL);
+ }
+ }
+ if (lret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed to make modify request: %s(%d)[%s]\n",
+ ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb)));
+ ret = EIO;
+ goto done;
+ }
+
+ /* Commit LDB Transaction */
+ lret = ldb_transaction_commit(sysdb->ldb);
+ if (lret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed ldb transaction start !? (%d)\n", lret));
+ ret = EIO;
+ goto done;
+ }
+
+ ret = EOK;
+done:
+ /* Cancel LDB Transaction */
+ if (ret != EOK) {
+ lret = ldb_transaction_cancel(sysdb->ldb);
+ if (lret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed to cancel ldb transaction (%d)\n", lret));
+ }
+ }
+
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
int sysdb_init(TALLOC_CTX *mem_ctx,
struct event_context *ev,
struct confdb_ctx *cdb,
diff --git a/server/db/sysdb.h b/server/db/sysdb.h
index 582b8abe..19781fb4 100644
--- a/server/db/sysdb.h
+++ b/server/db/sysdb.h
@@ -50,6 +50,7 @@
#define SYSDB_PW_FULLNAME "fullName"
#define SYSDB_PW_HOMEDIR "homeDirectory"
#define SYSDB_PW_SHELL "loginShell"
+#define SYSDB_PW_MEMBEROF "memberOf"
#define SYSDB_GR_NAME "cn"
#define SYSDB_GR_GIDNUM "gidNumber"
@@ -134,9 +135,12 @@ int sysdb_initgroups(TALLOC_CTX *mem_ctx,
int sysdb_store_account_posix(TALLOC_CTX *memctx,
struct sysdb_ctx *sysdb,
const char *domain,
- char *name, char *pwd,
+ const char *name,
+ const char *pwd,
uid_t uid, gid_t gid,
- char *gecos, char *homedir, char *shell);
+ const char *gecos,
+ const char *homedir,
+ const char *shell);
int sysdb_remove_account_posix(TALLOC_CTX *memctx,
struct sysdb_ctx *sysdb,
@@ -150,4 +154,10 @@ int sysdb_store_group_posix(TALLOC_CTX *memctx,
struct sysdb_ctx *sysdb,
const char *domain,
const char *name, gid_t gid);
+
+int sysdb_add_acct_to_posix_group(TALLOC_CTX *mem_ctx,
+ struct sysdb_ctx *sysdb,
+ const char *domain,
+ const char *gname,
+ const char *username);
#endif /* __SYS_DB_H__ */
diff --git a/server/tests/sysdb-tests.c b/server/tests/sysdb-tests.c
index ef49d415..45b4d4f3 100644
--- a/server/tests/sysdb-tests.c
+++ b/server/tests/sysdb-tests.c
@@ -28,18 +28,20 @@
#include "confdb/confdb.h"
#include "db/sysdb.h"
+#define SYSDB_POSIX_TEST_GROUP "sysdbtestgroup"
+
struct sysdb_test_ctx {
struct sysdb_ctx *sysdb;
struct confdb_ctx *confdb;
struct event_context *ev;
};
-static int setup_sysdb_tests(TALLOC_CTX *mem_ctx, struct sysdb_test_ctx **ctx)
+static int setup_sysdb_tests(struct sysdb_test_ctx **ctx)
{
struct sysdb_test_ctx *test_ctx;
int ret;
- test_ctx = talloc_zero(mem_ctx, struct sysdb_test_ctx);
+ test_ctx = talloc_zero(NULL, struct sysdb_test_ctx);
if (test_ctx == NULL) {
fail("Could not allocate memory for test context");
return ENOMEM;
@@ -56,7 +58,7 @@ static int setup_sysdb_tests(TALLOC_CTX *mem_ctx, struct sysdb_test_ctx **ctx)
}
/* Connect to the conf db */
- ret = confdb_init(mem_ctx, test_ctx->ev, &test_ctx->confdb);
+ ret = confdb_init(test_ctx, test_ctx->ev, &test_ctx->confdb);
if(ret != EOK) {
fail("Could not initialize connection to the confdb");
talloc_free(test_ctx);
@@ -74,47 +76,278 @@ static int setup_sysdb_tests(TALLOC_CTX *mem_ctx, struct sysdb_test_ctx **ctx)
return EOK;
}
-START_TEST (test_sysdb_store_group_posix)
+START_TEST (test_sysdb_store_local_account_posix)
{
int ret;
struct sysdb_test_ctx *test_ctx;
- TALLOC_CTX *mem_ctx;
/* Setup */
- mem_ctx = talloc_new(NULL);
- ret = setup_sysdb_tests(mem_ctx, &test_ctx);
+ ret = setup_sysdb_tests(&test_ctx);
if (ret != EOK) {
fail("Could not set up the test");
return;
}
- ret = sysdb_store_group_posix(test_ctx, test_ctx->sysdb,
- "LOCAL", "sysdbtestgroup", 67000);
- fail_if(ret != EOK, "Could not store sysdbtestgroup");
+ /* Store a user account with username, password,
+ * uid, gid, gecos, homedir and shell
+ */
+ const char *username = talloc_asprintf(test_ctx, "testuser%d", _i);
+ const char *home = talloc_asprintf(test_ctx, "/home/testuser%d", _i);
+
+ ret = sysdb_store_account_posix(test_ctx, test_ctx->sysdb,
+ "LOCAL", username, "password",
+ _i, _i,
+ "Test User",
+ home,
+ "/bin/bash");
+ fail_if(ret != EOK, "Could not store POSIX user %s", username);
- talloc_free(mem_ctx);
+ talloc_free(test_ctx);
}
END_TEST
-START_TEST (test_sysdb_replace_group_posix)
+START_TEST (test_sysdb_store_local_group_posix)
{
int ret;
struct sysdb_test_ctx *test_ctx;
- TALLOC_CTX *mem_ctx;
/* Setup */
- mem_ctx = talloc_new(NULL);
- ret = setup_sysdb_tests(mem_ctx, &test_ctx);
+ ret = setup_sysdb_tests(&test_ctx);
if (ret != EOK) {
fail("Could not set up the test");
return;
}
ret = sysdb_store_group_posix(test_ctx, test_ctx->sysdb,
- "LOCAL", "sysdbtestgroup", 67001);
- fail_if(ret != EOK, "Could not store sysdbtestgroup");
+ "LOCAL", SYSDB_POSIX_TEST_GROUP, _i);
+ fail_if(ret != EOK, "Could not store POSIX group");
+
+ talloc_free(test_ctx);
+}
+END_TEST
+
+START_TEST (test_sysdb_get_local_group_posix)
+{
+ int ret;
+ struct sysdb_test_ctx *test_ctx;
+ struct ldb_result *res;
+ struct ldb_dn *base_group_dn;
+ const char *attrs[] = { SYSDB_GR_NAME, SYSDB_GR_GIDNUM, NULL };
+ const char *name;
+ gid_t test_gid;
+
+ /* Setup */
+ ret = setup_sysdb_tests(&test_ctx);
+ if (ret != EOK) {
+ fail("Could not set up the test");
+ return;
+ }
+
+ /* Set up the base DN */
+ base_group_dn = ldb_dn_new_fmt(test_ctx, test_ctx->sysdb->ldb,
+ SYSDB_TMPL_GROUP_BASE, "LOCAL");
+ if (base_group_dn == NULL) {
+ fail("Could not create basedn for LOCAL groups");
+ return;
+ }
+
+ /* Look up the group by gid */
+ ret = ldb_search(test_ctx->sysdb->ldb, test_ctx,
+ &res, base_group_dn, LDB_SCOPE_ONELEVEL,
+ attrs, SYSDB_GRGID_FILTER, (unsigned long)_i);
+ if (ret != LDB_SUCCESS) {
+ fail("Could not locate group %d", _i);
+ return;
+ }
+
+ if (res->count < 1) {
+ fail("Local group %d doesn't exist.\n", _i);
+ return;
+ }
+ else if (res->count > 1) {
+ fail("More than one group shared gid %d", _i);
+ return;
+ }
+
+ name = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_GR_NAME, NULL);
+ fail_unless(strcmp(name, SYSDB_POSIX_TEST_GROUP) == 0,
+ "Returned group name was %s, expecting %s",
+ name, SYSDB_POSIX_TEST_GROUP);
+ talloc_free(res);
+
+ /* Look up the group by name */
+ ret = ldb_search(test_ctx->sysdb->ldb, test_ctx,
+ &res, base_group_dn, LDB_SCOPE_ONELEVEL,
+ attrs, SYSDB_GRNAM_FILTER, SYSDB_POSIX_TEST_GROUP);
+ if (ret != LDB_SUCCESS) {
+ fail("Could not locate group %d", _i);
+ return;
+ }
+
+ if (res->count < 1) {
+ fail("Local group %s doesn't exist.", SYSDB_POSIX_TEST_GROUP);
+ return;
+ }
+ else if (res->count > 1) {
+ fail("More than one group shared name %s", SYSDB_POSIX_TEST_GROUP);
+ return;
+ }
+
+ test_gid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_GR_GIDNUM, 0);
+ fail_unless(test_gid == _i,
+ "Returned group id was %lu, expecting %lu",
+ test_gid, _i);
+
+ talloc_free(test_ctx);
+}
+END_TEST
+
+START_TEST (test_sysdb_add_acct_to_posix_group)
+{
+ int ret;
+ struct sysdb_test_ctx *test_ctx;
+ char *username;
+
+ /* Setup */
+ ret = setup_sysdb_tests(&test_ctx);
+ if (ret != EOK) {
+ fail("Could not set up the test");
+ return;
+ }
+
+ /* Add user to test group */
+ username = talloc_asprintf(test_ctx, "testuser%d", _i);
+ ret = sysdb_add_acct_to_posix_group(test_ctx,
+ test_ctx->sysdb,
+ "LOCAL",
+ SYSDB_POSIX_TEST_GROUP,
+ username);
+ fail_if(ret != EOK,
+ "Failed to add user %s to group %s. Error was: %d",
+ username, SYSDB_POSIX_TEST_GROUP, ret);
- talloc_free(mem_ctx);
+ talloc_free(test_ctx);
+}
+END_TEST
+
+START_TEST (test_sysdb_verify_posix_group_members)
+{
+ char found_group, found_user;
+ int ret, i;
+ struct sysdb_test_ctx *test_ctx;
+ char *username;
+ char *member;
+ char *group;
+ struct ldb_dn *group_dn;
+ struct ldb_dn *user_dn;
+ struct ldb_result *res;
+ struct ldb_message_element *el;
+ const char *group_attrs[] = { SYSDB_GR_MEMBER, NULL };
+ const char *user_attrs[] = { SYSDB_PW_MEMBEROF, NULL };
+
+ /* Setup */
+ ret = setup_sysdb_tests(&test_ctx);
+ if (ret != EOK) {
+ fail("Could not set up the test");
+ return;
+ }
+
+ username = talloc_asprintf(test_ctx, "testuser%d", _i);
+ fail_if (username == NULL, "Could not allocate username");
+
+ member = talloc_asprintf(test_ctx,
+ SYSDB_PW_NAME"=%s,"SYSDB_TMPL_USER_BASE,
+ username, "LOCAL");
+ fail_if(member == NULL, "Could not allocate member dn");
+
+ user_dn = ldb_dn_new_fmt(test_ctx, test_ctx->sysdb->ldb, member);
+ fail_if(user_dn == NULL, "Could not create user_dn object");
+
+ group = talloc_asprintf(test_ctx,
+ SYSDB_GR_NAME"=%s,"SYSDB_TMPL_GROUP_BASE,
+ SYSDB_POSIX_TEST_GROUP, "LOCAL");
+ fail_if(group == NULL, "Could not allocate group dn");
+
+ group_dn = ldb_dn_new_fmt(test_ctx, test_ctx->sysdb->ldb, group);
+ fail_if(group_dn == NULL, "Could not create group_dn object");
+
+ /* Look up the group by name */
+ ret = ldb_search(test_ctx->sysdb->ldb, test_ctx,
+ &res, group_dn, LDB_SCOPE_BASE,
+ group_attrs, SYSDB_GRNAM_FILTER, SYSDB_POSIX_TEST_GROUP);
+ if (ret != LDB_SUCCESS) {
+ fail("Could not locate group %d", _i);
+ return;
+ }
+
+ if (res->count < 1) {
+ fail("Local group %s doesn't exist.", SYSDB_POSIX_TEST_GROUP);
+ return;
+ }
+ else if (res->count > 1) {
+ fail("More than one group shared name %s", SYSDB_POSIX_TEST_GROUP);
+ return;
+ }
+
+ /* Check the members for the requested user */
+ found_group = i = 0;
+ el = ldb_msg_find_element(res->msgs[0], SYSDB_GR_MEMBER);
+ if (el && el->num_values > 0) {
+ while (i < el->num_values && !found_group) {
+ struct ldb_val v = el->values[i];
+ char *value = talloc_strndup(test_ctx, (char *)v.data, v.length);
+ if (strcmp(value, member) == 0) {
+ found_group = 1;
+ }
+ talloc_free(value);
+ i++;
+ }
+ }
+ else {
+ fail("No member attributes for group %s", SYSDB_POSIX_TEST_GROUP);
+ }
+
+ fail_unless(found_group == 1, "%s does not have %s as a member", SYSDB_POSIX_TEST_GROUP, username);
+
+ /* Look up the user by name */
+ ret = ldb_search(test_ctx->sysdb->ldb, test_ctx,
+ &res, user_dn, LDB_SCOPE_BASE,
+ user_attrs, SYSDB_PWNAM_FILTER, username);
+ if (ret != LDB_SUCCESS) {
+ fail("Could not locate user %s", username);
+ return;
+ }
+
+ if (res->count < 1) {
+ fail("Local user %s doesn't exist.", username);
+ return;
+ }
+ else if (res->count > 1) {
+ fail("More than one user shared name %s", username);
+ return;
+ }
+
+ /* Check that the user is a member of the SYSDB_POSIX_TEST_GROUP */
+ found_user = i = 0;
+ el = ldb_msg_find_element(res->msgs[0], SYSDB_PW_MEMBEROF);
+ if (el && el->num_values > 0) {
+ while (i < el->num_values && !found_user) {
+ struct ldb_val v = el->values[i];
+ char *value = talloc_strndup(test_ctx, (char *)v.data, v.length);
+ if (strcmp(value, group) == 0) {
+ found_user = 1;
+ }
+ talloc_free(value);
+ i++;
+ }
+ }
+ else {
+ fail("No memberOf attributes for user %s", username);
+ }
+
+ fail_unless(found_group, "User %s not a memberOf group %s", username, SYSDB_POSIX_TEST_GROUP);
+
+ talloc_free(test_ctx);
}
END_TEST
@@ -122,10 +355,35 @@ Suite *create_sysdb_suite(void)
{
Suite *s = suite_create("sysdb");
- /* POSIX Group test case */
+/* POSIX User test case */
+ TCase *tc_posix_users = tcase_create("\tPOSIX Users");
+
+ /* Create a new user */
+ tcase_add_loop_test(tc_posix_users, test_sysdb_store_local_account_posix,26000,26010);
+
+/* POSIX Group test case */
TCase *tc_posix_gr = tcase_create("\tPOSIX Groups");
- tcase_add_test(tc_posix_gr, test_sysdb_store_group_posix);
- tcase_add_test(tc_posix_gr, test_sysdb_replace_group_posix);
+
+ /* Create a new group */
+ tcase_add_loop_test(tc_posix_gr, test_sysdb_store_local_group_posix,27000,27001);
+
+ /* Verify that the new group exists */
+ tcase_add_loop_test(tc_posix_gr, test_sysdb_get_local_group_posix,27000,27001);
+
+ /* Change the gid of the group we created */
+ tcase_add_loop_test(tc_posix_gr, test_sysdb_store_local_group_posix,27001,27002);
+
+ /* Verify that the group has been changed */
+ tcase_add_loop_test(tc_posix_gr, test_sysdb_get_local_group_posix,27001,27002);
+
+ /* Add users to the group */
+ tcase_add_loop_test(tc_posix_gr, test_sysdb_add_acct_to_posix_group, 26000, 26010);
+
+ /* Verify member and memberOf */
+ tcase_add_loop_test(tc_posix_gr, test_sysdb_verify_posix_group_members, 26000, 26010);
+
+/* Add all test cases to the test suite */
+ suite_add_tcase(s, tc_posix_users);
suite_add_tcase(s, tc_posix_gr);
return s;