summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2012-11-24 17:11:06 +0100
committerJakub Hrozek <jhrozek@redhat.com>2012-12-06 11:54:19 +0100
commit5b6ea01e0398adbeaba1eacb5de85b2e2f668699 (patch)
tree697edcb1dfd5c7de654afa365101fa216c122637
parentf0b828e9d57a1ec6160c04d050c23bab9a6bd4b5 (diff)
downloadsssd-5b6ea01e0398adbeaba1eacb5de85b2e2f668699.tar.gz
sssd-5b6ea01e0398adbeaba1eacb5de85b2e2f668699.tar.xz
sssd-5b6ea01e0398adbeaba1eacb5de85b2e2f668699.zip
MEMBEROF: Do not add the ghost attribute to self
When a nested group with ghost users is added, its ghost attribute should propagate within the nested group structure much like the memberuid attribute. Unlike the memberuid attribute, the ghost attribute is only semi-managed by the memberof plugin and added manually to the original entry. This bug caused LDB errors saying that attribute or value already exists when a group with a ghost user was added to the hierarchy as groups were updated with an attribute they already had.
-rw-r--r--src/ldb_modules/memberof.c12
-rw-r--r--src/tests/sysdb-tests.c88
2 files changed, 87 insertions, 13 deletions
diff --git a/src/ldb_modules/memberof.c b/src/ldb_modules/memberof.c
index f0b5b72ed..b884228d2 100644
--- a/src/ldb_modules/memberof.c
+++ b/src/ldb_modules/memberof.c
@@ -813,7 +813,7 @@ static int mbof_add_operation(struct mbof_add_operation *addop)
el = ldb_msg_find_element(addop->entry, DB_GHOST);
if (el) {
for (i = 0; i < el->num_values; i++) {
- /* add memberuid to all group's parents */
+ /* add ghost to all group's parents */
for (j = 0; j < parents->num; j++) {
ret = mbof_append_muop(add_ctx, &add_ctx->muops,
&add_ctx->num_muops,
@@ -826,16 +826,6 @@ static int mbof_add_operation(struct mbof_add_operation *addop)
}
}
- /* now add memberuid to the group itself */
- ret = mbof_append_muop(add_ctx, &add_ctx->muops,
- &add_ctx->num_muops,
- LDB_FLAG_MOD_ADD,
- addop->entry_dn,
- (char *)el->values[i].data,
- DB_GHOST);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
}
}
diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c
index 2b8b92d60..e2c062f5d 100644
--- a/src/tests/sysdb-tests.c
+++ b/src/tests/sysdb-tests.c
@@ -174,6 +174,7 @@ struct test_data {
struct sysdb_attrs *attrs;
const char **attrlist;
+ char **memberlist;
struct ldb_message *msg;
size_t msgs_count;
@@ -252,7 +253,7 @@ static int test_add_group(struct test_data *data)
int ret;
ret = sysdb_add_group(data->ctx->sysdb, data->groupname,
- data->gid, NULL, 0, 0);
+ data->gid, data->attrs, 0, 0);
return ret;
}
@@ -270,7 +271,7 @@ static int test_store_group(struct test_data *data)
int ret;
ret = sysdb_store_group(data->ctx->sysdb, data->groupname,
- data->gid, NULL, -1, 0);
+ data->gid, data->attrs, -1, 0);
return ret;
}
@@ -423,6 +424,43 @@ static int test_memberof_store_group(struct test_data *data)
return ret;
}
+static int test_memberof_store_group_with_ghosts(struct test_data *data)
+{
+ int ret;
+ struct sysdb_attrs *attrs = NULL;
+ char *member;
+ int i;
+
+ attrs = sysdb_new_attrs(data);
+ if (!attrs) {
+ return ENOMEM;
+ }
+
+ for (i = 0; data->attrlist && data->attrlist[i]; i++) {
+ member = sysdb_group_strdn(data, data->ctx->domain->name,
+ data->attrlist[i]);
+ if (!member) {
+ return ENOMEM;
+ }
+ ret = sysdb_attrs_steal_string(attrs, SYSDB_MEMBER, member);
+ if (ret != EOK) {
+ return ret;
+ }
+ }
+
+ for (i = 0; data->memberlist && data->memberlist[i]; i++) {
+ ret = sysdb_attrs_steal_string(attrs, SYSDB_GHOST,
+ data->memberlist[i]);
+ if (ret != EOK) {
+ return ret;
+ }
+ }
+
+ ret = sysdb_store_group(data->ctx->sysdb, data->groupname,
+ data->gid, attrs, -1, 0);
+ return ret;
+}
+
static int test_add_basic_netgroup(struct test_data *data)
{
const char *description;
@@ -1872,6 +1910,46 @@ START_TEST (test_sysdb_memberof_store_group)
}
END_TEST
+START_TEST (test_sysdb_memberof_store_group_with_ghosts)
+{
+ struct sysdb_test_ctx *test_ctx;
+ struct test_data *data;
+ int ret;
+
+ /* Setup */
+ ret = setup_sysdb_tests(&test_ctx);
+ if (ret != EOK) {
+ fail("Could not set up the test");
+ return;
+ }
+
+ data = talloc_zero(test_ctx, struct test_data);
+ data->ctx = test_ctx;
+ data->ev = test_ctx->ev;
+ data->gid = _i;
+ data->groupname = talloc_asprintf(data, "testgroup%d", data->gid);
+
+ if (_i == 0) {
+ data->attrlist = NULL;
+ } else {
+ data->attrlist = talloc_array(data, const char *, 2);
+ fail_unless(data->attrlist != NULL, "talloc_array failed.");
+ data->attrlist[0] = talloc_asprintf(data, "testgroup%d", data->gid - 1);
+ data->attrlist[1] = NULL;
+ }
+
+ data->memberlist = talloc_array(data, char *, 2);
+ fail_unless(data->memberlist != NULL, "talloc_array failed.");
+ data->memberlist[0] = talloc_asprintf(data, "testuser%d", data->gid);
+ data->memberlist[1] = NULL;
+
+ ret = test_memberof_store_group_with_ghosts(data);
+
+ fail_if(ret != EOK, "Could not store POSIX group #%d", data->gid);
+ talloc_free(test_ctx);
+}
+END_TEST
+
START_TEST (test_sysdb_memberof_close_loop)
{
struct sysdb_test_ctx *test_ctx;
@@ -4025,6 +4103,12 @@ Suite *create_sysdb_suite(void)
tcase_add_loop_test(tc_memberof, test_sysdb_remove_local_group_by_gid,
MBO_GROUP_BASE , MBO_GROUP_BASE + 10);
+ /* Ghost users tests */
+ tcase_add_loop_test(tc_memberof, test_sysdb_memberof_store_group_with_ghosts,
+ MBO_GROUP_BASE , MBO_GROUP_BASE + 10);
+ tcase_add_loop_test(tc_memberof, test_sysdb_remove_local_group_by_gid,
+ MBO_GROUP_BASE , MBO_GROUP_BASE + 10);
+
suite_add_tcase(s, tc_memberof);
TCase *tc_subdomain = tcase_create("SYSDB sub-domain Tests");