diff options
-rw-r--r-- | server/db/sysdb.c | 145 | ||||
-rw-r--r-- | server/db/sysdb.h | 11 | ||||
-rw-r--r-- | server/tests/sysdb-tests.c | 172 |
3 files changed, 236 insertions, 92 deletions
diff --git a/server/db/sysdb.c b/server/db/sysdb.c index 175bf545..edf3593f 100644 --- a/server/db/sysdb.c +++ b/server/db/sysdb.c @@ -1263,24 +1263,21 @@ done: return ret; } +/* Wrapper around adding a user account to a POSIX group */ int sysdb_add_acct_to_posix_group(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, const char *domain, - const char *gname, + const char *group, const char *username) { TALLOC_CTX *tmp_ctx; - int ret, lret; + int ret; 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) { + + if (!sysdb || !domain || !group || !username) { return EINVAL; } @@ -1292,88 +1289,86 @@ int sysdb_add_acct_to_posix_group(TALLOC_CTX *mem_ctx, account = talloc_asprintf(tmp_ctx, SYSDB_PW_NAME"=%s,"SYSDB_TMPL_USER_BASE, username, domain); - if (account == NULL) { - talloc_free(tmp_ctx); - return ENOMEM; - } + if (account == NULL) goto done; + acct_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, account); - if (acct_dn == NULL) { - talloc_free(tmp_ctx); - return ENOMEM; - } + if (acct_dn == NULL) goto done; 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; + group, domain); + if (group_dn == NULL) goto done; - /* 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; - } + ret = sysdb_add_member_to_posix_group(tmp_ctx, sysdb, acct_dn, group_dn); - /* 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; - } +done: + talloc_free(tmp_ctx); + return ret; +} - switch(res->count) { - case 0: - DEBUG(1, ("No such user to add to group.\n")); - goto done; - break; +/* Wrapper around adding a POSIX group to a POSIX group */ +int sysdb_add_group_to_posix_group(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + const char *domain, + const char *group, + const char *member_group) +{ + TALLOC_CTX *tmp_ctx; + int ret; + char *member_group_canonical; + struct ldb_dn *member_group_dn; + struct ldb_dn *group_dn; - 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; + if (!sysdb || !domain || !group || !member_group) { + return EINVAL; } - 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; + tmp_ctx = talloc_new(mem_ctx); + if (tmp_ctx == NULL) { + return ENOMEM; } - switch(res->count) { - case 0: - DEBUG(1, ("No such group.\n")); - goto done; - break; + member_group_canonical = talloc_asprintf(tmp_ctx, + SYSDB_GR_NAME"=%s,"SYSDB_TMPL_GROUP_BASE, + member_group, domain); + if (member_group_canonical == NULL) goto done; - case 1: - /* Exactly one user returned. Proceed */ - break; + member_group_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, member_group_canonical); + if (member_group_dn == NULL) goto done; - default: - DEBUG(0, ("Cache DB corrupted, base search returned %d results\n", - res->count)); - ret = EIO; - goto done; + group_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, + SYSDB_GR_NAME"=%s,"SYSDB_TMPL_GROUP_BASE, + group, domain); + if (group_dn == NULL) goto done; + + ret = sysdb_add_member_to_posix_group(tmp_ctx, sysdb, member_group_dn, group_dn); + +done: + talloc_free(tmp_ctx); + return ret; +} + +int sysdb_add_member_to_posix_group(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct ldb_dn *member_dn, + struct ldb_dn *group_dn) +{ + TALLOC_CTX *tmp_ctx; + int ret, lret; + struct ldb_message *msg; + struct ldb_request *req; + + tmp_ctx = talloc_new(mem_ctx); + if (!tmp_ctx) return ENOMEM; + + /* 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; } - talloc_free(res); /* Add the user as a member of the group */ msg = ldb_msg_new(tmp_ctx); @@ -1384,7 +1379,7 @@ int sysdb_add_acct_to_posix_group(TALLOC_CTX *mem_ctx, 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); + lret = ldb_msg_add_fmt(msg, SYSDB_GR_MEMBER, "%s", ldb_dn_alloc_linearized(tmp_ctx, member_dn)); } if (lret != LDB_SUCCESS) { ret = errno; diff --git a/server/db/sysdb.h b/server/db/sysdb.h index 19781fb4..014e2ce9 100644 --- a/server/db/sysdb.h +++ b/server/db/sysdb.h @@ -160,4 +160,15 @@ int sysdb_add_acct_to_posix_group(TALLOC_CTX *mem_ctx, const char *domain, const char *gname, const char *username); + +int sysdb_add_group_to_posix_group(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + const char *domain, + const char *group, + const char *member_group); + +int sysdb_add_member_to_posix_group(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct ldb_dn *member_dn, + struct ldb_dn *group_dn); #endif /* __SYS_DB_H__ */ diff --git a/server/tests/sysdb-tests.c b/server/tests/sysdb-tests.c index 45b4d4f3..d1cddec6 100644 --- a/server/tests/sysdb-tests.c +++ b/server/tests/sysdb-tests.c @@ -110,6 +110,7 @@ START_TEST (test_sysdb_store_local_group_posix) { int ret; struct sysdb_test_ctx *test_ctx; + char *group_name; /* Setup */ ret = setup_sysdb_tests(&test_ctx); @@ -118,8 +119,11 @@ START_TEST (test_sysdb_store_local_group_posix) return; } + group_name = talloc_asprintf(test_ctx, "%s%d", SYSDB_POSIX_TEST_GROUP, _i); + fail_if(group_name == NULL, "Could not allocate group name"); + ret = sysdb_store_group_posix(test_ctx, test_ctx->sysdb, - "LOCAL", SYSDB_POSIX_TEST_GROUP, _i); + "LOCAL", group_name, _i); fail_if(ret != EOK, "Could not store POSIX group"); talloc_free(test_ctx); @@ -134,6 +138,7 @@ START_TEST (test_sysdb_get_local_group_posix) struct ldb_dn *base_group_dn; const char *attrs[] = { SYSDB_GR_NAME, SYSDB_GR_GIDNUM, NULL }; const char *name; + char *expected_group; gid_t test_gid; /* Setup */ @@ -143,6 +148,9 @@ START_TEST (test_sysdb_get_local_group_posix) return; } + expected_group = talloc_asprintf(test_ctx, "%s%d", SYSDB_POSIX_TEST_GROUP, _i); + fail_if(expected_group == NULL, "Could not allocate expected_group"); + /* Set up the base DN */ base_group_dn = ldb_dn_new_fmt(test_ctx, test_ctx->sysdb->ldb, SYSDB_TMPL_GROUP_BASE, "LOCAL"); @@ -170,26 +178,26 @@ START_TEST (test_sysdb_get_local_group_posix) } name = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_GR_NAME, NULL); - fail_unless(strcmp(name, SYSDB_POSIX_TEST_GROUP) == 0, + fail_unless(strcmp(name, expected_group) == 0, "Returned group name was %s, expecting %s", - name, SYSDB_POSIX_TEST_GROUP); + name, expected_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); + attrs, SYSDB_GRNAM_FILTER, expected_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); + fail("Local group %s doesn't exist.", expected_group); return; } else if (res->count > 1) { - fail("More than one group shared name %s", SYSDB_POSIX_TEST_GROUP); + fail("More than one group shared name %s", expected_group); return; } @@ -207,6 +215,7 @@ START_TEST (test_sysdb_add_acct_to_posix_group) int ret; struct sysdb_test_ctx *test_ctx; char *username; + char *group; /* Setup */ ret = setup_sysdb_tests(&test_ctx); @@ -217,14 +226,16 @@ START_TEST (test_sysdb_add_acct_to_posix_group) /* Add user to test group */ username = talloc_asprintf(test_ctx, "testuser%d", _i); + group = talloc_asprintf(test_ctx, "%s%d",SYSDB_POSIX_TEST_GROUP, _i); + ret = sysdb_add_acct_to_posix_group(test_ctx, test_ctx->sysdb, "LOCAL", - SYSDB_POSIX_TEST_GROUP, + group, username); fail_if(ret != EOK, - "Failed to add user %s to group %s. Error was: %d", - username, SYSDB_POSIX_TEST_GROUP, ret); + "Failed to add user %s to group %s.", + username, group, ret); talloc_free(test_ctx); } @@ -238,6 +249,7 @@ START_TEST (test_sysdb_verify_posix_group_members) char *username; char *member; char *group; + char *group_name; struct ldb_dn *group_dn; struct ldb_dn *user_dn; struct ldb_result *res; @@ -263,9 +275,10 @@ START_TEST (test_sysdb_verify_posix_group_members) 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_name = talloc_asprintf(test_ctx, "%s%d", SYSDB_POSIX_TEST_GROUP, _i); group = talloc_asprintf(test_ctx, SYSDB_GR_NAME"=%s,"SYSDB_TMPL_GROUP_BASE, - SYSDB_POSIX_TEST_GROUP, "LOCAL"); + group_name, "LOCAL"); fail_if(group == NULL, "Could not allocate group dn"); group_dn = ldb_dn_new_fmt(test_ctx, test_ctx->sysdb->ldb, group); @@ -274,14 +287,14 @@ START_TEST (test_sysdb_verify_posix_group_members) /* 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); + group_attrs, SYSDB_GRNAM_FILTER, group_name); 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); + fail("Local group %s doesn't exist.", group_name); return; } else if (res->count > 1) { @@ -351,6 +364,125 @@ START_TEST (test_sysdb_verify_posix_group_members) } END_TEST +START_TEST (test_sysdb_add_invalid_member) +{ + char found_group; + int ret, i; + struct sysdb_test_ctx *test_ctx; + char *username; + char *member; + char *group; + char *group_name; + struct ldb_dn *group_dn; + struct ldb_result *res; + struct ldb_message_element *el; + const char *group_attrs[] = { SYSDB_GR_MEMBER, NULL }; + + /* Setup */ + ret = setup_sysdb_tests(&test_ctx); + if (ret != EOK) { + fail("Could not set up the test"); + return; + } + + /* Add nonexistent user to test group */ + username = talloc_asprintf(test_ctx, "nonexistentuser%d", _i); + ret = sysdb_add_acct_to_posix_group(test_ctx, + test_ctx->sysdb, + "LOCAL", + SYSDB_POSIX_TEST_GROUP, + username); + fail_if(ret == EOK, + "Unexpected success adding user %s to group %s. Error was: %d", + username, SYSDB_POSIX_TEST_GROUP, ret); + +/* Verify that the member wasn't added anyway */ + + member = talloc_asprintf(test_ctx, + SYSDB_PW_NAME"=%s,"SYSDB_TMPL_USER_BASE, + username, "LOCAL"); + fail_if(member == NULL, "Could not allocate member dn"); + + group_name = talloc_asprintf(test_ctx, "%s%d", SYSDB_POSIX_TEST_GROUP, _i); + group = talloc_asprintf(test_ctx, + SYSDB_GR_NAME"=%s,"SYSDB_TMPL_GROUP_BASE, + group_name, "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, group_name); + if (ret != LDB_SUCCESS) { + fail("Could not locate group %d", _i); + return; + } + + if (res->count < 1) { + fail("Local group %s doesn't exist.", group_name); + return; + } + else if (res->count > 1) { + fail("More than one group shared name %s", group_name); + 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_if(found_group == 1, "%s has added %s as a member", SYSDB_POSIX_TEST_GROUP, username); + talloc_free(test_ctx); +} +END_TEST + +START_TEST (test_sysdb_add_group_to_posix_group) +{ + int ret; + struct sysdb_test_ctx *test_ctx; + char *member_group; + char *group; + + /* Setup */ + ret = setup_sysdb_tests(&test_ctx); + if (ret != EOK) { + fail("Could not set up the test"); + return; + } + + /* Add user to test group */ + member_group = talloc_asprintf(test_ctx, "%s%d", SYSDB_POSIX_TEST_GROUP, _i-1); + group = talloc_asprintf(test_ctx, "%s%d", SYSDB_POSIX_TEST_GROUP, _i); + ret = sysdb_add_group_to_posix_group(test_ctx, + test_ctx->sysdb, + "LOCAL", + group, + member_group); + fail_if(ret != EOK, + "Failed to add group %s to group %s. Error was: %d", + member_group, group, ret); + + talloc_free(test_ctx); +} +END_TEST + Suite *create_sysdb_suite(void) { Suite *s = suite_create("sysdb"); @@ -359,16 +491,16 @@ Suite *create_sysdb_suite(void) 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); + tcase_add_loop_test(tc_posix_users, test_sysdb_store_local_account_posix,27000,27010); /* POSIX Group test case */ TCase *tc_posix_gr = tcase_create("\tPOSIX Groups"); /* Create a new group */ - tcase_add_loop_test(tc_posix_gr, test_sysdb_store_local_group_posix,27000,27001); + tcase_add_loop_test(tc_posix_gr, test_sysdb_store_local_group_posix,27000,27010); /* Verify that the new group exists */ - tcase_add_loop_test(tc_posix_gr, test_sysdb_get_local_group_posix,27000,27001); + tcase_add_loop_test(tc_posix_gr, test_sysdb_get_local_group_posix,27000,27010); /* Change the gid of the group we created */ tcase_add_loop_test(tc_posix_gr, test_sysdb_store_local_group_posix,27001,27002); @@ -377,10 +509,16 @@ Suite *create_sysdb_suite(void) 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); + tcase_add_loop_test(tc_posix_gr, test_sysdb_add_acct_to_posix_group, 27000, 27010); /* Verify member and memberOf */ - tcase_add_loop_test(tc_posix_gr, test_sysdb_verify_posix_group_members, 26000, 26010); + tcase_add_loop_test(tc_posix_gr, test_sysdb_verify_posix_group_members, 27000, 27010); + + /* A negative test: add nonexistent users as members of a group */ + tcase_add_loop_test(tc_posix_gr, test_sysdb_add_invalid_member, 27000, 27010); + + /* Add groups as members of groups */ + tcase_add_loop_test(tc_posix_gr, test_sysdb_add_group_to_posix_group, 27001, 27010); /* Add all test cases to the test suite */ suite_add_tcase(s, tc_posix_users); |