becbcfc8b649835239c02272840a90aa8dc8041f
[metze/samba/wip.git] / source4 / rpc_server / lsa / lsa_lookup.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    endpoint server for the lsarpc pipe
5
6    Copyright (C) Andrew Tridgell 2004
7    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2007
8    
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.
13    
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.
18    
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/>.
21 */
22
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"
28
29 struct dcesrv_lsa_TranslatedItem {
30         enum lsa_SidType type;
31         const struct dom_sid *sid;
32         const char *name;
33         const char *authority_name;
34         const struct dom_sid *authority_sid;
35         uint32_t flags;
36         uint32_t wb_idx;
37         bool done;
38         struct {
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" */
44         } hints;
45 };
46
47 struct dcesrv_lsa_LookupSids_base_state;
48 struct dcesrv_lsa_LookupNames_base_state;
49
50 struct dcesrv_lsa_Lookup_view {
51         const char *name;
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);
56 };
57
58 struct dcesrv_lsa_Lookup_view_table {
59         const char *name;
60         size_t count;
61         const struct dcesrv_lsa_Lookup_view **array;
62 };
63
64 static const struct dcesrv_lsa_Lookup_view_table *dcesrv_lsa_view_table(
65         enum lsa_LookupNamesLevel level);
66
67 /*
68   lookup a SID for 1 name
69 */
70 static NTSTATUS dcesrv_lsa_lookup_name(struct lsa_policy_state *state,
71                                        TALLOC_CTX *mem_ctx,
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)
78 {
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;
84         NTSTATUS status;
85         const struct dom_sid *sid = NULL;
86         uint32_t atype;
87         enum lsa_SidType type;
88         bool match = false;
89         int ret;
90
91         if ((principal == NULL) || (principal[0] == '\0')) {
92                 return NT_STATUS_NONE_MAPPED;
93         }
94
95         at = strchr(principal, '@');
96         if (at != NULL) {
97                 const char *nt4_domain = NULL;
98
99                 status = crack_name_to_nt4_name(mem_ctx,
100                                                 state->sam_ldb,
101                                                 DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
102                                                 principal,
103                                                 &nt4_domain,
104                                                 &nt4_account);
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)));
108                         return status;
109                 }
110
111                 match = strequal(nt4_domain, domain_name);
112                 if (!match) {
113                         /*
114                          * TODO: handle multiple domains in a forest.
115                          */
116                         return NT_STATUS_NONE_MAPPED;
117                 }
118         } else {
119                 nt4_account = principal;
120         }
121
122         encoded_account = ldb_binary_encode_string(mem_ctx, nt4_account);
123         if (encoded_account == NULL) {
124                 return NT_STATUS_NO_MEMORY;
125         }
126
127         ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs, 
128                            "(&(sAMAccountName=%s)(objectSid=*))", 
129                            encoded_account);
130         TALLOC_FREE(encoded_account);
131         if (ret < 0) {
132                 return NT_STATUS_INTERNAL_DB_ERROR;
133         }
134         if (ret == 0) {
135                 return NT_STATUS_NONE_MAPPED;
136         }
137         if (ret > 1) {
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));
141                 return status;
142         }
143
144         sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
145         if (sid == NULL) {
146                 return NT_STATUS_NO_MEMORY;
147         }
148
149         /* Check that this is in the domain */
150         match = dom_sid_in_domain(domain_sid, sid);
151         if (!match) {
152                 return NT_STATUS_NONE_MAPPED;
153         }
154
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;
159         }
160
161         *p_sid = sid;
162         *p_type = type;
163         return NT_STATUS_OK;
164 }
165
166
167 /*
168   add to the lsa_RefDomainList for LookupSids and LookupNames
169 */
170 static NTSTATUS dcesrv_lsa_authority_list(const char *authority_name,
171                                           const struct dom_sid *authority_sid,
172                                           struct lsa_RefDomainList *domains,
173                                           uint32_t *sid_index)
174 {
175         uint32_t i;
176
177         *sid_index = UINT32_MAX;
178
179         if (authority_name == NULL) {
180                 return NT_STATUS_OK;
181         }
182
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) {
186                         *sid_index = i;
187                         return NT_STATUS_OK;
188                 }
189         }
190
191         domains->domains = talloc_realloc(domains, 
192                                           domains->domains,
193                                           struct lsa_DomainInfo,
194                                           domains->count+1);
195         if (domains->domains == NULL) {
196                 return NT_STATUS_NO_MEMORY;
197         }
198         domains->domains[i].name.string = talloc_strdup(domains->domains,
199                                                         authority_name);
200         if (domains->domains[i].name.string == NULL) {
201                 return NT_STATUS_NO_MEMORY;
202         }
203         domains->domains[i].sid         = dom_sid_dup(domains->domains,
204                                                       authority_sid);
205         if (domains->domains[i].sid == NULL) {
206                 return NT_STATUS_NO_MEMORY;
207         }
208         domains->count++;
209         domains->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER * domains->count;
210         *sid_index = i;
211
212         return NT_STATUS_OK;
213 }
214
215 /*
216   lookup a name for 1 SID
217 */
218 static NTSTATUS dcesrv_lsa_lookup_sid(struct lsa_policy_state *state,
219                                       TALLOC_CTX *mem_ctx,
220                                       const char *domain_name,
221                                       const struct dom_sid *domain_sid,
222                                       struct ldb_dn *domain_dn,
223                                       const struct dom_sid *sid,
224                                       const char **p_name,
225                                       enum lsa_SidType *p_type)
226 {
227         const char * const attrs[] = { "sAMAccountName", "sAMAccountType", NULL};
228         struct ldb_message **res = NULL;
229         char *encoded_sid = NULL;
230         const char *name = NULL;
231         uint32_t atype;
232         enum lsa_SidType type;
233         int ret;
234
235         encoded_sid = ldap_encode_ndr_dom_sid(mem_ctx, sid);
236         if (encoded_sid == NULL) {
237                 return NT_STATUS_NO_MEMORY;
238         }
239
240         ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs, 
241                            "(&(objectSid=%s)(sAMAccountName=*))", encoded_sid);
242         TALLOC_FREE(encoded_sid);
243         if (ret < 0) {
244                 return NT_STATUS_INTERNAL_DB_ERROR;
245         }
246         if (ret == 0) {
247                 return NT_STATUS_NONE_MAPPED;
248         }
249         if (ret > 1) {
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));
253                 return status;
254         }
255
256         name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
257         if (name == NULL) {
258                 return NT_STATUS_INTERNAL_ERROR;
259         }
260
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;
265         }
266
267         *p_name = name;
268         *p_type = type;
269         return NT_STATUS_OK;
270 }
271
272 struct dcesrv_lsa_LookupSids_base_state {
273         struct dcesrv_call_state *dce_call;
274
275         TALLOC_CTX *mem_ctx;
276
277         struct lsa_policy_state *policy_state;
278
279         struct lsa_LookupSids3 r;
280
281         const struct dcesrv_lsa_Lookup_view_table *view_table;
282         struct dcesrv_lsa_TranslatedItem *items;
283
284         struct dsdb_trust_routing_table *routing_table;
285
286         struct {
287                 struct dcerpc_binding_handle *irpc_handle;
288                 struct lsa_SidArray sids;
289                 struct lsa_RefDomainList *domains;
290                 struct lsa_TransNameArray2 names;
291                 uint32_t count;
292                 NTSTATUS result;
293         } wb;
294
295         struct {
296                 struct lsa_LookupSids *l;
297                 struct lsa_LookupSids2 *l2;
298                 struct lsa_LookupSids3 *l3;
299         } _r;
300 };
301
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);
307
308 static NTSTATUS dcesrv_lsa_LookupSids_base_call(struct dcesrv_lsa_LookupSids_base_state *state)
309 {
310         struct lsa_LookupSids3 *r = &state->r;
311         struct tevent_req *subreq = NULL;
312         uint32_t v;
313         uint32_t i;
314
315         *r->out.domains = NULL;
316         r->out.names->count = 0;
317         r->out.names->names = NULL;
318         *r->out.count = 0;
319
320         state->view_table = dcesrv_lsa_view_table(r->in.level);
321         if (state->view_table == NULL) {
322                 return NT_STATUS_INVALID_PARAMETER;
323         }
324
325         *r->out.domains = talloc_zero(r->out.domains, struct lsa_RefDomainList);
326         if (*r->out.domains == NULL) {
327                 return NT_STATUS_NO_MEMORY;
328         }
329
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;
335         }
336
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;
342         }
343
344         for (i=0;i<r->in.sids->num_sids;i++) {
345                 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
346                 uint32_t rid = 0;
347
348                 if (r->in.sids->sids[i].sid == NULL) {
349                         return NT_STATUS_INVALID_PARAMETER;
350                 }
351
352                 item->type = SID_NAME_UNKNOWN;
353                 item->sid = r->in.sids->sids[i].sid;
354
355                 item->hints.sid = dom_sid_string(state->items, item->sid);
356                 if (item->hints.sid == NULL) {
357                         return NT_STATUS_NO_MEMORY;
358                 }
359
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;
365                 }
366         }
367
368         for (v=0; v < state->view_table->count; v++) {
369                 const struct dcesrv_lsa_Lookup_view *view =
370                         state->view_table->array[v];
371
372                 for (i=0; i < r->in.sids->num_sids; i++) {
373                         struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
374                         NTSTATUS status;
375
376                         if (item->done) {
377                                 continue;
378                         }
379
380                         status = view->lookup_sid(state, item);
381                         if (NT_STATUS_IS_OK(status)) {
382                                 item->done = true;
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;
387                         }
388                         if (!NT_STATUS_IS_OK(status)) {
389                                 return status;
390                         }
391                 }
392         }
393
394         if (state->wb.irpc_handle == NULL) {
395                 return dcesrv_lsa_LookupSids_base_finish(state);
396         }
397
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;
402         }
403
404         for (i=0; i < r->in.sids->num_sids; i++) {
405                 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
406
407                 if (item->done) {
408                         continue;
409                 }
410
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++;
414         }
415
416         subreq = dcerpc_lsa_LookupSids3_send(state,
417                                              state->dce_call->event_ctx,
418                                              state->wb.irpc_handle,
419                                              &state->wb.sids,
420                                              &state->wb.domains,
421                                              &state->wb.names,
422                                              state->r.in.level,
423                                              &state->wb.count,
424                                              state->r.in.lookup_options,
425                                              state->r.in.client_revision);
426         if (subreq == NULL) {
427                 return NT_STATUS_NO_MEMORY;;
428         }
429         state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
430         tevent_req_set_callback(subreq,
431                                 dcesrv_lsa_LookupSids_base_done,
432                                 state);
433
434         return NT_STATUS_OK;
435 }
436
437 static NTSTATUS dcesrv_lsa_LookupSids_base_finish(
438         struct dcesrv_lsa_LookupSids_base_state *state)
439 {
440         struct lsa_LookupSids3 *r = &state->r;
441         uint32_t i;
442
443         for (i=0;i<r->in.sids->num_sids;i++) {
444                 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
445                 NTSTATUS status;
446                 uint32_t sid_index = UINT32_MAX;
447
448                 status = dcesrv_lsa_authority_list(item->authority_name,
449                                                    item->authority_sid,
450                                                    *r->out.domains,
451                                                    &sid_index);
452                 if (!NT_STATUS_IS_OK(status)) {
453                         return status;
454                 }
455
456                 if (item->name == NULL && r->in.level == LSA_LOOKUP_NAMES_ALL) {
457                         if (sid_index == UINT32_MAX) {
458                                 item->name = item->hints.sid;
459                         } else {
460                                 item->name = item->hints.rid;
461                         }
462                 }
463
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;
468
469                 r->out.names->count++;
470                 if (item->type != SID_NAME_UNKNOWN) {
471                         (*r->out.count)++;
472                 }
473         }
474
475         if (*r->out.count == 0) {
476                 return NT_STATUS_NONE_MAPPED;
477         }
478         if (*r->out.count != r->in.sids->num_sids) {
479                 return STATUS_SOME_UNMAPPED;
480         }
481
482         return NT_STATUS_OK;
483 }
484
485 static void dcesrv_lsa_LookupSids_base_map(
486         struct dcesrv_lsa_LookupSids_base_state *state)
487 {
488         if (state->_r.l3 != NULL) {
489                 struct lsa_LookupSids3 *r = state->_r.l3;
490
491                 r->out.result = state->r.out.result;
492                 return;
493         }
494
495         if (state->_r.l2 != NULL) {
496                 struct lsa_LookupSids2 *r = state->_r.l2;
497
498                 r->out.result = state->r.out.result;
499                 return;
500         }
501
502         if (state->_r.l != NULL) {
503                 struct lsa_LookupSids *r = state->_r.l;
504                 uint32_t i;
505
506                 r->out.result = state->r.out.result;
507
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];
514
515                         n->sid_type = n2->sid_type;
516                         n->name = n2->name;
517                         n->sid_index = n2->sid_index;
518                 }
519                 r->out.names->count = state->r.out.names->count;
520                 return;
521         }
522 }
523
524 static void dcesrv_lsa_LookupSids_base_done(struct tevent_req *subreq)
525 {
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;
530         NTSTATUS status;
531         uint32_t i;
532
533         status = dcerpc_lsa_LookupSids3_recv(subreq, state->mem_ctx,
534                                              &state->wb.result);
535         TALLOC_FREE(subreq);
536         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
537                 DEBUG(0,(__location__ ": IRPC callback failed %s\n",
538                          nt_errstr(status)));
539                 goto finished;
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",
543                          nt_errstr(status)));
544                 goto finished;
545         }
546
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;
552         }
553         if (!NT_STATUS_IS_OK(status)) {
554                 goto finished;
555         }
556
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;
561
562                 if (item->done) {
563                         continue;
564                 }
565
566                 if (item->wb_idx >= state->wb.names.count) {
567                         status = NT_STATUS_INTERNAL_ERROR;
568                         goto finished;
569                 }
570
571                 s2 = &state->wb.names.names[item->wb_idx];
572
573                 item->type = s2->sid_type;
574                 item->name = s2->name.string;
575                 item->flags = s2->unknown;
576
577                 if (s2->sid_index == UINT32_MAX) {
578                         continue;
579                 }
580
581                 if (state->wb.domains == NULL) {
582                         status = NT_STATUS_INTERNAL_ERROR;
583                         goto finished;
584                 }
585
586                 if (s2->sid_index >= state->wb.domains->count) {
587                         status = NT_STATUS_INTERNAL_ERROR;
588                         goto finished;
589                 }
590
591                 d = &state->wb.domains->domains[s2->sid_index];
592
593                 item->authority_name = d->name.string;
594                 item->authority_sid = d->sid;
595         }
596
597         status = dcesrv_lsa_LookupSids_base_finish(state);
598  finished:
599         state->r.out.result = status;
600         dcesrv_lsa_LookupSids_base_map(state);
601         TALLOC_FREE(state);
602
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)));
606         }
607 }
608
609 /*
610   lsa_LookupSids2
611 */
612 NTSTATUS dcesrv_lsa_LookupSids2(struct dcesrv_call_state *dce_call,
613                                 TALLOC_CTX *mem_ctx,
614                                 struct lsa_LookupSids2 *r)
615 {
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;
620         NTSTATUS status;
621
622         if (transport != NCACN_NP && transport != NCALRPC) {
623                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
624         }
625
626         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
627
628         *r->out.domains = NULL;
629         r->out.names->count = 0;
630         r->out.names->names = NULL;
631         *r->out.count = 0;
632
633         state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupSids_base_state);
634         if (state == NULL) {
635                 return NT_STATUS_NO_MEMORY;
636         }
637
638         state->dce_call = dce_call;
639         state->mem_ctx = mem_ctx;
640
641         state->policy_state = policy_handle->data;
642
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;
652
653         state->_r.l2 = r;
654
655         status = dcesrv_lsa_LookupSids_base_call(state);
656
657         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
658                 return status;
659         }
660
661         state->r.out.result = status;
662         dcesrv_lsa_LookupSids_base_map(state);
663         TALLOC_FREE(state);
664         return status;
665 }
666
667
668 /*
669   lsa_LookupSids3
670
671   Identical to LookupSids2, but doesn't take a policy handle
672   
673 */
674 NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call,
675                                 TALLOC_CTX *mem_ctx,
676                                 struct lsa_LookupSids3 *r)
677 {
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;
682         NTSTATUS status;
683
684         if (transport != NCACN_IP_TCP) {
685                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
686         }
687
688         /*
689          * We don't have policy handles on this call. So this must be restricted
690          * to crypto connections only.
691          */
692         if (auth->auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
693             auth->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
694                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
695         }
696
697         *r->out.domains = NULL;
698         r->out.names->count = 0;
699         r->out.names->names = NULL;
700         *r->out.count = 0;
701
702         state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupSids_base_state);
703         if (state == NULL) {
704                 return NT_STATUS_NO_MEMORY;
705         }
706
707         state->dce_call = dce_call;
708         state->mem_ctx = mem_ctx;
709
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)) {
714                 return status;
715         }
716
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;
726
727         state->_r.l3 = r;
728
729         status = dcesrv_lsa_LookupSids_base_call(state);
730
731         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
732                 return status;
733         }
734
735         state->r.out.result = status;
736         dcesrv_lsa_LookupSids_base_map(state);
737         TALLOC_FREE(state);
738         return status;
739 }
740
741
742 /* 
743   lsa_LookupSids 
744 */
745 NTSTATUS dcesrv_lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
746                                struct lsa_LookupSids *r)
747 {
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;
752         NTSTATUS status;
753
754         if (transport != NCACN_NP && transport != NCALRPC) {
755                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
756         }
757
758         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
759
760         *r->out.domains = NULL;
761         r->out.names->count = 0;
762         r->out.names->names = NULL;
763         *r->out.count = 0;
764
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;
770         }
771
772         state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupSids_base_state);
773         if (state == NULL) {
774                 return NT_STATUS_NO_MEMORY;
775         }
776
777         state->dce_call = dce_call;
778         state->mem_ctx = mem_ctx;
779
780         state->policy_state = policy_handle->data;
781
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;
789         }
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;
795         }
796         state->r.out.count = r->out.count;
797
798         state->_r.l = r;
799
800         status = dcesrv_lsa_LookupSids_base_call(state);
801
802         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
803                 return status;
804         }
805
806         state->r.out.result = status;
807         dcesrv_lsa_LookupSids_base_map(state);
808         TALLOC_FREE(state);
809         return status;
810 }
811
812 struct dcesrv_lsa_LookupNames_base_state {
813         struct dcesrv_call_state *dce_call;
814
815         TALLOC_CTX *mem_ctx;
816
817         struct lsa_policy_state *policy_state;
818
819         struct lsa_LookupNames4 r;
820
821         const struct dcesrv_lsa_Lookup_view_table *view_table;
822         struct dcesrv_lsa_TranslatedItem *items;
823
824         struct dsdb_trust_routing_table *routing_table;
825
826         struct {
827                 struct dcerpc_binding_handle *irpc_handle;
828                 uint32_t num_names;
829                 struct lsa_String *names;
830                 struct lsa_RefDomainList *domains;
831                 struct lsa_TransSidArray3 sids;
832                 uint32_t count;
833                 NTSTATUS result;
834         } wb;
835
836         struct {
837                 struct lsa_LookupNames *l;
838                 struct lsa_LookupNames2 *l2;
839                 struct lsa_LookupNames3 *l3;
840                 struct lsa_LookupNames4 *l4;
841         } _r;
842 };
843
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);
849
850 static NTSTATUS dcesrv_lsa_LookupNames_base_call(struct dcesrv_lsa_LookupNames_base_state *state)
851 {
852         struct lsa_LookupNames4 *r = &state->r;
853         enum lsa_LookupOptions invalid_lookup_options = 0;
854         struct tevent_req *subreq = NULL;
855         uint32_t v;
856         uint32_t i;
857
858         *r->out.domains = NULL;
859         r->out.sids->count = 0;
860         r->out.sids->sids = NULL;
861         *r->out.count = 0;
862
863         if (r->in.level != LSA_LOOKUP_NAMES_ALL) {
864                 invalid_lookup_options |=
865                         LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES_LOCAL;
866         }
867         if (r->in.lookup_options & invalid_lookup_options) {
868                 return NT_STATUS_INVALID_PARAMETER;
869         }
870
871         state->view_table = dcesrv_lsa_view_table(r->in.level);
872         if (state->view_table == NULL) {
873                 return NT_STATUS_INVALID_PARAMETER;
874         }
875
876         *r->out.domains = talloc_zero(r->out.domains, struct lsa_RefDomainList);
877         if (*r->out.domains == NULL) {
878                 return NT_STATUS_NO_MEMORY;
879         }
880
881         r->out.sids->sids = talloc_zero_array(r->out.sids,
882                                               struct lsa_TranslatedSid3,
883                                               r->in.num_names);
884         if (r->out.sids->sids == NULL) {
885                 return NT_STATUS_NO_MEMORY;
886         }
887
888         state->items = talloc_zero_array(state,
889                                          struct dcesrv_lsa_TranslatedItem,
890                                          r->in.num_names);
891         if (state->items == NULL) {
892                 return NT_STATUS_NO_MEMORY;
893         }
894
895         for (i=0;i<r->in.num_names;i++) {
896                 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
897                 char *p = NULL;
898
899                 item->type = SID_NAME_UNKNOWN;
900                 item->name = r->in.names[i].string;
901                 /*
902                  * Note: that item->name can be NULL!
903                  *
904                  * See test_LookupNames_NULL() in
905                  * source4/torture/rpc/lsa.c
906                  *
907                  * nt4 returns NT_STATUS_NONE_MAPPED with sid_type
908                  * SID_NAME_UNKNOWN, rid 0, and sid_index -1;
909                  *
910                  * w2k3/w2k8 return NT_STATUS_OK with sid_type
911                  * SID_NAME_DOMAIN, rid -1 and sid_index 0 and BUILTIN domain
912                  */
913                 if (item->name == NULL) {
914                         continue;
915                 }
916
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,
921                                                             item->name,
922                                                             p - item->name);
923                         if (item->hints.domain == NULL) {
924                                 return NT_STATUS_NO_MEMORY;
925                         }
926                         item->hints.namespace = item->hints.domain;
927                         p++;
928                         if (p[0] == '\0') {
929                                 /*
930                                  * This is just 'BUILTIN\'.
931                                  */
932                                 item->hints.principal = NULL;
933                         } else {
934                                 item->hints.principal = p;
935                         }
936                 }
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;
941                         }
942                 }
943         }
944
945         for (v=0; v < state->view_table->count; v++) {
946                 const struct dcesrv_lsa_Lookup_view *view =
947                         state->view_table->array[v];
948
949                 for (i=0; i < r->in.num_names; i++) {
950                         struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
951                         NTSTATUS status;
952
953                         if (item->done) {
954                                 continue;
955                         }
956
957                         status = view->lookup_name(state, item);
958                         if (NT_STATUS_IS_OK(status)) {
959                                 item->done = true;
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;
964                         }
965                         if (!NT_STATUS_IS_OK(status)) {
966                                 return status;
967                         }
968                 }
969         }
970
971         if (state->wb.irpc_handle == NULL) {
972                 return dcesrv_lsa_LookupNames_base_finish(state);
973         }
974
975         state->wb.names = talloc_zero_array(state, struct lsa_String,
976                                             r->in.num_names);
977         if (state->wb.names == NULL) {
978                 return NT_STATUS_NO_MEMORY;
979         }
980
981         for (i=0;i<r->in.num_names;i++) {
982                 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
983
984                 if (item->done) {
985                         continue;
986                 }
987
988                 item->wb_idx = state->wb.num_names;
989                 state->wb.names[item->wb_idx] = r->in.names[i];
990                 state->wb.num_names++;
991         }
992
993         subreq = dcerpc_lsa_LookupNames4_send(state,
994                                               state->dce_call->event_ctx,
995                                               state->wb.irpc_handle,
996                                               state->wb.num_names,
997                                               state->wb.names,
998                                               &state->wb.domains,
999                                               &state->wb.sids,
1000                                               state->r.in.level,
1001                                               &state->wb.count,
1002                                               state->r.in.lookup_options,
1003                                               state->r.in.client_revision);
1004         if (subreq == NULL) {
1005                 return NT_STATUS_NO_MEMORY;
1006         }
1007         state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
1008         tevent_req_set_callback(subreq,
1009                                 dcesrv_lsa_LookupNames_base_done,
1010                                 state);
1011
1012         return NT_STATUS_OK;
1013 }
1014
1015 static NTSTATUS dcesrv_lsa_LookupNames_base_finish(
1016         struct dcesrv_lsa_LookupNames_base_state *state)
1017 {
1018         struct lsa_LookupNames4 *r = &state->r;
1019         uint32_t i;
1020
1021         for (i=0;i<r->in.num_names;i++) {
1022                 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
1023                 NTSTATUS status;
1024                 uint32_t sid_index = UINT32_MAX;
1025
1026                 status = dcesrv_lsa_authority_list(item->authority_name,
1027                                                    item->authority_sid,
1028                                                    *r->out.domains,
1029                                                    &sid_index);
1030                 if (!NT_STATUS_IS_OK(status)) {
1031                         return status;
1032                 }
1033
1034                 r->out.sids->sids[i].sid_type  = item->type;
1035                 r->out.sids->sids[i].sid       = discard_const_p(struct dom_sid,
1036                                                                  item->sid);
1037                 r->out.sids->sids[i].sid_index = sid_index;
1038                 r->out.sids->sids[i].flags     = item->flags;
1039
1040                 r->out.sids->count++;
1041                 if (item->type != SID_NAME_UNKNOWN) {
1042                         (*r->out.count)++;
1043                 }
1044         }
1045
1046         if (*r->out.count == 0) {
1047                 return NT_STATUS_NONE_MAPPED;
1048         }
1049         if (*r->out.count != r->in.num_names) {
1050                 return STATUS_SOME_UNMAPPED;
1051         }
1052
1053         return NT_STATUS_OK;
1054 }
1055
1056 static void dcesrv_lsa_LookupNames_base_map(
1057         struct dcesrv_lsa_LookupNames_base_state *state)
1058 {
1059         if (state->_r.l4 != NULL) {
1060                 struct lsa_LookupNames4 *r = state->_r.l4;
1061
1062                 r->out.result = state->r.out.result;
1063                 return;
1064         }
1065
1066         if (state->_r.l3 != NULL) {
1067                 struct lsa_LookupNames3 *r = state->_r.l3;
1068
1069                 r->out.result = state->r.out.result;
1070                 return;
1071         }
1072
1073         if (state->_r.l2 != NULL) {
1074                 struct lsa_LookupNames2 *r = state->_r.l2;
1075                 uint32_t i;
1076
1077                 r->out.result = state->r.out.result;
1078
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];
1085
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) {
1092                                 /*
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
1096                                  */
1097                                 s2->rid = 0;
1098                         } else {
1099                                 s2->rid = 0;
1100                                 dom_sid_split_rid(NULL, s3->sid,
1101                                                   NULL, &s2->rid);
1102                         }
1103                         s2->sid_index = s3->sid_index;
1104                         s2->unknown = s3->flags;
1105                 }
1106                 r->out.sids->count = state->r.out.sids->count;
1107                 return;
1108         }
1109
1110         if (state->_r.l != NULL) {
1111                 struct lsa_LookupNames *r = state->_r.l;
1112                 uint32_t i;
1113
1114                 r->out.result = state->r.out.result;
1115
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];
1122
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) {
1129                                 /*
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
1133                                  */
1134                                 s->rid = 0;
1135                         } else {
1136                                 s->rid = 0;
1137                                 dom_sid_split_rid(NULL, s3->sid,
1138                                                   NULL, &s->rid);
1139                         }
1140                         s->sid_index = s3->sid_index;
1141                 }
1142                 r->out.sids->count = state->r.out.sids->count;
1143                 return;
1144         }
1145 }
1146
1147 static void dcesrv_lsa_LookupNames_base_done(struct tevent_req *subreq)
1148 {
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;
1153         NTSTATUS status;
1154         uint32_t i;
1155
1156         status = dcerpc_lsa_LookupNames4_recv(subreq, state->mem_ctx,
1157                                               &state->wb.result);
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)));
1162                 goto finished;
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)));
1167                 goto finished;
1168         }
1169
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;
1175         }
1176         if (!NT_STATUS_IS_OK(status)) {
1177                 goto finished;
1178         }
1179
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;
1184
1185                 if (item->done) {
1186                         continue;
1187                 }
1188
1189                 if (item->wb_idx >= state->wb.sids.count) {
1190                         status = NT_STATUS_INTERNAL_ERROR;
1191                         goto finished;
1192                 }
1193
1194                 s3 = &state->wb.sids.sids[item->wb_idx];
1195
1196                 item->type = s3->sid_type;
1197                 item->sid = s3->sid;
1198                 item->flags = s3->flags;
1199
1200                 if (s3->sid_index == UINT32_MAX) {
1201                         continue;
1202                 }
1203
1204                 if (state->wb.domains == NULL) {
1205                         status = NT_STATUS_INTERNAL_ERROR;
1206                         goto finished;
1207                 }
1208
1209                 if (s3->sid_index >= state->wb.domains->count) {
1210                         status = NT_STATUS_INTERNAL_ERROR;
1211                         goto finished;
1212                 }
1213
1214                 d = &state->wb.domains->domains[s3->sid_index];
1215
1216                 item->authority_name = d->name.string;
1217                 item->authority_sid = d->sid;
1218         }
1219
1220         status = dcesrv_lsa_LookupNames_base_finish(state);
1221  finished:
1222         state->r.out.result = status;
1223         dcesrv_lsa_LookupNames_base_map(state);
1224         TALLOC_FREE(state);
1225
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)));
1229         }
1230 }
1231
1232 /*
1233   lsa_LookupNames3
1234 */
1235 NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call,
1236                                  TALLOC_CTX *mem_ctx,
1237                                  struct lsa_LookupNames3 *r)
1238 {
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;
1243         NTSTATUS status;
1244
1245         if (transport != NCACN_NP && transport != NCALRPC) {
1246                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
1247         }
1248
1249         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1250
1251         *r->out.domains = NULL;
1252         r->out.sids->count = 0;
1253         r->out.sids->sids = NULL;
1254         *r->out.count = 0;
1255
1256         state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
1257         if (state == NULL) {
1258                 return NT_STATUS_NO_MEMORY;
1259         }
1260
1261         state->dce_call = dce_call;
1262         state->mem_ctx = mem_ctx;
1263
1264         state->policy_state = policy_handle->data;
1265
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;
1276
1277         state->_r.l3 = r;
1278
1279         status = dcesrv_lsa_LookupNames_base_call(state);
1280
1281         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1282                 return status;
1283         }
1284
1285         state->r.out.result = status;
1286         dcesrv_lsa_LookupNames_base_map(state);
1287         TALLOC_FREE(state);
1288         return status;
1289 }
1290
1291 /* 
1292   lsa_LookupNames4
1293
1294   Identical to LookupNames3, but doesn't take a policy handle
1295   
1296 */
1297 NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1298                                  struct lsa_LookupNames4 *r)
1299 {
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;
1304         NTSTATUS status;
1305
1306         if (transport != NCACN_IP_TCP) {
1307                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
1308         }
1309
1310         /*
1311          * We don't have policy handles on this call. So this must be restricted
1312          * to crypto connections only.
1313          */
1314         if (auth->auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
1315             auth->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1316                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
1317         }
1318
1319         *r->out.domains = NULL;
1320         r->out.sids->count = 0;
1321         r->out.sids->sids = NULL;
1322         *r->out.count = 0;
1323
1324         state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
1325         if (state == NULL) {
1326                 return NT_STATUS_NO_MEMORY;
1327         }
1328
1329         state->dce_call = dce_call;
1330         state->mem_ctx = mem_ctx;
1331
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)) {
1336                 return status;
1337         }
1338
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;
1349
1350         state->_r.l4 = r;
1351
1352         status = dcesrv_lsa_LookupNames_base_call(state);
1353
1354         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1355                 return status;
1356         }
1357
1358         state->r.out.result = status;
1359         dcesrv_lsa_LookupNames_base_map(state);
1360         TALLOC_FREE(state);
1361         return status;
1362 }
1363
1364 /*
1365   lsa_LookupNames2
1366 */
1367 NTSTATUS dcesrv_lsa_LookupNames2(struct dcesrv_call_state *dce_call,
1368                                  TALLOC_CTX *mem_ctx,
1369                                  struct lsa_LookupNames2 *r)
1370 {
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;
1375         NTSTATUS status;
1376
1377         if (transport != NCACN_NP && transport != NCALRPC) {
1378                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
1379         }
1380
1381         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1382
1383         *r->out.domains = NULL;
1384         r->out.sids->count = 0;
1385         r->out.sids->sids = NULL;
1386         *r->out.count = 0;
1387
1388         r->out.sids->sids = talloc_zero_array(r->out.sids,
1389                                               struct lsa_TranslatedSid2,
1390                                               r->in.num_names);
1391         if (r->out.sids->sids == NULL) {
1392                 return NT_STATUS_NO_MEMORY;
1393         }
1394
1395         state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
1396         if (state == NULL) {
1397                 return NT_STATUS_NO_MEMORY;
1398         }
1399
1400         state->dce_call = dce_call;
1401         state->mem_ctx = mem_ctx;
1402
1403         state->policy_state = policy_handle->data;
1404
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;
1408         /*
1409          * MS-LSAT 3.1.4.7:
1410          *
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.
1414          */
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;
1420         }
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;
1426         }
1427         state->r.out.count = r->out.count;
1428
1429         state->_r.l2 = r;
1430
1431         status = dcesrv_lsa_LookupNames_base_call(state);
1432
1433         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1434                 return status;
1435         }
1436
1437         state->r.out.result = status;
1438         dcesrv_lsa_LookupNames_base_map(state);
1439         TALLOC_FREE(state);
1440         return status;
1441 }
1442
1443 /* 
1444   lsa_LookupNames 
1445 */
1446 NTSTATUS dcesrv_lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1447                        struct lsa_LookupNames *r)
1448 {
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;
1453         NTSTATUS status;
1454
1455         if (transport != NCACN_NP && transport != NCALRPC) {
1456                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
1457         }
1458
1459         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1460
1461         *r->out.domains = NULL;
1462         r->out.sids->count = 0;
1463         r->out.sids->sids = NULL;
1464         *r->out.count = 0;
1465
1466         r->out.sids->sids = talloc_zero_array(r->out.sids,
1467                                               struct lsa_TranslatedSid,
1468                                               r->in.num_names);
1469         if (r->out.sids->sids == NULL) {
1470                 return NT_STATUS_NO_MEMORY;
1471         }
1472
1473         state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
1474         if (state == NULL) {
1475                 return NT_STATUS_NO_MEMORY;
1476         }
1477
1478         state->dce_call = dce_call;
1479         state->mem_ctx = mem_ctx;
1480
1481         state->policy_state = policy_handle->data;
1482
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;
1491         }
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;
1497         }
1498         state->r.out.count = r->out.count;
1499
1500         state->_r.l = r;
1501
1502         status = dcesrv_lsa_LookupNames_base_call(state);
1503
1504         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1505                 return status;
1506         }
1507
1508         state->r.out.result = status;
1509         dcesrv_lsa_LookupNames_base_map(state);
1510         TALLOC_FREE(state);
1511         return status;
1512 }
1513
1514 static NTSTATUS dcesrv_lsa_lookup_name_predefined(
1515                 struct dcesrv_lsa_LookupNames_base_state *state,
1516                 struct dcesrv_lsa_TranslatedItem *item)
1517 {
1518         NTSTATUS status;
1519
1520         status = dom_sid_lookup_predefined_name(item->name,
1521                                                 &item->sid,
1522                                                 &item->type,
1523                                                 &item->authority_sid,
1524                                                 &item->authority_name);
1525         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1526                 return status;
1527         }
1528         if (!NT_STATUS_IS_OK(status)) {
1529                 return status;
1530         }
1531
1532         return NT_STATUS_OK;
1533 }
1534
1535 static NTSTATUS dcesrv_lsa_lookup_sid_predefined(
1536                 struct dcesrv_lsa_LookupSids_base_state *state,
1537                 struct dcesrv_lsa_TranslatedItem *item)
1538 {
1539         NTSTATUS status;
1540
1541         status = dom_sid_lookup_predefined_sid(item->sid,
1542                                                &item->name,
1543                                                &item->type,
1544                                                &item->authority_sid,
1545                                                &item->authority_name);
1546         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1547                 return status;
1548         }
1549         if (!NT_STATUS_IS_OK(status)) {
1550                 return status;
1551         }
1552
1553         return NT_STATUS_OK;
1554 }
1555
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,
1560 };
1561
1562 static NTSTATUS dcesrv_lsa_lookup_name_builtin(
1563                 struct dcesrv_lsa_LookupNames_base_state *state,
1564                 struct dcesrv_lsa_TranslatedItem *item)
1565 {
1566         struct lsa_policy_state *policy_state = state->policy_state;
1567         NTSTATUS status;
1568         bool is_builtin = false;
1569
1570         if (item->name == NULL) {
1571                 /*
1572                  * This should not be mapped.
1573                  */
1574                 return NT_STATUS_OK;
1575         }
1576
1577         /*
1578          * The predefined view already handled the BUILTIN domain.
1579          *
1580          * Now we just need to find the principal.
1581          *
1582          * We only allow 'BUILTIN\something' and
1583          * not 'something@BUILTIN.
1584          *
1585          * And we try out best for just 'something'.
1586          */
1587         is_builtin = strequal(item->hints.domain, NAME_BUILTIN);
1588         if (!is_builtin && item->hints.domain != NULL) {
1589                 return NT_STATUS_NONE_MAPPED;
1590         }
1591
1592         status = dcesrv_lsa_lookup_name(state->policy_state,
1593                                         state->mem_ctx,
1594                                         NAME_BUILTIN,
1595                                         policy_state->builtin_sid,
1596                                         policy_state->builtin_dn,
1597                                         item->hints.principal,
1598                                         &item->sid,
1599                                         &item->type);
1600         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1601                 if (!is_builtin) {
1602                         return NT_STATUS_NONE_MAPPED;
1603                 }
1604                 /*
1605                  * We know we're authoritive
1606                  */
1607                 status = NT_STATUS_OK;
1608         }
1609         if (!NT_STATUS_IS_OK(status)) {
1610                 return status;
1611         }
1612
1613         item->authority_name = NAME_BUILTIN;
1614         item->authority_sid = policy_state->builtin_sid;
1615         return NT_STATUS_OK;
1616 }
1617
1618 static NTSTATUS dcesrv_lsa_lookup_sid_builtin(
1619                 struct dcesrv_lsa_LookupSids_base_state *state,
1620                 struct dcesrv_lsa_TranslatedItem *item)
1621 {
1622         struct lsa_policy_state *policy_state = state->policy_state;
1623         NTSTATUS status;
1624         bool is_builtin = false;
1625
1626         /*
1627          * The predefined view already handled the BUILTIN domain.
1628          *
1629          * Now we just need to find the principal.
1630          */
1631         is_builtin = dom_sid_in_domain(policy_state->builtin_sid, item->sid);
1632         if (!is_builtin) {
1633                 return NT_STATUS_NONE_MAPPED;
1634         }
1635
1636         status = dcesrv_lsa_lookup_sid(state->policy_state,
1637                                        state->mem_ctx,
1638                                        NAME_BUILTIN,
1639                                        policy_state->builtin_sid,
1640                                        policy_state->builtin_dn,
1641                                        item->sid,
1642                                        &item->name,
1643                                        &item->type);
1644         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1645                 /*
1646                  * We know we're authoritive
1647                  */
1648                 status = NT_STATUS_OK;
1649         }
1650         if (!NT_STATUS_IS_OK(status)) {
1651                 return status;
1652         }
1653
1654         item->authority_name = NAME_BUILTIN;
1655         item->authority_sid = policy_state->builtin_sid;
1656         return NT_STATUS_OK;
1657 }
1658
1659 static const struct dcesrv_lsa_Lookup_view view_builtin = {
1660         .name = "Builtin",
1661         .lookup_sid = dcesrv_lsa_lookup_sid_builtin,
1662         .lookup_name = dcesrv_lsa_lookup_name_builtin,
1663 };
1664
1665 static NTSTATUS dcesrv_lsa_lookup_name_account(
1666                 struct dcesrv_lsa_LookupNames_base_state *state,
1667                 struct dcesrv_lsa_TranslatedItem *item)
1668 {
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;
1672         NTSTATUS status;
1673         int role;
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;
1678
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;
1682         } else {
1683                 is_local_match_fn = lpcfg_is_myname;
1684         }
1685
1686         if (item->name == NULL) {
1687                 /*
1688                  * This should not be mapped.
1689                  */
1690                 return NT_STATUS_OK;
1691         }
1692
1693         if (item->hints.domain != NULL && item->hints.principal == NULL) {
1694                 /*
1695                  * This is 'DOMAIN\'.
1696                  */
1697                 check_domain_name = item->hints.domain;
1698         } else {
1699                 /*
1700                  * This is just 'DOMAIN'.
1701                  */
1702                 check_domain_name = item->name;
1703         }
1704         is_domain = is_local_match_fn(lp_ctx, check_domain_name);
1705         if (is_domain) {
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;
1711         }
1712
1713         if (r->in.lookup_options & LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES_LOCAL) {
1714                 if (item->hints.domain != item->hints.namespace) {
1715                         /*
1716                          * This means the client asked for an UPN,
1717                          * and it should not be mapped.
1718                          */
1719                         return NT_STATUS_OK;
1720                 }
1721         }
1722
1723         if (item->hints.namespace != NULL) {
1724                 is_domain = is_local_match_fn(lp_ctx, item->hints.namespace);
1725                 try_lookup = is_domain;
1726         } else {
1727                 try_lookup = true;
1728         }
1729
1730         if (!try_lookup) {
1731                 struct dcesrv_lsa_TranslatedItem tmp;
1732
1733                 tmp = *item;
1734                 status = dom_sid_lookup_predefined_name(item->hints.namespace,
1735                                                         &tmp.sid,
1736                                                         &tmp.type,
1737                                                         &tmp.authority_sid,
1738                                                         &tmp.authority_name);
1739                 if (NT_STATUS_IS_OK(status)) {
1740                         /*
1741                          * It should not be handled by us.
1742                          */
1743                         return NT_STATUS_NONE_MAPPED;
1744                 }
1745                 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1746                         return status;
1747                 }
1748         }
1749
1750         if (!try_lookup) {
1751                 const struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
1752                 const struct lsa_ForestTrustDomainInfo *di = NULL;
1753
1754                 if (state->routing_table == NULL) {
1755                         status = dsdb_trust_routing_table_load(policy_state->sam_ldb,
1756                                                                state,
1757                                                                &state->routing_table);
1758                         if (!NT_STATUS_IS_OK(status)) {
1759                                 return status;
1760                         }
1761                 }
1762
1763                 tdo = dsdb_trust_domain_by_name(state->routing_table,
1764                                                 item->hints.namespace,
1765                                                 &di);
1766                 if (tdo == NULL) {
1767                         /*
1768                          * The name is not resolvable at all...
1769                          */
1770                         return NT_STATUS_OK;
1771                 }
1772
1773                 if (!(tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST)) {
1774                         /*
1775                          * The name is not resolvable here
1776                          */
1777                         return NT_STATUS_NONE_MAPPED;
1778                 }
1779
1780                 /*
1781                  * TODO: handle multiple domains in a forest together with
1782                  * LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY
1783                  */
1784                 is_domain = true;
1785                 try_lookup = true;
1786         }
1787
1788         if (!try_lookup) {
1789                 /*
1790                  * It should not be handled by us.
1791                  */
1792                 return NT_STATUS_NONE_MAPPED;
1793         }
1794
1795         /*
1796          * TODO: handle multiple domains in our forest.
1797          */
1798
1799         status = dcesrv_lsa_lookup_name(state->policy_state,
1800                                         state->mem_ctx,
1801                                         policy_state->domain_name,
1802                                         policy_state->domain_sid,
1803                                         policy_state->domain_dn,
1804                                         item->hints.principal,
1805                                         &item->sid,
1806                                         &item->type);
1807         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1808                 if (!is_domain) {
1809                         return NT_STATUS_NONE_MAPPED;
1810                 }
1811                 /*
1812                  * We know we're authoritive
1813                  */
1814                 status = NT_STATUS_OK;
1815         }
1816         if (!NT_STATUS_IS_OK(status)) {
1817                 return status;
1818         }
1819
1820         item->authority_name = policy_state->domain_name;
1821         item->authority_sid = policy_state->domain_sid;
1822         return NT_STATUS_OK;
1823 }
1824
1825 static NTSTATUS dcesrv_lsa_lookup_sid_account(
1826                 struct dcesrv_lsa_LookupSids_base_state *state,
1827                 struct dcesrv_lsa_TranslatedItem *item)
1828 {
1829         struct lsa_policy_state *policy_state = state->policy_state;
1830         NTSTATUS status;
1831         bool is_domain;
1832
1833         is_domain = dom_sid_equal(policy_state->domain_sid, item->sid);
1834         if (is_domain) {
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;
1840         }
1841         is_domain = dom_sid_in_domain(policy_state->domain_sid, item->sid);
1842         if (!is_domain) {
1843                 return NT_STATUS_NONE_MAPPED;
1844         }
1845
1846         status = dcesrv_lsa_lookup_sid(state->policy_state,
1847                                        state->mem_ctx,
1848                                        policy_state->domain_name,
1849                                        policy_state->domain_sid,
1850                                        policy_state->domain_dn,
1851                                        item->sid,
1852                                        &item->name,
1853                                        &item->type);
1854         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1855                 /*
1856                  * We know we're authoritive
1857                  */
1858                 status = NT_STATUS_OK;
1859         }
1860         if (!NT_STATUS_IS_OK(status)) {
1861                 return status;
1862         }
1863
1864         item->authority_name = policy_state->domain_name;
1865         item->authority_sid = policy_state->domain_sid;
1866         return NT_STATUS_OK;
1867 }
1868
1869 static const struct dcesrv_lsa_Lookup_view view_account = {
1870         .name = "Account",
1871         .lookup_sid = dcesrv_lsa_lookup_sid_account,
1872         .lookup_name = dcesrv_lsa_lookup_name_account,
1873 };
1874
1875 static NTSTATUS dcesrv_lsa_lookup_name_winbind(
1876                 struct dcesrv_lsa_LookupNames_base_state *state,
1877                 struct dcesrv_lsa_TranslatedItem *item)
1878 {
1879         struct lsa_LookupNames4 *r = &state->r;
1880         const struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
1881         const struct lsa_ForestTrustDomainInfo *di = NULL;
1882         NTSTATUS status;
1883         const char *check_domain_name = NULL;
1884         bool expect_domain = false;
1885
1886         if (item->name == NULL) {
1887                 /*
1888                  * This should not be mapped.
1889                  */
1890                 return NT_STATUS_OK;
1891         }
1892
1893         if (item->hints.domain != NULL && item->hints.principal == NULL) {
1894                 /*
1895                  * This is 'DOMAIN\'.
1896                  */
1897                 check_domain_name = item->hints.domain;
1898                 expect_domain = true;
1899         } else if (item->hints.namespace != NULL) {
1900                 /*
1901                  * This is 'DOMAIN\someone'
1902                  * or 'someone@DOMAIN'
1903                  */
1904                 check_domain_name = item->hints.namespace;
1905         } else {
1906                 /*
1907                  * This is just 'DOMAIN'.
1908                  */
1909                 check_domain_name = item->name;
1910                 expect_domain = true;
1911         }
1912
1913         if (state->routing_table == NULL) {
1914                 struct lsa_policy_state *policy_state = state->policy_state;
1915
1916                 status = dsdb_trust_routing_table_load(policy_state->sam_ldb,
1917                                                        state,
1918                                                        &state->routing_table);
1919                 if (!NT_STATUS_IS_OK(status)) {
1920                         return status;
1921                 }
1922         }
1923
1924         tdo = dsdb_trust_domain_by_name(state->routing_table,
1925                                         check_domain_name,
1926                                         &di);
1927         if (tdo == NULL) {
1928                 /*
1929                  * The name is not resolvable at all...
1930                  *
1931                  * And for now we don't send unqualified names
1932                  * to winbindd, as we don't handle them
1933                  * there yet.
1934                  *
1935                  * TODO: how should that work within
1936                  * winbindd?
1937                  */
1938                 return NT_STATUS_OK;
1939         }
1940
1941         if (tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
1942                 /*
1943                  * The name should have been resolved in the account view.
1944                  *
1945                  * TODO: handle multiple domains in a forest...
1946                  */
1947                 return NT_STATUS_OK;
1948         }
1949
1950         if (expect_domain) {
1951                 const char *name = NULL;
1952                 const struct dom_sid *sid = NULL;
1953
1954                 name = talloc_strdup(state->mem_ctx,
1955                                      di->netbios_domain_name.string);
1956                 if (name == NULL) {
1957                         return NT_STATUS_NO_MEMORY;
1958                 }
1959                 sid = dom_sid_dup(state->mem_ctx,
1960                                   di->domain_sid);
1961                 if (sid == NULL) {
1962                         return NT_STATUS_NO_MEMORY;
1963                 }
1964                 item->type = SID_NAME_DOMAIN;
1965                 item->sid = sid;
1966                 item->authority_name = name;
1967                 item->authority_sid = sid;
1968                 return NT_STATUS_OK;
1969         }
1970
1971         if (r->in.lookup_options & LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES_LOCAL) {
1972                 if (item->hints.namespace == NULL) {
1973                         /*
1974                          * We should not try to resolve isolated names
1975                          * remotely.
1976                          */
1977                         return NT_STATUS_OK;
1978                 }
1979         }
1980
1981         /*
1982          * We know at least the domain part of the name exists.
1983          *
1984          * For now the rest handled within winbindd.
1985          *
1986          * In future we can optimize it based on
1987          * r->in.level.
1988          *
1989          * We can also try to resolve SID_NAME_DOMAIN
1990          * just based on the routing table.
1991          */
1992
1993         if (state->wb.irpc_handle != NULL) {
1994                 /*
1995                  * already called...
1996                  */
1997                 return NT_STATUS_NONE_MAPPED;
1998         }
1999
2000         state->wb.irpc_handle = irpc_binding_handle_by_name(state,
2001                                         state->dce_call->msg_ctx,
2002                                         "winbind_server",
2003                                         &ndr_table_lsarpc);
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;
2008         }
2009
2010         /*
2011          * 60 seconds timeout should be enough
2012          */
2013         dcerpc_binding_handle_set_timeout(state->wb.irpc_handle, 60);
2014
2015         return NT_STATUS_NONE_MAPPED;
2016 }
2017
2018 static NTSTATUS dcesrv_lsa_lookup_sid_winbind(
2019                 struct dcesrv_lsa_LookupSids_base_state *state,
2020                 struct dcesrv_lsa_TranslatedItem *item)
2021 {
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,};
2026         NTSTATUS status;
2027         bool match;
2028
2029         /*
2030          * Verify the sid is not INVALID.
2031          */
2032         tmp = *item;
2033         status = dom_sid_lookup_predefined_sid(tmp.sid,
2034                                                &tmp.name,
2035                                                &tmp.type,
2036                                                &tmp.authority_sid,
2037                                                &tmp.authority_name);
2038         if (NT_STATUS_IS_OK(status)) {
2039                 status = NT_STATUS_NONE_MAPPED;
2040         }
2041         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
2042                 /*
2043                  * Typically INVALID_SID
2044                  */
2045                 return status;
2046         }
2047
2048         if (state->routing_table == NULL) {
2049                 struct lsa_policy_state *policy_state = state->policy_state;
2050
2051                 status = dsdb_trust_routing_table_load(policy_state->sam_ldb,
2052                                                        state,
2053                                                        &state->routing_table);
2054                 if (!NT_STATUS_IS_OK(status)) {
2055                         return status;
2056                 }
2057         }
2058
2059         domain_sid = *item->sid;
2060         if (domain_sid.num_auths == 5) {
2061                 sid_split_rid(&domain_sid, NULL);
2062         }
2063
2064         tdo = dsdb_trust_domain_by_sid(state->routing_table,
2065                                        &domain_sid, &di);
2066         if (tdo == NULL) {
2067                 /*
2068                  * The sid is not resolvable at all...
2069                  */
2070                 return NT_STATUS_OK;
2071         }
2072
2073         if (tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
2074                 /*
2075                  * The name should have been resolved in the account view.
2076                  *
2077                  * TODO: handle multiple domains in a forest...
2078                  */
2079                 return NT_STATUS_OK;
2080         }
2081
2082         match = dom_sid_equal(di->domain_sid, item->sid);
2083         if (match) {
2084                 const char *name = NULL;
2085
2086                 name = talloc_strdup(state->mem_ctx,
2087                                      di->netbios_domain_name.string);
2088                 if (name == NULL) {
2089                         return NT_STATUS_NO_MEMORY;
2090                 }
2091
2092                 item->type = SID_NAME_DOMAIN;
2093                 item->name = name;
2094                 item->authority_name = name;
2095                 item->authority_sid = item->sid;
2096                 return NT_STATUS_OK;
2097         }
2098
2099         /*
2100          * We know at least the domain part of the sid exists.
2101          *
2102          * For now the rest handled within winbindd.
2103          *
2104          * In future we can optimize it based on
2105          * r->in.level.
2106          *
2107          * We can also try to resolve SID_NAME_DOMAIN
2108          * just based on the routing table.
2109          */
2110         if (state->wb.irpc_handle != NULL) {
2111                 /*
2112                  * already called...
2113                  */
2114                 return NT_STATUS_NONE_MAPPED;
2115         }
2116
2117         state->wb.irpc_handle = irpc_binding_handle_by_name(state,
2118                                         state->dce_call->msg_ctx,
2119                                         "winbind_server",
2120                                         &ndr_table_lsarpc);
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;
2125         }
2126
2127         /*
2128          * 60 seconds timeout should be enough
2129          */
2130         dcerpc_binding_handle_set_timeout(state->wb.irpc_handle, 60);
2131
2132         return NT_STATUS_NONE_MAPPED;
2133 }
2134
2135 static const struct dcesrv_lsa_Lookup_view view_winbind = {
2136         .name = "Winbind",
2137         .lookup_sid = dcesrv_lsa_lookup_sid_winbind,
2138         .lookup_name = dcesrv_lsa_lookup_name_winbind,
2139 };
2140
2141 static const struct dcesrv_lsa_Lookup_view *table_all_views[] = {
2142         &view_predefined,
2143         &view_builtin,
2144         &view_account,
2145         &view_winbind,
2146 };
2147
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,
2152 };
2153
2154 static const struct dcesrv_lsa_Lookup_view *table_domains_views[] = {
2155         &view_account,
2156         &view_winbind,
2157 };
2158
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,
2163 };
2164
2165 static const struct dcesrv_lsa_Lookup_view *table_primary_views[] = {
2166         &view_account,
2167 };
2168
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,
2173 };
2174
2175 static const struct dcesrv_lsa_Lookup_view *table_remote_views[] = {
2176         &view_winbind,
2177 };
2178
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,
2183 };
2184
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,
2189 };
2190
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,
2195 };
2196
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,
2201 };
2202
2203 static const struct dcesrv_lsa_Lookup_view_table *dcesrv_lsa_view_table(
2204         enum lsa_LookupNamesLevel level)
2205 {
2206         switch (level) {
2207         case LSA_LOOKUP_NAMES_ALL:
2208                 return &table_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:
2214                 return &table_gc;
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:
2220                 return &table_rodc;
2221         }
2222
2223         return NULL;
2224 }