summaryrefslogtreecommitdiff
path: root/source4/rpc_server
diff options
context:
space:
mode:
Diffstat (limited to 'source4/rpc_server')
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.c59
1 files changed, 58 insertions, 1 deletions
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index d16afa2802..0daf33f5d9 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -3160,7 +3160,64 @@ static NTSTATUS samr_GetUserPwInfo(struct dcesrv_call_state *dce_call, TALLOC_CT
static NTSTATUS samr_RemoveMemberFromForeignDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct samr_RemoveMemberFromForeignDomain *r)
{
- DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+ struct dcesrv_handle *h;
+ struct samr_domain_state *d_state;
+ struct dom_sid *domain_sid;
+ const char *membersid, *memberdn;
+ struct ldb_message **res;
+ const char * const attrs[3] = { "dn", "objectSid", NULL };
+ int i, count;
+
+ DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
+
+ d_state = h->data;
+
+ domain_sid = dom_sid_parse_talloc(mem_ctx, d_state->domain_sid);
+ membersid = dom_sid_string(mem_ctx, r->in.sid);
+ if ((domain_sid == NULL) || (membersid == NULL))
+ return NT_STATUS_NO_MEMORY;
+
+ memberdn = samdb_search_string(d_state->sam_ctx, mem_ctx, NULL,
+ "dn", "(objectSid=%s)", membersid);
+ if (memberdn == NULL)
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+
+ /* TODO: Does this call only remove alias members, or does it do this
+ * for domain groups as well? */
+
+ count = samdb_search_domain(d_state->sam_ctx, mem_ctx,
+ d_state->domain_dn, &res, attrs,
+ domain_sid,
+ "(&(member=%s)(objectClass=group)"
+ "(|(groupType=%s)(groupType=%s)))",
+ memberdn,
+ ldb_hexstr(mem_ctx,
+ GTYPE_SECURITY_BUILTIN_LOCAL_GROUP),
+ ldb_hexstr(mem_ctx,
+ GTYPE_SECURITY_DOMAIN_LOCAL_GROUP));
+
+ if (count < 0)
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+
+ for (i=0; i<count; i++) {
+ struct ldb_message mod;
+ ZERO_STRUCT(mod);
+
+ mod.dn = talloc_reference(mem_ctx,
+ samdb_result_string(res[i], "dn",
+ NULL));
+ if (mod.dn == NULL)
+ continue;
+
+ if (samdb_msg_add_delval(d_state->sam_ctx, mem_ctx, &mod,
+ "member", memberdn) != 0)
+ return NT_STATUS_NO_MEMORY;
+
+ if (samdb_modify(d_state->sam_ctx, mem_ctx, &mod) != 0)
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ return NT_STATUS_OK;
}