mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
r4414: Various bits&pieces:
* Implement samr_search_domain, filter out all elements with no "objectSid" attribute and all objects outside a specified domain sid. * Minor cleanups in dcerpc_samr.c due to that. * Implement srvsvc_NetSrvGetInfo level 100. A quick hack to get usrmgr.exe one step further. * Same for samr_info_DomInfo1. Volker
This commit is contained in:
parent
b9284c16dc
commit
cdec896113
@ -54,6 +54,49 @@ int samdb_search(void *ctx,
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
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
|
||||
*/
|
||||
|
@ -340,6 +340,39 @@ static NTSTATUS samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *
|
||||
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
|
||||
*/
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user