diff options
-rw-r--r-- | source4/rpc_server/lsa/dcesrv_lsa.c | 215 |
1 files changed, 179 insertions, 36 deletions
diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 8dee8f189d..adfbda5504 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -396,16 +396,6 @@ static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX } -/* - lsa_LookupNames -*/ -static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct lsa_LookupNames *r) -{ - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); -} - - /* return the authority name and authority sid, given a sid */ @@ -433,6 +423,45 @@ static NTSTATUS lsa_authority_name(struct lsa_policy_state *state, return NT_STATUS_OK; } +static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, + struct dom_sid *sid, + struct lsa_RefDomainList *domains) +{ + NTSTATUS status; + const char *authority_name; + struct dom_sid *authority_sid; + int i; + + /* work out the authority name */ + status = lsa_authority_name(state, mem_ctx, sid, + &authority_name, &authority_sid); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* see if we've already done this authority name */ + for (i=0;i<domains->count;i++) { + if (strcmp(authority_name, domains->domains[i].name.string) == 0) { + break; + } + } + if (i == domains->count) { + domains->domains = talloc_realloc_p(domains, + domains->domains, + struct lsa_TrustInformation, + domains->count+1); + if (domains->domains == NULL) { + return NT_STATUS_NO_MEMORY; + } + domains->domains[i].name.string = authority_name; + domains->domains[i].sid = authority_sid; + domains->count++; + } + + return NT_STATUS_OK; +} + + /* lsa_LookupSids2 */ @@ -457,7 +486,7 @@ static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call, } r->out.names = talloc_zero_p(mem_ctx, struct lsa_TransNameArray2); - if (r->out.domains == NULL) { + if (r->out.names == NULL) { return NT_STATUS_NO_MEMORY; } @@ -473,10 +502,9 @@ static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call, const char * const attrs[] = { "sAMAccountName", "sAMAccountType", NULL}; struct dom_sid *sid = r->in.sids->sids[i].sid; char *sid_str = dom_sid_string(mem_ctx, sid); - int ret, j; + int ret; struct ldb_message **res; - const char *name, *authority_name; - struct dom_sid *authority_sid; + const char *name; uint32_t atype, rtype; NTSTATUS status2; @@ -495,31 +523,11 @@ static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call, } /* work out the authority name */ - status2 = lsa_authority_name(state, mem_ctx, sid, - &authority_name, &authority_sid); + status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains); if (!NT_STATUS_IS_OK(status2)) { return status2; } - /* see if we've already done this authority name */ - for (j=0;j<r->out.domains->count;j++) { - if (strcmp(authority_name, r->out.domains->domains[j].name.string) == 0) { - break; - } - } - if (j == r->out.domains->count) { - r->out.domains->domains = talloc_realloc_p(r->out.domains, - r->out.domains->domains, - struct lsa_TrustInformation, - r->out.domains->count+1); - if (r->out.domains == NULL) { - return NT_STATUS_NO_MEMORY; - } - r->out.domains->domains[j].name.string = authority_name; - r->out.domains->domains[j].sid = authority_sid; - r->out.domains->count++; - } - ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, "objectSid=%s", sid_str); if (ret != 1) { status = STATUS_SOME_UNMAPPED; @@ -995,9 +1003,144 @@ static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_LookupNames2 *r) { - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); + struct lsa_policy_state *state; + struct dcesrv_handle *h; + int i; + NTSTATUS status = NT_STATUS_OK; + + r->out.domains = NULL; + + DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY); + + state = h->data; + + r->out.domains = talloc_zero_p(mem_ctx, struct lsa_RefDomainList); + if (r->out.domains == NULL) { + return NT_STATUS_NO_MEMORY; + } + + r->out.sids = talloc_zero_p(mem_ctx, struct lsa_TransSidArray2); + if (r->out.sids == NULL) { + return NT_STATUS_NO_MEMORY; + } + + *r->out.count = 0; + + r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_TranslatedSid2, + r->in.num_names); + if (r->out.sids->sids == NULL) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0;i<r->in.num_names;i++) { + const char * const attrs[] = { "objectSid", "sAMAccountType", NULL}; + const char *name = r->in.names[i].string; + int ret; + const char *sid_str; + struct ldb_message **res; + struct dom_sid *sid; + uint32_t atype, rtype; + NTSTATUS status2; + + r->out.sids->count++; + (*r->out.count)++; + + r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN; + r->out.sids->sids[i].rid = 0xFFFFFFFF; + r->out.sids->sids[i].sid_index = 0xFFFFFFFF; + r->out.sids->sids[i].unknown = 0; + + ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", name); + if (ret != 1) { + status = STATUS_SOME_UNMAPPED; + continue; + } + + sid_str = ldb_msg_find_string(res[0], "objectSid", NULL); + if (sid_str == NULL) { + status = STATUS_SOME_UNMAPPED; + continue; + } + + sid = dom_sid_parse_talloc(mem_ctx, sid_str); + if (sid == NULL || sid->num_auths == 0) { + status = STATUS_SOME_UNMAPPED; + continue; + } + + atype = samdb_result_uint(res[0], "sAMAccountType", 0); + if (atype == 0) { + status = STATUS_SOME_UNMAPPED; + continue; + } + + rtype = samdb_atype_map(atype); + if (rtype == SID_NAME_UNKNOWN) { + status = STATUS_SOME_UNMAPPED; + continue; + } + + r->out.sids->sids[i].sid_type = rtype; + r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1]; + r->out.sids->sids[i].sid_index = 0; + r->out.sids->sids[i].unknown = 0; + + status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains); + if (!NT_STATUS_IS_OK(status2)) { + return status2; + } + } + + return status; +} + +/* + lsa_LookupNames +*/ +static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct lsa_LookupNames *r) +{ + struct lsa_LookupNames2 r2; + NTSTATUS status; + int i; + + r2.in.handle = r->in.handle; + r2.in.num_names = r->in.num_names; + r2.in.names = r->in.names; + r2.in.sids = NULL; + r2.in.level = r->in.level; + r2.in.count = r->in.count; + r2.in.unknown1 = 0; + r2.in.unknown2 = 0; + r2.out.count = r->out.count; + + status = lsa_LookupNames2(dce_call, mem_ctx, &r2); + if (dce_call->fault_code != 0) { + return status; + } + + r->out.domains = r2.out.domains; + r->out.sids = talloc_p(mem_ctx, struct lsa_TransSidArray); + if (r->out.sids == NULL) { + return NT_STATUS_NO_MEMORY; + } + r->out.sids->count = r2.out.sids->count; + r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_TranslatedSid, + r->out.sids->count); + if (r->out.sids->sids == NULL) { + return NT_STATUS_NO_MEMORY; + } + for (i=0;i<r->out.sids->count;i++) { + r->out.sids->sids[i].sid_type = r2.out.sids->sids[i].sid_type; + r->out.sids->sids[i].rid = r2.out.sids->sids[i].rid; + r->out.sids->sids[i].sid_index = r2.out.sids->sids[i].sid_index; + } + + return status; } + + /* lsa_CreateTrustedDomainEx2 */ |