Line data Source code
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 27787 : 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 27787 : const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
80 27787 : struct ldb_message **res = NULL;
81 27787 : const char *nt4_account = NULL;
82 27787 : char *encoded_account = NULL;
83 27787 : const char *at = NULL;
84 4800 : NTSTATUS status;
85 27787 : const struct dom_sid *sid = NULL;
86 4800 : uint32_t atype;
87 4800 : enum lsa_SidType type;
88 27787 : bool match = false;
89 4800 : int ret;
90 :
91 27787 : if ((principal == NULL) || (principal[0] == '\0')) {
92 0 : return NT_STATUS_NONE_MAPPED;
93 : }
94 :
95 27787 : at = strchr(principal, '@');
96 27787 : if (at != NULL) {
97 410 : const char *nt4_domain = NULL;
98 :
99 410 : 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 410 : if (!NT_STATUS_IS_OK(status)) {
106 0 : DEBUG(3, ("Failed to crack name %s into an NT4 name: %s\n",
107 : principal, nt_errstr(status)));
108 192 : return status;
109 : }
110 :
111 410 : match = strequal(nt4_domain, domain_name);
112 410 : if (!match) {
113 : /*
114 : * TODO: handle multiple domains in a forest.
115 : */
116 192 : return NT_STATUS_NONE_MAPPED;
117 : }
118 : } else {
119 27377 : nt4_account = principal;
120 : }
121 :
122 27595 : encoded_account = ldb_binary_encode_string(mem_ctx, nt4_account);
123 27595 : if (encoded_account == NULL) {
124 0 : return NT_STATUS_NO_MEMORY;
125 : }
126 :
127 27595 : ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs,
128 : "(&(sAMAccountName=%s)(objectSid=*))",
129 : encoded_account);
130 27595 : TALLOC_FREE(encoded_account);
131 27595 : if (ret < 0) {
132 0 : return NT_STATUS_INTERNAL_DB_ERROR;
133 : }
134 27595 : if (ret == 0) {
135 302 : return NT_STATUS_NONE_MAPPED;
136 : }
137 27293 : if (ret > 1) {
138 0 : status = NT_STATUS_INTERNAL_DB_CORRUPTION;
139 0 : DBG_ERR("nt4_account[%s] found %d times (principal[%s]) - %s\n",
140 : nt4_account, ret, principal, nt_errstr(status));
141 0 : return status;
142 : }
143 :
144 27293 : sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
145 27293 : if (sid == NULL) {
146 0 : return NT_STATUS_NO_MEMORY;
147 : }
148 :
149 : /* Check that this is in the domain */
150 27293 : match = dom_sid_in_domain(domain_sid, sid);
151 27293 : if (!match) {
152 0 : return NT_STATUS_NONE_MAPPED;
153 : }
154 :
155 27293 : atype = ldb_msg_find_attr_as_uint(res[0], "sAMAccountType", 0);
156 27293 : type = ds_atype_map(atype);
157 27293 : if (type == SID_NAME_UNKNOWN) {
158 0 : return NT_STATUS_NONE_MAPPED;
159 : }
160 :
161 27293 : *p_sid = sid;
162 27293 : *p_type = type;
163 27293 : return NT_STATUS_OK;
164 : }
165 :
166 :
167 : /*
168 : add to the lsa_RefDomainList for LookupSids and LookupNames
169 : */
170 55391 : 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 9600 : uint32_t i;
176 :
177 55391 : *sid_index = UINT32_MAX;
178 :
179 55391 : if (authority_name == NULL) {
180 324 : return NT_STATUS_OK;
181 : }
182 :
183 : /* see if we've already done this authority name */
184 55067 : for (i=0;i<domains->count;i++) {
185 53039 : if (strcasecmp_m(authority_name, domains->domains[i].name.string) == 0) {
186 53039 : *sid_index = i;
187 53039 : return NT_STATUS_OK;
188 : }
189 : }
190 :
191 2028 : domains->domains = talloc_realloc(domains,
192 : domains->domains,
193 : struct lsa_DomainInfo,
194 : domains->count+1);
195 2028 : if (domains->domains == NULL) {
196 0 : return NT_STATUS_NO_MEMORY;
197 : }
198 2028 : domains->domains[i].name.string = talloc_strdup(domains->domains,
199 : authority_name);
200 2028 : if (domains->domains[i].name.string == NULL) {
201 0 : return NT_STATUS_NO_MEMORY;
202 : }
203 2028 : domains->domains[i].sid = dom_sid_dup(domains->domains,
204 : authority_sid);
205 2028 : if (domains->domains[i].sid == NULL) {
206 0 : return NT_STATUS_NO_MEMORY;
207 : }
208 2028 : domains->count++;
209 2028 : domains->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER * domains->count;
210 2028 : *sid_index = i;
211 :
212 2028 : return NT_STATUS_OK;
213 : }
214 :
215 : /*
216 : lookup a name for 1 SID
217 : */
218 27359 : 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 27359 : const char * const attrs[] = { "sAMAccountName", "sAMAccountType", NULL};
228 27359 : struct ldb_message **res = NULL;
229 27359 : char *encoded_sid = NULL;
230 27359 : const char *name = NULL;
231 4800 : uint32_t atype;
232 4800 : enum lsa_SidType type;
233 4800 : int ret;
234 :
235 27359 : encoded_sid = ldap_encode_ndr_dom_sid(mem_ctx, sid);
236 27359 : if (encoded_sid == NULL) {
237 0 : return NT_STATUS_NO_MEMORY;
238 : }
239 :
240 27359 : ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs,
241 : "(&(objectSid=%s)(sAMAccountName=*))", encoded_sid);
242 27359 : TALLOC_FREE(encoded_sid);
243 27359 : if (ret < 0) {
244 0 : return NT_STATUS_INTERNAL_DB_ERROR;
245 : }
246 27359 : if (ret == 0) {
247 6 : return NT_STATUS_NONE_MAPPED;
248 : }
249 27353 : if (ret > 1) {
250 0 : NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
251 0 : DBG_ERR("sid[%s] found %d times - %s\n",
252 : dom_sid_string(mem_ctx, sid), ret, nt_errstr(status));
253 0 : return status;
254 : }
255 :
256 27353 : name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
257 27353 : if (name == NULL) {
258 0 : return NT_STATUS_INTERNAL_ERROR;
259 : }
260 :
261 27353 : atype = ldb_msg_find_attr_as_uint(res[0], "sAMAccountType", 0);
262 27353 : type = ds_atype_map(atype);
263 27353 : if (type == SID_NAME_UNKNOWN) {
264 0 : return NT_STATUS_NONE_MAPPED;
265 : }
266 :
267 27353 : *p_name = name;
268 27353 : *p_type = type;
269 27353 : 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 2042 : static NTSTATUS dcesrv_lsa_LookupSids_base_call(struct dcesrv_lsa_LookupSids_base_state *state)
309 : {
310 2042 : struct lsa_LookupSids3 *r = &state->r;
311 2042 : struct tevent_req *subreq = NULL;
312 48 : uint32_t v;
313 48 : uint32_t i;
314 :
315 2042 : *r->out.domains = NULL;
316 2042 : r->out.names->count = 0;
317 2042 : r->out.names->names = NULL;
318 2042 : *r->out.count = 0;
319 :
320 2090 : state->view_table = dcesrv_lsa_view_table(r->in.level);
321 2042 : if (state->view_table == NULL) {
322 0 : return NT_STATUS_INVALID_PARAMETER;
323 : }
324 :
325 2042 : *r->out.domains = talloc_zero(r->out.domains, struct lsa_RefDomainList);
326 2042 : if (*r->out.domains == NULL) {
327 0 : return NT_STATUS_NO_MEMORY;
328 : }
329 :
330 2042 : r->out.names->names = talloc_zero_array(r->out.names,
331 : struct lsa_TranslatedName2,
332 : r->in.sids->num_sids);
333 2042 : if (r->out.names->names == NULL) {
334 0 : return NT_STATUS_NO_MEMORY;
335 : }
336 :
337 2042 : state->items = talloc_zero_array(state,
338 : struct dcesrv_lsa_TranslatedItem,
339 : r->in.sids->num_sids);
340 2042 : if (state->items == NULL) {
341 0 : return NT_STATUS_NO_MEMORY;
342 : }
343 :
344 30320 : for (i=0;i<r->in.sids->num_sids;i++) {
345 28278 : struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
346 28278 : uint32_t rid = 0;
347 :
348 28278 : if (r->in.sids->sids[i].sid == NULL) {
349 0 : return NT_STATUS_INVALID_PARAMETER;
350 : }
351 :
352 28278 : item->type = SID_NAME_UNKNOWN;
353 28278 : item->sid = r->in.sids->sids[i].sid;
354 :
355 28278 : item->hints.sid = dom_sid_string(state->items, item->sid);
356 28278 : if (item->hints.sid == NULL) {
357 0 : return NT_STATUS_NO_MEMORY;
358 : }
359 :
360 28278 : dom_sid_split_rid(state->items, item->sid, NULL, &rid);
361 28278 : item->hints.rid = talloc_asprintf(state->items,
362 : "%08X", (unsigned)rid);
363 28278 : if (item->hints.rid == NULL) {
364 0 : return NT_STATUS_NO_MEMORY;
365 : }
366 : }
367 :
368 8108 : for (v=0; v < state->view_table->count; v++) {
369 6638 : const struct dcesrv_lsa_Lookup_view *view =
370 6638 : state->view_table->array[v];
371 :
372 117584 : for (i=0; i < r->in.sids->num_sids; i++) {
373 111518 : struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
374 19200 : NTSTATUS status;
375 :
376 111518 : if (item->done) {
377 54431 : continue;
378 : }
379 :
380 57087 : status = view->lookup_sid(state, item);
381 57087 : if (NT_STATUS_IS_OK(status)) {
382 27680 : item->done = true;
383 29407 : } else if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
384 24035 : status = NT_STATUS_OK;
385 572 : } else if (NT_STATUS_EQUAL(status, NT_STATUS_SOME_NOT_MAPPED)) {
386 0 : status = NT_STATUS_OK;
387 : }
388 57087 : if (!NT_STATUS_IS_OK(status)) {
389 572 : return status;
390 : }
391 : }
392 : }
393 :
394 1470 : if (state->wb.irpc_handle == NULL) {
395 1450 : return dcesrv_lsa_LookupSids_base_finish(state);
396 : }
397 :
398 20 : state->wb.sids.sids = talloc_zero_array(state, struct lsa_SidPtr,
399 : r->in.sids->num_sids);
400 20 : if (state->wb.sids.sids == NULL) {
401 0 : return NT_STATUS_NO_MEMORY;
402 : }
403 :
404 48 : for (i=0; i < r->in.sids->num_sids; i++) {
405 28 : struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
406 :
407 28 : if (item->done) {
408 2 : continue;
409 : }
410 :
411 26 : item->wb_idx = state->wb.sids.num_sids;
412 26 : state->wb.sids.sids[item->wb_idx] = r->in.sids->sids[i];
413 26 : state->wb.sids.num_sids++;
414 : }
415 :
416 20 : subreq = dcerpc_lsa_LookupSids3_send(state,
417 20 : 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 20 : if (subreq == NULL) {
427 0 : return NT_STATUS_NO_MEMORY;;
428 : }
429 20 : state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
430 20 : tevent_req_set_callback(subreq,
431 : dcesrv_lsa_LookupSids_base_done,
432 : state);
433 :
434 20 : return NT_STATUS_OK;
435 : }
436 :
437 1470 : static NTSTATUS dcesrv_lsa_LookupSids_base_finish(
438 : struct dcesrv_lsa_LookupSids_base_state *state)
439 : {
440 1470 : struct lsa_LookupSids3 *r = &state->r;
441 48 : uint32_t i;
442 :
443 29176 : for (i=0;i<r->in.sids->num_sids;i++) {
444 27706 : struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
445 4800 : NTSTATUS status;
446 27706 : uint32_t sid_index = UINT32_MAX;
447 :
448 27706 : status = dcesrv_lsa_authority_list(item->authority_name,
449 : item->authority_sid,
450 27706 : *r->out.domains,
451 : &sid_index);
452 27706 : if (!NT_STATUS_IS_OK(status)) {
453 0 : return status;
454 : }
455 :
456 27706 : if (item->name == NULL && r->in.level == LSA_LOOKUP_NAMES_ALL) {
457 299 : if (sid_index == UINT32_MAX) {
458 299 : item->name = item->hints.sid;
459 : } else {
460 0 : item->name = item->hints.rid;
461 : }
462 : }
463 :
464 27706 : r->out.names->names[i].sid_type = item->type;
465 27706 : r->out.names->names[i].name.string = item->name;
466 27706 : r->out.names->names[i].sid_index = sid_index;
467 27706 : r->out.names->names[i].unknown = item->flags;
468 :
469 27706 : r->out.names->count++;
470 27706 : if (item->type != SID_NAME_UNKNOWN) {
471 27401 : (*r->out.count)++;
472 : }
473 : }
474 :
475 1470 : if (*r->out.count == 0) {
476 301 : return NT_STATUS_NONE_MAPPED;
477 : }
478 1169 : if (*r->out.count != r->in.sids->num_sids) {
479 4 : return STATUS_SOME_UNMAPPED;
480 : }
481 :
482 1165 : return NT_STATUS_OK;
483 : }
484 :
485 2042 : static void dcesrv_lsa_LookupSids_base_map(
486 : struct dcesrv_lsa_LookupSids_base_state *state)
487 : {
488 2042 : if (state->_r.l3 != NULL) {
489 1416 : struct lsa_LookupSids3 *r = state->_r.l3;
490 :
491 1416 : r->out.result = state->r.out.result;
492 1416 : return;
493 : }
494 :
495 626 : if (state->_r.l2 != NULL) {
496 3 : struct lsa_LookupSids2 *r = state->_r.l2;
497 :
498 3 : r->out.result = state->r.out.result;
499 3 : return;
500 : }
501 :
502 623 : if (state->_r.l != NULL) {
503 623 : struct lsa_LookupSids *r = state->_r.l;
504 0 : uint32_t i;
505 :
506 623 : r->out.result = state->r.out.result;
507 :
508 623 : SMB_ASSERT(state->r.out.names->count <= r->in.sids->num_sids);
509 2449 : for (i = 0; i < state->r.out.names->count; i++) {
510 1826 : struct lsa_TranslatedName2 *n2 =
511 1826 : &state->r.out.names->names[i];
512 1826 : struct lsa_TranslatedName *n =
513 1826 : &r->out.names->names[i];
514 :
515 1826 : n->sid_type = n2->sid_type;
516 1826 : n->name = n2->name;
517 1826 : n->sid_index = n2->sid_index;
518 : }
519 623 : r->out.names->count = state->r.out.names->count;
520 623 : return;
521 : }
522 : }
523 :
524 20 : static void dcesrv_lsa_LookupSids_base_done(struct tevent_req *subreq)
525 : {
526 0 : struct dcesrv_lsa_LookupSids_base_state *state =
527 20 : tevent_req_callback_data(subreq,
528 : struct dcesrv_lsa_LookupSids_base_state);
529 20 : struct dcesrv_call_state *dce_call = state->dce_call;
530 0 : NTSTATUS status;
531 0 : uint32_t i;
532 :
533 20 : status = dcerpc_lsa_LookupSids3_recv(subreq, state->mem_ctx,
534 : &state->wb.result);
535 20 : TALLOC_FREE(subreq);
536 20 : TALLOC_FREE(state->wb.irpc_handle);
537 20 : if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
538 0 : DEBUG(0,(__location__ ": IRPC callback failed %s\n",
539 : nt_errstr(status)));
540 0 : goto finished;
541 20 : } else if (!NT_STATUS_IS_OK(status)) {
542 0 : state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
543 0 : DEBUG(0,(__location__ ": IRPC callback failed %s\n",
544 : nt_errstr(status)));
545 0 : goto finished;
546 : }
547 :
548 20 : status = state->wb.result;
549 20 : if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
550 0 : status = NT_STATUS_OK;
551 20 : } else if (NT_STATUS_EQUAL(status, NT_STATUS_SOME_NOT_MAPPED)) {
552 0 : status = NT_STATUS_OK;
553 : }
554 20 : if (!NT_STATUS_IS_OK(status)) {
555 0 : goto finished;
556 : }
557 :
558 48 : for (i=0; i < state->r.in.sids->num_sids; i++) {
559 28 : struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
560 28 : struct lsa_TranslatedName2 *s2 = NULL;
561 28 : struct lsa_DomainInfo *d = NULL;
562 :
563 28 : if (item->done) {
564 2 : continue;
565 : }
566 :
567 26 : if (item->wb_idx >= state->wb.names.count) {
568 0 : status = NT_STATUS_INTERNAL_ERROR;
569 0 : goto finished;
570 : }
571 :
572 26 : s2 = &state->wb.names.names[item->wb_idx];
573 :
574 26 : item->type = s2->sid_type;
575 26 : item->name = s2->name.string;
576 26 : item->flags = s2->unknown;
577 :
578 26 : if (s2->sid_index == UINT32_MAX) {
579 0 : continue;
580 : }
581 :
582 26 : if (state->wb.domains == NULL) {
583 0 : status = NT_STATUS_INTERNAL_ERROR;
584 0 : goto finished;
585 : }
586 :
587 26 : if (s2->sid_index >= state->wb.domains->count) {
588 0 : status = NT_STATUS_INTERNAL_ERROR;
589 0 : goto finished;
590 : }
591 :
592 26 : d = &state->wb.domains->domains[s2->sid_index];
593 :
594 26 : item->authority_name = d->name.string;
595 26 : item->authority_sid = d->sid;
596 : }
597 :
598 20 : status = dcesrv_lsa_LookupSids_base_finish(state);
599 20 : finished:
600 20 : state->r.out.result = status;
601 20 : dcesrv_lsa_LookupSids_base_map(state);
602 :
603 20 : dcesrv_async_reply(dce_call);
604 20 : }
605 :
606 : /*
607 : lsa_LookupSids2
608 : */
609 3 : NTSTATUS dcesrv_lsa_LookupSids2(struct dcesrv_call_state *dce_call,
610 : TALLOC_CTX *mem_ctx,
611 : struct lsa_LookupSids2 *r)
612 : {
613 0 : enum dcerpc_transport_t transport =
614 3 : dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
615 3 : struct dcesrv_lsa_LookupSids_base_state *state = NULL;
616 3 : struct dcesrv_handle *policy_handle = NULL;
617 0 : NTSTATUS status;
618 :
619 3 : if (transport != NCACN_NP && transport != NCALRPC) {
620 0 : DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
621 : }
622 :
623 3 : DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
624 :
625 3 : *r->out.domains = NULL;
626 3 : r->out.names->count = 0;
627 3 : r->out.names->names = NULL;
628 3 : *r->out.count = 0;
629 :
630 3 : state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupSids_base_state);
631 3 : if (state == NULL) {
632 0 : return NT_STATUS_NO_MEMORY;
633 : }
634 :
635 3 : state->dce_call = dce_call;
636 3 : state->mem_ctx = mem_ctx;
637 :
638 3 : state->policy_state = policy_handle->data;
639 :
640 3 : state->r.in.sids = r->in.sids;
641 3 : state->r.in.level = r->in.level;
642 3 : state->r.in.lookup_options = r->in.lookup_options;
643 3 : state->r.in.client_revision = r->in.client_revision;
644 3 : state->r.in.names = r->in.names;
645 3 : state->r.in.count = r->in.count;
646 3 : state->r.out.domains = r->out.domains;
647 3 : state->r.out.names = r->out.names;
648 3 : state->r.out.count = r->out.count;
649 :
650 3 : state->_r.l2 = r;
651 :
652 3 : status = dcesrv_lsa_LookupSids_base_call(state);
653 :
654 3 : if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
655 0 : return status;
656 : }
657 :
658 3 : state->r.out.result = status;
659 3 : dcesrv_lsa_LookupSids_base_map(state);
660 3 : return status;
661 : }
662 :
663 : /* A random hexadecimal number (honest!) */
664 : #define LSA_SERVER_IMPLICIT_POLICY_STATE_MAGIC 0xc0c99e00
665 :
666 : /*
667 : Ensure we're operating on an schannel connection,
668 : and use a lsa_policy_state cache on the connection.
669 : */
670 2263 : static NTSTATUS schannel_call_setup(struct dcesrv_call_state *dce_call,
671 : struct lsa_policy_state **_policy_state)
672 : {
673 2263 : struct lsa_policy_state *policy_state = NULL;
674 144 : enum dcerpc_transport_t transport =
675 2263 : dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
676 2263 : enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
677 2263 : if (transport != NCACN_IP_TCP) {
678 : /* We can't call DCESRV_FAULT() in the sub-function */
679 19 : dce_call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
680 19 : return NT_STATUS_ACCESS_DENIED;
681 : }
682 :
683 : /*
684 : * We don't have policy handles on this call. So this must be restricted
685 : * to crypto connections only.
686 : *
687 : * NB. gensec requires schannel connections to
688 : * have at least DCERPC_AUTH_LEVEL_INTEGRITY.
689 : */
690 2244 : dcesrv_call_auth_info(dce_call, &auth_type, NULL);
691 2244 : if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
692 : /* We can't call DCESRV_FAULT() in the sub-function */
693 7 : dce_call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
694 7 : return NT_STATUS_ACCESS_DENIED;
695 : }
696 :
697 : /*
698 : * We don't have a policy handle on this call, so we want to
699 : * make a policy state and cache it for the life of the
700 : * connection, to avoid re-opening the DB each call.
701 : */
702 144 : policy_state
703 2237 : = dcesrv_iface_state_find_conn(dce_call,
704 : LSA_SERVER_IMPLICIT_POLICY_STATE_MAGIC,
705 : struct lsa_policy_state);
706 :
707 2237 : if (policy_state == NULL) {
708 48 : NTSTATUS status
709 308 : = dcesrv_lsa_get_policy_state(dce_call,
710 : dce_call /* mem_ctx */,
711 : 0, /* we skip access checks */
712 : &policy_state);
713 308 : if (!NT_STATUS_IS_OK(status)) {
714 0 : return status;
715 : }
716 :
717 : /*
718 : * This will talloc_steal() policy_state onto the
719 : * connection, which has longer lifetime than the
720 : * immediate caller requires
721 : */
722 308 : status = dcesrv_iface_state_store_conn(dce_call,
723 : LSA_SERVER_IMPLICIT_POLICY_STATE_MAGIC,
724 : policy_state);
725 308 : if (!NT_STATUS_IS_OK(status)) {
726 0 : return status;
727 : }
728 : }
729 2237 : *_policy_state = policy_state;
730 2237 : return NT_STATUS_OK;
731 : }
732 :
733 : /*
734 : lsa_LookupSids3
735 :
736 : Identical to LookupSids2, but doesn't take a policy handle
737 :
738 : */
739 1429 : NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call,
740 : TALLOC_CTX *mem_ctx,
741 : struct lsa_LookupSids3 *r)
742 : {
743 1429 : struct dcesrv_lsa_LookupSids_base_state *state = NULL;
744 48 : NTSTATUS status;
745 :
746 1429 : *r->out.domains = NULL;
747 1429 : r->out.names->count = 0;
748 1429 : r->out.names->names = NULL;
749 1429 : *r->out.count = 0;
750 :
751 1429 : state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupSids_base_state);
752 1429 : if (state == NULL) {
753 0 : return NT_STATUS_NO_MEMORY;
754 : }
755 :
756 : /*
757 : * We don't have a policy handle on this call, so we want to
758 : * make a policy state and cache it for the life of the
759 : * connection, to avoid re-opening the DB each call.
760 : *
761 : * This also enforces that this is only available over
762 : * ncacn_ip_tcp and with SCHANNEL.
763 : *
764 : * schannel_call_setup may also set the fault state.
765 : *
766 : * state->policy_state is shared between all calls on this
767 : * connection and is moved with talloc_steal() under the
768 : * connection, not dce_call or state.
769 : */
770 1429 : status = schannel_call_setup(dce_call, &state->policy_state);
771 1429 : if (!NT_STATUS_IS_OK(status)) {
772 13 : return status;
773 : }
774 :
775 1416 : state->dce_call = dce_call;
776 1416 : state->mem_ctx = mem_ctx;
777 1416 : state->r.in.sids = r->in.sids;
778 1416 : state->r.in.level = r->in.level;
779 1416 : state->r.in.lookup_options = r->in.lookup_options;
780 1416 : state->r.in.client_revision = r->in.client_revision;
781 1416 : state->r.in.names = r->in.names;
782 1416 : state->r.in.count = r->in.count;
783 1416 : state->r.out.domains = r->out.domains;
784 1416 : state->r.out.names = r->out.names;
785 1416 : state->r.out.count = r->out.count;
786 :
787 1416 : state->_r.l3 = r;
788 :
789 1416 : status = dcesrv_lsa_LookupSids_base_call(state);
790 :
791 1416 : if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
792 20 : return status;
793 : }
794 :
795 1396 : state->r.out.result = status;
796 1396 : dcesrv_lsa_LookupSids_base_map(state);
797 1396 : return status;
798 : }
799 :
800 :
801 : /*
802 : lsa_LookupSids
803 : */
804 623 : NTSTATUS dcesrv_lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
805 : struct lsa_LookupSids *r)
806 : {
807 0 : enum dcerpc_transport_t transport =
808 623 : dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
809 623 : struct dcesrv_lsa_LookupSids_base_state *state = NULL;
810 623 : struct dcesrv_handle *policy_handle = NULL;
811 0 : NTSTATUS status;
812 :
813 623 : if (transport != NCACN_NP && transport != NCALRPC) {
814 0 : DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
815 : }
816 :
817 623 : DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
818 :
819 623 : *r->out.domains = NULL;
820 623 : r->out.names->count = 0;
821 623 : r->out.names->names = NULL;
822 623 : *r->out.count = 0;
823 :
824 623 : r->out.names->names = talloc_zero_array(r->out.names,
825 : struct lsa_TranslatedName,
826 : r->in.sids->num_sids);
827 623 : if (r->out.names->names == NULL) {
828 0 : return NT_STATUS_NO_MEMORY;
829 : }
830 :
831 623 : state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupSids_base_state);
832 623 : if (state == NULL) {
833 0 : return NT_STATUS_NO_MEMORY;
834 : }
835 :
836 623 : state->dce_call = dce_call;
837 623 : state->mem_ctx = mem_ctx;
838 :
839 623 : state->policy_state = policy_handle->data;
840 :
841 623 : state->r.in.sids = r->in.sids;
842 623 : state->r.in.level = r->in.level;
843 623 : state->r.in.lookup_options = LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES;
844 623 : state->r.in.client_revision = LSA_CLIENT_REVISION_1;
845 623 : state->r.in.names = talloc_zero(state, struct lsa_TransNameArray2);
846 623 : if (state->r.in.names == NULL) {
847 0 : return NT_STATUS_NO_MEMORY;
848 : }
849 623 : state->r.in.count = r->in.count;
850 623 : state->r.out.domains = r->out.domains;
851 623 : state->r.out.names = talloc_zero(state, struct lsa_TransNameArray2);
852 623 : if (state->r.out.names == NULL) {
853 0 : return NT_STATUS_NO_MEMORY;
854 : }
855 623 : state->r.out.count = r->out.count;
856 :
857 623 : state->_r.l = r;
858 :
859 623 : status = dcesrv_lsa_LookupSids_base_call(state);
860 :
861 623 : if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
862 0 : return status;
863 : }
864 :
865 623 : state->r.out.result = status;
866 623 : dcesrv_lsa_LookupSids_base_map(state);
867 623 : return status;
868 : }
869 :
870 : struct dcesrv_lsa_LookupNames_base_state {
871 : struct dcesrv_call_state *dce_call;
872 :
873 : TALLOC_CTX *mem_ctx;
874 :
875 : struct lsa_policy_state *policy_state;
876 :
877 : struct lsa_LookupNames4 r;
878 :
879 : const struct dcesrv_lsa_Lookup_view_table *view_table;
880 : struct dcesrv_lsa_TranslatedItem *items;
881 :
882 : struct dsdb_trust_routing_table *routing_table;
883 :
884 : struct {
885 : struct dcerpc_binding_handle *irpc_handle;
886 : uint32_t num_names;
887 : struct lsa_String *names;
888 : struct lsa_RefDomainList *domains;
889 : struct lsa_TransSidArray3 sids;
890 : uint32_t count;
891 : NTSTATUS result;
892 : } wb;
893 :
894 : struct {
895 : struct lsa_LookupNames *l;
896 : struct lsa_LookupNames2 *l2;
897 : struct lsa_LookupNames3 *l3;
898 : struct lsa_LookupNames4 *l4;
899 : } _r;
900 : };
901 :
902 : static NTSTATUS dcesrv_lsa_LookupNames_base_finish(
903 : struct dcesrv_lsa_LookupNames_base_state *state);
904 : static void dcesrv_lsa_LookupNames_base_map(
905 : struct dcesrv_lsa_LookupNames_base_state *state);
906 : static void dcesrv_lsa_LookupNames_base_done(struct tevent_req *subreq);
907 :
908 1146 : static NTSTATUS dcesrv_lsa_LookupNames_base_call(struct dcesrv_lsa_LookupNames_base_state *state)
909 : {
910 1146 : struct lsa_LookupNames4 *r = &state->r;
911 1146 : enum lsa_LookupOptions invalid_lookup_options = 0;
912 1146 : struct tevent_req *subreq = NULL;
913 96 : uint32_t v;
914 96 : uint32_t i;
915 :
916 1146 : *r->out.domains = NULL;
917 1146 : r->out.sids->count = 0;
918 1146 : r->out.sids->sids = NULL;
919 1146 : *r->out.count = 0;
920 :
921 1146 : if (r->in.level != LSA_LOOKUP_NAMES_ALL) {
922 361 : invalid_lookup_options |=
923 : LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES_LOCAL;
924 : }
925 1146 : if (r->in.lookup_options & invalid_lookup_options) {
926 0 : return NT_STATUS_INVALID_PARAMETER;
927 : }
928 :
929 1242 : state->view_table = dcesrv_lsa_view_table(r->in.level);
930 1146 : if (state->view_table == NULL) {
931 0 : return NT_STATUS_INVALID_PARAMETER;
932 : }
933 :
934 1146 : *r->out.domains = talloc_zero(r->out.domains, struct lsa_RefDomainList);
935 1146 : if (*r->out.domains == NULL) {
936 0 : return NT_STATUS_NO_MEMORY;
937 : }
938 :
939 1146 : r->out.sids->sids = talloc_zero_array(r->out.sids,
940 : struct lsa_TranslatedSid3,
941 : r->in.num_names);
942 1146 : if (r->out.sids->sids == NULL) {
943 0 : return NT_STATUS_NO_MEMORY;
944 : }
945 :
946 1146 : state->items = talloc_zero_array(state,
947 : struct dcesrv_lsa_TranslatedItem,
948 : r->in.num_names);
949 1146 : if (state->items == NULL) {
950 0 : return NT_STATUS_NO_MEMORY;
951 : }
952 :
953 28847 : for (i=0;i<r->in.num_names;i++) {
954 27701 : struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
955 27701 : char *p = NULL;
956 :
957 27701 : item->type = SID_NAME_UNKNOWN;
958 27701 : item->name = r->in.names[i].string;
959 : /*
960 : * Note: that item->name can be NULL!
961 : *
962 : * See test_LookupNames_NULL() in
963 : * source4/torture/rpc/lsa.c
964 : *
965 : * nt4 returns NT_STATUS_NONE_MAPPED with sid_type
966 : * SID_NAME_UNKNOWN, rid 0, and sid_index -1;
967 : *
968 : * w2k3/w2k8 return NT_STATUS_OK with sid_type
969 : * SID_NAME_DOMAIN, rid -1 and sid_index 0 and BUILTIN domain
970 : */
971 27701 : if (item->name == NULL) {
972 3 : continue;
973 : }
974 :
975 27698 : item->hints.principal = item->name;
976 27698 : p = strchr(item->name, '\\');
977 27698 : if (p != NULL && p != item->name) {
978 1572 : item->hints.domain = talloc_strndup(state->items,
979 : item->name,
980 786 : p - item->name);
981 786 : if (item->hints.domain == NULL) {
982 0 : return NT_STATUS_NO_MEMORY;
983 : }
984 786 : item->hints.namespace = item->hints.domain;
985 786 : p++;
986 786 : if (p[0] == '\0') {
987 : /*
988 : * This is just 'BUILTIN\'.
989 : */
990 99 : item->hints.principal = NULL;
991 : } else {
992 687 : item->hints.principal = p;
993 : }
994 : }
995 27698 : if (item->hints.domain == NULL) {
996 26912 : p = strchr(item->name, '@');
997 26912 : if (p != NULL && p != item->name && p[1] != '\0') {
998 210 : item->hints.namespace = p + 1;
999 : }
1000 : }
1001 : }
1002 :
1003 4978 : for (v=0; v < state->view_table->count; v++) {
1004 3832 : const struct dcesrv_lsa_Lookup_view *view =
1005 3832 : state->view_table->array[v];
1006 :
1007 113884 : for (i=0; i < r->in.num_names; i++) {
1008 110052 : struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
1009 19200 : NTSTATUS status;
1010 :
1011 110052 : if (item->done) {
1012 54132 : continue;
1013 : }
1014 :
1015 55920 : status = view->lookup_name(state, item);
1016 55920 : if (NT_STATUS_IS_OK(status)) {
1017 27653 : item->done = true;
1018 28267 : } else if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1019 23467 : status = NT_STATUS_OK;
1020 0 : } else if (NT_STATUS_EQUAL(status, NT_STATUS_SOME_NOT_MAPPED)) {
1021 0 : status = NT_STATUS_OK;
1022 : }
1023 55920 : if (!NT_STATUS_IS_OK(status)) {
1024 0 : return status;
1025 : }
1026 : }
1027 : }
1028 :
1029 1146 : if (state->wb.irpc_handle == NULL) {
1030 1098 : return dcesrv_lsa_LookupNames_base_finish(state);
1031 : }
1032 :
1033 48 : state->wb.names = talloc_zero_array(state, struct lsa_String,
1034 : r->in.num_names);
1035 48 : if (state->wb.names == NULL) {
1036 0 : return NT_STATUS_NO_MEMORY;
1037 : }
1038 :
1039 96 : for (i=0;i<r->in.num_names;i++) {
1040 48 : struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
1041 :
1042 48 : if (item->done) {
1043 0 : continue;
1044 : }
1045 :
1046 48 : item->wb_idx = state->wb.num_names;
1047 48 : state->wb.names[item->wb_idx] = r->in.names[i];
1048 48 : state->wb.num_names++;
1049 : }
1050 :
1051 48 : subreq = dcerpc_lsa_LookupNames4_send(state,
1052 48 : state->dce_call->event_ctx,
1053 : state->wb.irpc_handle,
1054 : state->wb.num_names,
1055 : state->wb.names,
1056 : &state->wb.domains,
1057 : &state->wb.sids,
1058 : state->r.in.level,
1059 : &state->wb.count,
1060 : state->r.in.lookup_options,
1061 : state->r.in.client_revision);
1062 48 : if (subreq == NULL) {
1063 0 : return NT_STATUS_NO_MEMORY;
1064 : }
1065 48 : state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
1066 48 : tevent_req_set_callback(subreq,
1067 : dcesrv_lsa_LookupNames_base_done,
1068 : state);
1069 :
1070 48 : return NT_STATUS_OK;
1071 : }
1072 :
1073 1130 : static NTSTATUS dcesrv_lsa_LookupNames_base_finish(
1074 : struct dcesrv_lsa_LookupNames_base_state *state)
1075 : {
1076 1130 : struct lsa_LookupNames4 *r = &state->r;
1077 96 : uint32_t i;
1078 :
1079 28815 : for (i=0;i<r->in.num_names;i++) {
1080 27685 : struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
1081 4800 : NTSTATUS status;
1082 27685 : uint32_t sid_index = UINT32_MAX;
1083 :
1084 27685 : status = dcesrv_lsa_authority_list(item->authority_name,
1085 : item->authority_sid,
1086 27685 : *r->out.domains,
1087 : &sid_index);
1088 27685 : if (!NT_STATUS_IS_OK(status)) {
1089 0 : return status;
1090 : }
1091 :
1092 27685 : r->out.sids->sids[i].sid_type = item->type;
1093 27685 : r->out.sids->sids[i].sid = discard_const_p(struct dom_sid,
1094 : item->sid);
1095 27685 : r->out.sids->sids[i].sid_index = sid_index;
1096 27685 : r->out.sids->sids[i].flags = item->flags;
1097 :
1098 27685 : r->out.sids->count++;
1099 27685 : if (item->type != SID_NAME_UNKNOWN) {
1100 27592 : (*r->out.count)++;
1101 : }
1102 : }
1103 :
1104 1130 : if (*r->out.count == 0) {
1105 345 : return NT_STATUS_NONE_MAPPED;
1106 : }
1107 785 : if (*r->out.count != r->in.num_names) {
1108 0 : return STATUS_SOME_UNMAPPED;
1109 : }
1110 :
1111 785 : return NT_STATUS_OK;
1112 : }
1113 :
1114 1146 : static void dcesrv_lsa_LookupNames_base_map(
1115 : struct dcesrv_lsa_LookupNames_base_state *state)
1116 : {
1117 1146 : if (state->_r.l4 != NULL) {
1118 821 : struct lsa_LookupNames4 *r = state->_r.l4;
1119 :
1120 821 : r->out.result = state->r.out.result;
1121 821 : return;
1122 : }
1123 :
1124 325 : if (state->_r.l3 != NULL) {
1125 6 : struct lsa_LookupNames3 *r = state->_r.l3;
1126 :
1127 6 : r->out.result = state->r.out.result;
1128 6 : return;
1129 : }
1130 :
1131 319 : if (state->_r.l2 != NULL) {
1132 6 : struct lsa_LookupNames2 *r = state->_r.l2;
1133 0 : uint32_t i;
1134 :
1135 6 : r->out.result = state->r.out.result;
1136 :
1137 6 : SMB_ASSERT(state->r.out.sids->count <= r->in.num_names);
1138 27 : for (i = 0; i < state->r.out.sids->count; i++) {
1139 21 : const struct lsa_TranslatedSid3 *s3 =
1140 21 : &state->r.out.sids->sids[i];
1141 21 : struct lsa_TranslatedSid2 *s2 =
1142 21 : &r->out.sids->sids[i];
1143 :
1144 21 : s2->sid_type = s3->sid_type;
1145 21 : if (s3->sid_type == SID_NAME_DOMAIN) {
1146 3 : s2->rid = UINT32_MAX;
1147 18 : } else if (s3->flags & 0x00000004) {
1148 0 : s2->rid = UINT32_MAX;
1149 18 : } else if (s3->sid == NULL) {
1150 : /*
1151 : * MS-LSAT 3.1.4.7 - rid zero is considered
1152 : * equivalent to sid NULL - so we should return
1153 : * 0 rid for unmapped entries
1154 : */
1155 0 : s2->rid = 0;
1156 : } else {
1157 18 : s2->rid = 0;
1158 18 : dom_sid_split_rid(NULL, s3->sid,
1159 : NULL, &s2->rid);
1160 : }
1161 21 : s2->sid_index = s3->sid_index;
1162 21 : s2->unknown = s3->flags;
1163 : }
1164 6 : r->out.sids->count = state->r.out.sids->count;
1165 6 : return;
1166 : }
1167 :
1168 313 : if (state->_r.l != NULL) {
1169 313 : struct lsa_LookupNames *r = state->_r.l;
1170 0 : uint32_t i;
1171 :
1172 313 : r->out.result = state->r.out.result;
1173 :
1174 313 : SMB_ASSERT(state->r.out.sids->count <= r->in.num_names);
1175 2454 : for (i = 0; i < state->r.out.sids->count; i++) {
1176 2141 : struct lsa_TranslatedSid3 *s3 =
1177 2141 : &state->r.out.sids->sids[i];
1178 2141 : struct lsa_TranslatedSid *s =
1179 2141 : &r->out.sids->sids[i];
1180 :
1181 2141 : s->sid_type = s3->sid_type;
1182 2141 : if (s3->sid_type == SID_NAME_DOMAIN) {
1183 225 : s->rid = UINT32_MAX;
1184 1916 : } else if (s3->flags & 0x00000004) {
1185 0 : s->rid = UINT32_MAX;
1186 1916 : } else if (s3->sid == NULL) {
1187 : /*
1188 : * MS-LSAT 3.1.4.7 - rid zero is considered
1189 : * equivalent to sid NULL - so we should return
1190 : * 0 rid for unmapped entries
1191 : */
1192 15 : s->rid = 0;
1193 : } else {
1194 1901 : s->rid = 0;
1195 1901 : dom_sid_split_rid(NULL, s3->sid,
1196 : NULL, &s->rid);
1197 : }
1198 2141 : s->sid_index = s3->sid_index;
1199 : }
1200 313 : r->out.sids->count = state->r.out.sids->count;
1201 313 : return;
1202 : }
1203 : }
1204 :
1205 48 : static void dcesrv_lsa_LookupNames_base_done(struct tevent_req *subreq)
1206 : {
1207 0 : struct dcesrv_lsa_LookupNames_base_state *state =
1208 48 : tevent_req_callback_data(subreq,
1209 : struct dcesrv_lsa_LookupNames_base_state);
1210 48 : struct dcesrv_call_state *dce_call = state->dce_call;
1211 0 : NTSTATUS status;
1212 0 : uint32_t i;
1213 :
1214 48 : status = dcerpc_lsa_LookupNames4_recv(subreq, state->mem_ctx,
1215 : &state->wb.result);
1216 48 : TALLOC_FREE(subreq);
1217 48 : TALLOC_FREE(state->wb.irpc_handle);
1218 48 : if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
1219 0 : DEBUG(0,(__location__ ": IRPC callback failed %s\n",
1220 : nt_errstr(status)));
1221 16 : goto finished;
1222 48 : } else if (!NT_STATUS_IS_OK(status)) {
1223 16 : state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
1224 16 : DEBUG(0,(__location__ ": IRPC callback failed %s\n",
1225 : nt_errstr(status)));
1226 16 : goto finished;
1227 : }
1228 :
1229 32 : status = state->wb.result;
1230 32 : if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1231 0 : status = NT_STATUS_OK;
1232 32 : } else if (NT_STATUS_EQUAL(status, NT_STATUS_SOME_NOT_MAPPED)) {
1233 0 : status = NT_STATUS_OK;
1234 : }
1235 32 : if (!NT_STATUS_IS_OK(status)) {
1236 0 : goto finished;
1237 : }
1238 :
1239 64 : for (i=0; i < state->r.in.num_names;i++) {
1240 32 : struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
1241 32 : struct lsa_TranslatedSid3 *s3 = NULL;
1242 32 : struct lsa_DomainInfo *d = NULL;
1243 :
1244 32 : if (item->done) {
1245 0 : continue;
1246 : }
1247 :
1248 32 : if (item->wb_idx >= state->wb.sids.count) {
1249 0 : status = NT_STATUS_INTERNAL_ERROR;
1250 0 : goto finished;
1251 : }
1252 :
1253 32 : s3 = &state->wb.sids.sids[item->wb_idx];
1254 :
1255 32 : item->type = s3->sid_type;
1256 32 : item->sid = s3->sid;
1257 32 : item->flags = s3->flags;
1258 :
1259 32 : if (s3->sid_index == UINT32_MAX) {
1260 0 : continue;
1261 : }
1262 :
1263 32 : if (state->wb.domains == NULL) {
1264 0 : status = NT_STATUS_INTERNAL_ERROR;
1265 0 : goto finished;
1266 : }
1267 :
1268 32 : if (s3->sid_index >= state->wb.domains->count) {
1269 0 : status = NT_STATUS_INTERNAL_ERROR;
1270 0 : goto finished;
1271 : }
1272 :
1273 32 : d = &state->wb.domains->domains[s3->sid_index];
1274 :
1275 32 : item->authority_name = d->name.string;
1276 32 : item->authority_sid = d->sid;
1277 : }
1278 :
1279 32 : status = dcesrv_lsa_LookupNames_base_finish(state);
1280 48 : finished:
1281 48 : state->r.out.result = status;
1282 48 : dcesrv_lsa_LookupNames_base_map(state);
1283 :
1284 48 : dcesrv_async_reply(dce_call);
1285 48 : }
1286 :
1287 : /*
1288 : lsa_LookupNames3
1289 : */
1290 6 : NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call,
1291 : TALLOC_CTX *mem_ctx,
1292 : struct lsa_LookupNames3 *r)
1293 : {
1294 0 : enum dcerpc_transport_t transport =
1295 6 : dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
1296 6 : struct dcesrv_lsa_LookupNames_base_state *state = NULL;
1297 6 : struct dcesrv_handle *policy_handle = NULL;
1298 0 : NTSTATUS status;
1299 :
1300 6 : if (transport != NCACN_NP && transport != NCALRPC) {
1301 0 : DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
1302 : }
1303 :
1304 6 : DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1305 :
1306 6 : *r->out.domains = NULL;
1307 6 : r->out.sids->count = 0;
1308 6 : r->out.sids->sids = NULL;
1309 6 : *r->out.count = 0;
1310 :
1311 6 : state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
1312 6 : if (state == NULL) {
1313 0 : return NT_STATUS_NO_MEMORY;
1314 : }
1315 :
1316 6 : state->dce_call = dce_call;
1317 6 : state->mem_ctx = mem_ctx;
1318 :
1319 6 : state->policy_state = policy_handle->data;
1320 :
1321 6 : state->r.in.num_names = r->in.num_names;
1322 6 : state->r.in.names = r->in.names;
1323 6 : state->r.in.level = r->in.level;
1324 6 : state->r.in.lookup_options = r->in.lookup_options;
1325 6 : state->r.in.client_revision = r->in.client_revision;
1326 6 : state->r.in.sids = r->in.sids;
1327 6 : state->r.in.count = r->in.count;
1328 6 : state->r.out.domains = r->out.domains;
1329 6 : state->r.out.sids = r->out.sids;
1330 6 : state->r.out.count = r->out.count;
1331 :
1332 6 : state->_r.l3 = r;
1333 :
1334 6 : status = dcesrv_lsa_LookupNames_base_call(state);
1335 :
1336 6 : if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1337 0 : return status;
1338 : }
1339 :
1340 6 : state->r.out.result = status;
1341 6 : dcesrv_lsa_LookupNames_base_map(state);
1342 6 : return status;
1343 : }
1344 :
1345 : /*
1346 : lsa_LookupNames4
1347 :
1348 : Identical to LookupNames3, but doesn't take a policy handle
1349 :
1350 : */
1351 834 : NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1352 : struct lsa_LookupNames4 *r)
1353 : {
1354 834 : struct dcesrv_lsa_LookupNames_base_state *state = NULL;
1355 96 : NTSTATUS status;
1356 :
1357 834 : *r->out.domains = NULL;
1358 834 : r->out.sids->count = 0;
1359 834 : r->out.sids->sids = NULL;
1360 834 : *r->out.count = 0;
1361 :
1362 834 : state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
1363 834 : if (state == NULL) {
1364 0 : return NT_STATUS_NO_MEMORY;
1365 : }
1366 :
1367 834 : state->dce_call = dce_call;
1368 834 : state->mem_ctx = mem_ctx;
1369 :
1370 : /*
1371 : * We don't have a policy handle on this call, so we want to
1372 : * make a policy state and cache it for the life of the
1373 : * connection, to avoid re-opening the DB each call.
1374 : *
1375 : * This also enforces that this is only available over
1376 : * ncacn_ip_tcp and with SCHANNEL.
1377 : *
1378 : * schannel_call_setup may also set the fault state.
1379 : *
1380 : * state->policy_state is shared between all calls on this
1381 : * connection and is moved with talloc_steal() under the
1382 : * connection, not dce_call or state.
1383 : */
1384 834 : status = schannel_call_setup(dce_call, &state->policy_state);
1385 834 : if (!NT_STATUS_IS_OK(status)) {
1386 13 : return status;
1387 : }
1388 :
1389 821 : state->r.in.num_names = r->in.num_names;
1390 821 : state->r.in.names = r->in.names;
1391 821 : state->r.in.level = r->in.level;
1392 821 : state->r.in.lookup_options = r->in.lookup_options;
1393 821 : state->r.in.client_revision = r->in.client_revision;
1394 821 : state->r.in.sids = r->in.sids;
1395 821 : state->r.in.count = r->in.count;
1396 821 : state->r.out.domains = r->out.domains;
1397 821 : state->r.out.sids = r->out.sids;
1398 821 : state->r.out.count = r->out.count;
1399 :
1400 821 : state->_r.l4 = r;
1401 :
1402 821 : status = dcesrv_lsa_LookupNames_base_call(state);
1403 :
1404 821 : if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1405 36 : return status;
1406 : }
1407 :
1408 785 : state->r.out.result = status;
1409 785 : dcesrv_lsa_LookupNames_base_map(state);
1410 785 : return status;
1411 : }
1412 :
1413 : /*
1414 : lsa_LookupNames2
1415 : */
1416 6 : NTSTATUS dcesrv_lsa_LookupNames2(struct dcesrv_call_state *dce_call,
1417 : TALLOC_CTX *mem_ctx,
1418 : struct lsa_LookupNames2 *r)
1419 : {
1420 0 : enum dcerpc_transport_t transport =
1421 6 : dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
1422 6 : struct dcesrv_lsa_LookupNames_base_state *state = NULL;
1423 6 : struct dcesrv_handle *policy_handle = NULL;
1424 0 : NTSTATUS status;
1425 :
1426 6 : if (transport != NCACN_NP && transport != NCALRPC) {
1427 0 : DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
1428 : }
1429 :
1430 6 : DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1431 :
1432 6 : *r->out.domains = NULL;
1433 6 : r->out.sids->count = 0;
1434 6 : r->out.sids->sids = NULL;
1435 6 : *r->out.count = 0;
1436 :
1437 6 : r->out.sids->sids = talloc_zero_array(r->out.sids,
1438 : struct lsa_TranslatedSid2,
1439 : r->in.num_names);
1440 6 : if (r->out.sids->sids == NULL) {
1441 0 : return NT_STATUS_NO_MEMORY;
1442 : }
1443 :
1444 6 : state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
1445 6 : if (state == NULL) {
1446 0 : return NT_STATUS_NO_MEMORY;
1447 : }
1448 :
1449 6 : state->dce_call = dce_call;
1450 6 : state->mem_ctx = mem_ctx;
1451 :
1452 6 : state->policy_state = policy_handle->data;
1453 :
1454 6 : state->r.in.num_names = r->in.num_names;
1455 6 : state->r.in.names = r->in.names;
1456 6 : state->r.in.level = r->in.level;
1457 : /*
1458 : * MS-LSAT 3.1.4.7:
1459 : *
1460 : * The LookupOptions and ClientRevision parameters MUST be ignored.
1461 : * Message processing MUST happen as if LookupOptions is set to
1462 : * 0x00000000 and ClientRevision is set to 0x00000002.
1463 : */
1464 6 : state->r.in.lookup_options = LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES;
1465 6 : state->r.in.client_revision = LSA_CLIENT_REVISION_2;
1466 6 : state->r.in.sids = talloc_zero(state, struct lsa_TransSidArray3);
1467 6 : if (state->r.in.sids == NULL) {
1468 0 : return NT_STATUS_NO_MEMORY;
1469 : }
1470 6 : state->r.in.count = r->in.count;
1471 6 : state->r.out.domains = r->out.domains;
1472 6 : state->r.out.sids = talloc_zero(state, struct lsa_TransSidArray3);
1473 6 : if (state->r.out.sids == NULL) {
1474 0 : return NT_STATUS_NO_MEMORY;
1475 : }
1476 6 : state->r.out.count = r->out.count;
1477 :
1478 6 : state->_r.l2 = r;
1479 :
1480 6 : status = dcesrv_lsa_LookupNames_base_call(state);
1481 :
1482 6 : if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1483 0 : return status;
1484 : }
1485 :
1486 6 : state->r.out.result = status;
1487 6 : dcesrv_lsa_LookupNames_base_map(state);
1488 6 : return status;
1489 : }
1490 :
1491 : /*
1492 : lsa_LookupNames
1493 : */
1494 313 : NTSTATUS dcesrv_lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1495 : struct lsa_LookupNames *r)
1496 : {
1497 0 : enum dcerpc_transport_t transport =
1498 313 : dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
1499 313 : struct dcesrv_lsa_LookupNames_base_state *state = NULL;
1500 313 : struct dcesrv_handle *policy_handle = NULL;
1501 0 : NTSTATUS status;
1502 :
1503 313 : if (transport != NCACN_NP && transport != NCALRPC) {
1504 0 : DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
1505 : }
1506 :
1507 313 : DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1508 :
1509 313 : *r->out.domains = NULL;
1510 313 : r->out.sids->count = 0;
1511 313 : r->out.sids->sids = NULL;
1512 313 : *r->out.count = 0;
1513 :
1514 313 : r->out.sids->sids = talloc_zero_array(r->out.sids,
1515 : struct lsa_TranslatedSid,
1516 : r->in.num_names);
1517 313 : if (r->out.sids->sids == NULL) {
1518 0 : return NT_STATUS_NO_MEMORY;
1519 : }
1520 :
1521 313 : state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
1522 313 : if (state == NULL) {
1523 0 : return NT_STATUS_NO_MEMORY;
1524 : }
1525 :
1526 313 : state->dce_call = dce_call;
1527 313 : state->mem_ctx = mem_ctx;
1528 :
1529 313 : state->policy_state = policy_handle->data;
1530 :
1531 313 : state->r.in.num_names = r->in.num_names;
1532 313 : state->r.in.names = r->in.names;
1533 313 : state->r.in.level = r->in.level;
1534 313 : state->r.in.lookup_options = LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES;
1535 313 : state->r.in.client_revision = LSA_CLIENT_REVISION_1;
1536 313 : state->r.in.sids = talloc_zero(state, struct lsa_TransSidArray3);
1537 313 : if (state->r.in.sids == NULL) {
1538 0 : return NT_STATUS_NO_MEMORY;
1539 : }
1540 313 : state->r.in.count = r->in.count;
1541 313 : state->r.out.domains = r->out.domains;
1542 313 : state->r.out.sids = talloc_zero(state, struct lsa_TransSidArray3);
1543 313 : if (state->r.out.sids == NULL) {
1544 0 : return NT_STATUS_NO_MEMORY;
1545 : }
1546 313 : state->r.out.count = r->out.count;
1547 :
1548 313 : state->_r.l = r;
1549 :
1550 313 : status = dcesrv_lsa_LookupNames_base_call(state);
1551 :
1552 313 : if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1553 12 : return status;
1554 : }
1555 :
1556 301 : state->r.out.result = status;
1557 301 : dcesrv_lsa_LookupNames_base_map(state);
1558 301 : return status;
1559 : }
1560 :
1561 27340 : static NTSTATUS dcesrv_lsa_lookup_name_predefined(
1562 : struct dcesrv_lsa_LookupNames_base_state *state,
1563 : struct dcesrv_lsa_TranslatedItem *item)
1564 : {
1565 4800 : NTSTATUS status;
1566 :
1567 27340 : status = dom_sid_lookup_predefined_name(item->name,
1568 : &item->sid,
1569 : &item->type,
1570 : &item->authority_sid,
1571 : &item->authority_name);
1572 27340 : if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1573 27304 : return status;
1574 : }
1575 36 : if (!NT_STATUS_IS_OK(status)) {
1576 0 : return status;
1577 : }
1578 :
1579 36 : return NT_STATUS_OK;
1580 : }
1581 :
1582 27484 : static NTSTATUS dcesrv_lsa_lookup_sid_predefined(
1583 : struct dcesrv_lsa_LookupSids_base_state *state,
1584 : struct dcesrv_lsa_TranslatedItem *item)
1585 : {
1586 4800 : NTSTATUS status;
1587 :
1588 27484 : status = dom_sid_lookup_predefined_sid(item->sid,
1589 : &item->name,
1590 : &item->type,
1591 : &item->authority_sid,
1592 : &item->authority_name);
1593 27484 : if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1594 27474 : return status;
1595 : }
1596 10 : if (!NT_STATUS_IS_OK(status)) {
1597 0 : return status;
1598 : }
1599 :
1600 10 : return NT_STATUS_OK;
1601 : }
1602 :
1603 : static const struct dcesrv_lsa_Lookup_view view_predefined = {
1604 : .name = "Predefined",
1605 : .lookup_sid = dcesrv_lsa_lookup_sid_predefined,
1606 : .lookup_name = dcesrv_lsa_lookup_name_predefined,
1607 : };
1608 :
1609 27304 : static NTSTATUS dcesrv_lsa_lookup_name_builtin(
1610 : struct dcesrv_lsa_LookupNames_base_state *state,
1611 : struct dcesrv_lsa_TranslatedItem *item)
1612 : {
1613 27304 : struct lsa_policy_state *policy_state = state->policy_state;
1614 4800 : NTSTATUS status;
1615 27304 : bool is_builtin = false;
1616 :
1617 27304 : if (item->name == NULL) {
1618 : /*
1619 : * This should not be mapped.
1620 : */
1621 0 : return NT_STATUS_OK;
1622 : }
1623 :
1624 : /*
1625 : * The predefined view already handled the BUILTIN domain.
1626 : *
1627 : * Now we just need to find the principal.
1628 : *
1629 : * We only allow 'BUILTIN\something' and
1630 : * not 'something@BUILTIN.
1631 : *
1632 : * And we try out best for just 'something'.
1633 : */
1634 27304 : is_builtin = strequal(item->hints.domain, NAME_BUILTIN);
1635 27304 : if (!is_builtin && item->hints.domain != NULL) {
1636 441 : return NT_STATUS_NONE_MAPPED;
1637 : }
1638 :
1639 31663 : status = dcesrv_lsa_lookup_name(state->policy_state,
1640 : state->mem_ctx,
1641 : NAME_BUILTIN,
1642 26863 : policy_state->builtin_sid,
1643 : policy_state->builtin_dn,
1644 : item->hints.principal,
1645 : &item->sid,
1646 : &item->type);
1647 26863 : if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1648 406 : if (!is_builtin) {
1649 406 : return NT_STATUS_NONE_MAPPED;
1650 : }
1651 : /*
1652 : * We know we're authoritative
1653 : */
1654 0 : status = NT_STATUS_OK;
1655 : }
1656 26457 : if (!NT_STATUS_IS_OK(status)) {
1657 0 : return status;
1658 : }
1659 :
1660 26457 : item->authority_name = NAME_BUILTIN;
1661 26457 : item->authority_sid = policy_state->builtin_sid;
1662 26457 : return NT_STATUS_OK;
1663 : }
1664 :
1665 27474 : static NTSTATUS dcesrv_lsa_lookup_sid_builtin(
1666 : struct dcesrv_lsa_LookupSids_base_state *state,
1667 : struct dcesrv_lsa_TranslatedItem *item)
1668 : {
1669 27474 : struct lsa_policy_state *policy_state = state->policy_state;
1670 4800 : NTSTATUS status;
1671 27474 : bool is_builtin = false;
1672 :
1673 : /*
1674 : * The predefined view already handled the BUILTIN domain.
1675 : *
1676 : * Now we just need to find the principal.
1677 : */
1678 27474 : is_builtin = dom_sid_in_domain(policy_state->builtin_sid, item->sid);
1679 27474 : if (!is_builtin) {
1680 438 : return NT_STATUS_NONE_MAPPED;
1681 : }
1682 :
1683 31836 : status = dcesrv_lsa_lookup_sid(state->policy_state,
1684 : state->mem_ctx,
1685 : NAME_BUILTIN,
1686 27036 : policy_state->builtin_sid,
1687 : policy_state->builtin_dn,
1688 : item->sid,
1689 : &item->name,
1690 : &item->type);
1691 27036 : if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1692 : /*
1693 : * We know we're authoritative
1694 : */
1695 0 : status = NT_STATUS_OK;
1696 : }
1697 27036 : if (!NT_STATUS_IS_OK(status)) {
1698 0 : return status;
1699 : }
1700 :
1701 27036 : item->authority_name = NAME_BUILTIN;
1702 27036 : item->authority_sid = policy_state->builtin_sid;
1703 27036 : return NT_STATUS_OK;
1704 : }
1705 :
1706 : static const struct dcesrv_lsa_Lookup_view view_builtin = {
1707 : .name = "Builtin",
1708 : .lookup_sid = dcesrv_lsa_lookup_sid_builtin,
1709 : .lookup_name = dcesrv_lsa_lookup_name_builtin,
1710 : };
1711 :
1712 1208 : static NTSTATUS dcesrv_lsa_lookup_name_account(
1713 : struct dcesrv_lsa_LookupNames_base_state *state,
1714 : struct dcesrv_lsa_TranslatedItem *item)
1715 : {
1716 1208 : struct lsa_policy_state *policy_state = state->policy_state;
1717 1208 : struct loadparm_context *lp_ctx = state->dce_call->conn->dce_ctx->lp_ctx;
1718 1208 : struct lsa_LookupNames4 *r = &state->r;
1719 0 : NTSTATUS status;
1720 0 : int role;
1721 1208 : bool (*is_local_match_fn)(struct loadparm_context *, const char *) = NULL;
1722 1208 : bool is_domain = false;
1723 1208 : bool try_lookup = false;
1724 1208 : const char *check_domain_name = NULL;
1725 :
1726 1208 : role = lpcfg_server_role(lp_ctx);
1727 1208 : if (role == ROLE_ACTIVE_DIRECTORY_DC) {
1728 1206 : is_local_match_fn = lpcfg_is_my_domain_or_realm;
1729 : } else {
1730 2 : is_local_match_fn = lpcfg_is_myname;
1731 : }
1732 :
1733 1208 : if (item->name == NULL) {
1734 : /*
1735 : * This should not be mapped.
1736 : */
1737 0 : return NT_STATUS_OK;
1738 : }
1739 :
1740 1208 : if (item->hints.domain != NULL && item->hints.principal == NULL) {
1741 : /*
1742 : * This is 'DOMAIN\'.
1743 : */
1744 96 : check_domain_name = item->hints.domain;
1745 : } else {
1746 : /*
1747 : * This is just 'DOMAIN'.
1748 : */
1749 1112 : check_domain_name = item->name;
1750 : }
1751 1208 : is_domain = is_local_match_fn(lp_ctx, check_domain_name);
1752 1208 : if (is_domain) {
1753 217 : item->type = SID_NAME_DOMAIN;
1754 217 : item->sid = policy_state->domain_sid;
1755 217 : item->authority_name = policy_state->domain_name;
1756 217 : item->authority_sid = policy_state->domain_sid;
1757 217 : return NT_STATUS_OK;
1758 : }
1759 :
1760 991 : if (r->in.lookup_options & LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES_LOCAL) {
1761 0 : if (item->hints.domain != item->hints.namespace) {
1762 : /*
1763 : * This means the client asked for an UPN,
1764 : * and it should not be mapped.
1765 : */
1766 0 : return NT_STATUS_OK;
1767 : }
1768 : }
1769 :
1770 991 : if (item->hints.namespace != NULL) {
1771 883 : is_domain = is_local_match_fn(lp_ctx, item->hints.namespace);
1772 883 : try_lookup = is_domain;
1773 : } else {
1774 108 : try_lookup = true;
1775 : }
1776 :
1777 991 : if (!try_lookup) {
1778 0 : struct dcesrv_lsa_TranslatedItem tmp;
1779 :
1780 67 : tmp = *item;
1781 67 : status = dom_sid_lookup_predefined_name(item->hints.namespace,
1782 : &tmp.sid,
1783 : &tmp.type,
1784 : &tmp.authority_sid,
1785 : &tmp.authority_name);
1786 67 : if (NT_STATUS_IS_OK(status)) {
1787 : /*
1788 : * It should not be handled by us.
1789 : */
1790 0 : return NT_STATUS_NONE_MAPPED;
1791 : }
1792 67 : if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1793 0 : return status;
1794 : }
1795 : }
1796 :
1797 991 : if (!try_lookup) {
1798 67 : const struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
1799 67 : const struct lsa_ForestTrustDomainInfo *di = NULL;
1800 :
1801 67 : if (state->routing_table == NULL) {
1802 67 : status = dsdb_trust_routing_table_load(policy_state->sam_ldb,
1803 : state,
1804 : &state->routing_table);
1805 67 : if (!NT_STATUS_IS_OK(status)) {
1806 67 : return status;
1807 : }
1808 : }
1809 :
1810 67 : tdo = dsdb_trust_domain_by_name(state->routing_table,
1811 : item->hints.namespace,
1812 : &di);
1813 67 : if (tdo == NULL) {
1814 : /*
1815 : * The name is not resolvable at all...
1816 : */
1817 19 : return NT_STATUS_OK;
1818 : }
1819 :
1820 48 : if (!(tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST)) {
1821 : /*
1822 : * The name is not resolvable here
1823 : */
1824 48 : return NT_STATUS_NONE_MAPPED;
1825 : }
1826 :
1827 : /*
1828 : * TODO: handle multiple domains in a forest together with
1829 : * LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY
1830 : */
1831 0 : is_domain = true;
1832 0 : try_lookup = true;
1833 : }
1834 :
1835 924 : if (!try_lookup) {
1836 : /*
1837 : * It should not be handled by us.
1838 : */
1839 0 : return NT_STATUS_NONE_MAPPED;
1840 : }
1841 :
1842 : /*
1843 : * TODO: handle multiple domains in our forest.
1844 : */
1845 :
1846 924 : status = dcesrv_lsa_lookup_name(state->policy_state,
1847 : state->mem_ctx,
1848 : policy_state->domain_name,
1849 924 : policy_state->domain_sid,
1850 : policy_state->domain_dn,
1851 : item->hints.principal,
1852 : &item->sid,
1853 : &item->type);
1854 924 : if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1855 88 : if (!is_domain) {
1856 20 : return NT_STATUS_NONE_MAPPED;
1857 : }
1858 : /*
1859 : * We know we're authoritative
1860 : */
1861 68 : status = NT_STATUS_OK;
1862 : }
1863 904 : if (!NT_STATUS_IS_OK(status)) {
1864 0 : return status;
1865 : }
1866 :
1867 904 : item->authority_name = policy_state->domain_name;
1868 904 : item->authority_sid = policy_state->domain_sid;
1869 904 : return NT_STATUS_OK;
1870 : }
1871 :
1872 1232 : static NTSTATUS dcesrv_lsa_lookup_sid_account(
1873 : struct dcesrv_lsa_LookupSids_base_state *state,
1874 : struct dcesrv_lsa_TranslatedItem *item)
1875 : {
1876 1232 : struct lsa_policy_state *policy_state = state->policy_state;
1877 0 : NTSTATUS status;
1878 0 : bool is_domain;
1879 :
1880 1232 : is_domain = dom_sid_equal(policy_state->domain_sid, item->sid);
1881 1232 : if (is_domain) {
1882 12 : item->type = SID_NAME_DOMAIN;
1883 12 : item->name = policy_state->domain_name;
1884 12 : item->authority_name = policy_state->domain_name;
1885 12 : item->authority_sid = policy_state->domain_sid;
1886 12 : return NT_STATUS_OK;
1887 : }
1888 1220 : is_domain = dom_sid_in_domain(policy_state->domain_sid, item->sid);
1889 1220 : if (!is_domain) {
1890 897 : return NT_STATUS_NONE_MAPPED;
1891 : }
1892 :
1893 323 : status = dcesrv_lsa_lookup_sid(state->policy_state,
1894 : state->mem_ctx,
1895 : policy_state->domain_name,
1896 323 : policy_state->domain_sid,
1897 : policy_state->domain_dn,
1898 : item->sid,
1899 : &item->name,
1900 : &item->type);
1901 323 : if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1902 : /*
1903 : * We know we're authoritative
1904 : */
1905 6 : status = NT_STATUS_OK;
1906 : }
1907 323 : if (!NT_STATUS_IS_OK(status)) {
1908 0 : return status;
1909 : }
1910 :
1911 323 : item->authority_name = policy_state->domain_name;
1912 323 : item->authority_sid = policy_state->domain_sid;
1913 323 : return NT_STATUS_OK;
1914 : }
1915 :
1916 : static const struct dcesrv_lsa_Lookup_view view_account = {
1917 : .name = "Account",
1918 : .lookup_sid = dcesrv_lsa_lookup_sid_account,
1919 : .lookup_name = dcesrv_lsa_lookup_name_account,
1920 : };
1921 :
1922 68 : static NTSTATUS dcesrv_lsa_lookup_name_winbind(
1923 : struct dcesrv_lsa_LookupNames_base_state *state,
1924 : struct dcesrv_lsa_TranslatedItem *item)
1925 : {
1926 68 : struct lsa_LookupNames4 *r = &state->r;
1927 68 : const struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
1928 68 : const struct lsa_ForestTrustDomainInfo *di = NULL;
1929 0 : NTSTATUS status;
1930 68 : const char *check_domain_name = NULL;
1931 68 : bool expect_domain = false;
1932 0 : struct imessaging_context *imsg_ctx =
1933 68 : dcesrv_imessaging_context(state->dce_call->conn);
1934 :
1935 68 : if (item->name == NULL) {
1936 : /*
1937 : * This should not be mapped.
1938 : */
1939 0 : return NT_STATUS_OK;
1940 : }
1941 :
1942 68 : if (item->hints.domain != NULL && item->hints.principal == NULL) {
1943 : /*
1944 : * This is 'DOMAIN\'.
1945 : */
1946 0 : check_domain_name = item->hints.domain;
1947 0 : expect_domain = true;
1948 68 : } else if (item->hints.namespace != NULL) {
1949 : /*
1950 : * This is 'DOMAIN\someone'
1951 : * or 'someone@DOMAIN'
1952 : */
1953 48 : check_domain_name = item->hints.namespace;
1954 : } else {
1955 : /*
1956 : * This is just 'DOMAIN'.
1957 : */
1958 20 : check_domain_name = item->name;
1959 20 : expect_domain = true;
1960 : }
1961 :
1962 68 : if (state->routing_table == NULL) {
1963 20 : struct lsa_policy_state *policy_state = state->policy_state;
1964 :
1965 20 : status = dsdb_trust_routing_table_load(policy_state->sam_ldb,
1966 : state,
1967 : &state->routing_table);
1968 20 : if (!NT_STATUS_IS_OK(status)) {
1969 0 : return status;
1970 : }
1971 : }
1972 :
1973 68 : tdo = dsdb_trust_domain_by_name(state->routing_table,
1974 : check_domain_name,
1975 : &di);
1976 68 : if (tdo == NULL) {
1977 : /*
1978 : * The name is not resolvable at all...
1979 : *
1980 : * And for now we don't send unqualified names
1981 : * to winbindd, as we don't handle them
1982 : * there yet.
1983 : *
1984 : * TODO: how should that work within
1985 : * winbindd?
1986 : */
1987 6 : return NT_STATUS_OK;
1988 : }
1989 :
1990 62 : if (tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
1991 : /*
1992 : * The name should have been resolved in the account view.
1993 : *
1994 : * TODO: handle multiple domains in a forest...
1995 : */
1996 0 : return NT_STATUS_OK;
1997 : }
1998 :
1999 62 : if (expect_domain) {
2000 14 : const char *name = NULL;
2001 14 : const struct dom_sid *sid = NULL;
2002 :
2003 14 : name = talloc_strdup(state->mem_ctx,
2004 14 : di->netbios_domain_name.string);
2005 14 : if (name == NULL) {
2006 0 : return NT_STATUS_NO_MEMORY;
2007 : }
2008 14 : sid = dom_sid_dup(state->mem_ctx,
2009 14 : di->domain_sid);
2010 14 : if (sid == NULL) {
2011 0 : return NT_STATUS_NO_MEMORY;
2012 : }
2013 14 : item->type = SID_NAME_DOMAIN;
2014 14 : item->sid = sid;
2015 14 : item->authority_name = name;
2016 14 : item->authority_sid = sid;
2017 14 : return NT_STATUS_OK;
2018 : }
2019 :
2020 48 : if (r->in.lookup_options & LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES_LOCAL) {
2021 0 : if (item->hints.namespace == NULL) {
2022 : /*
2023 : * We should not try to resolve isolated names
2024 : * remotely.
2025 : */
2026 0 : return NT_STATUS_OK;
2027 : }
2028 : }
2029 :
2030 : /*
2031 : * We know at least the domain part of the name exists.
2032 : *
2033 : * For now the rest handled within winbindd.
2034 : *
2035 : * In future we can optimize it based on
2036 : * r->in.level.
2037 : *
2038 : * We can also try to resolve SID_NAME_DOMAIN
2039 : * just based on the routing table.
2040 : */
2041 :
2042 48 : if (state->wb.irpc_handle != NULL) {
2043 : /*
2044 : * already called...
2045 : */
2046 0 : return NT_STATUS_NONE_MAPPED;
2047 : }
2048 :
2049 48 : state->wb.irpc_handle = irpc_binding_handle_by_name(state,
2050 : imsg_ctx,
2051 : "winbind_server",
2052 : &ndr_table_lsarpc);
2053 48 : if (state->wb.irpc_handle == NULL) {
2054 0 : DEBUG(0,("Failed to get binding_handle for winbind_server task\n"));
2055 0 : state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
2056 0 : return NT_STATUS_INVALID_SYSTEM_SERVICE;
2057 : }
2058 :
2059 : /*
2060 : * 60 seconds timeout should be enough
2061 : */
2062 48 : dcerpc_binding_handle_set_timeout(state->wb.irpc_handle, 60);
2063 :
2064 48 : return NT_STATUS_NONE_MAPPED;
2065 : }
2066 :
2067 897 : static NTSTATUS dcesrv_lsa_lookup_sid_winbind(
2068 : struct dcesrv_lsa_LookupSids_base_state *state,
2069 : struct dcesrv_lsa_TranslatedItem *item)
2070 : {
2071 897 : const struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
2072 897 : const struct lsa_ForestTrustDomainInfo *di = NULL;
2073 0 : struct dcesrv_lsa_TranslatedItem tmp;
2074 897 : struct dom_sid domain_sid = {0,};
2075 0 : NTSTATUS status;
2076 0 : bool match;
2077 0 : struct imessaging_context *imsg_ctx =
2078 897 : dcesrv_imessaging_context(state->dce_call->conn);
2079 :
2080 : /*
2081 : * Verify the sid is not INVALID.
2082 : */
2083 897 : tmp = *item;
2084 897 : status = dom_sid_lookup_predefined_sid(tmp.sid,
2085 : &tmp.name,
2086 : &tmp.type,
2087 : &tmp.authority_sid,
2088 : &tmp.authority_name);
2089 897 : if (NT_STATUS_IS_OK(status)) {
2090 0 : status = NT_STATUS_NONE_MAPPED;
2091 : }
2092 897 : if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
2093 : /*
2094 : * Typically INVALID_SID
2095 : */
2096 572 : return status;
2097 : }
2098 :
2099 325 : if (state->routing_table == NULL) {
2100 317 : struct lsa_policy_state *policy_state = state->policy_state;
2101 :
2102 317 : status = dsdb_trust_routing_table_load(policy_state->sam_ldb,
2103 : state,
2104 : &state->routing_table);
2105 317 : if (!NT_STATUS_IS_OK(status)) {
2106 0 : return status;
2107 : }
2108 : }
2109 :
2110 325 : domain_sid = *item->sid;
2111 325 : if (domain_sid.num_auths == 5) {
2112 325 : sid_split_rid(&domain_sid, NULL);
2113 : }
2114 :
2115 325 : tdo = dsdb_trust_domain_by_sid(state->routing_table,
2116 : &domain_sid, &di);
2117 325 : if (tdo == NULL) {
2118 : /*
2119 : * The sid is not resolvable at all...
2120 : */
2121 299 : return NT_STATUS_OK;
2122 : }
2123 :
2124 26 : if (tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
2125 : /*
2126 : * The name should have been resolved in the account view.
2127 : *
2128 : * TODO: handle multiple domains in a forest...
2129 : */
2130 0 : return NT_STATUS_OK;
2131 : }
2132 :
2133 26 : match = dom_sid_equal(di->domain_sid, item->sid);
2134 26 : if (match) {
2135 0 : const char *name = NULL;
2136 :
2137 0 : name = talloc_strdup(state->mem_ctx,
2138 0 : di->netbios_domain_name.string);
2139 0 : if (name == NULL) {
2140 0 : return NT_STATUS_NO_MEMORY;
2141 : }
2142 :
2143 0 : item->type = SID_NAME_DOMAIN;
2144 0 : item->name = name;
2145 0 : item->authority_name = name;
2146 0 : item->authority_sid = item->sid;
2147 0 : return NT_STATUS_OK;
2148 : }
2149 :
2150 : /*
2151 : * We know at least the domain part of the sid exists.
2152 : *
2153 : * For now the rest handled within winbindd.
2154 : *
2155 : * In future we can optimize it based on
2156 : * r->in.level.
2157 : *
2158 : * We can also try to resolve SID_NAME_DOMAIN
2159 : * just based on the routing table.
2160 : */
2161 26 : if (state->wb.irpc_handle != NULL) {
2162 : /*
2163 : * already called...
2164 : */
2165 6 : return NT_STATUS_NONE_MAPPED;
2166 : }
2167 :
2168 20 : state->wb.irpc_handle = irpc_binding_handle_by_name(state,
2169 : imsg_ctx,
2170 : "winbind_server",
2171 : &ndr_table_lsarpc);
2172 20 : if (state->wb.irpc_handle == NULL) {
2173 0 : DEBUG(0,("Failed to get binding_handle for winbind_server task\n"));
2174 0 : state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
2175 0 : return NT_STATUS_INVALID_SYSTEM_SERVICE;
2176 : }
2177 :
2178 : /*
2179 : * 60 seconds timeout should be enough
2180 : */
2181 20 : dcerpc_binding_handle_set_timeout(state->wb.irpc_handle, 60);
2182 :
2183 20 : return NT_STATUS_NONE_MAPPED;
2184 : }
2185 :
2186 : static const struct dcesrv_lsa_Lookup_view view_winbind = {
2187 : .name = "Winbind",
2188 : .lookup_sid = dcesrv_lsa_lookup_sid_winbind,
2189 : .lookup_name = dcesrv_lsa_lookup_name_winbind,
2190 : };
2191 :
2192 : static const struct dcesrv_lsa_Lookup_view *table_all_views[] = {
2193 : &view_predefined,
2194 : &view_builtin,
2195 : &view_account,
2196 : &view_winbind,
2197 : };
2198 :
2199 : static const struct dcesrv_lsa_Lookup_view_table table_all = {
2200 : .name = "LSA_LOOKUP_NAMES_ALL",
2201 : .count = ARRAY_SIZE(table_all_views),
2202 : .array = table_all_views,
2203 : };
2204 :
2205 : static const struct dcesrv_lsa_Lookup_view *table_domains_views[] = {
2206 : &view_account,
2207 : &view_winbind,
2208 : };
2209 :
2210 : static const struct dcesrv_lsa_Lookup_view_table table_domains = {
2211 : .name = "LSA_LOOKUP_NAMES_DOMAINS_ONLY",
2212 : .count = ARRAY_SIZE(table_domains_views),
2213 : .array = table_domains_views,
2214 : };
2215 :
2216 : static const struct dcesrv_lsa_Lookup_view *table_primary_views[] = {
2217 : &view_account,
2218 : };
2219 :
2220 : static const struct dcesrv_lsa_Lookup_view_table table_primary = {
2221 : .name = "LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY",
2222 : .count = ARRAY_SIZE(table_primary_views),
2223 : .array = table_primary_views,
2224 : };
2225 :
2226 : static const struct dcesrv_lsa_Lookup_view *table_remote_views[] = {
2227 : &view_winbind,
2228 : };
2229 :
2230 : static const struct dcesrv_lsa_Lookup_view_table table_gc = {
2231 : .name = "LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY",
2232 : .count = ARRAY_SIZE(table_domains_views),
2233 : .array = table_domains_views,
2234 : };
2235 :
2236 : static const struct dcesrv_lsa_Lookup_view_table table_xreferral = {
2237 : .name = "LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY",
2238 : .count = ARRAY_SIZE(table_remote_views),
2239 : .array = table_remote_views,
2240 : };
2241 :
2242 : static const struct dcesrv_lsa_Lookup_view_table table_xresolve = {
2243 : .name = "LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2",
2244 : .count = ARRAY_SIZE(table_domains_views),
2245 : .array = table_domains_views,
2246 : };
2247 :
2248 : static const struct dcesrv_lsa_Lookup_view_table table_rodc = {
2249 : .name = "LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC",
2250 : .count = ARRAY_SIZE(table_remote_views),
2251 : .array = table_remote_views,
2252 : };
2253 :
2254 3188 : static const struct dcesrv_lsa_Lookup_view_table *dcesrv_lsa_view_table(
2255 : enum lsa_LookupNamesLevel level)
2256 : {
2257 3188 : switch (level) {
2258 1921 : case LSA_LOOKUP_NAMES_ALL:
2259 1921 : return &table_all;
2260 993 : case LSA_LOOKUP_NAMES_DOMAINS_ONLY:
2261 993 : return &table_domains;
2262 36 : case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY:
2263 36 : return &table_primary;
2264 0 : case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY:
2265 0 : return &table_gc;
2266 0 : case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY:
2267 0 : return &table_xreferral;
2268 94 : case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2:
2269 94 : return &table_xresolve;
2270 0 : case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC:
2271 0 : return &table_rodc;
2272 : }
2273 :
2274 0 : return NULL;
2275 : }
|