2 Unix SMB/CIFS implementation.
4 endpoint server for the lsarpc pipe
6 Copyright (C) Andrew Tridgell 2004
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2007
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "rpc_server/lsa/lsa.h"
24 #include "libds/common/roles.h"
25 #include "libds/common/flag_mapping.h"
26 #include "lib/messaging/irpc.h"
27 #include "librpc/gen_ndr/ndr_lsa_c.h"
29 struct dcesrv_lsa_TranslatedItem {
30 enum lsa_SidType type;
31 const struct dom_sid *sid;
33 const char *authority_name;
34 const struct dom_sid *authority_sid;
39 const char *domain; /* only $DOMAIN\ */
40 const char *namespace; /* $NAMESPACE\ or @$NAMESPACE */
41 const char *principal; /* \$PRINCIPAL or $PRIN@IPAL */
42 const char *sid; /* "S-1-5-21-9000-8000-7000-6000" */
43 const char *rid; /* "00001770" */
47 struct dcesrv_lsa_LookupSids_base_state;
48 struct dcesrv_lsa_LookupNames_base_state;
50 struct dcesrv_lsa_Lookup_view {
52 NTSTATUS (*lookup_sid)(struct dcesrv_lsa_LookupSids_base_state *state,
53 struct dcesrv_lsa_TranslatedItem *item);
54 NTSTATUS (*lookup_name)(struct dcesrv_lsa_LookupNames_base_state *state,
55 struct dcesrv_lsa_TranslatedItem *item);
58 struct dcesrv_lsa_Lookup_view_table {
61 const struct dcesrv_lsa_Lookup_view **array;
64 static const struct dcesrv_lsa_Lookup_view_table *dcesrv_lsa_view_table(
65 enum lsa_LookupNamesLevel level);
68 lookup a SID for 1 name
70 static NTSTATUS dcesrv_lsa_lookup_name(struct lsa_policy_state *state,
72 const char *domain_name,
73 const struct dom_sid *domain_sid,
74 struct ldb_dn *domain_dn,
75 const char *principal,
76 const struct dom_sid **p_sid,
77 enum lsa_SidType *p_type)
79 const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
80 struct ldb_message **res = NULL;
81 const char *nt4_account = NULL;
82 char *encoded_account = NULL;
83 const char *at = NULL;
85 const struct dom_sid *sid = NULL;
87 enum lsa_SidType type;
91 if ((principal == NULL) || (principal[0] == '\0')) {
92 return NT_STATUS_NONE_MAPPED;
95 at = strchr(principal, '@');
97 const char *nt4_domain = NULL;
99 status = crack_name_to_nt4_name(mem_ctx,
101 DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
105 if (!NT_STATUS_IS_OK(status)) {
106 DEBUG(3, ("Failed to crack name %s into an NT4 name: %s\n",
107 principal, nt_errstr(status)));
111 match = strequal(nt4_domain, domain_name);
114 * TODO: handle multiple domains in a forest.
116 return NT_STATUS_NONE_MAPPED;
119 nt4_account = principal;
122 encoded_account = ldb_binary_encode_string(mem_ctx, nt4_account);
123 if (encoded_account == NULL) {
124 return NT_STATUS_NO_MEMORY;
127 ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs,
128 "(&(sAMAccountName=%s)(objectSid=*))",
130 TALLOC_FREE(encoded_account);
132 return NT_STATUS_INTERNAL_DB_ERROR;
135 return NT_STATUS_NONE_MAPPED;
138 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
139 DBG_ERR("nt4_account[%s] found %d times (principal[%s]) - %s\n",
140 nt4_account, ret, principal, nt_errstr(status));
144 sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
146 return NT_STATUS_NO_MEMORY;
149 /* Check that this is in the domain */
150 match = dom_sid_in_domain(domain_sid, sid);
152 return NT_STATUS_NONE_MAPPED;
155 atype = ldb_msg_find_attr_as_uint(res[0], "sAMAccountType", 0);
156 type = ds_atype_map(atype);
157 if (type == SID_NAME_UNKNOWN) {
158 return NT_STATUS_NONE_MAPPED;
168 add to the lsa_RefDomainList for LookupSids and LookupNames
170 static NTSTATUS dcesrv_lsa_authority_list(const char *authority_name,
171 const struct dom_sid *authority_sid,
172 struct lsa_RefDomainList *domains,
177 *sid_index = UINT32_MAX;
179 if (authority_name == NULL) {
183 /* see if we've already done this authority name */
184 for (i=0;i<domains->count;i++) {
185 if (strcasecmp_m(authority_name, domains->domains[i].name.string) == 0) {
191 domains->domains = talloc_realloc(domains,
193 struct lsa_DomainInfo,
195 if (domains->domains == NULL) {
196 return NT_STATUS_NO_MEMORY;
198 domains->domains[i].name.string = talloc_strdup(domains->domains,
200 if (domains->domains[i].name.string == NULL) {
201 return NT_STATUS_NO_MEMORY;
203 domains->domains[i].sid = dom_sid_dup(domains->domains,
205 if (domains->domains[i].sid == NULL) {
206 return NT_STATUS_NO_MEMORY;
209 domains->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER * domains->count;
216 lookup a name for 1 SID
218 static NTSTATUS dcesrv_lsa_lookup_sid(struct lsa_policy_state *state,
220 const char *domain_name,
221 const struct dom_sid *domain_sid,
222 struct ldb_dn *domain_dn,
223 const struct dom_sid *sid,
225 enum lsa_SidType *p_type)
227 const char * const attrs[] = { "sAMAccountName", "sAMAccountType", NULL};
228 struct ldb_message **res = NULL;
229 char *encoded_sid = NULL;
230 const char *name = NULL;
232 enum lsa_SidType type;
235 encoded_sid = ldap_encode_ndr_dom_sid(mem_ctx, sid);
236 if (encoded_sid == NULL) {
237 return NT_STATUS_NO_MEMORY;
240 ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs,
241 "(&(objectSid=%s)(sAMAccountName=*))", encoded_sid);
242 TALLOC_FREE(encoded_sid);
244 return NT_STATUS_INTERNAL_DB_ERROR;
247 return NT_STATUS_NONE_MAPPED;
250 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
251 DBG_ERR("sid[%s] found %d times - %s\n",
252 dom_sid_string(mem_ctx, sid), ret, nt_errstr(status));
256 name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
258 return NT_STATUS_INTERNAL_ERROR;
261 atype = ldb_msg_find_attr_as_uint(res[0], "sAMAccountType", 0);
262 type = ds_atype_map(atype);
263 if (type == SID_NAME_UNKNOWN) {
264 return NT_STATUS_NONE_MAPPED;
272 struct dcesrv_lsa_LookupSids_base_state {
273 struct dcesrv_call_state *dce_call;
277 struct lsa_policy_state *policy_state;
279 struct lsa_LookupSids3 r;
281 const struct dcesrv_lsa_Lookup_view_table *view_table;
282 struct dcesrv_lsa_TranslatedItem *items;
284 struct dsdb_trust_routing_table *routing_table;
287 struct dcerpc_binding_handle *irpc_handle;
288 struct lsa_SidArray sids;
289 struct lsa_RefDomainList *domains;
290 struct lsa_TransNameArray2 names;
296 struct lsa_LookupSids *l;
297 struct lsa_LookupSids2 *l2;
298 struct lsa_LookupSids3 *l3;
302 static NTSTATUS dcesrv_lsa_LookupSids_base_finish(
303 struct dcesrv_lsa_LookupSids_base_state *state);
304 static void dcesrv_lsa_LookupSids_base_map(
305 struct dcesrv_lsa_LookupSids_base_state *state);
306 static void dcesrv_lsa_LookupSids_base_done(struct tevent_req *subreq);
308 static NTSTATUS dcesrv_lsa_LookupSids_base_call(struct dcesrv_lsa_LookupSids_base_state *state)
310 struct lsa_LookupSids3 *r = &state->r;
311 struct tevent_req *subreq = NULL;
315 *r->out.domains = NULL;
316 r->out.names->count = 0;
317 r->out.names->names = NULL;
320 state->view_table = dcesrv_lsa_view_table(r->in.level);
321 if (state->view_table == NULL) {
322 return NT_STATUS_INVALID_PARAMETER;
325 *r->out.domains = talloc_zero(r->out.domains, struct lsa_RefDomainList);
326 if (*r->out.domains == NULL) {
327 return NT_STATUS_NO_MEMORY;
330 r->out.names->names = talloc_zero_array(r->out.names,
331 struct lsa_TranslatedName2,
332 r->in.sids->num_sids);
333 if (r->out.names->names == NULL) {
334 return NT_STATUS_NO_MEMORY;
337 state->items = talloc_zero_array(state,
338 struct dcesrv_lsa_TranslatedItem,
339 r->in.sids->num_sids);
340 if (state->items == NULL) {
341 return NT_STATUS_NO_MEMORY;
344 for (i=0;i<r->in.sids->num_sids;i++) {
345 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
348 if (r->in.sids->sids[i].sid == NULL) {
349 return NT_STATUS_INVALID_PARAMETER;
352 item->type = SID_NAME_UNKNOWN;
353 item->sid = r->in.sids->sids[i].sid;
355 item->hints.sid = dom_sid_string(state->items, item->sid);
356 if (item->hints.sid == NULL) {
357 return NT_STATUS_NO_MEMORY;
360 dom_sid_split_rid(state->items, item->sid, NULL, &rid);
361 item->hints.rid = talloc_asprintf(state->items,
362 "%08X", (unsigned)rid);
363 if (item->hints.rid == NULL) {
364 return NT_STATUS_NO_MEMORY;
368 for (v=0; v < state->view_table->count; v++) {
369 const struct dcesrv_lsa_Lookup_view *view =
370 state->view_table->array[v];
372 for (i=0; i < r->in.sids->num_sids; i++) {
373 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
380 status = view->lookup_sid(state, item);
381 if (NT_STATUS_IS_OK(status)) {
383 } else if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
384 status = NT_STATUS_OK;
385 } else if (NT_STATUS_EQUAL(status, NT_STATUS_SOME_NOT_MAPPED)) {
386 status = NT_STATUS_OK;
388 if (!NT_STATUS_IS_OK(status)) {
394 if (state->wb.irpc_handle == NULL) {
395 return dcesrv_lsa_LookupSids_base_finish(state);
398 state->wb.sids.sids = talloc_zero_array(state, struct lsa_SidPtr,
399 r->in.sids->num_sids);
400 if (state->wb.sids.sids == NULL) {
401 return NT_STATUS_NO_MEMORY;
404 for (i=0; i < r->in.sids->num_sids; i++) {
405 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
411 item->wb_idx = state->wb.sids.num_sids;
412 state->wb.sids.sids[item->wb_idx] = r->in.sids->sids[i];
413 state->wb.sids.num_sids++;
416 subreq = dcerpc_lsa_LookupSids3_send(state,
417 state->dce_call->event_ctx,
418 state->wb.irpc_handle,
424 state->r.in.lookup_options,
425 state->r.in.client_revision);
426 if (subreq == NULL) {
427 return NT_STATUS_NO_MEMORY;;
429 state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
430 tevent_req_set_callback(subreq,
431 dcesrv_lsa_LookupSids_base_done,
437 static NTSTATUS dcesrv_lsa_LookupSids_base_finish(
438 struct dcesrv_lsa_LookupSids_base_state *state)
440 struct lsa_LookupSids3 *r = &state->r;
443 for (i=0;i<r->in.sids->num_sids;i++) {
444 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
446 uint32_t sid_index = UINT32_MAX;
448 status = dcesrv_lsa_authority_list(item->authority_name,
452 if (!NT_STATUS_IS_OK(status)) {
456 if (item->name == NULL && r->in.level == LSA_LOOKUP_NAMES_ALL) {
457 if (sid_index == UINT32_MAX) {
458 item->name = item->hints.sid;
460 item->name = item->hints.rid;
464 r->out.names->names[i].sid_type = item->type;
465 r->out.names->names[i].name.string = item->name;
466 r->out.names->names[i].sid_index = sid_index;
467 r->out.names->names[i].unknown = item->flags;
469 r->out.names->count++;
470 if (item->type != SID_NAME_UNKNOWN) {
475 if (*r->out.count == 0) {
476 return NT_STATUS_NONE_MAPPED;
478 if (*r->out.count != r->in.sids->num_sids) {
479 return STATUS_SOME_UNMAPPED;
485 static void dcesrv_lsa_LookupSids_base_map(
486 struct dcesrv_lsa_LookupSids_base_state *state)
488 if (state->_r.l3 != NULL) {
489 struct lsa_LookupSids3 *r = state->_r.l3;
491 r->out.result = state->r.out.result;
495 if (state->_r.l2 != NULL) {
496 struct lsa_LookupSids2 *r = state->_r.l2;
498 r->out.result = state->r.out.result;
502 if (state->_r.l != NULL) {
503 struct lsa_LookupSids *r = state->_r.l;
506 r->out.result = state->r.out.result;
508 SMB_ASSERT(state->r.out.names->count <= r->in.sids->num_sids);
509 for (i = 0; i < state->r.out.names->count; i++) {
510 struct lsa_TranslatedName2 *n2 =
511 &state->r.out.names->names[i];
512 struct lsa_TranslatedName *n =
513 &r->out.names->names[i];
515 n->sid_type = n2->sid_type;
517 n->sid_index = n2->sid_index;
519 r->out.names->count = state->r.out.names->count;
524 static void dcesrv_lsa_LookupSids_base_done(struct tevent_req *subreq)
526 struct dcesrv_lsa_LookupSids_base_state *state =
527 tevent_req_callback_data(subreq,
528 struct dcesrv_lsa_LookupSids_base_state);
529 struct dcesrv_call_state *dce_call = state->dce_call;
533 status = dcerpc_lsa_LookupSids3_recv(subreq, state->mem_ctx,
536 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
537 DEBUG(0,(__location__ ": IRPC callback failed %s\n",
540 } else if (!NT_STATUS_IS_OK(status)) {
541 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
542 DEBUG(0,(__location__ ": IRPC callback failed %s\n",
547 status = state->wb.result;
548 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
549 status = NT_STATUS_OK;
550 } else if (NT_STATUS_EQUAL(status, NT_STATUS_SOME_NOT_MAPPED)) {
551 status = NT_STATUS_OK;
553 if (!NT_STATUS_IS_OK(status)) {
557 for (i=0; i < state->r.in.sids->num_sids; i++) {
558 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
559 struct lsa_TranslatedName2 *s2 = NULL;
560 struct lsa_DomainInfo *d = NULL;
566 if (item->wb_idx >= state->wb.names.count) {
567 status = NT_STATUS_INTERNAL_ERROR;
571 s2 = &state->wb.names.names[item->wb_idx];
573 item->type = s2->sid_type;
574 item->name = s2->name.string;
575 item->flags = s2->unknown;
577 if (s2->sid_index == UINT32_MAX) {
581 if (state->wb.domains == NULL) {
582 status = NT_STATUS_INTERNAL_ERROR;
586 if (s2->sid_index >= state->wb.domains->count) {
587 status = NT_STATUS_INTERNAL_ERROR;
591 d = &state->wb.domains->domains[s2->sid_index];
593 item->authority_name = d->name.string;
594 item->authority_sid = d->sid;
597 status = dcesrv_lsa_LookupSids_base_finish(state);
599 state->r.out.result = status;
600 dcesrv_lsa_LookupSids_base_map(state);
603 status = dcesrv_reply(dce_call);
604 if (!NT_STATUS_IS_OK(status)) {
605 DEBUG(0,(__location__ ": dcesrv_reply() failed - %s\n", nt_errstr(status)));
612 NTSTATUS dcesrv_lsa_LookupSids2(struct dcesrv_call_state *dce_call,
614 struct lsa_LookupSids2 *r)
616 enum dcerpc_transport_t transport =
617 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
618 struct dcesrv_lsa_LookupSids_base_state *state = NULL;
619 struct dcesrv_handle *policy_handle = NULL;
622 if (transport != NCACN_NP && transport != NCALRPC) {
623 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
626 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
628 *r->out.domains = NULL;
629 r->out.names->count = 0;
630 r->out.names->names = NULL;
633 state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupSids_base_state);
635 return NT_STATUS_NO_MEMORY;
638 state->dce_call = dce_call;
639 state->mem_ctx = mem_ctx;
641 state->policy_state = policy_handle->data;
643 state->r.in.sids = r->in.sids;
644 state->r.in.level = r->in.level;
645 state->r.in.lookup_options = r->in.lookup_options;
646 state->r.in.client_revision = r->in.client_revision;
647 state->r.in.names = r->in.names;
648 state->r.in.count = r->in.count;
649 state->r.out.domains = r->out.domains;
650 state->r.out.names = r->out.names;
651 state->r.out.count = r->out.count;
655 status = dcesrv_lsa_LookupSids_base_call(state);
657 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
661 state->r.out.result = status;
662 dcesrv_lsa_LookupSids_base_map(state);
671 Identical to LookupSids2, but doesn't take a policy handle
674 NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call,
676 struct lsa_LookupSids3 *r)
678 enum dcerpc_transport_t transport =
679 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
680 const struct dcesrv_auth *auth = &dce_call->conn->auth_state;
681 struct dcesrv_lsa_LookupSids_base_state *state = NULL;
684 if (transport != NCACN_IP_TCP) {
685 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
689 * We don't have policy handles on this call. So this must be restricted
690 * to crypto connections only.
692 if (auth->auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
693 auth->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
694 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
697 *r->out.domains = NULL;
698 r->out.names->count = 0;
699 r->out.names->names = NULL;
702 state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupSids_base_state);
704 return NT_STATUS_NO_MEMORY;
707 state->dce_call = dce_call;
708 state->mem_ctx = mem_ctx;
710 status = dcesrv_lsa_get_policy_state(state->dce_call, mem_ctx,
711 0, /* we skip access checks */
712 &state->policy_state);
713 if (!NT_STATUS_IS_OK(status)) {
717 state->r.in.sids = r->in.sids;
718 state->r.in.level = r->in.level;
719 state->r.in.lookup_options = r->in.lookup_options;
720 state->r.in.client_revision = r->in.client_revision;
721 state->r.in.names = r->in.names;
722 state->r.in.count = r->in.count;
723 state->r.out.domains = r->out.domains;
724 state->r.out.names = r->out.names;
725 state->r.out.count = r->out.count;
729 status = dcesrv_lsa_LookupSids_base_call(state);
731 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
735 state->r.out.result = status;
736 dcesrv_lsa_LookupSids_base_map(state);
745 NTSTATUS dcesrv_lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
746 struct lsa_LookupSids *r)
748 enum dcerpc_transport_t transport =
749 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
750 struct dcesrv_lsa_LookupSids_base_state *state = NULL;
751 struct dcesrv_handle *policy_handle = NULL;
754 if (transport != NCACN_NP && transport != NCALRPC) {
755 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
758 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
760 *r->out.domains = NULL;
761 r->out.names->count = 0;
762 r->out.names->names = NULL;
765 r->out.names->names = talloc_zero_array(r->out.names,
766 struct lsa_TranslatedName,
767 r->in.sids->num_sids);
768 if (r->out.names->names == NULL) {
769 return NT_STATUS_NO_MEMORY;
772 state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupSids_base_state);
774 return NT_STATUS_NO_MEMORY;
777 state->dce_call = dce_call;
778 state->mem_ctx = mem_ctx;
780 state->policy_state = policy_handle->data;
782 state->r.in.sids = r->in.sids;
783 state->r.in.level = r->in.level;
784 state->r.in.lookup_options = LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES;
785 state->r.in.client_revision = LSA_CLIENT_REVISION_1;
786 state->r.in.names = talloc_zero(state, struct lsa_TransNameArray2);
787 if (state->r.in.names == NULL) {
788 return NT_STATUS_NO_MEMORY;
790 state->r.in.count = r->in.count;
791 state->r.out.domains = r->out.domains;
792 state->r.out.names = talloc_zero(state, struct lsa_TransNameArray2);
793 if (state->r.out.names == NULL) {
794 return NT_STATUS_NO_MEMORY;
796 state->r.out.count = r->out.count;
800 status = dcesrv_lsa_LookupSids_base_call(state);
802 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
806 state->r.out.result = status;
807 dcesrv_lsa_LookupSids_base_map(state);
812 struct dcesrv_lsa_LookupNames_base_state {
813 struct dcesrv_call_state *dce_call;
817 struct lsa_policy_state *policy_state;
819 struct lsa_LookupNames4 r;
821 const struct dcesrv_lsa_Lookup_view_table *view_table;
822 struct dcesrv_lsa_TranslatedItem *items;
824 struct dsdb_trust_routing_table *routing_table;
827 struct dcerpc_binding_handle *irpc_handle;
829 struct lsa_String *names;
830 struct lsa_RefDomainList *domains;
831 struct lsa_TransSidArray3 sids;
837 struct lsa_LookupNames *l;
838 struct lsa_LookupNames2 *l2;
839 struct lsa_LookupNames3 *l3;
840 struct lsa_LookupNames4 *l4;
844 static NTSTATUS dcesrv_lsa_LookupNames_base_finish(
845 struct dcesrv_lsa_LookupNames_base_state *state);
846 static void dcesrv_lsa_LookupNames_base_map(
847 struct dcesrv_lsa_LookupNames_base_state *state);
848 static void dcesrv_lsa_LookupNames_base_done(struct tevent_req *subreq);
850 static NTSTATUS dcesrv_lsa_LookupNames_base_call(struct dcesrv_lsa_LookupNames_base_state *state)
852 struct lsa_LookupNames4 *r = &state->r;
853 enum lsa_LookupOptions invalid_lookup_options = 0;
854 struct tevent_req *subreq = NULL;
858 *r->out.domains = NULL;
859 r->out.sids->count = 0;
860 r->out.sids->sids = NULL;
863 if (r->in.level != LSA_LOOKUP_NAMES_ALL) {
864 invalid_lookup_options |=
865 LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES_LOCAL;
867 if (r->in.lookup_options & invalid_lookup_options) {
868 return NT_STATUS_INVALID_PARAMETER;
871 state->view_table = dcesrv_lsa_view_table(r->in.level);
872 if (state->view_table == NULL) {
873 return NT_STATUS_INVALID_PARAMETER;
876 *r->out.domains = talloc_zero(r->out.domains, struct lsa_RefDomainList);
877 if (*r->out.domains == NULL) {
878 return NT_STATUS_NO_MEMORY;
881 r->out.sids->sids = talloc_zero_array(r->out.sids,
882 struct lsa_TranslatedSid3,
884 if (r->out.sids->sids == NULL) {
885 return NT_STATUS_NO_MEMORY;
888 state->items = talloc_zero_array(state,
889 struct dcesrv_lsa_TranslatedItem,
891 if (state->items == NULL) {
892 return NT_STATUS_NO_MEMORY;
895 for (i=0;i<r->in.num_names;i++) {
896 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
899 item->type = SID_NAME_UNKNOWN;
900 item->name = r->in.names[i].string;
902 * Note: that item->name can be NULL!
904 * See test_LookupNames_NULL() in
905 * source4/torture/rpc/lsa.c
907 * nt4 returns NT_STATUS_NONE_MAPPED with sid_type
908 * SID_NAME_UNKNOWN, rid 0, and sid_index -1;
910 * w2k3/w2k8 return NT_STATUS_OK with sid_type
911 * SID_NAME_DOMAIN, rid -1 and sid_index 0 and BUILTIN domain
913 if (item->name == NULL) {
917 item->hints.principal = item->name;
918 p = strchr(item->name, '\\');
919 if (p != NULL && p != item->name) {
920 item->hints.domain = talloc_strndup(state->items,
923 if (item->hints.domain == NULL) {
924 return NT_STATUS_NO_MEMORY;
926 item->hints.namespace = item->hints.domain;
930 * This is just 'BUILTIN\'.
932 item->hints.principal = NULL;
934 item->hints.principal = p;
937 if (item->hints.domain == NULL) {
938 p = strchr(item->name, '@');
939 if (p != NULL && p != item->name && p[1] != '\0') {
940 item->hints.namespace = p + 1;
945 for (v=0; v < state->view_table->count; v++) {
946 const struct dcesrv_lsa_Lookup_view *view =
947 state->view_table->array[v];
949 for (i=0; i < r->in.num_names; i++) {
950 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
957 status = view->lookup_name(state, item);
958 if (NT_STATUS_IS_OK(status)) {
960 } else if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
961 status = NT_STATUS_OK;
962 } else if (NT_STATUS_EQUAL(status, NT_STATUS_SOME_NOT_MAPPED)) {
963 status = NT_STATUS_OK;
965 if (!NT_STATUS_IS_OK(status)) {
971 if (state->wb.irpc_handle == NULL) {
972 return dcesrv_lsa_LookupNames_base_finish(state);
975 state->wb.names = talloc_zero_array(state, struct lsa_String,
977 if (state->wb.names == NULL) {
978 return NT_STATUS_NO_MEMORY;
981 for (i=0;i<r->in.num_names;i++) {
982 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
988 item->wb_idx = state->wb.num_names;
989 state->wb.names[item->wb_idx] = r->in.names[i];
990 state->wb.num_names++;
993 subreq = dcerpc_lsa_LookupNames4_send(state,
994 state->dce_call->event_ctx,
995 state->wb.irpc_handle,
1002 state->r.in.lookup_options,
1003 state->r.in.client_revision);
1004 if (subreq == NULL) {
1005 return NT_STATUS_NO_MEMORY;
1007 state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
1008 tevent_req_set_callback(subreq,
1009 dcesrv_lsa_LookupNames_base_done,
1012 return NT_STATUS_OK;
1015 static NTSTATUS dcesrv_lsa_LookupNames_base_finish(
1016 struct dcesrv_lsa_LookupNames_base_state *state)
1018 struct lsa_LookupNames4 *r = &state->r;
1021 for (i=0;i<r->in.num_names;i++) {
1022 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
1024 uint32_t sid_index = UINT32_MAX;
1026 status = dcesrv_lsa_authority_list(item->authority_name,
1027 item->authority_sid,
1030 if (!NT_STATUS_IS_OK(status)) {
1034 r->out.sids->sids[i].sid_type = item->type;
1035 r->out.sids->sids[i].sid = discard_const_p(struct dom_sid,
1037 r->out.sids->sids[i].sid_index = sid_index;
1038 r->out.sids->sids[i].flags = item->flags;
1040 r->out.sids->count++;
1041 if (item->type != SID_NAME_UNKNOWN) {
1046 if (*r->out.count == 0) {
1047 return NT_STATUS_NONE_MAPPED;
1049 if (*r->out.count != r->in.num_names) {
1050 return STATUS_SOME_UNMAPPED;
1053 return NT_STATUS_OK;
1056 static void dcesrv_lsa_LookupNames_base_map(
1057 struct dcesrv_lsa_LookupNames_base_state *state)
1059 if (state->_r.l4 != NULL) {
1060 struct lsa_LookupNames4 *r = state->_r.l4;
1062 r->out.result = state->r.out.result;
1066 if (state->_r.l3 != NULL) {
1067 struct lsa_LookupNames3 *r = state->_r.l3;
1069 r->out.result = state->r.out.result;
1073 if (state->_r.l2 != NULL) {
1074 struct lsa_LookupNames2 *r = state->_r.l2;
1077 r->out.result = state->r.out.result;
1079 SMB_ASSERT(state->r.out.sids->count <= r->in.num_names);
1080 for (i = 0; i < state->r.out.sids->count; i++) {
1081 const struct lsa_TranslatedSid3 *s3 =
1082 &state->r.out.sids->sids[i];
1083 struct lsa_TranslatedSid2 *s2 =
1084 &r->out.sids->sids[i];
1086 s2->sid_type = s3->sid_type;
1087 if (s3->sid_type == SID_NAME_DOMAIN) {
1088 s2->rid = UINT32_MAX;
1089 } else if (s3->flags & 0x00000004) {
1090 s2->rid = UINT32_MAX;
1091 } else if (s3->sid == NULL) {
1093 * MS-LSAT 3.1.4.7 - rid zero is considered
1094 * equivalent to sid NULL - so we should return
1095 * 0 rid for unmapped entries
1100 dom_sid_split_rid(NULL, s3->sid,
1103 s2->sid_index = s3->sid_index;
1104 s2->unknown = s3->flags;
1106 r->out.sids->count = state->r.out.sids->count;
1110 if (state->_r.l != NULL) {
1111 struct lsa_LookupNames *r = state->_r.l;
1114 r->out.result = state->r.out.result;
1116 SMB_ASSERT(state->r.out.sids->count <= r->in.num_names);
1117 for (i = 0; i < state->r.out.sids->count; i++) {
1118 struct lsa_TranslatedSid3 *s3 =
1119 &state->r.out.sids->sids[i];
1120 struct lsa_TranslatedSid *s =
1121 &r->out.sids->sids[i];
1123 s->sid_type = s3->sid_type;
1124 if (s3->sid_type == SID_NAME_DOMAIN) {
1125 s->rid = UINT32_MAX;
1126 } else if (s3->flags & 0x00000004) {
1127 s->rid = UINT32_MAX;
1128 } else if (s3->sid == NULL) {
1130 * MS-LSAT 3.1.4.7 - rid zero is considered
1131 * equivalent to sid NULL - so we should return
1132 * 0 rid for unmapped entries
1137 dom_sid_split_rid(NULL, s3->sid,
1140 s->sid_index = s3->sid_index;
1142 r->out.sids->count = state->r.out.sids->count;
1147 static void dcesrv_lsa_LookupNames_base_done(struct tevent_req *subreq)
1149 struct dcesrv_lsa_LookupNames_base_state *state =
1150 tevent_req_callback_data(subreq,
1151 struct dcesrv_lsa_LookupNames_base_state);
1152 struct dcesrv_call_state *dce_call = state->dce_call;
1156 status = dcerpc_lsa_LookupNames4_recv(subreq, state->mem_ctx,
1158 TALLOC_FREE(subreq);
1159 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
1160 DEBUG(0,(__location__ ": IRPC callback failed %s\n",
1161 nt_errstr(status)));
1163 } else if (!NT_STATUS_IS_OK(status)) {
1164 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
1165 DEBUG(0,(__location__ ": IRPC callback failed %s\n",
1166 nt_errstr(status)));
1170 status = state->wb.result;
1171 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1172 status = NT_STATUS_OK;
1173 } else if (NT_STATUS_EQUAL(status, NT_STATUS_SOME_NOT_MAPPED)) {
1174 status = NT_STATUS_OK;
1176 if (!NT_STATUS_IS_OK(status)) {
1180 for (i=0; i < state->r.in.num_names;i++) {
1181 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
1182 struct lsa_TranslatedSid3 *s3 = NULL;
1183 struct lsa_DomainInfo *d = NULL;
1189 if (item->wb_idx >= state->wb.sids.count) {
1190 status = NT_STATUS_INTERNAL_ERROR;
1194 s3 = &state->wb.sids.sids[item->wb_idx];
1196 item->type = s3->sid_type;
1197 item->sid = s3->sid;
1198 item->flags = s3->flags;
1200 if (s3->sid_index == UINT32_MAX) {
1204 if (state->wb.domains == NULL) {
1205 status = NT_STATUS_INTERNAL_ERROR;
1209 if (s3->sid_index >= state->wb.domains->count) {
1210 status = NT_STATUS_INTERNAL_ERROR;
1214 d = &state->wb.domains->domains[s3->sid_index];
1216 item->authority_name = d->name.string;
1217 item->authority_sid = d->sid;
1220 status = dcesrv_lsa_LookupNames_base_finish(state);
1222 state->r.out.result = status;
1223 dcesrv_lsa_LookupNames_base_map(state);
1226 status = dcesrv_reply(dce_call);
1227 if (!NT_STATUS_IS_OK(status)) {
1228 DEBUG(0,(__location__ ": dcesrv_reply() failed - %s\n", nt_errstr(status)));
1235 NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call,
1236 TALLOC_CTX *mem_ctx,
1237 struct lsa_LookupNames3 *r)
1239 enum dcerpc_transport_t transport =
1240 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
1241 struct dcesrv_lsa_LookupNames_base_state *state = NULL;
1242 struct dcesrv_handle *policy_handle = NULL;
1245 if (transport != NCACN_NP && transport != NCALRPC) {
1246 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
1249 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1251 *r->out.domains = NULL;
1252 r->out.sids->count = 0;
1253 r->out.sids->sids = NULL;
1256 state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
1257 if (state == NULL) {
1258 return NT_STATUS_NO_MEMORY;
1261 state->dce_call = dce_call;
1262 state->mem_ctx = mem_ctx;
1264 state->policy_state = policy_handle->data;
1266 state->r.in.num_names = r->in.num_names;
1267 state->r.in.names = r->in.names;
1268 state->r.in.level = r->in.level;
1269 state->r.in.lookup_options = r->in.lookup_options;
1270 state->r.in.client_revision = r->in.client_revision;
1271 state->r.in.sids = r->in.sids;
1272 state->r.in.count = r->in.count;
1273 state->r.out.domains = r->out.domains;
1274 state->r.out.sids = r->out.sids;
1275 state->r.out.count = r->out.count;
1279 status = dcesrv_lsa_LookupNames_base_call(state);
1281 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1285 state->r.out.result = status;
1286 dcesrv_lsa_LookupNames_base_map(state);
1294 Identical to LookupNames3, but doesn't take a policy handle
1297 NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1298 struct lsa_LookupNames4 *r)
1300 enum dcerpc_transport_t transport =
1301 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
1302 const struct dcesrv_auth *auth = &dce_call->conn->auth_state;
1303 struct dcesrv_lsa_LookupNames_base_state *state = NULL;
1306 if (transport != NCACN_IP_TCP) {
1307 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
1311 * We don't have policy handles on this call. So this must be restricted
1312 * to crypto connections only.
1314 if (auth->auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
1315 auth->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1316 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
1319 *r->out.domains = NULL;
1320 r->out.sids->count = 0;
1321 r->out.sids->sids = NULL;
1324 state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
1325 if (state == NULL) {
1326 return NT_STATUS_NO_MEMORY;
1329 state->dce_call = dce_call;
1330 state->mem_ctx = mem_ctx;
1332 status = dcesrv_lsa_get_policy_state(state->dce_call, state,
1333 0, /* we skip access checks */
1334 &state->policy_state);
1335 if (!NT_STATUS_IS_OK(status)) {
1339 state->r.in.num_names = r->in.num_names;
1340 state->r.in.names = r->in.names;
1341 state->r.in.level = r->in.level;
1342 state->r.in.lookup_options = r->in.lookup_options;
1343 state->r.in.client_revision = r->in.client_revision;
1344 state->r.in.sids = r->in.sids;
1345 state->r.in.count = r->in.count;
1346 state->r.out.domains = r->out.domains;
1347 state->r.out.sids = r->out.sids;
1348 state->r.out.count = r->out.count;
1352 status = dcesrv_lsa_LookupNames_base_call(state);
1354 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1358 state->r.out.result = status;
1359 dcesrv_lsa_LookupNames_base_map(state);
1367 NTSTATUS dcesrv_lsa_LookupNames2(struct dcesrv_call_state *dce_call,
1368 TALLOC_CTX *mem_ctx,
1369 struct lsa_LookupNames2 *r)
1371 enum dcerpc_transport_t transport =
1372 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
1373 struct dcesrv_lsa_LookupNames_base_state *state = NULL;
1374 struct dcesrv_handle *policy_handle = NULL;
1377 if (transport != NCACN_NP && transport != NCALRPC) {
1378 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
1381 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1383 *r->out.domains = NULL;
1384 r->out.sids->count = 0;
1385 r->out.sids->sids = NULL;
1388 r->out.sids->sids = talloc_zero_array(r->out.sids,
1389 struct lsa_TranslatedSid2,
1391 if (r->out.sids->sids == NULL) {
1392 return NT_STATUS_NO_MEMORY;
1395 state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
1396 if (state == NULL) {
1397 return NT_STATUS_NO_MEMORY;
1400 state->dce_call = dce_call;
1401 state->mem_ctx = mem_ctx;
1403 state->policy_state = policy_handle->data;
1405 state->r.in.num_names = r->in.num_names;
1406 state->r.in.names = r->in.names;
1407 state->r.in.level = r->in.level;
1411 * The LookupOptions and ClientRevision parameters MUST be ignored.
1412 * Message processing MUST happen as if LookupOptions is set to
1413 * 0x00000000 and ClientRevision is set to 0x00000002.
1415 state->r.in.lookup_options = LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES;
1416 state->r.in.client_revision = LSA_CLIENT_REVISION_2;
1417 state->r.in.sids = talloc_zero(state, struct lsa_TransSidArray3);
1418 if (state->r.in.sids == NULL) {
1419 return NT_STATUS_NO_MEMORY;
1421 state->r.in.count = r->in.count;
1422 state->r.out.domains = r->out.domains;
1423 state->r.out.sids = talloc_zero(state, struct lsa_TransSidArray3);
1424 if (state->r.out.sids == NULL) {
1425 return NT_STATUS_NO_MEMORY;
1427 state->r.out.count = r->out.count;
1431 status = dcesrv_lsa_LookupNames_base_call(state);
1433 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1437 state->r.out.result = status;
1438 dcesrv_lsa_LookupNames_base_map(state);
1446 NTSTATUS dcesrv_lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1447 struct lsa_LookupNames *r)
1449 enum dcerpc_transport_t transport =
1450 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
1451 struct dcesrv_lsa_LookupNames_base_state *state = NULL;
1452 struct dcesrv_handle *policy_handle = NULL;
1455 if (transport != NCACN_NP && transport != NCALRPC) {
1456 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
1459 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1461 *r->out.domains = NULL;
1462 r->out.sids->count = 0;
1463 r->out.sids->sids = NULL;
1466 r->out.sids->sids = talloc_zero_array(r->out.sids,
1467 struct lsa_TranslatedSid,
1469 if (r->out.sids->sids == NULL) {
1470 return NT_STATUS_NO_MEMORY;
1473 state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
1474 if (state == NULL) {
1475 return NT_STATUS_NO_MEMORY;
1478 state->dce_call = dce_call;
1479 state->mem_ctx = mem_ctx;
1481 state->policy_state = policy_handle->data;
1483 state->r.in.num_names = r->in.num_names;
1484 state->r.in.names = r->in.names;
1485 state->r.in.level = r->in.level;
1486 state->r.in.lookup_options = LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES;
1487 state->r.in.client_revision = LSA_CLIENT_REVISION_1;
1488 state->r.in.sids = talloc_zero(state, struct lsa_TransSidArray3);
1489 if (state->r.in.sids == NULL) {
1490 return NT_STATUS_NO_MEMORY;
1492 state->r.in.count = r->in.count;
1493 state->r.out.domains = r->out.domains;
1494 state->r.out.sids = talloc_zero(state, struct lsa_TransSidArray3);
1495 if (state->r.out.sids == NULL) {
1496 return NT_STATUS_NO_MEMORY;
1498 state->r.out.count = r->out.count;
1502 status = dcesrv_lsa_LookupNames_base_call(state);
1504 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1508 state->r.out.result = status;
1509 dcesrv_lsa_LookupNames_base_map(state);
1514 static NTSTATUS dcesrv_lsa_lookup_name_predefined(
1515 struct dcesrv_lsa_LookupNames_base_state *state,
1516 struct dcesrv_lsa_TranslatedItem *item)
1520 status = dom_sid_lookup_predefined_name(item->name,
1523 &item->authority_sid,
1524 &item->authority_name);
1525 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1528 if (!NT_STATUS_IS_OK(status)) {
1532 return NT_STATUS_OK;
1535 static NTSTATUS dcesrv_lsa_lookup_sid_predefined(
1536 struct dcesrv_lsa_LookupSids_base_state *state,
1537 struct dcesrv_lsa_TranslatedItem *item)
1541 status = dom_sid_lookup_predefined_sid(item->sid,
1544 &item->authority_sid,
1545 &item->authority_name);
1546 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1549 if (!NT_STATUS_IS_OK(status)) {
1553 return NT_STATUS_OK;
1556 static const struct dcesrv_lsa_Lookup_view view_predefined = {
1557 .name = "Predefined",
1558 .lookup_sid = dcesrv_lsa_lookup_sid_predefined,
1559 .lookup_name = dcesrv_lsa_lookup_name_predefined,
1562 static NTSTATUS dcesrv_lsa_lookup_name_builtin(
1563 struct dcesrv_lsa_LookupNames_base_state *state,
1564 struct dcesrv_lsa_TranslatedItem *item)
1566 struct lsa_policy_state *policy_state = state->policy_state;
1568 bool is_builtin = false;
1570 if (item->name == NULL) {
1572 * This should not be mapped.
1574 return NT_STATUS_OK;
1578 * The predefined view already handled the BUILTIN domain.
1580 * Now we just need to find the principal.
1582 * We only allow 'BUILTIN\something' and
1583 * not 'something@BUILTIN.
1585 * And we try out best for just 'something'.
1587 is_builtin = strequal(item->hints.domain, NAME_BUILTIN);
1588 if (!is_builtin && item->hints.domain != NULL) {
1589 return NT_STATUS_NONE_MAPPED;
1592 status = dcesrv_lsa_lookup_name(state->policy_state,
1595 policy_state->builtin_sid,
1596 policy_state->builtin_dn,
1597 item->hints.principal,
1600 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1602 return NT_STATUS_NONE_MAPPED;
1605 * We know we're authoritive
1607 status = NT_STATUS_OK;
1609 if (!NT_STATUS_IS_OK(status)) {
1613 item->authority_name = NAME_BUILTIN;
1614 item->authority_sid = policy_state->builtin_sid;
1615 return NT_STATUS_OK;
1618 static NTSTATUS dcesrv_lsa_lookup_sid_builtin(
1619 struct dcesrv_lsa_LookupSids_base_state *state,
1620 struct dcesrv_lsa_TranslatedItem *item)
1622 struct lsa_policy_state *policy_state = state->policy_state;
1624 bool is_builtin = false;
1627 * The predefined view already handled the BUILTIN domain.
1629 * Now we just need to find the principal.
1631 is_builtin = dom_sid_in_domain(policy_state->builtin_sid, item->sid);
1633 return NT_STATUS_NONE_MAPPED;
1636 status = dcesrv_lsa_lookup_sid(state->policy_state,
1639 policy_state->builtin_sid,
1640 policy_state->builtin_dn,
1644 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1646 * We know we're authoritive
1648 status = NT_STATUS_OK;
1650 if (!NT_STATUS_IS_OK(status)) {
1654 item->authority_name = NAME_BUILTIN;
1655 item->authority_sid = policy_state->builtin_sid;
1656 return NT_STATUS_OK;
1659 static const struct dcesrv_lsa_Lookup_view view_builtin = {
1661 .lookup_sid = dcesrv_lsa_lookup_sid_builtin,
1662 .lookup_name = dcesrv_lsa_lookup_name_builtin,
1665 static NTSTATUS dcesrv_lsa_lookup_name_account(
1666 struct dcesrv_lsa_LookupNames_base_state *state,
1667 struct dcesrv_lsa_TranslatedItem *item)
1669 struct lsa_policy_state *policy_state = state->policy_state;
1670 struct loadparm_context *lp_ctx = state->dce_call->conn->dce_ctx->lp_ctx;
1671 struct lsa_LookupNames4 *r = &state->r;
1674 bool (*is_local_match_fn)(struct loadparm_context *, const char *) = NULL;
1675 bool is_domain = false;
1676 bool try_lookup = false;
1677 const char *check_domain_name = NULL;
1679 role = lpcfg_server_role(lp_ctx);
1680 if (role == ROLE_ACTIVE_DIRECTORY_DC) {
1681 is_local_match_fn = lpcfg_is_my_domain_or_realm;
1683 is_local_match_fn = lpcfg_is_myname;
1686 if (item->name == NULL) {
1688 * This should not be mapped.
1690 return NT_STATUS_OK;
1693 if (item->hints.domain != NULL && item->hints.principal == NULL) {
1695 * This is 'DOMAIN\'.
1697 check_domain_name = item->hints.domain;
1700 * This is just 'DOMAIN'.
1702 check_domain_name = item->name;
1704 is_domain = is_local_match_fn(lp_ctx, check_domain_name);
1706 item->type = SID_NAME_DOMAIN;
1707 item->sid = policy_state->domain_sid;
1708 item->authority_name = policy_state->domain_name;
1709 item->authority_sid = policy_state->domain_sid;
1710 return NT_STATUS_OK;
1713 if (r->in.lookup_options & LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES_LOCAL) {
1714 if (item->hints.domain != item->hints.namespace) {
1716 * This means the client asked for an UPN,
1717 * and it should not be mapped.
1719 return NT_STATUS_OK;
1723 if (item->hints.namespace != NULL) {
1724 is_domain = is_local_match_fn(lp_ctx, item->hints.namespace);
1725 try_lookup = is_domain;
1731 struct dcesrv_lsa_TranslatedItem tmp;
1734 status = dom_sid_lookup_predefined_name(item->hints.namespace,
1738 &tmp.authority_name);
1739 if (NT_STATUS_IS_OK(status)) {
1741 * It should not be handled by us.
1743 return NT_STATUS_NONE_MAPPED;
1745 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1751 const struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
1752 const struct lsa_ForestTrustDomainInfo *di = NULL;
1754 if (state->routing_table == NULL) {
1755 status = dsdb_trust_routing_table_load(policy_state->sam_ldb,
1757 &state->routing_table);
1758 if (!NT_STATUS_IS_OK(status)) {
1763 tdo = dsdb_trust_domain_by_name(state->routing_table,
1764 item->hints.namespace,
1768 * The name is not resolvable at all...
1770 return NT_STATUS_OK;
1773 if (!(tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST)) {
1775 * The name is not resolvable here
1777 return NT_STATUS_NONE_MAPPED;
1781 * TODO: handle multiple domains in a forest together with
1782 * LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY
1790 * It should not be handled by us.
1792 return NT_STATUS_NONE_MAPPED;
1796 * TODO: handle multiple domains in our forest.
1799 status = dcesrv_lsa_lookup_name(state->policy_state,
1801 policy_state->domain_name,
1802 policy_state->domain_sid,
1803 policy_state->domain_dn,
1804 item->hints.principal,
1807 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1809 return NT_STATUS_NONE_MAPPED;
1812 * We know we're authoritive
1814 status = NT_STATUS_OK;
1816 if (!NT_STATUS_IS_OK(status)) {
1820 item->authority_name = policy_state->domain_name;
1821 item->authority_sid = policy_state->domain_sid;
1822 return NT_STATUS_OK;
1825 static NTSTATUS dcesrv_lsa_lookup_sid_account(
1826 struct dcesrv_lsa_LookupSids_base_state *state,
1827 struct dcesrv_lsa_TranslatedItem *item)
1829 struct lsa_policy_state *policy_state = state->policy_state;
1833 is_domain = dom_sid_equal(policy_state->domain_sid, item->sid);
1835 item->type = SID_NAME_DOMAIN;
1836 item->name = policy_state->domain_name;
1837 item->authority_name = policy_state->domain_name;
1838 item->authority_sid = policy_state->domain_sid;
1839 return NT_STATUS_OK;
1841 is_domain = dom_sid_in_domain(policy_state->domain_sid, item->sid);
1843 return NT_STATUS_NONE_MAPPED;
1846 status = dcesrv_lsa_lookup_sid(state->policy_state,
1848 policy_state->domain_name,
1849 policy_state->domain_sid,
1850 policy_state->domain_dn,
1854 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1856 * We know we're authoritive
1858 status = NT_STATUS_OK;
1860 if (!NT_STATUS_IS_OK(status)) {
1864 item->authority_name = policy_state->domain_name;
1865 item->authority_sid = policy_state->domain_sid;
1866 return NT_STATUS_OK;
1869 static const struct dcesrv_lsa_Lookup_view view_account = {
1871 .lookup_sid = dcesrv_lsa_lookup_sid_account,
1872 .lookup_name = dcesrv_lsa_lookup_name_account,
1875 static NTSTATUS dcesrv_lsa_lookup_name_winbind(
1876 struct dcesrv_lsa_LookupNames_base_state *state,
1877 struct dcesrv_lsa_TranslatedItem *item)
1879 struct lsa_LookupNames4 *r = &state->r;
1880 const struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
1881 const struct lsa_ForestTrustDomainInfo *di = NULL;
1883 const char *check_domain_name = NULL;
1884 bool expect_domain = false;
1886 if (item->name == NULL) {
1888 * This should not be mapped.
1890 return NT_STATUS_OK;
1893 if (item->hints.domain != NULL && item->hints.principal == NULL) {
1895 * This is 'DOMAIN\'.
1897 check_domain_name = item->hints.domain;
1898 expect_domain = true;
1899 } else if (item->hints.namespace != NULL) {
1901 * This is 'DOMAIN\someone'
1902 * or 'someone@DOMAIN'
1904 check_domain_name = item->hints.namespace;
1907 * This is just 'DOMAIN'.
1909 check_domain_name = item->name;
1910 expect_domain = true;
1913 if (state->routing_table == NULL) {
1914 struct lsa_policy_state *policy_state = state->policy_state;
1916 status = dsdb_trust_routing_table_load(policy_state->sam_ldb,
1918 &state->routing_table);
1919 if (!NT_STATUS_IS_OK(status)) {
1924 tdo = dsdb_trust_domain_by_name(state->routing_table,
1929 * The name is not resolvable at all...
1931 * And for now we don't send unqualified names
1932 * to winbindd, as we don't handle them
1935 * TODO: how should that work within
1938 return NT_STATUS_OK;
1941 if (tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
1943 * The name should have been resolved in the account view.
1945 * TODO: handle multiple domains in a forest...
1947 return NT_STATUS_OK;
1950 if (expect_domain) {
1951 const char *name = NULL;
1952 const struct dom_sid *sid = NULL;
1954 name = talloc_strdup(state->mem_ctx,
1955 di->netbios_domain_name.string);
1957 return NT_STATUS_NO_MEMORY;
1959 sid = dom_sid_dup(state->mem_ctx,
1962 return NT_STATUS_NO_MEMORY;
1964 item->type = SID_NAME_DOMAIN;
1966 item->authority_name = name;
1967 item->authority_sid = sid;
1968 return NT_STATUS_OK;
1971 if (r->in.lookup_options & LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES_LOCAL) {
1972 if (item->hints.namespace == NULL) {
1974 * We should not try to resolve isolated names
1977 return NT_STATUS_OK;
1982 * We know at least the domain part of the name exists.
1984 * For now the rest handled within winbindd.
1986 * In future we can optimize it based on
1989 * We can also try to resolve SID_NAME_DOMAIN
1990 * just based on the routing table.
1993 if (state->wb.irpc_handle != NULL) {
1997 return NT_STATUS_NONE_MAPPED;
2000 state->wb.irpc_handle = irpc_binding_handle_by_name(state,
2001 state->dce_call->msg_ctx,
2004 if (state->wb.irpc_handle == NULL) {
2005 DEBUG(0,("Failed to get binding_handle for winbind_server task\n"));
2006 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
2007 return NT_STATUS_INVALID_SYSTEM_SERVICE;
2011 * 60 seconds timeout should be enough
2013 dcerpc_binding_handle_set_timeout(state->wb.irpc_handle, 60);
2015 return NT_STATUS_NONE_MAPPED;
2018 static NTSTATUS dcesrv_lsa_lookup_sid_winbind(
2019 struct dcesrv_lsa_LookupSids_base_state *state,
2020 struct dcesrv_lsa_TranslatedItem *item)
2022 const struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
2023 const struct lsa_ForestTrustDomainInfo *di = NULL;
2024 struct dcesrv_lsa_TranslatedItem tmp;
2025 struct dom_sid domain_sid = {0,};
2030 * Verify the sid is not INVALID.
2033 status = dom_sid_lookup_predefined_sid(tmp.sid,
2037 &tmp.authority_name);
2038 if (NT_STATUS_IS_OK(status)) {
2039 status = NT_STATUS_NONE_MAPPED;
2041 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
2043 * Typically INVALID_SID
2048 if (state->routing_table == NULL) {
2049 struct lsa_policy_state *policy_state = state->policy_state;
2051 status = dsdb_trust_routing_table_load(policy_state->sam_ldb,
2053 &state->routing_table);
2054 if (!NT_STATUS_IS_OK(status)) {
2059 domain_sid = *item->sid;
2060 if (domain_sid.num_auths == 5) {
2061 sid_split_rid(&domain_sid, NULL);
2064 tdo = dsdb_trust_domain_by_sid(state->routing_table,
2068 * The sid is not resolvable at all...
2070 return NT_STATUS_OK;
2073 if (tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
2075 * The name should have been resolved in the account view.
2077 * TODO: handle multiple domains in a forest...
2079 return NT_STATUS_OK;
2082 match = dom_sid_equal(di->domain_sid, item->sid);
2084 const char *name = NULL;
2086 name = talloc_strdup(state->mem_ctx,
2087 di->netbios_domain_name.string);
2089 return NT_STATUS_NO_MEMORY;
2092 item->type = SID_NAME_DOMAIN;
2094 item->authority_name = name;
2095 item->authority_sid = item->sid;
2096 return NT_STATUS_OK;
2100 * We know at least the domain part of the sid exists.
2102 * For now the rest handled within winbindd.
2104 * In future we can optimize it based on
2107 * We can also try to resolve SID_NAME_DOMAIN
2108 * just based on the routing table.
2110 if (state->wb.irpc_handle != NULL) {
2114 return NT_STATUS_NONE_MAPPED;
2117 state->wb.irpc_handle = irpc_binding_handle_by_name(state,
2118 state->dce_call->msg_ctx,
2121 if (state->wb.irpc_handle == NULL) {
2122 DEBUG(0,("Failed to get binding_handle for winbind_server task\n"));
2123 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
2124 return NT_STATUS_INVALID_SYSTEM_SERVICE;
2128 * 60 seconds timeout should be enough
2130 dcerpc_binding_handle_set_timeout(state->wb.irpc_handle, 60);
2132 return NT_STATUS_NONE_MAPPED;
2135 static const struct dcesrv_lsa_Lookup_view view_winbind = {
2137 .lookup_sid = dcesrv_lsa_lookup_sid_winbind,
2138 .lookup_name = dcesrv_lsa_lookup_name_winbind,
2141 static const struct dcesrv_lsa_Lookup_view *table_all_views[] = {
2148 static const struct dcesrv_lsa_Lookup_view_table table_all = {
2149 .name = "LSA_LOOKUP_NAMES_ALL",
2150 .count = ARRAY_SIZE(table_all_views),
2151 .array = table_all_views,
2154 static const struct dcesrv_lsa_Lookup_view *table_domains_views[] = {
2159 static const struct dcesrv_lsa_Lookup_view_table table_domains = {
2160 .name = "LSA_LOOKUP_NAMES_DOMAINS_ONLY",
2161 .count = ARRAY_SIZE(table_domains_views),
2162 .array = table_domains_views,
2165 static const struct dcesrv_lsa_Lookup_view *table_primary_views[] = {
2169 static const struct dcesrv_lsa_Lookup_view_table table_primary = {
2170 .name = "LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY",
2171 .count = ARRAY_SIZE(table_primary_views),
2172 .array = table_primary_views,
2175 static const struct dcesrv_lsa_Lookup_view *table_remote_views[] = {
2179 static const struct dcesrv_lsa_Lookup_view_table table_gc = {
2180 .name = "LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY",
2181 .count = ARRAY_SIZE(table_domains_views),
2182 .array = table_domains_views,
2185 static const struct dcesrv_lsa_Lookup_view_table table_xreferral = {
2186 .name = "LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY",
2187 .count = ARRAY_SIZE(table_remote_views),
2188 .array = table_remote_views,
2191 static const struct dcesrv_lsa_Lookup_view_table table_xresolve = {
2192 .name = "LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2",
2193 .count = ARRAY_SIZE(table_domains_views),
2194 .array = table_domains_views,
2197 static const struct dcesrv_lsa_Lookup_view_table table_rodc = {
2198 .name = "LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC",
2199 .count = ARRAY_SIZE(table_remote_views),
2200 .array = table_remote_views,
2203 static const struct dcesrv_lsa_Lookup_view_table *dcesrv_lsa_view_table(
2204 enum lsa_LookupNamesLevel level)
2207 case LSA_LOOKUP_NAMES_ALL:
2209 case LSA_LOOKUP_NAMES_DOMAINS_ONLY:
2210 return &table_domains;
2211 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY:
2212 return &table_primary;
2213 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY:
2215 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY:
2216 return &table_xreferral;
2217 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2:
2218 return &table_xresolve;
2219 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: