endpoint server for the samr pipe
Copyright (C) Andrew Tridgell 2004
+ Copyright (C) Volker Lendecke 2004
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
return NT_STATUS_OK;
}
+/*
+ return DomInfo1
+*/
+static NTSTATUS samr_info_DomInfo1(struct samr_domain_state *state,
+ TALLOC_CTX *mem_ctx,
+ struct samr_DomInfo1 *info)
+{
+ const char * const attrs[] = { "minPwdLength", "pwdHistoryLength",
+ "pwdProperties", "maxPwdAge",
+ "minPwdAge", NULL };
+ int ret;
+ struct ldb_message **res;
+
+ ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs,
+ "dn=%s", state->domain_dn);
+ if (ret != 1) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ info->min_password_length =
+ samdb_result_uint(res[0], "minPwdLength", 0);
+ info->password_history_length =
+ samdb_result_uint(res[0], "pwdHistoryLength", 0);
+ info->password_properties =
+ samdb_result_uint(res[0], "pwdProperties", 0);
+ info->max_password_age =
+ samdb_result_int64(res[0], "maxPwdAge", 0);
+ info->min_password_age =
+ samdb_result_int64(res[0], "minPwdAge", 0);
+
+ return NT_STATUS_OK;
+}
+
/*
return DomInfo2
*/
ZERO_STRUCTP(r->out.info);
switch (r->in.level) {
+ case 1:
+ return samr_info_DomInfo1(d_state, mem_ctx,
+ &r->out.info->info1);
case 2:
return samr_info_DomInfo2(d_state, mem_ctx, &r->out.info->info2);
}
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);
+ if (domain_sid == NULL)
+ return NT_STATUS_NO_MEMORY;
/* search for all domain groups in this domain. This could possibly be
cached and resumed based on resume_key */
- ldb_cnt = samdb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn,
- &res, attrs,
- "(&(grouptype=%s)(objectclass=group))",
- ldb_hexstr(mem_ctx,
- GTYPE_SECURITY_GLOBAL_GROUP));
+ ldb_cnt = samdb_search_domain(d_state->sam_ctx, mem_ctx,
+ d_state->domain_dn, &res, attrs,
+ domain_sid,
+ "(&(grouptype=%s)(objectclass=group))",
+ ldb_hexstr(mem_ctx,
+ GTYPE_SECURITY_GLOBAL_GROUP));
if (ldb_cnt == -1) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
}
count = 0;
- domain_sid = dom_sid_parse_talloc(mem_ctx, d_state->domain_sid);
for (i=0;i<ldb_cnt;i++) {
- struct dom_sid *alias_sid;
+ struct dom_sid *group_sid;
- alias_sid = samdb_result_dom_sid(mem_ctx, res[i],
+ group_sid = samdb_result_dom_sid(mem_ctx, res[i],
"objectSid");
-
- if (alias_sid == NULL)
+ if (group_sid == NULL)
continue;
- if (!dom_sid_in_domain(domain_sid, alias_sid))
- continue;
-
entries[count].idx =
- alias_sid->sub_auths[alias_sid->num_auths-1];
+ group_sid->sub_auths[group_sid->num_auths-1];
entries[count].name.string =
samdb_result_string(res[i], "sAMAccountName", "");
count += 1;
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);
+ if (domain_sid == NULL)
+ return NT_STATUS_NO_MEMORY;
/* search for all domain groups in this domain. This could possibly be
cached and resumed based on resume_key */
- ldb_cnt = samdb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn,
- &res, attrs,
- "(&(|(grouptype=%s)(grouptype=%s)))"
- "(objectclass=group))",
- ldb_hexstr(mem_ctx,
- GTYPE_SECURITY_BUILTIN_LOCAL_GROUP),
- ldb_hexstr(mem_ctx,
- GTYPE_SECURITY_DOMAIN_LOCAL_GROUP));
+ ldb_cnt = samdb_search_domain(d_state->sam_ctx, mem_ctx,
+ d_state->domain_dn,
+ &res, attrs, domain_sid,
+ "(&(|(grouptype=%s)(grouptype=%s)))"
+ "(objectclass=group))",
+ ldb_hexstr(mem_ctx,
+ GTYPE_SECURITY_BUILTIN_LOCAL_GROUP),
+ ldb_hexstr(mem_ctx,
+ GTYPE_SECURITY_DOMAIN_LOCAL_GROUP));
if (ldb_cnt == -1) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
}
count = 0;
- domain_sid = dom_sid_parse_talloc(mem_ctx, d_state->domain_sid);
for (i=0;i<ldb_cnt;i++) {
struct dom_sid *alias_sid;
if (alias_sid == NULL)
continue;
- if (!dom_sid_in_domain(domain_sid, alias_sid))
- continue;
-
entries[count].idx =
alias_sid->sub_auths[alias_sid->num_auths-1];
entries[count].name.string =
static NTSTATUS samr_GetAliasMembership(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct samr_GetAliasMembership *r)
{
- DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+ struct dcesrv_handle *h;
+ struct samr_domain_state *d_state;
+ struct ldb_message **res;
+ struct dom_sid *domain_sid;
+ int i, count = 0;
+
+ DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
+
+ d_state = h->data;
+
+ if (r->in.sids->num_sids > 0) {
+ const char *filter;
+ const char * const attrs[2] = { "objectSid", NULL };
+
+ filter = talloc_asprintf(mem_ctx,
+ "(&(|(grouptype=%s)(grouptype=%s))"
+ "(objectclass=group)(|",
+ ldb_hexstr(mem_ctx,
+ GTYPE_SECURITY_BUILTIN_LOCAL_GROUP),
+ ldb_hexstr(mem_ctx,
+ GTYPE_SECURITY_DOMAIN_LOCAL_GROUP));
+ if (filter == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ for (i=0; i<r->in.sids->num_sids; i++) {
+ const char *sidstr, *memberdn;
+
+ sidstr = dom_sid_string(mem_ctx,
+ r->in.sids->sids[i].sid);
+ if (sidstr == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ memberdn = samdb_search_string(d_state->sam_ctx,
+ mem_ctx, NULL, "dn",
+ "(objectSid=%s)",
+ sidstr);
+
+ if (memberdn == NULL)
+ continue;
+
+ filter = talloc_asprintf(mem_ctx, "%s(member=%s)",
+ filter, memberdn);
+ if (filter == NULL)
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ domain_sid = dom_sid_parse_talloc(mem_ctx,
+ d_state->domain_sid);
+ if (domain_sid == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ count = samdb_search_domain(d_state->sam_ctx, mem_ctx,
+ d_state->domain_dn, &res, attrs,
+ domain_sid, "%s))", filter);
+ if (count < 0)
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ r->out.rids->count = 0;
+ r->out.rids->ids = talloc_array_p(mem_ctx, uint32_t, count);
+ if (r->out.rids->ids == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ for (i=0; i<count; i++) {
+ struct dom_sid *alias_sid;
+
+ alias_sid = samdb_result_dom_sid(mem_ctx, res[i], "objectSid");
+
+ if (alias_sid == NULL) {
+ DEBUG(0, ("Could not find objectSid\n"));
+ continue;
+ }
+
+ r->out.rids->ids[r->out.rids->count] =
+ alias_sid->sub_auths[alias_sid->num_auths-1];
+ r->out.rids->count += 1;
+ }
+
+ return NT_STATUS_OK;
}
if (ret != 1)
return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ r->out.sids->num_sids = 0;
+ r->out.sids->sids = NULL;
+
el = ldb_msg_find_element(msgs[0], "member");
if (el != NULL) {
if (sids[i].sid == NULL)
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
+ r->out.sids->num_sids = el->num_values;
+ r->out.sids->sids = sids;
}
- r->out.sids->num_sids = el->num_values;
- r->out.sids->sids = sids;
-
return NT_STATUS_OK;
}
static NTSTATUS samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct samr_GetGroupsForUser *r)
{
- DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+ struct dcesrv_handle *h;
+ struct samr_account_state *a_state;
+ struct samr_domain_state *d_state;
+ struct ldb_message **res;
+ struct dom_sid *domain_sid;
+ const char * const attrs[2] = { "objectSid", NULL };
+ struct samr_RidArray *array;
+ int count;
+
+ DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER);
+
+ a_state = h->data;
+ d_state = a_state->domain_state;
+ domain_sid = dom_sid_parse_talloc(mem_ctx, d_state->domain_sid);
+ if (domain_sid == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ count = samdb_search_domain(a_state->sam_ctx, mem_ctx, NULL, &res,
+ attrs, domain_sid,
+ "(&(member=%s)(grouptype=%s)(objectclass=group))",
+ a_state->account_dn,
+ ldb_hexstr(mem_ctx,
+ GTYPE_SECURITY_GLOBAL_GROUP));
+ if (count < 0)
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+
+ array = talloc_p(mem_ctx, struct samr_RidArray);
+ if (array == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ array->count = 0;
+ array->rid = NULL;
+
+ if (count > 0) {
+ int i;
+ array->rid = talloc_array_p(mem_ctx, struct samr_RidType,
+ count);
+
+ if (array->rid == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ for (i=0; i<count; i++) {
+ struct dom_sid *group_sid;
+
+ group_sid = samdb_result_dom_sid(mem_ctx, res[i],
+ "objectSid");
+ if (group_sid == NULL) {
+ DEBUG(0, ("Couldn't find objectSid attrib\n"));
+ continue;
+ }
+
+ array->rid[array->count].rid =
+ group_sid->sub_auths[group_sid->num_auths-1];
+ array->rid[array->count].type = 7;
+ array->count += 1;
+ }
+ }
+
+ r->out.rids = array;
+
+ return NT_STATUS_OK;
}
return NT_STATUS_INVALID_INFO_CLASS;
}
- /* search for all domain groups in this domain. This could possibly be
- cached and resumed based on resume_key */
- ldb_cnt = samdb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn,
- &res, attrs, "%s", filter);
+ domain_sid = dom_sid_parse_talloc(mem_ctx, d_state->domain_sid);
+ if (domain_sid == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ /* search for all requested objects in this domain. This could
+ possibly be cached and resumed based on resume_key */
+ ldb_cnt = samdb_search_domain(d_state->sam_ctx, mem_ctx,
+ d_state->domain_dn, &res, attrs,
+ domain_sid, "%s", filter);
if (ldb_cnt == -1) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
return NT_STATUS_NO_MEMORY;
count = 0;
- domain_sid = dom_sid_parse_talloc(mem_ctx, d_state->domain_sid);
for (i=0; i<ldb_cnt; i++) {
struct dom_sid *objectsid;
if (objectsid == NULL)
continue;
- if (!dom_sid_in_domain(domain_sid, objectsid))
- continue;
-
switch(r->in.level) {
case 1:
entriesGeneral[count].idx = count;
static NTSTATUS samr_QueryDisplayInfo2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct samr_QueryDisplayInfo2 *r)
{
- DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+ struct samr_QueryDisplayInfo q;
+ NTSTATUS result;
+
+ q.in.domain_handle = r->in.domain_handle;
+ q.in.level = r->in.level;
+ q.in.start_idx = r->in.start_idx;
+ q.in.max_entries = r->in.max_entries;
+ q.in.buf_size = r->in.buf_size;
+
+ result = samr_QueryDisplayInfo(dce_call, mem_ctx, &q);
+
+ r->out.total_size = q.out.total_size;
+ r->out.returned_size = q.out.returned_size;
+ r->out.info = q.out.info;
+
+ return result;
}