From c6ffd884d95eadf634b2e596d8fe5cb952f52ee2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 21 May 2010 08:42:21 +1000 Subject: s4:samr Push most of samr_QueryGroupMember into a helper function This is a rewrite of the group membership lookup code, using the stored extended DNs to avoid doing the lookup into each member to find the SID By splitting this out, the logic is able to be shared, rather than copied, into a passdb wrapper. Andrew Bartlett --- source4/dsdb/common/util_samr.c | 67 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'source4/dsdb/common/util_samr.c') diff --git a/source4/dsdb/common/util_samr.c b/source4/dsdb/common/util_samr.c index 58d5b3fd21..3faf513e37 100644 --- a/source4/dsdb/common/util_samr.c +++ b/source4/dsdb/common/util_samr.c @@ -399,3 +399,70 @@ NTSTATUS dsdb_add_domain_alias(struct ldb_context *ldb, return NT_STATUS_OK; } +/* Return the members of this group (which may be a domain group or an alias) */ +NTSTATUS dsdb_enum_group_mem(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *dn, + struct dom_sid **members_out, + size_t *pnum_members) +{ + struct ldb_message *msg; + int i, ret; + struct dom_sid *members; + struct ldb_message_element *member_el; + const char *attrs[] = { "member", NULL }; + NTSTATUS status; + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); + + ret = dsdb_search_one(ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, + DSDB_SEARCH_SHOW_EXTENDED_DN, NULL); + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + talloc_free(tmp_ctx); + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + if (ret != LDB_SUCCESS) { + DEBUG(1, ("dsdb_enum_group_mem: dsdb_search for %s failed: %s\n", + ldb_dn_get_linearized(dn), ldb_errstring(ldb))); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + member_el = ldb_msg_find_element(msg, "member"); + if (!member_el) { + *members_out = NULL; + *pnum_members = 0; + talloc_free(tmp_ctx); + return NT_STATUS_OK; + } + + members = talloc_array(mem_ctx, struct dom_sid, member_el->num_values); + if (members == NULL) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i num_values; i++) { + struct ldb_dn *member_dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, + &member_el->values[i]); + if (!member_dn || !ldb_dn_validate(member_dn)) { + DEBUG(1, ("Could not parse %*.*s as a DN\n", + (int)member_el->values[i].length, + (int)member_el->values[i].length, + (const char *)member_el->values[i].data)); + talloc_free(tmp_ctx); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + status = dsdb_get_extended_dn_sid(member_dn, &members[i], "SID"); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Could find SID attribute on extended DN %s\n", + ldb_dn_get_extended_linearized(tmp_ctx, dn, 1))); + talloc_free(tmp_ctx); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + } + + *members_out = talloc_steal(mem_ctx, members); + *pnum_members = member_el->num_values; + talloc_free(tmp_ctx); + return NT_STATUS_OK; +} -- cgit