summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/common/util_samr.c67
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.c133
2 files changed, 120 insertions, 80 deletions
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 <member_el->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;
+}
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index 1e5686ae72..0fef07a909 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -2145,68 +2145,58 @@ static NTSTATUS dcesrv_samr_DeleteGroupMember(struct dcesrv_call_state *dce_call
static NTSTATUS dcesrv_samr_QueryGroupMember(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct samr_QueryGroupMember *r)
{
+ NTSTATUS status;
struct dcesrv_handle *h;
struct samr_account_state *a_state;
- struct ldb_message **res;
- struct ldb_message_element *el;
struct samr_RidTypeArray *array;
- const char * const attrs[2] = { "member", NULL };
- int ret;
+ size_t i;
+ struct dom_sid *members_as_sids;
+ size_t num_members;
+ struct dom_sid *dom_sid;
DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP);
a_state = h->data;
- /* pull the member attribute */
- ret = gendb_search_dn(a_state->sam_ctx, mem_ctx,
- a_state->account_dn, &res, attrs);
+ dom_sid = a_state->domain_state->domain_sid;
+ status = dsdb_enum_group_mem(a_state->sam_ctx, mem_ctx, a_state->account_dn, &members_as_sids, &num_members);
- if (ret != 1) {
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
- array = talloc(mem_ctx, struct samr_RidTypeArray);
+ array = talloc_zero(mem_ctx, struct samr_RidTypeArray);
if (array == NULL)
return NT_STATUS_NO_MEMORY;
- ZERO_STRUCTP(array);
-
- el = ldb_msg_find_element(res[0], "member");
-
- if (el != NULL) {
- unsigned int i;
-
- array->count = el->num_values;
+ if (num_members == 0) {
+ *r->out.rids = array;
- array->rids = talloc_array(mem_ctx, uint32_t,
- el->num_values);
- if (array->rids == NULL)
- return NT_STATUS_NO_MEMORY;
-
- array->types = talloc_array(mem_ctx, uint32_t,
- el->num_values);
- if (array->types == NULL)
- return NT_STATUS_NO_MEMORY;
-
- for (i=0; i<el->num_values; i++) {
- struct ldb_message **res2;
- const char * const attrs2[2] = { "objectSid", NULL };
- ret = gendb_search_dn(a_state->sam_ctx, mem_ctx,
- ldb_dn_from_ldb_val(mem_ctx, a_state->sam_ctx, &el->values[i]),
- &res2, attrs2);
- if (ret != 1)
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ return NT_STATUS_OK;
+ }
- array->rids[i] =
- samdb_result_rid_from_sid(mem_ctx, res2[0],
- "objectSid", 0);
+ array->count = 0;
+ array->rids = talloc_array(array, uint32_t,
+ num_members);
+ if (array->rids == NULL)
+ return NT_STATUS_NO_MEMORY;
- if (array->rids[i] == 0)
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ array->types = talloc_array(array, uint32_t,
+ num_members);
+ if (array->types == NULL)
+ return NT_STATUS_NO_MEMORY;
- array->types[i] = 7; /* RID type of some kind, not sure what the value means. */
+ for (i=0; i<num_members; i++) {
+ if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
+ continue;
}
+ status = dom_sid_split_rid(NULL, &members_as_sids[i], NULL, &array->rids[array->count]);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ array->types[array->count] = 7; /* RID type of some kind, not sure what the value means. */
+ array->count++;
}
*r->out.rids = array;
@@ -2561,60 +2551,43 @@ static NTSTATUS dcesrv_samr_GetMembersInAlias(struct dcesrv_call_state *dce_call
struct dcesrv_handle *h;
struct samr_account_state *a_state;
struct samr_domain_state *d_state;
- struct ldb_message **msgs;
struct lsa_SidPtr *sids;
- struct ldb_message_element *el;
- const char * const attrs[2] = { "member", NULL};
- int ret;
-
+ size_t i;
+ struct dom_sid *members;
+ size_t num_members;
+ NTSTATUS status;
DCESRV_PULL_HANDLE(h, r->in.alias_handle, SAMR_HANDLE_ALIAS);
a_state = h->data;
d_state = a_state->domain_state;
- ret = gendb_search_dn(d_state->sam_ctx, mem_ctx,
- a_state->account_dn, &msgs, attrs);
-
- if (ret == -1) {
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- } else if (ret == 0) {
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- } else if (ret != 1) {
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ status = dsdb_enum_group_mem(d_state->sam_ctx, mem_ctx,
+ a_state->account_dn, &members, &num_members);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
- r->out.sids->num_sids = 0;
r->out.sids->sids = NULL;
- el = ldb_msg_find_element(msgs[0], "member");
-
- if (el != NULL) {
- unsigned int i;
-
- sids = talloc_array(mem_ctx, struct lsa_SidPtr,
- el->num_values);
+ if (num_members == 0) {
+ return NT_STATUS_OK;
+ }
- if (sids == NULL)
- return NT_STATUS_NO_MEMORY;
+ sids = talloc_array(mem_ctx, struct lsa_SidPtr,
+ num_members);
- for (i=0; i<el->num_values; i++) {
- struct ldb_message **msgs2;
- const char * const attrs2[2] = { "objectSid", NULL };
- ret = gendb_search_dn(a_state->sam_ctx, mem_ctx,
- ldb_dn_from_ldb_val(mem_ctx, a_state->sam_ctx, &el->values[i]),
- &msgs2, attrs2);
- if (ret != 1)
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ if (sids == NULL)
+ return NT_STATUS_NO_MEMORY;
- sids[i].sid = samdb_result_dom_sid(mem_ctx, msgs2[0],
- "objectSid");
+ for (i=0; i<num_members; i++) {
- if (sids[i].sid == NULL)
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ sids[i].sid = dom_sid_dup(sids, &members[i]);
+ if (sids[i].sid == NULL) {
+ return NT_STATUS_NO_MEMORY;
}
- r->out.sids->num_sids = el->num_values;
- r->out.sids->sids = sids;
}
+ r->out.sids->num_sids = num_members;
+ r->out.sids->sids = sids;
return NT_STATUS_OK;
}