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