From ee8ebcec8062d75e98da796b291973fd96d45b1c Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Tue, 26 Jul 2016 21:30:41 +0200 Subject: [PATCH] sysdb_get_user_members_recursively: use memberof search --- src/db/sysdb_ops.c | 181 ++++------------------------------------ src/tests/cmocka/test_nss_srv.c | 30 +++---- 2 files changed, 33 insertions(+), 178 deletions(-) diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index b7c04cb4ab64c2767e211d6ead1463a3a3024e68..9a8a55ed8aa69e1638d0ab6f636e43baa3d0bfea 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -4711,159 +4711,42 @@ done: return ret; } -static -errno_t sysdb_get_user_members_recursively_int(TALLOC_CTX *mem_ctx, - struct sss_domain_info *dom, - struct ldb_dn *group_dn, - hash_table_t *users, - hash_table_t *groups) -{ - errno_t ret; - size_t c; - size_t m_count; - struct ldb_message **members; - const char *oc; - hash_key_t key; - hash_value_t value; - int hret; - - /* Get all elemets pointed to by group members */ - ret = sysdb_asq_search(mem_ctx, dom, group_dn, NULL, SYSDB_MEMBER, - NULL /* requesting all attributes */, - &m_count, &members); - if (ret != EOK) { - if (ret != ENOENT) { - DEBUG(SSSDBG_OP_FAILURE, "sysdb_asq_search failed.\n"); - } - goto done; - } - - key.type = HASH_KEY_STRING; - - for (c = 0; c < m_count; c++) { - - oc = ldb_msg_find_attr_as_string(members[c], SYSDB_OBJECTCLASS, NULL); - if (oc == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Missing objectclass in object [%s].\n", - ldb_dn_get_linearized(members[c]->dn)); - ret = EINVAL; - goto done; - } - - if (strcmp(oc, SYSDB_USER_CLASS) == 0) { - key.str = discard_const(ldb_dn_get_linearized(members[c]->dn)); - if (key.str == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "ldb_dn_get_linearized failed.\n"); - ret = EFAULT; - goto done; - } - - value.type = HASH_VALUE_PTR; - value.ptr = members[c]; - - hret = hash_enter(users, &key, &value); - if (hret != HASH_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed.\n"); - ret = ENOMEM; - goto done; - } - - } else if (strcmp(oc, SYSDB_GROUP_CLASS) == 0) { - key.str = discard_const(ldb_dn_get_linearized(members[c]->dn)); - if (key.str == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "ldb_dn_get_linearized failed.\n"); - ret = EFAULT; - goto done; - } - - hret = hash_lookup(groups, &key, &value); - if (hret == HASH_SUCCESS) { - /* Already seen this group, skipping */ - continue; - } else if (hret != HASH_ERROR_KEY_NOT_FOUND) { - DEBUG(SSSDBG_OP_FAILURE, "hash_lookup failed.\n"); - ret = EFAULT; - goto done; - } - - /* group was not found in the hash, adding and processing it */ - - value.type = HASH_VALUE_PTR; - value.ptr = members[c]; - - hret = hash_enter(groups, &key, &value); - if (hret != HASH_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed.\n"); - ret = ENOMEM; - goto done; - } - - ret = sysdb_get_user_members_recursively_int(mem_ctx, dom, - members[c]->dn, - users, groups); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "sysdb_get_user_members_recursively_int failed.\n"); - goto done; - } - - } else { - DEBUG(SSSDBG_CRIT_FAILURE, - "Unexpected objectclass [%s] in object [%s].\n", oc, - ldb_dn_get_linearized(members[c]->dn)); - ret = EINVAL; - goto done; - } - } - - ret = EOK; - -done: - - return ret; -} - errno_t sysdb_get_user_members_recursively(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, struct ldb_dn *group_dn, struct ldb_result **members) { TALLOC_CTX *tmp_ctx; - hash_table_t *users; - hash_table_t *groups; int ret; - int hret; - size_t c; - unsigned long count; + size_t count; struct ldb_result *res; - hash_value_t *values; + struct ldb_dn *base_dn; + char *filter; + const char *attrs[] = SYSDB_PW_ATTRS; + struct ldb_message **msgs; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } - ret = sss_hash_create(tmp_ctx, 10, &users); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "sss_hash_create failed.\n"); + base_dn = sysdb_base_dn(dom->sysdb, tmp_ctx); + if (base_dn == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "sysdb_base_dn failed.\n"); + ret = ENOMEM; goto done; } - ret = sss_hash_create(tmp_ctx, 10, &groups); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "sss_hash_create failed.\n"); + filter = talloc_asprintf(tmp_ctx, "(&("SYSDB_UC")("SYSDB_MEMBEROF"=%s))", + ldb_dn_get_linearized(group_dn)); + if (filter == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); + ret = ENOMEM; goto done; } - ret = sysdb_get_user_members_recursively_int(tmp_ctx, dom, group_dn, users, - groups); - if (ret != EOK) { - if (ret != ENOENT) { - DEBUG(SSSDBG_OP_FAILURE, - "sysdb_get_user_members_recursively_int failed.\n"); - } - goto done; - } + ret = sysdb_search_entry(tmp_ctx, dom->sysdb, base_dn, LDB_SCOPE_SUBTREE, + filter, attrs, &count, &msgs); res = talloc_zero(tmp_ctx, struct ldb_result); if (res == NULL) { @@ -4872,36 +4755,8 @@ errno_t sysdb_get_user_members_recursively(TALLOC_CTX *mem_ctx, goto done; } - hret = hash_values(users, &count, &values); - if (hret != HASH_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, "hash_values failed.\n"); - ret = ENOMEM; - goto done; - } - if (count <= UINTMAX_MAX) { - res->count = count; - } else { - DEBUG(SSSDBG_CRIT_FAILURE, "More then [%"PRIuMAX"] results.\n", - UINTMAX_MAX); - ret = EINVAL; - goto done; - } - if (res->count == 0) { - ret = EOK; - goto done; - } - - res->msgs = talloc_array(res, struct ldb_message *, res->count); - if (res->msgs == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n"); - ret = ENOMEM; - goto done; - } - - for (c = 0; c < res->count; c++) { - res->msgs[c] = (struct ldb_message *) talloc_steal(res->msgs, - values[c].ptr); - } + res->count = count; + res->msgs = talloc_steal(res, msgs); ret = EOK; diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c index 892bebe63816a0dac0317dd1fd0135523f0e64d7..6fa167aa464d5685c5fe6d11e792006cc1b0075c 100644 --- a/src/tests/cmocka/test_nss_srv.c +++ b/src/tests/cmocka/test_nss_srv.c @@ -1342,8 +1342,8 @@ static int test_nss_getgrnam_members_check(uint32_t status, int ret; uint32_t nmem; struct group gr; - const char *exp_members[] = { testmember2.pw_name, - testmember1.pw_name }; + const char *exp_members[] = { testmember1.pw_name, + testmember2.pw_name }; struct group expected = { .gr_gid = testgroup_members.gr_gid, .gr_name = testgroup_members.gr_name, @@ -1429,10 +1429,10 @@ static int test_nss_getgrnam_members_check_fqdn(uint32_t status, assert_non_null(tmp_ctx); exp_members[0] = sss_tc_fqname(tmp_ctx, nss_test_ctx->tctx->dom->names, - nss_test_ctx->tctx->dom, testmember2.pw_name); + nss_test_ctx->tctx->dom, testmember1.pw_name); assert_non_null(exp_members[0]); exp_members[1] = sss_tc_fqname(tmp_ctx, nss_test_ctx->tctx->dom->names, - nss_test_ctx->tctx->dom, testmember1.pw_name); + nss_test_ctx->tctx->dom, testmember2.pw_name); assert_non_null(exp_members[1]); expected.gr_name = sss_tc_fqname(tmp_ctx, @@ -1619,11 +1619,11 @@ static int test_nss_getgrnam_check_mix_dom(uint32_t status, tmp_ctx = talloc_new(nss_test_ctx); assert_non_null(tmp_ctx); - exp_members[0] = testmember2.pw_name; + exp_members[0] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names, + nss_test_ctx->subdom, submember1.pw_name); + assert_non_null(exp_members[0]); exp_members[1] = testmember1.pw_name; - exp_members[2] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names, - nss_test_ctx->subdom, submember1.pw_name); - assert_non_null(exp_members[2]); + exp_members[2] = testmember2.pw_name; assert_int_equal(status, EOK); @@ -1682,14 +1682,14 @@ static int test_nss_getgrnam_check_mix_dom_fqdn(uint32_t status, tmp_ctx = talloc_new(nss_test_ctx); assert_non_null(tmp_ctx); - exp_members[0] = sss_tc_fqname(tmp_ctx, nss_test_ctx->tctx->dom->names, - nss_test_ctx->tctx->dom, testmember2.pw_name); + exp_members[0] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names, + nss_test_ctx->subdom, submember1.pw_name); assert_non_null(exp_members[0]); exp_members[1] = sss_tc_fqname(tmp_ctx, nss_test_ctx->tctx->dom->names, nss_test_ctx->tctx->dom, testmember1.pw_name); assert_non_null(exp_members[1]); - exp_members[2] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names, - nss_test_ctx->subdom, submember1.pw_name); + exp_members[2] = sss_tc_fqname(tmp_ctx, nss_test_ctx->tctx->dom->names, + nss_test_ctx->tctx->dom, testmember2.pw_name); assert_non_null(exp_members[2]); expected.gr_name = sss_tc_fqname(tmp_ctx, @@ -1752,16 +1752,16 @@ static int test_nss_getgrnam_check_mix_subdom(uint32_t status, tmp_ctx = talloc_new(nss_test_ctx); assert_non_null(tmp_ctx); - exp_members[1] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names, + exp_members[0] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names, nss_test_ctx->subdom, submember1.pw_name); assert_non_null(exp_members[1]); - exp_members[2] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names, + exp_members[1] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names, nss_test_ctx->subdom, submember2.pw_name); assert_non_null(exp_members[2]); /* Important: this member is from a non-qualified domain, so his name will * not be qualified either */ - exp_members[0] = testmember1.pw_name; + exp_members[2] = testmember1.pw_name; expected.gr_name = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names, nss_test_ctx->subdom, testsubdomgroup.gr_name); -- 2.1.0