diff options
-rw-r--r-- | source4/dsdb/samdb/samdb.c | 43 | ||||
-rw-r--r-- | source4/rpc_server/samr/dcesrv_samr.c | 164 | ||||
-rw-r--r-- | source4/rpc_server/srvsvc/dcesrv_srvsvc.c | 11 |
3 files changed, 160 insertions, 58 deletions
diff --git a/source4/dsdb/samdb/samdb.c b/source4/dsdb/samdb/samdb.c index 934e6c240f..8188bf2016 100644 --- a/source4/dsdb/samdb/samdb.c +++ b/source4/dsdb/samdb/samdb.c @@ -55,6 +55,49 @@ int samdb_search(void *ctx, } /* + search the sam for the specified attributes in a specific domain, filter on + objectSid being in domain_sid. +*/ +int samdb_search_domain(void *ctx, + TALLOC_CTX *mem_ctx, + const char *basedn, + struct ldb_message ***res, + const char * const *attrs, + const struct dom_sid *domain_sid, + const char *format, ...) _PRINTF_ATTRIBUTE(7,8) +{ + struct ldb_wrap *sam_ctx = ctx; + va_list ap; + int i, count; + + va_start(ap, format); + count = gendb_search_v(sam_ctx->ldb, mem_ctx, basedn, res, attrs, + format, ap); + va_end(ap); + + i=0; + + while (i<count) { + struct dom_sid *entry_sid; + + entry_sid = samdb_result_dom_sid(mem_ctx, (*res)[i], + "objectSid"); + + if ((entry_sid == NULL) || + (!dom_sid_in_domain(domain_sid, entry_sid))) { + + /* Delete that entry from the result set */ + (*res)[i] = (*res)[count-1]; + count -= 1; + continue; + } + i += 1; + } + + return count; +} + +/* free up a search result */ int samdb_search_free(void *ctx, diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 216feaa52a..d16afa2802 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -341,6 +341,39 @@ static NTSTATUS samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX * } /* + 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 */ static NTSTATUS samr_info_DomInfo2(struct samr_domain_state *state, TALLOC_CTX *mem_ctx, @@ -399,6 +432,9 @@ static NTSTATUS samr_QueryDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_ 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); } @@ -568,14 +604,19 @@ static NTSTATUS samr_EnumDomainGroups(struct dcesrv_call_state *dce_call, TALLOC 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; } @@ -590,22 +631,17 @@ static NTSTATUS samr_EnumDomainGroups(struct dcesrv_call_state *dce_call, TALLOC } 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; @@ -1069,17 +1105,22 @@ static NTSTATUS samr_EnumDomainAliases(struct dcesrv_call_state *dce_call, TALLO 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; } @@ -1094,7 +1135,6 @@ static NTSTATUS samr_EnumDomainAliases(struct dcesrv_call_state *dce_call, TALLO } 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; @@ -1105,9 +1145,6 @@ static NTSTATUS samr_EnumDomainAliases(struct dcesrv_call_state *dce_call, TALLO 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 = @@ -1201,9 +1238,14 @@ static NTSTATUS samr_GetAliasMembership(struct dcesrv_call_state *dce_call, TALL return NT_STATUS_NO_MEMORY; } - count = 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; + + 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; } @@ -1213,10 +1255,6 @@ static NTSTATUS samr_GetAliasMembership(struct dcesrv_call_state *dce_call, TALL if (r->out.rids->ids == 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; - for (i=0; i<count; i++) { struct dom_sid *alias_sid; @@ -1227,9 +1265,6 @@ static NTSTATUS samr_GetAliasMembership(struct dcesrv_call_state *dce_call, TALL continue; } - if (!dom_sid_in_domain(domain_sid, alias_sid)) - continue; - r->out.rids->ids[r->out.rids->count] = alias_sid->sub_auths[alias_sid->num_auths-1]; r->out.rids->count += 1; @@ -2801,6 +2836,7 @@ static NTSTATUS samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, TALLOC 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; @@ -2809,11 +2845,16 @@ static NTSTATUS samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, TALLOC 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(a_state->sam_ctx, mem_ctx, NULL, &res, attrs, - "(&(member=%s)(grouptype=%s)(objectclass=group))", - a_state->account_dn, - ldb_hexstr(mem_ctx, GTYPE_SECURITY_GLOBAL_GROUP)); + 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; @@ -2826,14 +2867,10 @@ static NTSTATUS samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, TALLOC if (count > 0) { int i; - struct dom_sid *domain_sid; - - domain_sid = dom_sid_parse_talloc(mem_ctx, - d_state->domain_sid); array->rid = talloc_array_p(mem_ctx, struct samr_RidType, count); - if ((domain_sid == NULL) || (array->rid == NULL)) + if (array->rid == NULL) return NT_STATUS_NO_MEMORY; for (i=0; i<count; i++) { @@ -2846,9 +2883,6 @@ static NTSTATUS samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, TALLOC continue; } - if (!dom_sid_in_domain(domain_sid, group_sid)) - continue; - array->rid[array->count].rid = group_sid->sub_auths[group_sid->num_auths-1]; array->rid[array->count].type = 7; @@ -2908,10 +2942,15 @@ static NTSTATUS samr_QueryDisplayInfo(struct dcesrv_call_state *dce_call, TALLOC 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; } @@ -2944,7 +2983,6 @@ static NTSTATUS samr_QueryDisplayInfo(struct dcesrv_call_state *dce_call, TALLOC 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; @@ -2954,9 +2992,6 @@ static NTSTATUS samr_QueryDisplayInfo(struct dcesrv_call_state *dce_call, TALLOC if (objectsid == NULL) continue; - if (!dom_sid_in_domain(domain_sid, objectsid)) - continue; - switch(r->in.level) { case 1: entriesGeneral[count].idx = count; @@ -3167,7 +3202,22 @@ static NTSTATUS samr_QueryUserInfo2(struct dcesrv_call_state *dce_call, TALLOC_C 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; } diff --git a/source4/rpc_server/srvsvc/dcesrv_srvsvc.c b/source4/rpc_server/srvsvc/dcesrv_srvsvc.c index 8909fc17a7..12dcf5b738 100644 --- a/source4/rpc_server/srvsvc/dcesrv_srvsvc.c +++ b/source4/rpc_server/srvsvc/dcesrv_srvsvc.c @@ -666,7 +666,16 @@ static WERROR srvsvc_NetShareCheck(struct dcesrv_call_state *dce_call, TALLOC_CT static WERROR srvsvc_NetSrvGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct srvsvc_NetSrvGetInfo *r) { - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); + if (r->in.level != 100) + return WERR_UNKNOWN_LEVEL; + + r->out.info.info100 = talloc_p(mem_ctx, struct srvsvc_NetSrvInfo100); + if (r->out.info.info100 == NULL) + return WERR_NOMEM; + + r->out.info.info100->platform_id = 500; /* W2k3 returns this */ + r->out.info.info100->server_unc = lp_netbios_name(); + return WERR_OK; } |