Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : * RPC Pipe client / server routines
4 : * Copyright (C) Andrew Tridgell 1992-1997,
5 : * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 : * Copyright (C) Paul Ashton 1997,
7 : * Copyright (C) Jeremy Allison 2001, 2006.
8 : * Copyright (C) Rafal Szczesniak 2002,
9 : * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
10 : * Copyright (C) Simo Sorce 2003.
11 : * Copyright (C) Gerald (Jerry) Carter 2005.
12 : * Copyright (C) Volker Lendecke 2005.
13 : * Copyright (C) Guenther Deschner 2008.
14 : * Copyright (C) Andrew Bartlett 2010.
15 : *
16 : * This program is free software; you can redistribute it and/or modify
17 : * it under the terms of the GNU General Public License as published by
18 : * the Free Software Foundation; either version 3 of the License, or
19 : * (at your option) any later version.
20 : *
21 : * This program is distributed in the hope that it will be useful,
22 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 : * GNU General Public License for more details.
25 : *
26 : * You should have received a copy of the GNU General Public License
27 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
28 : */
29 :
30 : /* This is the implementation of the lsa server code. */
31 :
32 : #include "includes.h"
33 : #include "ntdomain.h"
34 : #include "librpc/gen_ndr/ndr_lsa.h"
35 : #include "librpc/gen_ndr/ndr_lsa_scompat.h"
36 : #include "secrets.h"
37 : #include "../librpc/gen_ndr/netlogon.h"
38 : #include "rpc_client/init_lsa.h"
39 : #include "../libcli/security/security.h"
40 : #include "../libcli/security/dom_sid.h"
41 : #include "../librpc/gen_ndr/drsblobs.h"
42 : #include "../librpc/gen_ndr/ndr_drsblobs.h"
43 : #include "../libcli/security/dom_sid.h"
44 : #include "../librpc/gen_ndr/ndr_security.h"
45 : #include "passdb.h"
46 : #include "auth.h"
47 : #include "lib/privileges.h"
48 : #include "rpc_server/srv_access_check.h"
49 : #include "../librpc/gen_ndr/ndr_wkssvc.h"
50 : #include "../libcli/auth/libcli_auth.h"
51 : #include "../libcli/lsarpc/util_lsarpc.h"
52 : #include "lsa.h"
53 : #include "librpc/rpc/dcesrv_core.h"
54 : #include "librpc/rpc/dcerpc_helper.h"
55 : #include "lib/param/loadparm.h"
56 : #include "source3/lib/substitute.h"
57 :
58 : #include "lib/crypto/gnutls_helpers.h"
59 : #include <gnutls/gnutls.h>
60 : #include <gnutls/crypto.h>
61 :
62 : #undef DBGC_CLASS
63 : #define DBGC_CLASS DBGC_RPC_SRV
64 :
65 : #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
66 :
67 : enum lsa_handle_type {
68 : LSA_HANDLE_POLICY_TYPE = 1,
69 : LSA_HANDLE_ACCOUNT_TYPE = 2,
70 : LSA_HANDLE_TRUST_TYPE = 3,
71 : LSA_HANDLE_SECRET_TYPE = 4};
72 :
73 : struct lsa_info {
74 : struct dom_sid sid;
75 : const char *name;
76 : uint32_t access;
77 : enum lsa_handle_type type;
78 : struct security_descriptor *sd;
79 : };
80 :
81 : const struct generic_mapping lsa_account_mapping = {
82 : LSA_ACCOUNT_READ,
83 : LSA_ACCOUNT_WRITE,
84 : LSA_ACCOUNT_EXECUTE,
85 : LSA_ACCOUNT_ALL_ACCESS
86 : };
87 :
88 : const struct generic_mapping lsa_policy_mapping = {
89 : LSA_POLICY_READ,
90 : LSA_POLICY_WRITE,
91 : LSA_POLICY_EXECUTE,
92 : LSA_POLICY_ALL_ACCESS
93 : };
94 :
95 : const struct generic_mapping lsa_secret_mapping = {
96 : LSA_SECRET_READ,
97 : LSA_SECRET_WRITE,
98 : LSA_SECRET_EXECUTE,
99 : LSA_SECRET_ALL_ACCESS
100 : };
101 :
102 : const struct generic_mapping lsa_trusted_domain_mapping = {
103 : LSA_TRUSTED_DOMAIN_READ,
104 : LSA_TRUSTED_DOMAIN_WRITE,
105 : LSA_TRUSTED_DOMAIN_EXECUTE,
106 : LSA_TRUSTED_DOMAIN_ALL_ACCESS
107 : };
108 :
109 : /***************************************************************************
110 : initialize a lsa_DomainInfo structure.
111 : ***************************************************************************/
112 :
113 58 : static void init_dom_query_3(struct lsa_DomainInfo *r,
114 : const char *name,
115 : struct dom_sid *sid)
116 : {
117 58 : init_lsa_StringLarge(&r->name, name);
118 58 : r->sid = sid;
119 58 : }
120 :
121 : /***************************************************************************
122 : initialize a lsa_DomainInfo structure.
123 : ***************************************************************************/
124 :
125 754 : static void init_dom_query_5(struct lsa_DomainInfo *r,
126 : const char *name,
127 : struct dom_sid *sid)
128 : {
129 754 : init_lsa_StringLarge(&r->name, name);
130 754 : r->sid = sid;
131 754 : }
132 :
133 : /***************************************************************************
134 : lookup_lsa_rids. Must be called as root for lookup_name to work.
135 : ***************************************************************************/
136 :
137 255 : static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
138 : struct lsa_RefDomainList *ref,
139 : struct lsa_TranslatedSid *prid,
140 : uint32_t num_entries,
141 : struct lsa_String *name,
142 : int flags,
143 : uint32_t *pmapped_count)
144 : {
145 0 : uint32_t mapped_count, i;
146 :
147 255 : SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
148 :
149 255 : mapped_count = 0;
150 255 : *pmapped_count = 0;
151 :
152 728 : for (i = 0; i < num_entries; i++) {
153 0 : struct dom_sid sid;
154 0 : uint32_t rid;
155 0 : int dom_idx;
156 0 : const char *full_name;
157 0 : const char *domain;
158 0 : enum lsa_SidType type;
159 :
160 : /* Split name into domain and user component */
161 :
162 : /* follow w2k8 behavior and return the builtin domain when no
163 : * input has been passed in */
164 :
165 473 : if (name[i].string) {
166 471 : full_name = name[i].string;
167 : } else {
168 2 : full_name = "BUILTIN";
169 : }
170 :
171 473 : DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
172 :
173 473 : if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
174 : &sid, &type)) {
175 9 : type = SID_NAME_UNKNOWN;
176 : }
177 :
178 473 : switch (type) {
179 464 : case SID_NAME_USER:
180 : case SID_NAME_DOM_GRP:
181 : case SID_NAME_DOMAIN:
182 : case SID_NAME_ALIAS:
183 : case SID_NAME_WKN_GRP:
184 464 : DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
185 : /* Leave these unchanged */
186 464 : break;
187 9 : default:
188 : /* Don't hand out anything but the list above */
189 9 : DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
190 9 : type = SID_NAME_UNKNOWN;
191 9 : break;
192 : }
193 :
194 473 : rid = 0;
195 473 : dom_idx = -1;
196 :
197 473 : if (type != SID_NAME_UNKNOWN) {
198 464 : if (type == SID_NAME_DOMAIN) {
199 12 : rid = (uint32_t)-1;
200 : } else {
201 452 : sid_split_rid(&sid, &rid);
202 : }
203 464 : dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
204 464 : mapped_count++;
205 : }
206 :
207 473 : prid[i].sid_type = type;
208 473 : prid[i].rid = rid;
209 473 : prid[i].sid_index = dom_idx;
210 : }
211 :
212 255 : *pmapped_count = mapped_count;
213 255 : return NT_STATUS_OK;
214 : }
215 :
216 : /***************************************************************************
217 : lookup_lsa_sids. Must be called as root for lookup_name to work.
218 : ***************************************************************************/
219 :
220 46 : static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
221 : struct lsa_RefDomainList *ref,
222 : struct lsa_TranslatedSid3 *trans_sids,
223 : uint32_t num_entries,
224 : struct lsa_String *name,
225 : int flags,
226 : uint32_t *pmapped_count)
227 : {
228 0 : uint32_t mapped_count, i;
229 :
230 46 : SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
231 :
232 46 : mapped_count = 0;
233 46 : *pmapped_count = 0;
234 :
235 2160 : for (i = 0; i < num_entries; i++) {
236 0 : struct dom_sid sid;
237 0 : uint32_t rid;
238 0 : int dom_idx;
239 0 : const char *full_name;
240 0 : const char *domain;
241 0 : enum lsa_SidType type;
242 :
243 2114 : ZERO_STRUCT(sid);
244 :
245 : /* Split name into domain and user component */
246 :
247 2114 : full_name = name[i].string;
248 2114 : if (full_name == NULL) {
249 0 : return NT_STATUS_NO_MEMORY;
250 : }
251 :
252 2114 : DEBUG(5, ("lookup_lsa_sids: looking up name %s\n", full_name));
253 :
254 2114 : if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
255 : &sid, &type)) {
256 0 : type = SID_NAME_UNKNOWN;
257 : }
258 :
259 2114 : switch (type) {
260 2114 : case SID_NAME_USER:
261 : case SID_NAME_DOM_GRP:
262 : case SID_NAME_DOMAIN:
263 : case SID_NAME_ALIAS:
264 : case SID_NAME_WKN_GRP:
265 2114 : DEBUG(5, ("lookup_lsa_sids: %s found\n", full_name));
266 : /* Leave these unchanged */
267 2114 : break;
268 0 : default:
269 : /* Don't hand out anything but the list above */
270 0 : DEBUG(5, ("lookup_lsa_sids: %s not found\n", full_name));
271 0 : type = SID_NAME_UNKNOWN;
272 0 : break;
273 : }
274 :
275 2114 : rid = 0;
276 2114 : dom_idx = -1;
277 :
278 2114 : if (type != SID_NAME_UNKNOWN) {
279 0 : struct dom_sid domain_sid;
280 2114 : sid_copy(&domain_sid, &sid);
281 2114 : sid_split_rid(&domain_sid, &rid);
282 2114 : dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
283 2114 : mapped_count++;
284 : }
285 :
286 : /* Initialize the lsa_TranslatedSid3 return. */
287 2114 : trans_sids[i].sid_type = type;
288 2114 : trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
289 2114 : trans_sids[i].sid_index = dom_idx;
290 : }
291 :
292 46 : *pmapped_count = mapped_count;
293 46 : return NT_STATUS_OK;
294 : }
295 :
296 2484 : static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
297 : const struct generic_mapping *map,
298 : struct dom_sid *sid, uint32_t sid_access)
299 : {
300 0 : struct dom_sid adm_sid;
301 0 : struct security_ace ace[5];
302 2484 : size_t i = 0;
303 :
304 2484 : struct security_acl *psa = NULL;
305 :
306 : /* READ|EXECUTE access for Everyone */
307 :
308 2484 : init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
309 2484 : map->generic_execute | map->generic_read, 0);
310 :
311 : /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
312 :
313 2484 : init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
314 2484 : SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
315 2484 : init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
316 2484 : SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
317 :
318 : /* Add Full Access for Domain Admins */
319 2484 : sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
320 2484 : init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
321 2484 : map->generic_all, 0);
322 :
323 : /* If we have a sid, give it some special access */
324 :
325 2484 : if (sid) {
326 16 : init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
327 : sid_access, 0);
328 : }
329 :
330 2484 : if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
331 0 : return NT_STATUS_NO_MEMORY;
332 :
333 2484 : if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
334 : SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
335 : psa, sd_size)) == NULL)
336 0 : return NT_STATUS_NO_MEMORY;
337 :
338 2484 : return NT_STATUS_OK;
339 : }
340 :
341 : /***************************************************************************
342 : ***************************************************************************/
343 :
344 2440 : static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
345 : struct pipes_struct *p,
346 : enum lsa_handle_type type,
347 : uint32_t acc_granted,
348 : struct dom_sid *sid,
349 : const char *name,
350 : const struct security_descriptor *sd,
351 : struct policy_handle *handle)
352 : {
353 0 : struct lsa_info *info;
354 :
355 2440 : ZERO_STRUCTP(handle);
356 :
357 2440 : info = talloc_zero(mem_ctx, struct lsa_info);
358 2440 : if (!info) {
359 0 : return NT_STATUS_NO_MEMORY;
360 : }
361 :
362 2440 : info->type = type;
363 2440 : info->access = acc_granted;
364 :
365 2440 : if (sid) {
366 2096 : sid_copy(&info->sid, sid);
367 : }
368 :
369 2440 : info->name = talloc_strdup(info, name);
370 :
371 2440 : if (sd != NULL) {
372 2440 : info->sd = security_descriptor_copy(info, sd);
373 2440 : if (info->sd == NULL) {
374 0 : talloc_free(info);
375 0 : return NT_STATUS_NO_MEMORY;
376 : }
377 : }
378 :
379 2440 : if (!create_policy_hnd(p, handle, type, info)) {
380 0 : talloc_free(info);
381 0 : ZERO_STRUCTP(handle);
382 0 : return NT_STATUS_NO_MEMORY;
383 : }
384 :
385 2440 : return NT_STATUS_OK;
386 : }
387 :
388 : /***************************************************************************
389 : _lsa_OpenPolicy2
390 : ***************************************************************************/
391 :
392 2084 : NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
393 : struct lsa_OpenPolicy2 *r)
394 : {
395 2084 : struct dcesrv_call_state *dce_call = p->dce_call;
396 0 : struct auth_session_info *session_info =
397 2084 : dcesrv_call_session_info(dce_call);
398 2084 : struct security_descriptor *psd = NULL;
399 0 : size_t sd_size;
400 2084 : uint32_t des_access = r->in.access_mask;
401 0 : uint32_t acc_granted;
402 0 : NTSTATUS status;
403 :
404 2084 : if (p->transport != NCACN_NP && p->transport != NCALRPC) {
405 4 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
406 4 : return NT_STATUS_ACCESS_DENIED;
407 : }
408 :
409 : /* Work out max allowed. */
410 2080 : map_max_allowed_access(session_info->security_token,
411 2080 : session_info->unix_token,
412 : &des_access);
413 :
414 : /* map the generic bits to the lsa policy ones */
415 2080 : se_map_generic(&des_access, &lsa_policy_mapping);
416 :
417 : /* get the generic lsa policy SD until we store it */
418 2080 : status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
419 : NULL, 0);
420 2080 : if (!NT_STATUS_IS_OK(status)) {
421 0 : return status;
422 : }
423 :
424 2080 : status = access_check_object(psd, session_info->security_token,
425 : SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
426 : &acc_granted, "_lsa_OpenPolicy2" );
427 2080 : if (!NT_STATUS_IS_OK(status)) {
428 0 : return status;
429 : }
430 :
431 2080 : status = create_lsa_policy_handle(p->mem_ctx, p,
432 : LSA_HANDLE_POLICY_TYPE,
433 : acc_granted,
434 : get_global_sam_sid(),
435 : NULL,
436 : psd,
437 : r->out.handle);
438 2080 : if (!NT_STATUS_IS_OK(status)) {
439 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
440 : }
441 :
442 2080 : return NT_STATUS_OK;
443 : }
444 :
445 : /***************************************************************************
446 : _lsa_OpenPolicy
447 : ***************************************************************************/
448 :
449 1431 : NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
450 : struct lsa_OpenPolicy *r)
451 : {
452 0 : struct lsa_OpenPolicy2 o;
453 :
454 : /* _lsa_OpenPolicy2 will check if this is a NCACN_NP connection */
455 :
456 1431 : o.in.system_name = NULL; /* should be ignored */
457 1431 : o.in.attr = r->in.attr;
458 1431 : o.in.access_mask = r->in.access_mask;
459 :
460 1431 : o.out.handle = r->out.handle;
461 :
462 1431 : return _lsa_OpenPolicy2(p, &o);
463 : }
464 :
465 : /***************************************************************************
466 : _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
467 : ufff, done :) mimir
468 : ***************************************************************************/
469 :
470 0 : NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
471 : struct lsa_EnumTrustDom *r)
472 : {
473 0 : struct lsa_info *info;
474 0 : uint32_t i, count;
475 0 : struct trustdom_info **domains;
476 0 : struct lsa_DomainInfo *entries;
477 0 : NTSTATUS nt_status;
478 :
479 0 : info = find_policy_by_hnd(p,
480 : r->in.handle,
481 : LSA_HANDLE_POLICY_TYPE,
482 : struct lsa_info,
483 0 : &nt_status);
484 0 : if (!NT_STATUS_IS_OK(nt_status)) {
485 0 : return NT_STATUS_INVALID_HANDLE;
486 : }
487 :
488 : /* check if the user has enough rights */
489 0 : if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
490 0 : return NT_STATUS_ACCESS_DENIED;
491 :
492 0 : become_root();
493 0 : nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
494 0 : unbecome_root();
495 :
496 0 : if (!NT_STATUS_IS_OK(nt_status)) {
497 0 : return nt_status;
498 : }
499 :
500 0 : entries = talloc_zero_array(p->mem_ctx, struct lsa_DomainInfo, count);
501 0 : if (!entries) {
502 0 : return NT_STATUS_NO_MEMORY;
503 : }
504 :
505 0 : for (i=0; i<count; i++) {
506 0 : init_lsa_StringLarge(&entries[i].name, domains[i]->name);
507 0 : entries[i].sid = &domains[i]->sid;
508 : }
509 :
510 0 : if (*r->in.resume_handle >= count) {
511 0 : *r->out.resume_handle = -1;
512 0 : TALLOC_FREE(entries);
513 0 : return NT_STATUS_NO_MORE_ENTRIES;
514 : }
515 :
516 : /* return the rest, limit by max_size. Note that we
517 : use the w2k3 element size value of 60 */
518 0 : r->out.domains->count = count - *r->in.resume_handle;
519 0 : r->out.domains->count = MIN(r->out.domains->count,
520 : 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
521 :
522 0 : r->out.domains->domains = entries + *r->in.resume_handle;
523 :
524 0 : if (r->out.domains->count < count - *r->in.resume_handle) {
525 0 : *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
526 0 : return STATUS_MORE_ENTRIES;
527 : }
528 :
529 : /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
530 : * always be larger than the previous input resume handle, in
531 : * particular when hitting the last query it is vital to set the
532 : * resume handle correctly to avoid infinite client loops, as
533 : * seen e.g. with Windows XP SP3 when resume handle is 0 and
534 : * status is NT_STATUS_OK - gd */
535 :
536 0 : *r->out.resume_handle = (uint32_t)-1;
537 :
538 0 : return NT_STATUS_OK;
539 : }
540 :
541 : #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
542 : #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
543 : #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
544 :
545 : /***************************************************************************
546 : _lsa_QueryInfoPolicy
547 : ***************************************************************************/
548 :
549 838 : NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
550 : struct lsa_QueryInfoPolicy *r)
551 : {
552 838 : NTSTATUS status = NT_STATUS_OK;
553 0 : struct lsa_info *handle;
554 0 : struct dom_sid domain_sid;
555 0 : const char *name;
556 838 : struct dom_sid *sid = NULL;
557 838 : union lsa_PolicyInformation *info = NULL;
558 838 : uint32_t acc_required = 0;
559 :
560 838 : handle = find_policy_by_hnd(p,
561 : r->in.handle,
562 : LSA_HANDLE_POLICY_TYPE,
563 : struct lsa_info,
564 0 : &status);
565 838 : if (!NT_STATUS_IS_OK(status)) {
566 0 : return NT_STATUS_INVALID_HANDLE;
567 : }
568 :
569 838 : switch (r->in.level) {
570 4 : case LSA_POLICY_INFO_AUDIT_LOG:
571 : case LSA_POLICY_INFO_AUDIT_EVENTS:
572 4 : acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
573 4 : break;
574 58 : case LSA_POLICY_INFO_DOMAIN:
575 58 : acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
576 58 : break;
577 2 : case LSA_POLICY_INFO_PD:
578 2 : acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
579 2 : break;
580 754 : case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
581 754 : acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
582 754 : break;
583 4 : case LSA_POLICY_INFO_ROLE:
584 : case LSA_POLICY_INFO_REPLICA:
585 4 : acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
586 4 : break;
587 2 : case LSA_POLICY_INFO_QUOTA:
588 2 : acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
589 2 : break;
590 4 : case LSA_POLICY_INFO_MOD:
591 : case LSA_POLICY_INFO_AUDIT_FULL_SET:
592 : /* according to MS-LSAD 3.1.4.4.3 */
593 4 : return NT_STATUS_INVALID_PARAMETER;
594 2 : case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
595 2 : acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
596 2 : break;
597 8 : case LSA_POLICY_INFO_DNS:
598 : case LSA_POLICY_INFO_DNS_INT:
599 : case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
600 8 : acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
601 8 : break;
602 0 : default:
603 0 : break;
604 : }
605 :
606 834 : if (!(handle->access & acc_required)) {
607 : /* return NT_STATUS_ACCESS_DENIED; */
608 0 : }
609 :
610 834 : info = talloc_zero(p->mem_ctx, union lsa_PolicyInformation);
611 834 : if (!info) {
612 0 : return NT_STATUS_NO_MEMORY;
613 : }
614 :
615 834 : switch (r->in.level) {
616 : /* according to MS-LSAD 3.1.4.4.3 */
617 2 : case LSA_POLICY_INFO_MOD:
618 : case LSA_POLICY_INFO_AUDIT_FULL_SET:
619 : case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
620 2 : return NT_STATUS_INVALID_PARAMETER;
621 2 : case LSA_POLICY_INFO_AUDIT_LOG:
622 2 : info->audit_log.percent_full = 0;
623 2 : info->audit_log.maximum_log_size = 0;
624 2 : info->audit_log.retention_time = 0;
625 2 : info->audit_log.shutdown_in_progress = 0;
626 2 : info->audit_log.time_to_shutdown = 0;
627 2 : info->audit_log.next_audit_record = 0;
628 2 : status = NT_STATUS_OK;
629 2 : break;
630 2 : case LSA_POLICY_INFO_PD:
631 2 : info->pd.name.string = NULL;
632 2 : status = NT_STATUS_OK;
633 2 : break;
634 2 : case LSA_POLICY_INFO_REPLICA:
635 2 : info->replica.source.string = NULL;
636 2 : info->replica.account.string = NULL;
637 2 : status = NT_STATUS_OK;
638 2 : break;
639 2 : case LSA_POLICY_INFO_QUOTA:
640 2 : info->quota.paged_pool = 0;
641 2 : info->quota.non_paged_pool = 0;
642 2 : info->quota.min_wss = 0;
643 2 : info->quota.max_wss = 0;
644 2 : info->quota.pagefile = 0;
645 2 : info->quota.unknown = 0;
646 2 : status = NT_STATUS_OK;
647 2 : break;
648 2 : case LSA_POLICY_INFO_AUDIT_EVENTS:
649 : {
650 :
651 2 : uint32_t policy_def = LSA_AUDIT_POLICY_ALL;
652 :
653 : /* check if the user has enough rights */
654 2 : if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
655 0 : DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
656 0 : return NT_STATUS_ACCESS_DENIED;
657 : }
658 :
659 : /* fake info: We audit everything. ;) */
660 :
661 2 : info->audit_events.auditing_mode = true;
662 2 : info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
663 2 : info->audit_events.settings = talloc_zero_array(p->mem_ctx,
664 : enum lsa_PolicyAuditPolicy,
665 : info->audit_events.count);
666 2 : if (!info->audit_events.settings) {
667 0 : return NT_STATUS_NO_MEMORY;
668 : }
669 :
670 2 : info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
671 2 : info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
672 2 : info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
673 2 : info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
674 2 : info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
675 2 : info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
676 2 : info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
677 :
678 2 : break;
679 : }
680 58 : case LSA_POLICY_INFO_DOMAIN:
681 : /* check if the user has enough rights */
682 58 : if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
683 0 : return NT_STATUS_ACCESS_DENIED;
684 :
685 : /* Request PolicyPrimaryDomainInformation. */
686 58 : switch (lp_server_role()) {
687 58 : case ROLE_DOMAIN_PDC:
688 : case ROLE_DOMAIN_BDC:
689 : case ROLE_IPA_DC:
690 58 : name = get_global_sam_name();
691 58 : sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
692 58 : if (!sid) {
693 0 : return NT_STATUS_NO_MEMORY;
694 : }
695 58 : break;
696 0 : case ROLE_DOMAIN_MEMBER:
697 0 : name = lp_workgroup();
698 : /* We need to return the Domain SID here. */
699 0 : if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
700 0 : sid = dom_sid_dup(p->mem_ctx, &domain_sid);
701 0 : if (!sid) {
702 0 : return NT_STATUS_NO_MEMORY;
703 : }
704 : } else {
705 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
706 : }
707 0 : break;
708 0 : case ROLE_STANDALONE:
709 0 : name = lp_workgroup();
710 0 : sid = NULL;
711 0 : break;
712 0 : default:
713 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
714 : }
715 58 : init_dom_query_3(&info->domain, name, sid);
716 58 : break;
717 754 : case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
718 : /* check if the user has enough rights */
719 754 : if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
720 0 : return NT_STATUS_ACCESS_DENIED;
721 :
722 : /* Request PolicyAccountDomainInformation. */
723 754 : name = get_global_sam_name();
724 754 : sid = get_global_sam_sid();
725 :
726 754 : init_dom_query_5(&info->account_domain, name, sid);
727 754 : break;
728 2 : case LSA_POLICY_INFO_ROLE:
729 : /* check if the user has enough rights */
730 2 : if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
731 0 : return NT_STATUS_ACCESS_DENIED;
732 :
733 2 : switch (lp_server_role()) {
734 0 : case ROLE_DOMAIN_BDC:
735 : /*
736 : * only a BDC is a backup controller
737 : * of the domain, it controls.
738 : */
739 0 : info->role.role = LSA_ROLE_BACKUP;
740 0 : break;
741 2 : default:
742 : /*
743 : * any other role is a primary
744 : * of the domain, it controls.
745 : */
746 2 : info->role.role = LSA_ROLE_PRIMARY;
747 2 : break;
748 : }
749 2 : break;
750 6 : case LSA_POLICY_INFO_DNS:
751 : case LSA_POLICY_INFO_DNS_INT: {
752 0 : struct pdb_domain_info *dominfo;
753 :
754 6 : if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
755 4 : DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
756 : "without ADS passdb backend\n"));
757 4 : status = NT_STATUS_INVALID_INFO_CLASS;
758 4 : break;
759 : }
760 :
761 2 : dominfo = pdb_get_domain_info(info);
762 2 : if (dominfo == NULL) {
763 0 : status = NT_STATUS_NO_MEMORY;
764 0 : break;
765 : }
766 :
767 2 : init_lsa_StringLarge(&info->dns.name,
768 2 : dominfo->name);
769 2 : init_lsa_StringLarge(&info->dns.dns_domain,
770 2 : dominfo->dns_domain);
771 2 : init_lsa_StringLarge(&info->dns.dns_forest,
772 2 : dominfo->dns_forest);
773 2 : info->dns.domain_guid = dominfo->guid;
774 2 : info->dns.sid = &dominfo->sid;
775 2 : break;
776 : }
777 2 : default:
778 2 : DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
779 : r->in.level));
780 2 : status = NT_STATUS_INVALID_INFO_CLASS;
781 2 : break;
782 : }
783 :
784 832 : *r->out.info = info;
785 :
786 832 : return status;
787 : }
788 :
789 : /***************************************************************************
790 : _lsa_QueryInfoPolicy2
791 : ***************************************************************************/
792 :
793 121 : NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
794 : struct lsa_QueryInfoPolicy2 *r2)
795 : {
796 0 : struct lsa_QueryInfoPolicy r;
797 :
798 121 : if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
799 119 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
800 119 : return NT_STATUS_NOT_IMPLEMENTED;
801 : }
802 :
803 2 : ZERO_STRUCT(r);
804 2 : r.in.handle = r2->in.handle;
805 2 : r.in.level = r2->in.level;
806 2 : r.out.info = r2->out.info;
807 :
808 2 : return _lsa_QueryInfoPolicy(p, &r);
809 : }
810 :
811 : /***************************************************************************
812 : _lsa_lookup_sids_internal
813 : ***************************************************************************/
814 :
815 1890 : static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
816 : TALLOC_CTX *mem_ctx,
817 : uint16_t level, /* input */
818 : int num_sids, /* input */
819 : struct lsa_SidPtr *sid, /* input */
820 : struct lsa_RefDomainList **pp_ref, /* input/output */
821 : struct lsa_TranslatedName2 **pp_names,/* input/output */
822 : uint32_t *pp_mapped_count) /* input/output */
823 : {
824 0 : NTSTATUS status;
825 0 : int i;
826 1890 : const struct dom_sid **sids = NULL;
827 1890 : struct lsa_RefDomainList *ref = NULL;
828 1890 : uint32_t mapped_count = 0;
829 1890 : struct lsa_dom_info *dom_infos = NULL;
830 1890 : struct lsa_name_info *name_infos = NULL;
831 1890 : struct lsa_TranslatedName2 *names = NULL;
832 :
833 1890 : *pp_mapped_count = 0;
834 1890 : *pp_names = NULL;
835 1890 : *pp_ref = NULL;
836 :
837 1890 : if (num_sids == 0) {
838 0 : return NT_STATUS_OK;
839 : }
840 :
841 1890 : sids = talloc_array(p->mem_ctx, const struct dom_sid *, num_sids);
842 1890 : ref = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
843 :
844 1890 : if (sids == NULL || ref == NULL) {
845 0 : return NT_STATUS_NO_MEMORY;
846 : }
847 :
848 6082 : for (i=0; i<num_sids; i++) {
849 4192 : sids[i] = sid[i].sid;
850 : }
851 :
852 1890 : status = lookup_sids(p->mem_ctx, num_sids, sids, level,
853 : &dom_infos, &name_infos);
854 :
855 1890 : if (!NT_STATUS_IS_OK(status)) {
856 0 : return status;
857 : }
858 :
859 1890 : names = talloc_array(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
860 1890 : if (names == NULL) {
861 0 : return NT_STATUS_NO_MEMORY;
862 : }
863 :
864 3784 : for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
865 :
866 3784 : if (!dom_infos[i].valid) {
867 1890 : break;
868 : }
869 :
870 1894 : if (init_lsa_ref_domain_list(mem_ctx, ref,
871 1894 : dom_infos[i].name,
872 1894 : &dom_infos[i].sid) != i) {
873 0 : DEBUG(0, ("Domain %s mentioned twice??\n",
874 : dom_infos[i].name));
875 0 : return NT_STATUS_INTERNAL_ERROR;
876 : }
877 : }
878 :
879 6082 : for (i=0; i<num_sids; i++) {
880 4192 : struct lsa_name_info *name = &name_infos[i];
881 :
882 4192 : if (name->type == SID_NAME_UNKNOWN) {
883 159 : name->dom_idx = -1;
884 : /* Unknown sids should return the string
885 : * representation of the SID. Windows 2003 behaves
886 : * rather erratic here, in many cases it returns the
887 : * RID as 8 bytes hex, in others it returns the full
888 : * SID. We (Jerry/VL) could not figure out which the
889 : * hard cases are, so leave it with the SID. */
890 159 : name->name = dom_sid_string(p->mem_ctx, sids[i]);
891 159 : if (name->name == NULL) {
892 0 : return NT_STATUS_NO_MEMORY;
893 : }
894 : } else {
895 4033 : mapped_count += 1;
896 : }
897 :
898 4192 : names[i].sid_type = name->type;
899 4192 : names[i].name.string = name->name;
900 4192 : names[i].sid_index = name->dom_idx;
901 4192 : names[i].unknown = 0;
902 : }
903 :
904 1890 : status = NT_STATUS_NONE_MAPPED;
905 1890 : if (mapped_count > 0) {
906 1736 : status = (mapped_count < num_sids) ?
907 0 : STATUS_SOME_UNMAPPED : NT_STATUS_OK;
908 : }
909 :
910 1890 : DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
911 : num_sids, mapped_count, nt_errstr(status)));
912 :
913 1890 : *pp_mapped_count = mapped_count;
914 1890 : *pp_names = names;
915 1890 : *pp_ref = ref;
916 :
917 1890 : return status;
918 : }
919 :
920 : /***************************************************************************
921 : _lsa_LookupSids
922 : ***************************************************************************/
923 :
924 1867 : NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
925 : struct lsa_LookupSids *r)
926 : {
927 0 : NTSTATUS status;
928 0 : struct lsa_info *handle;
929 1867 : int num_sids = r->in.sids->num_sids;
930 1867 : uint32_t mapped_count = 0;
931 1867 : struct lsa_RefDomainList *domains = NULL;
932 1867 : struct lsa_TranslatedName *names_out = NULL;
933 1867 : struct lsa_TranslatedName2 *names = NULL;
934 0 : int i;
935 :
936 1867 : if (p->transport != NCACN_NP && p->transport != NCALRPC) {
937 0 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
938 0 : return NT_STATUS_ACCESS_DENIED;
939 : }
940 :
941 1867 : if ((r->in.level < 1) || (r->in.level > 6)) {
942 0 : return NT_STATUS_INVALID_PARAMETER;
943 : }
944 :
945 1867 : handle = find_policy_by_hnd(p,
946 : r->in.handle,
947 : LSA_HANDLE_POLICY_TYPE,
948 : struct lsa_info,
949 0 : &status);
950 1867 : if (!NT_STATUS_IS_OK(status)) {
951 0 : return NT_STATUS_INVALID_HANDLE;
952 : }
953 :
954 : /* check if the user has enough rights */
955 1867 : if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
956 0 : return NT_STATUS_ACCESS_DENIED;
957 : }
958 :
959 1867 : if (num_sids > MAX_LOOKUP_SIDS) {
960 0 : DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
961 : MAX_LOOKUP_SIDS, num_sids));
962 0 : return NT_STATUS_NONE_MAPPED;
963 : }
964 :
965 1867 : status = _lsa_lookup_sids_internal(p,
966 : p->mem_ctx,
967 1867 : r->in.level,
968 : num_sids,
969 1867 : r->in.sids->sids,
970 : &domains,
971 : &names,
972 : &mapped_count);
973 :
974 : /* Only return here when there is a real error.
975 : NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
976 : the requested sids could be resolved. Older versions of XP (pre SP3)
977 : rely that we return with the string representations of those SIDs in
978 : that case. If we don't, XP crashes - Guenther
979 : */
980 :
981 1867 : if (NT_STATUS_IS_ERR(status) &&
982 154 : !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
983 0 : return status;
984 : }
985 :
986 : /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
987 1867 : names_out = talloc_array(p->mem_ctx, struct lsa_TranslatedName,
988 : num_sids);
989 1867 : if (!names_out) {
990 0 : return NT_STATUS_NO_MEMORY;
991 : }
992 :
993 3947 : for (i=0; i<num_sids; i++) {
994 2080 : names_out[i].sid_type = names[i].sid_type;
995 2080 : names_out[i].name = names[i].name;
996 2080 : names_out[i].sid_index = names[i].sid_index;
997 : }
998 :
999 1867 : *r->out.domains = domains;
1000 1867 : r->out.names->count = num_sids;
1001 1867 : r->out.names->names = names_out;
1002 1867 : *r->out.count = mapped_count;
1003 :
1004 1867 : return status;
1005 : }
1006 :
1007 23 : static NTSTATUS _lsa_LookupSids_common(struct pipes_struct *p,
1008 : struct lsa_LookupSids2 *r)
1009 : {
1010 23 : struct dcesrv_call_state *dce_call = p->dce_call;
1011 0 : NTSTATUS status;
1012 0 : struct lsa_info *handle;
1013 23 : int num_sids = r->in.sids->num_sids;
1014 23 : uint32_t mapped_count = 0;
1015 23 : struct lsa_RefDomainList *domains = NULL;
1016 23 : struct lsa_TranslatedName2 *names = NULL;
1017 23 : bool check_policy = true;
1018 :
1019 23 : switch (dce_call->pkt.u.request.opnum) {
1020 21 : case NDR_LSA_LOOKUPSIDS3:
1021 21 : check_policy = false;
1022 21 : break;
1023 2 : case NDR_LSA_LOOKUPSIDS2:
1024 : default:
1025 2 : check_policy = true;
1026 : }
1027 :
1028 23 : if ((r->in.level < 1) || (r->in.level > 6)) {
1029 0 : return NT_STATUS_INVALID_PARAMETER;
1030 : }
1031 :
1032 23 : if (check_policy) {
1033 2 : handle = find_policy_by_hnd(p,
1034 : r->in.handle,
1035 : LSA_HANDLE_POLICY_TYPE,
1036 : struct lsa_info,
1037 0 : &status);
1038 2 : if (!NT_STATUS_IS_OK(status)) {
1039 0 : return NT_STATUS_INVALID_HANDLE;
1040 : }
1041 :
1042 : /* check if the user has enough rights */
1043 2 : if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1044 0 : return NT_STATUS_ACCESS_DENIED;
1045 : }
1046 : }
1047 :
1048 23 : if (num_sids > MAX_LOOKUP_SIDS) {
1049 0 : DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1050 : MAX_LOOKUP_SIDS, num_sids));
1051 0 : return NT_STATUS_NONE_MAPPED;
1052 : }
1053 :
1054 23 : status = _lsa_lookup_sids_internal(p,
1055 : p->mem_ctx,
1056 23 : r->in.level,
1057 : num_sids,
1058 23 : r->in.sids->sids,
1059 : &domains,
1060 : &names,
1061 : &mapped_count);
1062 :
1063 23 : *r->out.domains = domains;
1064 23 : r->out.names->count = num_sids;
1065 23 : r->out.names->names = names;
1066 23 : *r->out.count = mapped_count;
1067 :
1068 23 : return status;
1069 : }
1070 :
1071 : /***************************************************************************
1072 : _lsa_LookupSids2
1073 : ***************************************************************************/
1074 :
1075 2 : NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1076 : struct lsa_LookupSids2 *r)
1077 : {
1078 2 : if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1079 0 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1080 0 : return NT_STATUS_ACCESS_DENIED;
1081 : }
1082 :
1083 2 : return _lsa_LookupSids_common(p, r);
1084 : }
1085 :
1086 : /***************************************************************************
1087 : _lsa_LookupSids3
1088 : ***************************************************************************/
1089 :
1090 25 : NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1091 : struct lsa_LookupSids3 *r)
1092 : {
1093 25 : struct dcesrv_call_state *dce_call = p->dce_call;
1094 25 : enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1095 25 : enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
1096 0 : struct lsa_LookupSids2 q;
1097 :
1098 25 : if (p->transport != NCACN_IP_TCP) {
1099 2 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1100 2 : return NT_STATUS_ACCESS_DENIED;
1101 : }
1102 :
1103 23 : dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
1104 :
1105 : /* No policy handle on this call. Restrict to crypto connections. */
1106 23 : if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
1107 21 : auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1108 2 : DEBUG(1, ("_lsa_LookupSids3: The client %s is not using "
1109 : "a secure connection over netlogon\n",
1110 : get_remote_machine_name() ));
1111 2 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1112 2 : return NT_STATUS_ACCESS_DENIED;
1113 : }
1114 :
1115 21 : q.in.handle = NULL;
1116 21 : q.in.sids = r->in.sids;
1117 21 : q.in.level = r->in.level;
1118 21 : q.in.lookup_options = r->in.lookup_options;
1119 21 : q.in.client_revision = r->in.client_revision;
1120 21 : q.in.names = r->in.names;
1121 21 : q.in.count = r->in.count;
1122 :
1123 21 : q.out.domains = r->out.domains;
1124 21 : q.out.names = r->out.names;
1125 21 : q.out.count = r->out.count;
1126 :
1127 21 : return _lsa_LookupSids_common(p, &q);
1128 : }
1129 :
1130 : /***************************************************************************
1131 : ***************************************************************************/
1132 :
1133 301 : static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1134 : {
1135 0 : int flags;
1136 :
1137 301 : switch (level) {
1138 292 : case LSA_LOOKUP_NAMES_ALL: /* 1 */
1139 292 : flags = LOOKUP_NAME_ALL;
1140 292 : break;
1141 9 : case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1142 9 : flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1143 9 : break;
1144 0 : case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1145 0 : flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1146 0 : break;
1147 0 : case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1148 : case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1149 : case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1150 : case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1151 : default:
1152 0 : flags = LOOKUP_NAME_NONE;
1153 0 : break;
1154 : }
1155 :
1156 301 : return flags;
1157 : }
1158 :
1159 : /***************************************************************************
1160 : _lsa_LookupNames
1161 : ***************************************************************************/
1162 :
1163 255 : NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1164 : struct lsa_LookupNames *r)
1165 : {
1166 255 : NTSTATUS status = NT_STATUS_NONE_MAPPED;
1167 0 : struct lsa_info *handle;
1168 255 : struct lsa_String *names = r->in.names;
1169 255 : uint32_t num_entries = r->in.num_names;
1170 255 : struct lsa_RefDomainList *domains = NULL;
1171 255 : struct lsa_TranslatedSid *rids = NULL;
1172 255 : uint32_t mapped_count = 0;
1173 255 : int flags = 0;
1174 :
1175 255 : if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1176 0 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1177 0 : return NT_STATUS_ACCESS_DENIED;
1178 : }
1179 :
1180 255 : if (num_entries > MAX_LOOKUP_SIDS) {
1181 0 : num_entries = MAX_LOOKUP_SIDS;
1182 0 : DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1183 : num_entries));
1184 : }
1185 :
1186 255 : flags = lsa_lookup_level_to_flags(r->in.level);
1187 :
1188 255 : domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1189 255 : if (!domains) {
1190 0 : return NT_STATUS_NO_MEMORY;
1191 : }
1192 :
1193 255 : if (num_entries) {
1194 255 : rids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid,
1195 : num_entries);
1196 255 : if (!rids) {
1197 0 : return NT_STATUS_NO_MEMORY;
1198 : }
1199 : } else {
1200 0 : rids = NULL;
1201 : }
1202 :
1203 255 : handle = find_policy_by_hnd(p,
1204 : r->in.handle,
1205 : LSA_HANDLE_POLICY_TYPE,
1206 : struct lsa_info,
1207 0 : &status);
1208 255 : if (!NT_STATUS_IS_OK(status)) {
1209 0 : status = NT_STATUS_INVALID_HANDLE;
1210 0 : goto done;
1211 : }
1212 :
1213 : /* check if the user has enough rights */
1214 255 : if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1215 0 : status = NT_STATUS_ACCESS_DENIED;
1216 0 : goto done;
1217 : }
1218 :
1219 : /* set up the LSA Lookup RIDs response */
1220 255 : become_root(); /* lookup_name can require root privs */
1221 255 : status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1222 : names, flags, &mapped_count);
1223 255 : unbecome_root();
1224 :
1225 255 : done:
1226 :
1227 255 : if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1228 255 : if (mapped_count == 0) {
1229 9 : status = NT_STATUS_NONE_MAPPED;
1230 246 : } else if (mapped_count != num_entries) {
1231 0 : status = STATUS_SOME_UNMAPPED;
1232 : }
1233 : }
1234 :
1235 255 : *r->out.count = mapped_count;
1236 255 : *r->out.domains = domains;
1237 255 : r->out.sids->sids = rids;
1238 255 : r->out.sids->count = num_entries;
1239 :
1240 255 : return status;
1241 : }
1242 :
1243 : /***************************************************************************
1244 : _lsa_LookupNames2
1245 : ***************************************************************************/
1246 :
1247 4 : NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1248 : struct lsa_LookupNames2 *r)
1249 : {
1250 0 : NTSTATUS status;
1251 0 : struct lsa_LookupNames q;
1252 4 : struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1253 4 : struct lsa_TransSidArray *sid_array = NULL;
1254 0 : uint32_t i;
1255 :
1256 4 : if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1257 0 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1258 0 : return NT_STATUS_ACCESS_DENIED;
1259 : }
1260 :
1261 4 : sid_array = talloc_zero(p->mem_ctx, struct lsa_TransSidArray);
1262 4 : if (!sid_array) {
1263 0 : return NT_STATUS_NO_MEMORY;
1264 : }
1265 :
1266 4 : q.in.handle = r->in.handle;
1267 4 : q.in.num_names = r->in.num_names;
1268 4 : q.in.names = r->in.names;
1269 4 : q.in.level = r->in.level;
1270 4 : q.in.sids = sid_array;
1271 4 : q.in.count = r->in.count;
1272 : /* we do not know what this is for */
1273 : /* = r->in.unknown1; */
1274 : /* = r->in.unknown2; */
1275 :
1276 4 : q.out.domains = r->out.domains;
1277 4 : q.out.sids = sid_array;
1278 4 : q.out.count = r->out.count;
1279 :
1280 4 : status = _lsa_LookupNames(p, &q);
1281 :
1282 4 : sid_array2->count = sid_array->count;
1283 4 : sid_array2->sids = talloc_array(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1284 4 : if (!sid_array2->sids) {
1285 0 : return NT_STATUS_NO_MEMORY;
1286 : }
1287 :
1288 18 : for (i=0; i<sid_array->count; i++) {
1289 14 : sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1290 14 : sid_array2->sids[i].rid = sid_array->sids[i].rid;
1291 14 : sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1292 14 : sid_array2->sids[i].unknown = 0;
1293 : }
1294 :
1295 4 : r->out.sids = sid_array2;
1296 :
1297 4 : return status;
1298 : }
1299 :
1300 46 : static NTSTATUS _lsa_LookupNames_common(struct pipes_struct *p,
1301 : struct lsa_LookupNames3 *r)
1302 : {
1303 46 : struct dcesrv_call_state *dce_call = p->dce_call;
1304 0 : NTSTATUS status;
1305 0 : struct lsa_info *handle;
1306 46 : struct lsa_String *names = r->in.names;
1307 46 : uint32_t num_entries = r->in.num_names;
1308 46 : struct lsa_RefDomainList *domains = NULL;
1309 46 : struct lsa_TranslatedSid3 *trans_sids = NULL;
1310 46 : uint32_t mapped_count = 0;
1311 46 : int flags = 0;
1312 46 : bool check_policy = true;
1313 :
1314 46 : switch (dce_call->pkt.u.request.opnum) {
1315 42 : case NDR_LSA_LOOKUPNAMES4:
1316 42 : check_policy = false;
1317 42 : break;
1318 4 : case NDR_LSA_LOOKUPNAMES3:
1319 : default:
1320 4 : check_policy = true;
1321 : }
1322 :
1323 46 : if (num_entries > MAX_LOOKUP_SIDS) {
1324 0 : num_entries = MAX_LOOKUP_SIDS;
1325 0 : DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1326 : }
1327 :
1328 46 : flags = lsa_lookup_level_to_flags(r->in.level);
1329 :
1330 46 : domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1331 46 : if (!domains) {
1332 0 : return NT_STATUS_NO_MEMORY;
1333 : }
1334 :
1335 46 : if (num_entries) {
1336 25 : trans_sids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid3,
1337 : num_entries);
1338 25 : if (!trans_sids) {
1339 0 : return NT_STATUS_NO_MEMORY;
1340 : }
1341 : } else {
1342 21 : trans_sids = NULL;
1343 : }
1344 :
1345 46 : if (check_policy) {
1346 :
1347 4 : handle = find_policy_by_hnd(p,
1348 : r->in.handle,
1349 : LSA_HANDLE_POLICY_TYPE,
1350 : struct lsa_info,
1351 0 : &status);
1352 4 : if (!NT_STATUS_IS_OK(status)) {
1353 0 : status = NT_STATUS_INVALID_HANDLE;
1354 0 : goto done;
1355 : }
1356 :
1357 : /* check if the user has enough rights */
1358 4 : if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1359 0 : status = NT_STATUS_ACCESS_DENIED;
1360 0 : goto done;
1361 : }
1362 : }
1363 :
1364 : /* set up the LSA Lookup SIDs response */
1365 46 : become_root(); /* lookup_name can require root privs */
1366 46 : status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1367 : names, flags, &mapped_count);
1368 46 : unbecome_root();
1369 :
1370 46 : done:
1371 :
1372 46 : if (NT_STATUS_IS_OK(status)) {
1373 46 : if (mapped_count == 0) {
1374 21 : status = NT_STATUS_NONE_MAPPED;
1375 25 : } else if (mapped_count != num_entries) {
1376 0 : status = STATUS_SOME_UNMAPPED;
1377 : }
1378 : }
1379 :
1380 46 : *r->out.count = mapped_count;
1381 46 : *r->out.domains = domains;
1382 46 : r->out.sids->sids = trans_sids;
1383 46 : r->out.sids->count = num_entries;
1384 :
1385 46 : return status;
1386 : }
1387 :
1388 : /***************************************************************************
1389 : _lsa_LookupNames3
1390 : ***************************************************************************/
1391 :
1392 4 : NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1393 : struct lsa_LookupNames3 *r)
1394 : {
1395 4 : if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1396 0 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1397 0 : return NT_STATUS_ACCESS_DENIED;
1398 : }
1399 :
1400 4 : return _lsa_LookupNames_common(p, r);
1401 : }
1402 :
1403 : /***************************************************************************
1404 : _lsa_LookupNames4
1405 : ***************************************************************************/
1406 :
1407 46 : NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1408 : struct lsa_LookupNames4 *r)
1409 : {
1410 46 : struct dcesrv_call_state *dce_call = p->dce_call;
1411 46 : enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1412 46 : enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
1413 0 : struct lsa_LookupNames3 q;
1414 :
1415 46 : if (p->transport != NCACN_IP_TCP) {
1416 2 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1417 2 : return NT_STATUS_ACCESS_DENIED;
1418 : }
1419 :
1420 44 : dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
1421 :
1422 : /* No policy handle on this call. Restrict to crypto connections. */
1423 44 : if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
1424 42 : auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1425 2 : DEBUG(1, ("_lsa_LookupNames4: The client %s is not using "
1426 : "a secure connection over netlogon\n",
1427 : get_remote_machine_name()));
1428 2 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1429 2 : return NT_STATUS_ACCESS_DENIED;
1430 : }
1431 :
1432 42 : q.in.handle = NULL;
1433 42 : q.in.num_names = r->in.num_names;
1434 42 : q.in.names = r->in.names;
1435 42 : q.in.level = r->in.level;
1436 42 : q.in.lookup_options = r->in.lookup_options;
1437 42 : q.in.client_revision = r->in.client_revision;
1438 42 : q.in.sids = r->in.sids;
1439 42 : q.in.count = r->in.count;
1440 :
1441 42 : q.out.domains = r->out.domains;
1442 42 : q.out.sids = r->out.sids;
1443 42 : q.out.count = r->out.count;
1444 :
1445 42 : return _lsa_LookupNames_common(p, &q);
1446 : }
1447 :
1448 : /***************************************************************************
1449 : _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1450 : ***************************************************************************/
1451 :
1452 903 : NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1453 : {
1454 0 : NTSTATUS status;
1455 :
1456 903 : if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1457 0 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1458 0 : return NT_STATUS_ACCESS_DENIED;
1459 : }
1460 :
1461 903 : (void)find_policy_by_hnd(p,
1462 : r->in.handle,
1463 : DCESRV_HANDLE_ANY,
1464 : struct lsa_info,
1465 0 : &status);
1466 903 : if (!NT_STATUS_IS_OK(status)) {
1467 25 : return NT_STATUS_INVALID_HANDLE;
1468 : }
1469 :
1470 878 : close_policy_hnd(p, r->in.handle);
1471 878 : ZERO_STRUCTP(r->out.handle);
1472 878 : return NT_STATUS_OK;
1473 : }
1474 :
1475 : /***************************************************************************
1476 : ***************************************************************************/
1477 :
1478 0 : static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1479 : const struct dom_sid *sid,
1480 : struct trustdom_info **info)
1481 : {
1482 0 : NTSTATUS status;
1483 0 : uint32_t num_domains = 0;
1484 0 : struct trustdom_info **domains = NULL;
1485 0 : int i;
1486 :
1487 0 : status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1488 0 : if (!NT_STATUS_IS_OK(status)) {
1489 0 : return status;
1490 : }
1491 :
1492 0 : for (i=0; i < num_domains; i++) {
1493 0 : if (dom_sid_equal(&domains[i]->sid, sid)) {
1494 0 : break;
1495 : }
1496 : }
1497 :
1498 0 : if (i == num_domains) {
1499 0 : return NT_STATUS_INVALID_PARAMETER;
1500 : }
1501 :
1502 0 : *info = domains[i];
1503 :
1504 0 : return NT_STATUS_OK;
1505 : }
1506 :
1507 : /***************************************************************************
1508 : ***************************************************************************/
1509 :
1510 0 : static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1511 : const char *netbios_domain_name,
1512 : struct trustdom_info **info_p)
1513 : {
1514 0 : NTSTATUS status;
1515 0 : struct trustdom_info *info;
1516 0 : struct pdb_trusted_domain *td;
1517 :
1518 0 : status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1519 0 : if (!NT_STATUS_IS_OK(status)) {
1520 0 : return status;
1521 : }
1522 :
1523 0 : info = talloc(mem_ctx, struct trustdom_info);
1524 0 : if (!info) {
1525 0 : return NT_STATUS_NO_MEMORY;
1526 : }
1527 :
1528 0 : info->name = talloc_strdup(info, netbios_domain_name);
1529 0 : NT_STATUS_HAVE_NO_MEMORY(info->name);
1530 :
1531 0 : sid_copy(&info->sid, &td->security_identifier);
1532 :
1533 0 : *info_p = info;
1534 :
1535 0 : return NT_STATUS_OK;
1536 : }
1537 :
1538 : /***************************************************************************
1539 : _lsa_OpenSecret
1540 : ***************************************************************************/
1541 :
1542 8 : NTSTATUS _lsa_OpenSecret(struct pipes_struct *p,
1543 : struct lsa_OpenSecret *r)
1544 : {
1545 8 : struct dcesrv_call_state *dce_call = p->dce_call;
1546 0 : struct auth_session_info *session_info =
1547 8 : dcesrv_call_session_info(dce_call);
1548 0 : struct security_descriptor *psd;
1549 0 : NTSTATUS status;
1550 0 : uint32_t acc_granted;
1551 :
1552 8 : (void)find_policy_by_hnd(p,
1553 : r->in.handle,
1554 : LSA_HANDLE_POLICY_TYPE,
1555 : struct lsa_info,
1556 0 : &status);
1557 8 : if (!NT_STATUS_IS_OK(status)) {
1558 0 : return NT_STATUS_INVALID_HANDLE;
1559 : }
1560 :
1561 8 : if (!r->in.name.string) {
1562 0 : return NT_STATUS_INVALID_PARAMETER;
1563 : }
1564 :
1565 : /* Work out max allowed. */
1566 8 : map_max_allowed_access(session_info->security_token,
1567 8 : session_info->unix_token,
1568 : &r->in.access_mask);
1569 :
1570 : /* map the generic bits to the lsa policy ones */
1571 8 : se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
1572 :
1573 8 : status = pdb_get_secret(p->mem_ctx, r->in.name.string,
1574 : NULL,
1575 : NULL,
1576 : NULL,
1577 : NULL,
1578 : &psd);
1579 8 : if (!NT_STATUS_IS_OK(status)) {
1580 4 : return status;
1581 : }
1582 :
1583 4 : status = access_check_object(psd, session_info->security_token,
1584 : SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1585 : r->in.access_mask,
1586 : &acc_granted, "_lsa_OpenSecret");
1587 4 : if (!NT_STATUS_IS_OK(status)) {
1588 0 : return status;
1589 : }
1590 :
1591 4 : status = create_lsa_policy_handle(p->mem_ctx, p,
1592 : LSA_HANDLE_SECRET_TYPE,
1593 : acc_granted,
1594 : NULL,
1595 : r->in.name.string,
1596 : psd,
1597 : r->out.sec_handle);
1598 4 : if (!NT_STATUS_IS_OK(status)) {
1599 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1600 : }
1601 :
1602 4 : return NT_STATUS_OK;
1603 : }
1604 :
1605 : /***************************************************************************
1606 : _lsa_OpenTrustedDomain_base
1607 : ***************************************************************************/
1608 :
1609 0 : static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1610 : uint32_t access_mask,
1611 : struct trustdom_info *info,
1612 : struct policy_handle *handle)
1613 : {
1614 0 : struct dcesrv_call_state *dce_call = p->dce_call;
1615 0 : struct auth_session_info *session_info =
1616 0 : dcesrv_call_session_info(dce_call);
1617 0 : struct security_descriptor *psd = NULL;
1618 0 : size_t sd_size;
1619 0 : uint32_t acc_granted;
1620 0 : NTSTATUS status;
1621 :
1622 : /* des_access is for the account here, not the policy
1623 : * handle - so don't check against policy handle. */
1624 :
1625 : /* Work out max allowed. */
1626 0 : map_max_allowed_access(session_info->security_token,
1627 0 : session_info->unix_token,
1628 : &access_mask);
1629 :
1630 : /* map the generic bits to the lsa account ones */
1631 0 : se_map_generic(&access_mask, &lsa_trusted_domain_mapping);
1632 :
1633 : /* get the generic lsa account SD until we store it */
1634 0 : status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1635 : &lsa_trusted_domain_mapping,
1636 : NULL, 0);
1637 0 : if (!NT_STATUS_IS_OK(status)) {
1638 0 : return status;
1639 : }
1640 :
1641 0 : status = access_check_object(psd, session_info->security_token,
1642 : SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1643 : access_mask, &acc_granted,
1644 : "_lsa_OpenTrustedDomain");
1645 0 : if (!NT_STATUS_IS_OK(status)) {
1646 0 : return status;
1647 : }
1648 :
1649 0 : status = create_lsa_policy_handle(p->mem_ctx, p,
1650 : LSA_HANDLE_TRUST_TYPE,
1651 : acc_granted,
1652 : &info->sid,
1653 0 : info->name,
1654 : psd,
1655 : handle);
1656 0 : if (!NT_STATUS_IS_OK(status)) {
1657 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1658 : }
1659 :
1660 0 : return NT_STATUS_OK;
1661 : }
1662 :
1663 : /***************************************************************************
1664 : _lsa_OpenTrustedDomain
1665 : ***************************************************************************/
1666 :
1667 0 : NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1668 : struct lsa_OpenTrustedDomain *r)
1669 : {
1670 0 : struct trustdom_info *info = NULL;
1671 0 : NTSTATUS status;
1672 :
1673 0 : (void)find_policy_by_hnd(p,
1674 : r->in.handle,
1675 : LSA_HANDLE_POLICY_TYPE,
1676 : struct lsa_info,
1677 0 : &status);
1678 0 : if (!NT_STATUS_IS_OK(status)) {
1679 0 : return NT_STATUS_INVALID_HANDLE;
1680 : }
1681 :
1682 0 : status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1683 0 : r->in.sid,
1684 : &info);
1685 0 : if (!NT_STATUS_IS_OK(status)) {
1686 0 : return status;
1687 : }
1688 :
1689 0 : return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1690 : r->out.trustdom_handle);
1691 : }
1692 :
1693 : /***************************************************************************
1694 : _lsa_OpenTrustedDomainByName
1695 : ***************************************************************************/
1696 :
1697 0 : NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1698 : struct lsa_OpenTrustedDomainByName *r)
1699 : {
1700 0 : struct trustdom_info *info = NULL;
1701 0 : NTSTATUS status;
1702 :
1703 0 : (void)find_policy_by_hnd(p,
1704 : r->in.handle,
1705 : LSA_HANDLE_POLICY_TYPE,
1706 : struct lsa_info,
1707 0 : &status);
1708 0 : if (!NT_STATUS_IS_OK(status)) {
1709 0 : return NT_STATUS_INVALID_HANDLE;
1710 : }
1711 :
1712 0 : status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1713 : r->in.name.string,
1714 : &info);
1715 0 : if (!NT_STATUS_IS_OK(status)) {
1716 0 : return status;
1717 : }
1718 :
1719 0 : return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1720 : r->out.trustdom_handle);
1721 : }
1722 :
1723 0 : static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
1724 : TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
1725 : struct trustDomainPasswords *auth_struct)
1726 : {
1727 0 : struct dcesrv_call_state *dce_call = p->dce_call;
1728 0 : struct auth_session_info *session_info =
1729 0 : dcesrv_call_session_info(dce_call);
1730 0 : enum ndr_err_code ndr_err;
1731 0 : DATA_BLOB lsession_key;
1732 0 : gnutls_cipher_hd_t cipher_hnd = NULL;
1733 0 : gnutls_datum_t my_session_key;
1734 0 : NTSTATUS status;
1735 0 : int rc;
1736 0 : bool encrypted;
1737 :
1738 0 : encrypted = dcerpc_is_transport_encrypted(session_info);
1739 0 : if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
1740 0 : !encrypted) {
1741 0 : return NT_STATUS_ACCESS_DENIED;
1742 : }
1743 :
1744 0 : status = session_extract_session_key(
1745 : session_info, &lsession_key, KEY_USE_16BYTES);
1746 0 : if (!NT_STATUS_IS_OK(status)) {
1747 0 : return NT_STATUS_INVALID_PARAMETER;
1748 : }
1749 :
1750 0 : my_session_key = (gnutls_datum_t) {
1751 0 : .data = lsession_key.data,
1752 0 : .size = lsession_key.length,
1753 : };
1754 :
1755 0 : GNUTLS_FIPS140_SET_LAX_MODE();
1756 0 : rc = gnutls_cipher_init(&cipher_hnd,
1757 : GNUTLS_CIPHER_ARCFOUR_128,
1758 : &my_session_key,
1759 : NULL);
1760 0 : if (rc < 0) {
1761 0 : GNUTLS_FIPS140_SET_STRICT_MODE();
1762 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
1763 0 : goto out;
1764 : }
1765 :
1766 0 : rc = gnutls_cipher_decrypt(cipher_hnd,
1767 0 : auth_blob->data,
1768 : auth_blob->length);
1769 0 : gnutls_cipher_deinit(cipher_hnd);
1770 0 : GNUTLS_FIPS140_SET_STRICT_MODE();
1771 0 : if (rc < 0) {
1772 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
1773 0 : goto out;
1774 : }
1775 :
1776 0 : ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
1777 : auth_struct,
1778 : (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
1779 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1780 0 : status = NT_STATUS_INVALID_PARAMETER;
1781 0 : goto out;
1782 : }
1783 :
1784 0 : status = NT_STATUS_OK;
1785 0 : out:
1786 0 : return status;
1787 : }
1788 :
1789 0 : static NTSTATUS get_trustauth_inout_blob(TALLOC_CTX *mem_ctx,
1790 : struct trustAuthInOutBlob *iopw,
1791 : DATA_BLOB *trustauth_blob)
1792 : {
1793 0 : enum ndr_err_code ndr_err;
1794 :
1795 0 : if (iopw->current.count != iopw->count) {
1796 0 : return NT_STATUS_INVALID_PARAMETER;
1797 : }
1798 :
1799 0 : if (iopw->previous.count > iopw->current.count) {
1800 0 : return NT_STATUS_INVALID_PARAMETER;
1801 : }
1802 :
1803 0 : if (iopw->previous.count == 0) {
1804 : /*
1805 : * If the previous credentials are not present
1806 : * we need to make a copy.
1807 : */
1808 0 : iopw->previous = iopw->current;
1809 : }
1810 :
1811 0 : if (iopw->previous.count < iopw->current.count) {
1812 0 : struct AuthenticationInformationArray *c = &iopw->current;
1813 0 : struct AuthenticationInformationArray *p = &iopw->previous;
1814 :
1815 : /*
1816 : * The previous array needs to have the same size
1817 : * as the current one.
1818 : *
1819 : * We may have to fill with TRUST_AUTH_TYPE_NONE
1820 : * elements.
1821 : */
1822 0 : p->array = talloc_realloc(mem_ctx, p->array,
1823 : struct AuthenticationInformation,
1824 : c->count);
1825 0 : if (p->array == NULL) {
1826 0 : return NT_STATUS_NO_MEMORY;
1827 : }
1828 :
1829 0 : while (p->count < c->count) {
1830 0 : struct AuthenticationInformation *a =
1831 0 : &p->array[p->count++];
1832 :
1833 0 : *a = (struct AuthenticationInformation) {
1834 0 : .LastUpdateTime = p->array[0].LastUpdateTime,
1835 : .AuthType = TRUST_AUTH_TYPE_NONE,
1836 : };
1837 : }
1838 : }
1839 :
1840 0 : ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
1841 : iopw,
1842 : (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
1843 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1844 0 : return NT_STATUS_INVALID_PARAMETER;
1845 : }
1846 :
1847 0 : return NT_STATUS_OK;
1848 : }
1849 :
1850 : /***************************************************************************
1851 : _lsa_CreateTrustedDomainEx2
1852 : ***************************************************************************/
1853 :
1854 0 : NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1855 : struct lsa_CreateTrustedDomainEx2 *r)
1856 : {
1857 0 : struct dcesrv_call_state *dce_call = p->dce_call;
1858 0 : struct auth_session_info *session_info =
1859 0 : dcesrv_call_session_info(dce_call);
1860 0 : struct lsa_info *policy;
1861 0 : NTSTATUS status;
1862 0 : uint32_t acc_granted;
1863 0 : struct security_descriptor *psd;
1864 0 : size_t sd_size;
1865 0 : struct pdb_trusted_domain td;
1866 0 : struct trustDomainPasswords auth_struct;
1867 0 : DATA_BLOB auth_blob;
1868 :
1869 0 : if (!IS_DC) {
1870 0 : return NT_STATUS_NOT_SUPPORTED;
1871 : }
1872 :
1873 0 : policy = find_policy_by_hnd(p,
1874 : r->in.policy_handle,
1875 : LSA_HANDLE_POLICY_TYPE,
1876 : struct lsa_info,
1877 0 : &status);
1878 0 : if (!NT_STATUS_IS_OK(status)) {
1879 0 : return NT_STATUS_INVALID_HANDLE;
1880 : }
1881 :
1882 0 : if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1883 0 : return NT_STATUS_ACCESS_DENIED;
1884 : }
1885 :
1886 0 : if (session_info->unix_token->uid != sec_initial_uid() &&
1887 0 : !nt_token_check_domain_rid(
1888 : session_info->security_token, DOMAIN_RID_ADMINS)) {
1889 0 : return NT_STATUS_ACCESS_DENIED;
1890 : }
1891 :
1892 : /* Work out max allowed. */
1893 0 : map_max_allowed_access(session_info->security_token,
1894 0 : session_info->unix_token,
1895 : &r->in.access_mask);
1896 :
1897 : /* map the generic bits to the lsa policy ones */
1898 0 : se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1899 :
1900 0 : status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1901 : &lsa_trusted_domain_mapping,
1902 : NULL, 0);
1903 0 : if (!NT_STATUS_IS_OK(status)) {
1904 0 : return status;
1905 : }
1906 :
1907 0 : status = access_check_object(psd, session_info->security_token,
1908 : SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1909 : r->in.access_mask, &acc_granted,
1910 : "_lsa_CreateTrustedDomainEx2");
1911 0 : if (!NT_STATUS_IS_OK(status)) {
1912 0 : return status;
1913 : }
1914 :
1915 0 : ZERO_STRUCT(td);
1916 :
1917 0 : td.domain_name = talloc_strdup(p->mem_ctx,
1918 0 : r->in.info->domain_name.string);
1919 0 : if (td.domain_name == NULL) {
1920 0 : return NT_STATUS_NO_MEMORY;
1921 : }
1922 0 : td.netbios_name = talloc_strdup(p->mem_ctx,
1923 0 : r->in.info->netbios_name.string);
1924 0 : if (td.netbios_name == NULL) {
1925 0 : return NT_STATUS_NO_MEMORY;
1926 : }
1927 0 : sid_copy(&td.security_identifier, r->in.info->sid);
1928 0 : td.trust_direction = r->in.info->trust_direction;
1929 0 : td.trust_type = r->in.info->trust_type;
1930 0 : td.trust_attributes = r->in.info->trust_attributes;
1931 :
1932 0 : if (r->in.auth_info_internal->auth_blob.size != 0) {
1933 0 : auth_blob.length = r->in.auth_info_internal->auth_blob.size;
1934 0 : auth_blob.data = r->in.auth_info_internal->auth_blob.data;
1935 :
1936 0 : status = get_trustdom_auth_blob(p, p->mem_ctx, &auth_blob, &auth_struct);
1937 0 : if (!NT_STATUS_IS_OK(status)) {
1938 0 : return NT_STATUS_UNSUCCESSFUL;
1939 : }
1940 :
1941 0 : status = get_trustauth_inout_blob(p->mem_ctx, &auth_struct.incoming, &td.trust_auth_incoming);
1942 0 : if (!NT_STATUS_IS_OK(status)) {
1943 0 : return NT_STATUS_UNSUCCESSFUL;
1944 : }
1945 :
1946 0 : status = get_trustauth_inout_blob(p->mem_ctx, &auth_struct.outgoing, &td.trust_auth_outgoing);
1947 0 : if (!NT_STATUS_IS_OK(status)) {
1948 0 : return NT_STATUS_UNSUCCESSFUL;
1949 : }
1950 : } else {
1951 0 : td.trust_auth_incoming.data = NULL;
1952 0 : td.trust_auth_incoming.length = 0;
1953 0 : td.trust_auth_outgoing.data = NULL;
1954 0 : td.trust_auth_outgoing.length = 0;
1955 : }
1956 :
1957 0 : status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1958 0 : if (!NT_STATUS_IS_OK(status)) {
1959 0 : return status;
1960 : }
1961 :
1962 0 : status = create_lsa_policy_handle(p->mem_ctx, p,
1963 : LSA_HANDLE_TRUST_TYPE,
1964 : acc_granted,
1965 0 : r->in.info->sid,
1966 0 : r->in.info->netbios_name.string,
1967 : psd,
1968 : r->out.trustdom_handle);
1969 0 : if (!NT_STATUS_IS_OK(status)) {
1970 0 : pdb_del_trusted_domain(r->in.info->netbios_name.string);
1971 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1972 : }
1973 :
1974 0 : return NT_STATUS_OK;
1975 : }
1976 :
1977 : /***************************************************************************
1978 : _lsa_CreateTrustedDomainEx
1979 : ***************************************************************************/
1980 :
1981 0 : NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1982 : struct lsa_CreateTrustedDomainEx *r)
1983 : {
1984 0 : struct lsa_CreateTrustedDomainEx2 q;
1985 0 : struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1986 :
1987 0 : ZERO_STRUCT(auth_info);
1988 :
1989 0 : q.in.policy_handle = r->in.policy_handle;
1990 0 : q.in.info = r->in.info;
1991 0 : q.in.auth_info_internal = &auth_info;
1992 0 : q.in.access_mask = r->in.access_mask;
1993 0 : q.out.trustdom_handle = r->out.trustdom_handle;
1994 :
1995 0 : return _lsa_CreateTrustedDomainEx2(p, &q);
1996 : }
1997 :
1998 : /***************************************************************************
1999 : _lsa_CreateTrustedDomain
2000 : ***************************************************************************/
2001 :
2002 0 : NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
2003 : struct lsa_CreateTrustedDomain *r)
2004 : {
2005 0 : struct lsa_CreateTrustedDomainEx2 c;
2006 0 : struct lsa_TrustDomainInfoInfoEx info;
2007 0 : struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
2008 :
2009 0 : ZERO_STRUCT(auth_info);
2010 :
2011 0 : info.domain_name = r->in.info->name;
2012 0 : info.netbios_name = r->in.info->name;
2013 0 : info.sid = r->in.info->sid;
2014 0 : info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
2015 0 : info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
2016 0 : info.trust_attributes = 0;
2017 :
2018 0 : c.in.policy_handle = r->in.policy_handle;
2019 0 : c.in.info = &info;
2020 0 : c.in.auth_info_internal = &auth_info;
2021 0 : c.in.access_mask = r->in.access_mask;
2022 0 : c.out.trustdom_handle = r->out.trustdom_handle;
2023 :
2024 0 : return _lsa_CreateTrustedDomainEx2(p, &c);
2025 : }
2026 :
2027 : /***************************************************************************
2028 : _lsa_DeleteTrustedDomain
2029 : ***************************************************************************/
2030 :
2031 0 : NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
2032 : struct lsa_DeleteTrustedDomain *r)
2033 : {
2034 0 : NTSTATUS status;
2035 0 : struct lsa_info *handle;
2036 0 : struct pdb_trusted_domain *td;
2037 :
2038 : /* find the connection policy handle. */
2039 0 : handle = find_policy_by_hnd(p,
2040 : r->in.handle,
2041 : LSA_HANDLE_POLICY_TYPE,
2042 : struct lsa_info,
2043 0 : &status);
2044 0 : if (!NT_STATUS_IS_OK(status)) {
2045 0 : return NT_STATUS_INVALID_HANDLE;
2046 : }
2047 :
2048 0 : if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
2049 0 : return NT_STATUS_ACCESS_DENIED;
2050 : }
2051 :
2052 0 : status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
2053 0 : if (!NT_STATUS_IS_OK(status)) {
2054 0 : return status;
2055 : }
2056 :
2057 0 : if (td->netbios_name == NULL || *td->netbios_name == '\0') {
2058 0 : struct dom_sid_buf buf;
2059 0 : DEBUG(10, ("Missing netbios name for trusted domain %s.\n",
2060 : dom_sid_str_buf(r->in.dom_sid, &buf)));
2061 0 : return NT_STATUS_UNSUCCESSFUL;
2062 : }
2063 :
2064 0 : status = pdb_del_trusted_domain(td->netbios_name);
2065 0 : if (!NT_STATUS_IS_OK(status)) {
2066 0 : return status;
2067 : }
2068 :
2069 0 : return NT_STATUS_OK;
2070 : }
2071 :
2072 : /***************************************************************************
2073 : _lsa_CloseTrustedDomainEx
2074 : ***************************************************************************/
2075 :
2076 0 : NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
2077 : struct lsa_CloseTrustedDomainEx *r)
2078 : {
2079 0 : return NT_STATUS_NOT_IMPLEMENTED;
2080 : }
2081 :
2082 : /***************************************************************************
2083 : _lsa_QueryTrustedDomainInfo
2084 : ***************************************************************************/
2085 :
2086 0 : static NTSTATUS pdb_trusted_domain_2_info_ex(TALLOC_CTX *mem_ctx,
2087 : struct pdb_trusted_domain *td,
2088 : struct lsa_TrustDomainInfoInfoEx *info_ex)
2089 : {
2090 0 : if (td->domain_name == NULL ||
2091 0 : td->netbios_name == NULL ||
2092 0 : is_null_sid(&td->security_identifier)) {
2093 0 : return NT_STATUS_INVALID_PARAMETER;
2094 : }
2095 :
2096 0 : info_ex->domain_name.string = talloc_strdup(mem_ctx, td->domain_name);
2097 0 : info_ex->netbios_name.string = talloc_strdup(mem_ctx, td->netbios_name);
2098 0 : info_ex->sid = dom_sid_dup(mem_ctx, &td->security_identifier);
2099 0 : if (info_ex->domain_name.string == NULL ||
2100 0 : info_ex->netbios_name.string == NULL ||
2101 0 : info_ex->sid == NULL) {
2102 0 : return NT_STATUS_NO_MEMORY;
2103 : }
2104 :
2105 0 : info_ex->trust_direction = td->trust_direction;
2106 0 : info_ex->trust_type = td->trust_type;
2107 0 : info_ex->trust_attributes = td->trust_attributes;
2108 :
2109 0 : return NT_STATUS_OK;
2110 : }
2111 :
2112 0 : NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
2113 : struct lsa_QueryTrustedDomainInfo *r)
2114 : {
2115 0 : NTSTATUS status;
2116 0 : struct lsa_info *handle;
2117 0 : union lsa_TrustedDomainInfo *info;
2118 0 : struct pdb_trusted_domain *td;
2119 0 : uint32_t acc_required;
2120 :
2121 : /* find the connection policy handle. */
2122 0 : handle = find_policy_by_hnd(p,
2123 : r->in.trustdom_handle,
2124 : LSA_HANDLE_TRUST_TYPE,
2125 : struct lsa_info,
2126 0 : &status);
2127 0 : if (!NT_STATUS_IS_OK(status)) {
2128 0 : return NT_STATUS_INVALID_HANDLE;
2129 : }
2130 :
2131 0 : switch (r->in.level) {
2132 0 : case LSA_TRUSTED_DOMAIN_INFO_NAME:
2133 0 : acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2134 0 : break;
2135 0 : case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2136 0 : acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
2137 0 : break;
2138 0 : case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2139 0 : acc_required = LSA_TRUSTED_QUERY_POSIX;
2140 0 : break;
2141 0 : case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2142 0 : acc_required = LSA_TRUSTED_QUERY_AUTH;
2143 0 : break;
2144 0 : case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2145 0 : acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2146 0 : break;
2147 0 : case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2148 0 : acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2149 0 : break;
2150 0 : case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2151 0 : acc_required = LSA_TRUSTED_QUERY_AUTH;
2152 0 : break;
2153 0 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2154 0 : acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2155 : LSA_TRUSTED_QUERY_POSIX |
2156 : LSA_TRUSTED_QUERY_AUTH;
2157 0 : break;
2158 0 : case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2159 0 : acc_required = LSA_TRUSTED_QUERY_AUTH;
2160 0 : break;
2161 0 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2162 0 : acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2163 : LSA_TRUSTED_QUERY_POSIX |
2164 : LSA_TRUSTED_QUERY_AUTH;
2165 0 : break;
2166 0 : case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2167 0 : acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2168 0 : break;
2169 0 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2170 0 : acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2171 : LSA_TRUSTED_QUERY_POSIX |
2172 : LSA_TRUSTED_QUERY_AUTH;
2173 0 : break;
2174 0 : case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2175 0 : acc_required = LSA_TRUSTED_QUERY_POSIX;
2176 0 : break;
2177 0 : default:
2178 0 : return NT_STATUS_INVALID_PARAMETER;
2179 : }
2180 :
2181 0 : if (!(handle->access & acc_required)) {
2182 0 : return NT_STATUS_ACCESS_DENIED;
2183 : }
2184 :
2185 0 : status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2186 0 : if (!NT_STATUS_IS_OK(status)) {
2187 0 : return status;
2188 : }
2189 :
2190 0 : info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
2191 0 : if (!info) {
2192 0 : return NT_STATUS_NO_MEMORY;
2193 : }
2194 :
2195 0 : switch (r->in.level) {
2196 0 : case LSA_TRUSTED_DOMAIN_INFO_NAME:
2197 0 : init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2198 0 : break;
2199 0 : case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2200 0 : return NT_STATUS_INVALID_PARAMETER;
2201 0 : case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2202 0 : info->posix_offset.posix_offset = *td->trust_posix_offset;
2203 0 : break;
2204 0 : case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2205 0 : return NT_STATUS_INVALID_INFO_CLASS;
2206 0 : case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2207 0 : return NT_STATUS_INVALID_PARAMETER;
2208 0 : case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2209 0 : status = pdb_trusted_domain_2_info_ex(info, td, &info->info_ex);
2210 0 : if (!NT_STATUS_IS_OK(status)) {
2211 0 : return status;
2212 : }
2213 0 : break;
2214 0 : case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2215 0 : return NT_STATUS_INVALID_INFO_CLASS;
2216 0 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2217 0 : status = pdb_trusted_domain_2_info_ex(info, td,
2218 : &info->full_info.info_ex);
2219 0 : if (!NT_STATUS_IS_OK(status)) {
2220 0 : return status;
2221 : }
2222 0 : info->full_info.posix_offset.posix_offset = *td->trust_posix_offset;
2223 0 : status = auth_blob_2_auth_info(p->mem_ctx,
2224 0 : td->trust_auth_incoming,
2225 0 : td->trust_auth_outgoing,
2226 : &info->full_info.auth_info);
2227 0 : if (!NT_STATUS_IS_OK(status)) {
2228 0 : return status;
2229 : }
2230 0 : break;
2231 0 : case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2232 0 : return NT_STATUS_INVALID_INFO_CLASS;
2233 0 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2234 0 : return NT_STATUS_INVALID_INFO_CLASS;
2235 0 : case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2236 0 : return NT_STATUS_INVALID_PARAMETER;
2237 0 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2238 0 : info->full_info2_internal.posix_offset.posix_offset = *td->trust_posix_offset;
2239 0 : status = auth_blob_2_auth_info(p->mem_ctx,
2240 0 : td->trust_auth_incoming,
2241 0 : td->trust_auth_outgoing,
2242 : &info->full_info2_internal.auth_info);
2243 0 : if (!NT_STATUS_IS_OK(status)) {
2244 0 : return status;
2245 : }
2246 0 : break;
2247 0 : case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2248 0 : info->enc_types.enc_types = *td->supported_enc_type;
2249 0 : break;
2250 0 : default:
2251 0 : return NT_STATUS_INVALID_PARAMETER;
2252 : }
2253 :
2254 0 : *r->out.info = info;
2255 :
2256 0 : return NT_STATUS_OK;
2257 : }
2258 :
2259 : /***************************************************************************
2260 : _lsa_QueryTrustedDomainInfoBySid
2261 : ***************************************************************************/
2262 :
2263 0 : NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2264 : struct lsa_QueryTrustedDomainInfoBySid *r)
2265 : {
2266 0 : NTSTATUS status;
2267 0 : struct policy_handle trustdom_handle;
2268 0 : struct lsa_OpenTrustedDomain o;
2269 0 : struct lsa_QueryTrustedDomainInfo q;
2270 0 : struct lsa_Close c;
2271 :
2272 0 : o.in.handle = r->in.handle;
2273 0 : o.in.sid = r->in.dom_sid;
2274 0 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2275 0 : o.out.trustdom_handle = &trustdom_handle;
2276 :
2277 0 : status = _lsa_OpenTrustedDomain(p, &o);
2278 0 : if (!NT_STATUS_IS_OK(status)) {
2279 0 : return status;
2280 : }
2281 :
2282 0 : q.in.trustdom_handle = &trustdom_handle;
2283 0 : q.in.level = r->in.level;
2284 0 : q.out.info = r->out.info;
2285 :
2286 0 : status = _lsa_QueryTrustedDomainInfo(p, &q);
2287 0 : if (!NT_STATUS_IS_OK(status)) {
2288 0 : return status;
2289 : }
2290 :
2291 0 : c.in.handle = &trustdom_handle;
2292 0 : c.out.handle = &trustdom_handle;
2293 :
2294 0 : return _lsa_Close(p, &c);
2295 : }
2296 :
2297 : /***************************************************************************
2298 : _lsa_QueryTrustedDomainInfoByName
2299 : ***************************************************************************/
2300 :
2301 0 : NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2302 : struct lsa_QueryTrustedDomainInfoByName *r)
2303 : {
2304 0 : NTSTATUS status;
2305 0 : struct policy_handle trustdom_handle;
2306 0 : struct lsa_OpenTrustedDomainByName o;
2307 0 : struct lsa_QueryTrustedDomainInfo q;
2308 0 : struct lsa_Close c;
2309 :
2310 0 : o.in.handle = r->in.handle;
2311 0 : o.in.name.string = r->in.trusted_domain->string;
2312 0 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2313 0 : o.out.trustdom_handle = &trustdom_handle;
2314 :
2315 0 : status = _lsa_OpenTrustedDomainByName(p, &o);
2316 0 : if (!NT_STATUS_IS_OK(status)) {
2317 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2318 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2319 : }
2320 0 : return status;
2321 : }
2322 :
2323 0 : q.in.trustdom_handle = &trustdom_handle;
2324 0 : q.in.level = r->in.level;
2325 0 : q.out.info = r->out.info;
2326 :
2327 0 : status = _lsa_QueryTrustedDomainInfo(p, &q);
2328 0 : if (!NT_STATUS_IS_OK(status)) {
2329 0 : return status;
2330 : }
2331 :
2332 0 : c.in.handle = &trustdom_handle;
2333 0 : c.out.handle = &trustdom_handle;
2334 :
2335 0 : return _lsa_Close(p, &c);
2336 : }
2337 :
2338 : /***************************************************************************
2339 : _lsa_CreateSecret
2340 : ***************************************************************************/
2341 :
2342 344 : NTSTATUS _lsa_CreateSecret(struct pipes_struct *p,
2343 : struct lsa_CreateSecret *r)
2344 : {
2345 344 : struct dcesrv_call_state *dce_call = p->dce_call;
2346 0 : struct auth_session_info *session_info =
2347 344 : dcesrv_call_session_info(dce_call);
2348 0 : NTSTATUS status;
2349 0 : struct lsa_info *handle;
2350 0 : uint32_t acc_granted;
2351 0 : struct security_descriptor *psd;
2352 0 : size_t sd_size;
2353 :
2354 : /* find the connection policy handle. */
2355 344 : handle = find_policy_by_hnd(p,
2356 : r->in.handle,
2357 : LSA_HANDLE_POLICY_TYPE,
2358 : struct lsa_info,
2359 0 : &status);
2360 344 : if (!NT_STATUS_IS_OK(status)) {
2361 0 : return NT_STATUS_INVALID_HANDLE;
2362 : }
2363 :
2364 : /* check if the user has enough rights */
2365 :
2366 344 : if (!(handle->access & LSA_POLICY_CREATE_SECRET)) {
2367 0 : return NT_STATUS_ACCESS_DENIED;
2368 : }
2369 :
2370 : /* Work out max allowed. */
2371 344 : map_max_allowed_access(session_info->security_token,
2372 344 : session_info->unix_token,
2373 : &r->in.access_mask);
2374 :
2375 : /* map the generic bits to the lsa policy ones */
2376 344 : se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
2377 :
2378 344 : status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2379 : &lsa_secret_mapping,
2380 : NULL, 0);
2381 344 : if (!NT_STATUS_IS_OK(status)) {
2382 0 : return status;
2383 : }
2384 :
2385 344 : status = access_check_object(psd, session_info->security_token,
2386 : SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2387 : r->in.access_mask,
2388 : &acc_granted, "_lsa_CreateSecret");
2389 344 : if (!NT_STATUS_IS_OK(status)) {
2390 0 : return status;
2391 : }
2392 :
2393 344 : if (!r->in.name.string) {
2394 0 : return NT_STATUS_INVALID_PARAMETER;
2395 : }
2396 :
2397 344 : if (strlen(r->in.name.string) > 128) {
2398 0 : return NT_STATUS_NAME_TOO_LONG;
2399 : }
2400 :
2401 344 : status = pdb_get_secret(p->mem_ctx, r->in.name.string,
2402 : NULL, NULL, NULL, NULL, NULL);
2403 344 : if (NT_STATUS_IS_OK(status)) {
2404 4 : return NT_STATUS_OBJECT_NAME_COLLISION;
2405 : }
2406 :
2407 340 : status = pdb_set_secret(r->in.name.string, NULL, NULL, psd);
2408 340 : if (!NT_STATUS_IS_OK(status)) {
2409 0 : return status;
2410 : }
2411 :
2412 340 : status = create_lsa_policy_handle(p->mem_ctx, p,
2413 : LSA_HANDLE_SECRET_TYPE,
2414 : acc_granted,
2415 : NULL,
2416 : r->in.name.string,
2417 : psd,
2418 : r->out.sec_handle);
2419 340 : if (!NT_STATUS_IS_OK(status)) {
2420 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2421 : }
2422 :
2423 340 : return NT_STATUS_OK;
2424 : }
2425 :
2426 : /***************************************************************************
2427 : _lsa_SetSecret
2428 : ***************************************************************************/
2429 :
2430 464 : NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
2431 : struct lsa_SetSecret *r)
2432 : {
2433 464 : struct dcesrv_call_state *dce_call = p->dce_call;
2434 0 : struct auth_session_info *session_info =
2435 464 : dcesrv_call_session_info(dce_call);
2436 0 : NTSTATUS status;
2437 464 : struct lsa_info *info = NULL;
2438 0 : DATA_BLOB blob_new, blob_old;
2439 464 : DATA_BLOB cleartext_blob_new = data_blob_null;
2440 464 : DATA_BLOB cleartext_blob_old = data_blob_null;
2441 464 : DATA_BLOB *cleartext_blob_new_p = NULL;
2442 464 : DATA_BLOB *cleartext_blob_old_p = NULL;
2443 0 : DATA_BLOB session_key;
2444 :
2445 464 : info = find_policy_by_hnd(p,
2446 : r->in.sec_handle,
2447 : LSA_HANDLE_SECRET_TYPE,
2448 : struct lsa_info,
2449 0 : &status);
2450 464 : if (!NT_STATUS_IS_OK(status)) {
2451 0 : return NT_STATUS_INVALID_HANDLE;
2452 : }
2453 :
2454 464 : if (!(info->access & LSA_SECRET_SET_VALUE)) {
2455 0 : return NT_STATUS_ACCESS_DENIED;
2456 : }
2457 :
2458 464 : status = session_extract_session_key(
2459 : session_info, &session_key, KEY_USE_16BYTES);
2460 464 : if(!NT_STATUS_IS_OK(status)) {
2461 0 : return status;
2462 : }
2463 :
2464 464 : if (r->in.new_val) {
2465 460 : blob_new = data_blob_const(r->in.new_val->data,
2466 460 : r->in.new_val->length);
2467 :
2468 460 : status = sess_decrypt_blob(p->mem_ctx, &blob_new,
2469 : &session_key,
2470 : &cleartext_blob_new);
2471 460 : if (!NT_STATUS_IS_OK(status)) {
2472 228 : return status;
2473 : }
2474 :
2475 232 : cleartext_blob_new_p = &cleartext_blob_new;
2476 : }
2477 :
2478 236 : if (r->in.old_val) {
2479 4 : blob_old = data_blob_const(r->in.old_val->data,
2480 4 : r->in.old_val->length);
2481 :
2482 4 : status = sess_decrypt_blob(p->mem_ctx, &blob_old,
2483 : &session_key,
2484 : &cleartext_blob_old);
2485 4 : if (!NT_STATUS_IS_OK(status)) {
2486 0 : return status;
2487 : }
2488 :
2489 4 : cleartext_blob_old_p = &cleartext_blob_old;
2490 : }
2491 :
2492 236 : status = pdb_set_secret(info->name, cleartext_blob_new_p, cleartext_blob_old_p, NULL);
2493 236 : if (!NT_STATUS_IS_OK(status)) {
2494 0 : return status;
2495 : }
2496 :
2497 : #ifdef DEBUG_PASSWORD
2498 236 : DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
2499 236 : dump_data(10, cleartext_blob_new.data, cleartext_blob_new.length);
2500 236 : DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
2501 236 : dump_data(10, cleartext_blob_old.data, cleartext_blob_old.length);
2502 : #endif
2503 :
2504 236 : return NT_STATUS_OK;
2505 : }
2506 :
2507 : /***************************************************************************
2508 : _lsa_QuerySecret
2509 : ***************************************************************************/
2510 :
2511 236 : NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
2512 : struct lsa_QuerySecret *r)
2513 : {
2514 236 : struct dcesrv_call_state *dce_call = p->dce_call;
2515 0 : struct auth_session_info *session_info =
2516 236 : dcesrv_call_session_info(dce_call);
2517 236 : struct lsa_info *info = NULL;
2518 0 : DATA_BLOB blob_new, blob_old;
2519 0 : DATA_BLOB blob_new_crypt, blob_old_crypt;
2520 0 : DATA_BLOB session_key;
2521 0 : NTTIME nttime_new, nttime_old;
2522 0 : NTSTATUS status;
2523 :
2524 236 : info = find_policy_by_hnd(p,
2525 : r->in.sec_handle,
2526 : LSA_HANDLE_SECRET_TYPE,
2527 : struct lsa_info,
2528 0 : &status);
2529 236 : if (!NT_STATUS_IS_OK(status)) {
2530 0 : return NT_STATUS_INVALID_HANDLE;
2531 : }
2532 :
2533 236 : if (!(info->access & LSA_SECRET_QUERY_VALUE)) {
2534 0 : return NT_STATUS_ACCESS_DENIED;
2535 : }
2536 :
2537 236 : status = pdb_get_secret(p->mem_ctx, info->name,
2538 : &blob_new, &nttime_new,
2539 : &blob_old, &nttime_old,
2540 : NULL);
2541 236 : if (!NT_STATUS_IS_OK(status)) {
2542 0 : return status;
2543 : }
2544 :
2545 236 : status = session_extract_session_key(
2546 : session_info, &session_key, KEY_USE_16BYTES);
2547 236 : if(!NT_STATUS_IS_OK(status)) {
2548 0 : return status;
2549 : }
2550 :
2551 236 : if (r->in.new_val) {
2552 236 : if (blob_new.length) {
2553 232 : if (!r->out.new_val->buf) {
2554 232 : r->out.new_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2555 : }
2556 232 : if (!r->out.new_val->buf) {
2557 0 : return NT_STATUS_NO_MEMORY;
2558 : }
2559 :
2560 232 : blob_new_crypt = sess_encrypt_blob(p->mem_ctx, &blob_new,
2561 : &session_key);
2562 232 : if (!blob_new_crypt.length) {
2563 0 : return NT_STATUS_NO_MEMORY;
2564 : }
2565 :
2566 232 : r->out.new_val->buf->data = blob_new_crypt.data;
2567 232 : r->out.new_val->buf->length = blob_new_crypt.length;
2568 232 : r->out.new_val->buf->size = blob_new_crypt.length;
2569 : }
2570 : }
2571 :
2572 236 : if (r->in.old_val) {
2573 8 : if (blob_old.length) {
2574 8 : if (!r->out.old_val->buf) {
2575 8 : r->out.old_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2576 : }
2577 8 : if (!r->out.old_val->buf) {
2578 0 : return NT_STATUS_NO_MEMORY;
2579 : }
2580 :
2581 8 : blob_old_crypt = sess_encrypt_blob(p->mem_ctx, &blob_old,
2582 : &session_key);
2583 8 : if (!blob_old_crypt.length) {
2584 0 : return NT_STATUS_NO_MEMORY;
2585 : }
2586 :
2587 8 : r->out.old_val->buf->data = blob_old_crypt.data;
2588 8 : r->out.old_val->buf->length = blob_old_crypt.length;
2589 8 : r->out.old_val->buf->size = blob_old_crypt.length;
2590 : }
2591 : }
2592 :
2593 236 : if (r->out.new_mtime) {
2594 236 : *r->out.new_mtime = nttime_new;
2595 : }
2596 :
2597 236 : if (r->out.old_mtime) {
2598 8 : *r->out.old_mtime = nttime_old;
2599 : }
2600 :
2601 236 : return NT_STATUS_OK;
2602 : }
2603 :
2604 : /***************************************************************************
2605 : _lsa_DeleteObject
2606 : ***************************************************************************/
2607 :
2608 347 : NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2609 : struct lsa_DeleteObject *r)
2610 : {
2611 0 : NTSTATUS status;
2612 347 : struct lsa_info *info = NULL;
2613 :
2614 347 : info = find_policy_by_hnd(p,
2615 : r->in.handle,
2616 : DCESRV_HANDLE_ANY,
2617 : struct lsa_info,
2618 0 : &status);
2619 347 : if (!NT_STATUS_IS_OK(status)) {
2620 0 : return NT_STATUS_INVALID_HANDLE;
2621 : }
2622 :
2623 347 : if (!(info->access & SEC_STD_DELETE)) {
2624 0 : return NT_STATUS_ACCESS_DENIED;
2625 : }
2626 :
2627 347 : switch (info->type) {
2628 3 : case LSA_HANDLE_ACCOUNT_TYPE:
2629 3 : status = privilege_delete_account(&info->sid);
2630 3 : if (!NT_STATUS_IS_OK(status)) {
2631 0 : DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2632 : nt_errstr(status)));
2633 4 : return status;
2634 : }
2635 3 : break;
2636 0 : case LSA_HANDLE_TRUST_TYPE:
2637 0 : if (!pdb_del_trusteddom_pw(info->name)) {
2638 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2639 : }
2640 0 : status = NT_STATUS_OK;
2641 0 : break;
2642 344 : case LSA_HANDLE_SECRET_TYPE:
2643 344 : status = pdb_delete_secret(info->name);
2644 344 : if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2645 4 : return NT_STATUS_INVALID_HANDLE;
2646 : }
2647 340 : break;
2648 0 : default:
2649 0 : return NT_STATUS_INVALID_HANDLE;
2650 : }
2651 :
2652 343 : close_policy_hnd(p, r->in.handle);
2653 343 : ZERO_STRUCTP(r->out.handle);
2654 :
2655 343 : return status;
2656 : }
2657 :
2658 : /***************************************************************************
2659 : _lsa_EnumPrivs
2660 : ***************************************************************************/
2661 :
2662 2 : NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2663 : struct lsa_EnumPrivs *r)
2664 : {
2665 0 : struct lsa_info *handle;
2666 0 : uint32_t i;
2667 2 : uint32_t enum_context = *r->in.resume_handle;
2668 2 : int num_privs = num_privileges_in_short_list();
2669 2 : struct lsa_PrivEntry *entries = NULL;
2670 0 : NTSTATUS status;
2671 :
2672 : /* remember that the enum_context starts at 0 and not 1 */
2673 :
2674 2 : if ( enum_context >= num_privs )
2675 0 : return NT_STATUS_NO_MORE_ENTRIES;
2676 :
2677 2 : DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2678 : enum_context, num_privs));
2679 :
2680 2 : handle = find_policy_by_hnd(p,
2681 : r->in.handle,
2682 : LSA_HANDLE_POLICY_TYPE,
2683 : struct lsa_info,
2684 0 : &status);
2685 2 : if (!NT_STATUS_IS_OK(status)) {
2686 0 : return NT_STATUS_INVALID_HANDLE;
2687 : }
2688 :
2689 : /* check if the user has enough rights
2690 : I don't know if it's the right one. not documented. */
2691 :
2692 2 : if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2693 0 : return NT_STATUS_ACCESS_DENIED;
2694 :
2695 2 : if (num_privs) {
2696 2 : entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2697 2 : if (!entries) {
2698 0 : return NT_STATUS_NO_MEMORY;
2699 : }
2700 : } else {
2701 0 : entries = NULL;
2702 : }
2703 :
2704 20 : for (i = 0; i < num_privs; i++) {
2705 18 : if( i < enum_context) {
2706 :
2707 0 : init_lsa_StringLarge(&entries[i].name, NULL);
2708 :
2709 0 : entries[i].luid.low = 0;
2710 0 : entries[i].luid.high = 0;
2711 : } else {
2712 :
2713 18 : init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2714 :
2715 18 : entries[i].luid.low = sec_privilege_from_index(i);
2716 18 : entries[i].luid.high = 0;
2717 : }
2718 : }
2719 :
2720 2 : enum_context = num_privs;
2721 :
2722 2 : *r->out.resume_handle = enum_context;
2723 2 : r->out.privs->count = num_privs;
2724 2 : r->out.privs->privs = entries;
2725 :
2726 2 : return NT_STATUS_OK;
2727 : }
2728 :
2729 : /***************************************************************************
2730 : _lsa_LookupPrivDisplayName
2731 : ***************************************************************************/
2732 :
2733 18 : NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2734 : struct lsa_LookupPrivDisplayName *r)
2735 : {
2736 0 : struct lsa_info *handle;
2737 0 : const char *description;
2738 0 : struct lsa_StringLarge *lsa_name;
2739 0 : NTSTATUS status;
2740 :
2741 18 : handle = find_policy_by_hnd(p,
2742 : r->in.handle,
2743 : LSA_HANDLE_POLICY_TYPE,
2744 : struct lsa_info,
2745 0 : &status);
2746 18 : if (!NT_STATUS_IS_OK(status)) {
2747 0 : return NT_STATUS_INVALID_HANDLE;
2748 : }
2749 :
2750 : /* check if the user has enough rights */
2751 :
2752 : /*
2753 : * I don't know if it's the right one. not documented.
2754 : */
2755 18 : if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2756 0 : return NT_STATUS_ACCESS_DENIED;
2757 :
2758 18 : DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2759 :
2760 18 : description = get_privilege_dispname(r->in.name->string);
2761 18 : if (!description) {
2762 0 : DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2763 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
2764 : }
2765 :
2766 18 : DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2767 :
2768 18 : lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2769 18 : if (!lsa_name) {
2770 0 : return NT_STATUS_NO_MEMORY;
2771 : }
2772 :
2773 18 : init_lsa_StringLarge(lsa_name, description);
2774 :
2775 18 : *r->out.returned_language_id = r->in.language_id;
2776 18 : *r->out.disp_name = lsa_name;
2777 :
2778 18 : return NT_STATUS_OK;
2779 : }
2780 :
2781 : /***************************************************************************
2782 : _lsa_EnumAccounts
2783 : ***************************************************************************/
2784 :
2785 7 : NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2786 : struct lsa_EnumAccounts *r)
2787 : {
2788 0 : struct lsa_info *handle;
2789 0 : struct dom_sid *sid_list;
2790 0 : int i, j, num_entries;
2791 0 : NTSTATUS status;
2792 7 : struct lsa_SidPtr *sids = NULL;
2793 :
2794 7 : handle = find_policy_by_hnd(p,
2795 : r->in.handle,
2796 : LSA_HANDLE_POLICY_TYPE,
2797 : struct lsa_info,
2798 0 : &status);
2799 7 : if (!NT_STATUS_IS_OK(status)) {
2800 0 : return NT_STATUS_INVALID_HANDLE;
2801 : }
2802 :
2803 7 : if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2804 0 : return NT_STATUS_ACCESS_DENIED;
2805 :
2806 7 : sid_list = NULL;
2807 7 : num_entries = 0;
2808 :
2809 : /* The only way we can currently find out all the SIDs that have been
2810 : privileged is to scan all privileges */
2811 :
2812 7 : status = privilege_enumerate_accounts(&sid_list, &num_entries);
2813 7 : if (!NT_STATUS_IS_OK(status)) {
2814 0 : return status;
2815 : }
2816 :
2817 7 : if (*r->in.resume_handle >= num_entries) {
2818 2 : return NT_STATUS_NO_MORE_ENTRIES;
2819 : }
2820 :
2821 5 : if (num_entries - *r->in.resume_handle) {
2822 5 : sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2823 : num_entries - *r->in.resume_handle);
2824 5 : if (!sids) {
2825 0 : talloc_free(sid_list);
2826 0 : return NT_STATUS_NO_MEMORY;
2827 : }
2828 :
2829 37 : for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2830 32 : sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2831 32 : if (!sids[j].sid) {
2832 0 : talloc_free(sid_list);
2833 0 : return NT_STATUS_NO_MEMORY;
2834 : }
2835 : }
2836 : }
2837 :
2838 5 : talloc_free(sid_list);
2839 :
2840 5 : *r->out.resume_handle = num_entries;
2841 5 : r->out.sids->num_sids = num_entries;
2842 5 : r->out.sids->sids = sids;
2843 :
2844 5 : return NT_STATUS_OK;
2845 : }
2846 :
2847 : /***************************************************************************
2848 : _lsa_GetUserName
2849 : ***************************************************************************/
2850 :
2851 275 : NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2852 : struct lsa_GetUserName *r)
2853 : {
2854 275 : struct dcesrv_call_state *dce_call = p->dce_call;
2855 0 : struct auth_session_info *session_info =
2856 275 : dcesrv_call_session_info(dce_call);
2857 0 : const char *username, *domname;
2858 275 : struct lsa_String *account_name = NULL;
2859 275 : struct lsa_String *authority_name = NULL;
2860 :
2861 275 : if (p->transport != NCACN_NP && p->transport != NCALRPC) {
2862 0 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
2863 0 : return NT_STATUS_ACCESS_DENIED;
2864 : }
2865 :
2866 275 : if (r->in.account_name &&
2867 275 : *r->in.account_name) {
2868 0 : return NT_STATUS_INVALID_PARAMETER;
2869 : }
2870 :
2871 275 : if (r->in.authority_name &&
2872 268 : *r->in.authority_name) {
2873 0 : return NT_STATUS_INVALID_PARAMETER;
2874 : }
2875 :
2876 275 : if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
2877 : /*
2878 : * I'm 99% sure this is not the right place to do this,
2879 : * global_sid_Anonymous should probably be put into the token
2880 : * instead of the guest id -- vl
2881 : */
2882 83 : if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2883 : &domname, &username, NULL)) {
2884 0 : return NT_STATUS_NO_MEMORY;
2885 : }
2886 : } else {
2887 192 : username = session_info->unix_info->sanitized_username;
2888 192 : domname = session_info->info->domain_name;
2889 : }
2890 :
2891 275 : account_name = talloc(p->mem_ctx, struct lsa_String);
2892 275 : if (!account_name) {
2893 0 : return NT_STATUS_NO_MEMORY;
2894 : }
2895 275 : init_lsa_String(account_name, username);
2896 :
2897 275 : if (r->out.authority_name) {
2898 268 : authority_name = talloc(p->mem_ctx, struct lsa_String);
2899 268 : if (!authority_name) {
2900 0 : return NT_STATUS_NO_MEMORY;
2901 : }
2902 268 : init_lsa_String(authority_name, domname);
2903 : }
2904 :
2905 275 : *r->out.account_name = account_name;
2906 275 : if (r->out.authority_name) {
2907 268 : *r->out.authority_name = authority_name;
2908 : }
2909 :
2910 275 : return NT_STATUS_OK;
2911 : }
2912 :
2913 : /***************************************************************************
2914 : _lsa_CreateAccount
2915 : ***************************************************************************/
2916 :
2917 2 : NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2918 : struct lsa_CreateAccount *r)
2919 : {
2920 2 : struct dcesrv_call_state *dce_call = p->dce_call;
2921 0 : struct auth_session_info *session_info =
2922 2 : dcesrv_call_session_info(dce_call);
2923 0 : NTSTATUS status;
2924 0 : struct lsa_info *handle;
2925 0 : uint32_t acc_granted;
2926 0 : struct security_descriptor *psd;
2927 0 : size_t sd_size;
2928 2 : uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
2929 : ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
2930 : LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2931 : SEC_STD_DELETE));
2932 :
2933 : /* find the connection policy handle. */
2934 2 : handle = find_policy_by_hnd(p,
2935 : r->in.handle,
2936 : LSA_HANDLE_POLICY_TYPE,
2937 : struct lsa_info,
2938 0 : &status);
2939 2 : if (!NT_STATUS_IS_OK(status)) {
2940 0 : return NT_STATUS_INVALID_HANDLE;
2941 : }
2942 :
2943 : /* check if the user has enough rights */
2944 :
2945 2 : if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2946 0 : return NT_STATUS_ACCESS_DENIED;
2947 : }
2948 :
2949 : /* Work out max allowed. */
2950 2 : map_max_allowed_access(session_info->security_token,
2951 2 : session_info->unix_token,
2952 : &r->in.access_mask);
2953 :
2954 : /* map the generic bits to the lsa policy ones */
2955 2 : se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2956 :
2957 2 : status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2958 : &lsa_account_mapping,
2959 : r->in.sid, owner_access);
2960 2 : if (!NT_STATUS_IS_OK(status)) {
2961 0 : return status;
2962 : }
2963 :
2964 2 : status = access_check_object(psd, session_info->security_token,
2965 : SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2966 : &acc_granted, "_lsa_CreateAccount");
2967 2 : if (!NT_STATUS_IS_OK(status)) {
2968 0 : return status;
2969 : }
2970 :
2971 2 : if ( is_privileged_sid( r->in.sid ) )
2972 0 : return NT_STATUS_OBJECT_NAME_COLLISION;
2973 :
2974 2 : status = create_lsa_policy_handle(p->mem_ctx, p,
2975 : LSA_HANDLE_ACCOUNT_TYPE,
2976 : acc_granted,
2977 : r->in.sid,
2978 : NULL,
2979 : psd,
2980 : r->out.acct_handle);
2981 2 : if (!NT_STATUS_IS_OK(status)) {
2982 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2983 : }
2984 :
2985 2 : return privilege_create_account(r->in.sid);
2986 : }
2987 :
2988 : /***************************************************************************
2989 : _lsa_OpenAccount
2990 : ***************************************************************************/
2991 :
2992 14 : NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2993 : struct lsa_OpenAccount *r)
2994 : {
2995 14 : struct dcesrv_call_state *dce_call = p->dce_call;
2996 0 : struct auth_session_info *session_info =
2997 14 : dcesrv_call_session_info(dce_call);
2998 14 : struct security_descriptor *psd = NULL;
2999 0 : size_t sd_size;
3000 14 : uint32_t des_access = r->in.access_mask;
3001 0 : uint32_t acc_granted;
3002 14 : uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
3003 : ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
3004 : LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3005 : SEC_STD_DELETE));
3006 0 : NTSTATUS status;
3007 :
3008 : /* find the connection policy handle. */
3009 14 : (void)find_policy_by_hnd(p,
3010 : r->in.handle,
3011 : LSA_HANDLE_POLICY_TYPE,
3012 : struct lsa_info,
3013 0 : &status);
3014 14 : if (!NT_STATUS_IS_OK(status)) {
3015 0 : return NT_STATUS_INVALID_HANDLE;
3016 : }
3017 :
3018 : /* des_access is for the account here, not the policy
3019 : * handle - so don't check against policy handle. */
3020 :
3021 : /* Work out max allowed. */
3022 14 : map_max_allowed_access(session_info->security_token,
3023 14 : session_info->unix_token,
3024 : &des_access);
3025 :
3026 : /* map the generic bits to the lsa account ones */
3027 14 : se_map_generic(&des_access, &lsa_account_mapping);
3028 :
3029 : /* get the generic lsa account SD until we store it */
3030 14 : status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3031 : &lsa_account_mapping,
3032 : r->in.sid, owner_access);
3033 14 : if (!NT_STATUS_IS_OK(status)) {
3034 0 : return status;
3035 : }
3036 :
3037 14 : status = access_check_object(psd, session_info->security_token,
3038 : SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
3039 : &acc_granted, "_lsa_OpenAccount" );
3040 14 : if (!NT_STATUS_IS_OK(status)) {
3041 0 : return status;
3042 : }
3043 :
3044 : /* TODO: Fis the parsing routine before reenabling this check! */
3045 : #if 0
3046 : if (!lookup_sid(&handle->sid, dom_name, name, &type))
3047 : return NT_STATUS_ACCESS_DENIED;
3048 : #endif
3049 :
3050 14 : status = create_lsa_policy_handle(p->mem_ctx, p,
3051 : LSA_HANDLE_ACCOUNT_TYPE,
3052 : acc_granted,
3053 : r->in.sid,
3054 : NULL,
3055 : psd,
3056 : r->out.acct_handle);
3057 14 : if (!NT_STATUS_IS_OK(status)) {
3058 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3059 : }
3060 :
3061 14 : return NT_STATUS_OK;
3062 : }
3063 :
3064 : /***************************************************************************
3065 : _lsa_EnumPrivsAccount
3066 : For a given SID, enumerate all the privilege this account has.
3067 : ***************************************************************************/
3068 :
3069 26 : NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
3070 : struct lsa_EnumPrivsAccount *r)
3071 : {
3072 26 : NTSTATUS status = NT_STATUS_OK;
3073 26 : struct lsa_info *info=NULL;
3074 0 : PRIVILEGE_SET *privileges;
3075 26 : struct lsa_PrivilegeSet *priv_set = NULL;
3076 0 : struct dom_sid_buf buf;
3077 :
3078 : /* find the connection policy handle. */
3079 26 : info = find_policy_by_hnd(p,
3080 : r->in.handle,
3081 : LSA_HANDLE_ACCOUNT_TYPE,
3082 : struct lsa_info,
3083 0 : &status);
3084 26 : if (!NT_STATUS_IS_OK(status)) {
3085 0 : return NT_STATUS_INVALID_HANDLE;
3086 : }
3087 :
3088 26 : if (!(info->access & LSA_ACCOUNT_VIEW))
3089 0 : return NT_STATUS_ACCESS_DENIED;
3090 :
3091 26 : status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
3092 26 : if (!NT_STATUS_IS_OK(status)) {
3093 0 : return status;
3094 : }
3095 :
3096 26 : *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
3097 26 : if (!priv_set) {
3098 0 : return NT_STATUS_NO_MEMORY;
3099 : }
3100 :
3101 26 : DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
3102 : dom_sid_str_buf(&info->sid, &buf),
3103 : privileges->count));
3104 :
3105 26 : priv_set->count = privileges->count;
3106 26 : priv_set->unknown = 0;
3107 26 : priv_set->set = talloc_move(priv_set, &privileges->set);
3108 :
3109 26 : return status;
3110 : }
3111 :
3112 : /***************************************************************************
3113 : _lsa_GetSystemAccessAccount
3114 : ***************************************************************************/
3115 :
3116 14 : NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
3117 : struct lsa_GetSystemAccessAccount *r)
3118 : {
3119 0 : NTSTATUS status;
3120 14 : struct lsa_info *info = NULL;
3121 0 : struct lsa_EnumPrivsAccount e;
3122 0 : struct lsa_PrivilegeSet *privset;
3123 :
3124 : /* find the connection policy handle. */
3125 :
3126 14 : info = find_policy_by_hnd(p,
3127 : r->in.handle,
3128 : LSA_HANDLE_ACCOUNT_TYPE,
3129 : struct lsa_info,
3130 0 : &status);
3131 14 : if (!NT_STATUS_IS_OK(status)) {
3132 0 : return NT_STATUS_INVALID_HANDLE;
3133 : }
3134 :
3135 14 : if (!(info->access & LSA_ACCOUNT_VIEW))
3136 0 : return NT_STATUS_ACCESS_DENIED;
3137 :
3138 14 : privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
3139 14 : if (!privset) {
3140 0 : return NT_STATUS_NO_MEMORY;
3141 : }
3142 :
3143 14 : e.in.handle = r->in.handle;
3144 14 : e.out.privs = &privset;
3145 :
3146 14 : status = _lsa_EnumPrivsAccount(p, &e);
3147 14 : if (!NT_STATUS_IS_OK(status)) {
3148 0 : DEBUG(10,("_lsa_GetSystemAccessAccount: "
3149 : "failed to call _lsa_EnumPrivsAccount(): %s\n",
3150 : nt_errstr(status)));
3151 0 : return status;
3152 : }
3153 :
3154 : /* Samba4 would iterate over the privset to merge the policy mode bits,
3155 : * not sure samba3 can do the same here, so just return what we did in
3156 : * the past - gd */
3157 :
3158 : /*
3159 : 0x01 -> Log on locally
3160 : 0x02 -> Access this computer from network
3161 : 0x04 -> Log on as a batch job
3162 : 0x10 -> Log on as a service
3163 :
3164 : they can be ORed together
3165 : */
3166 :
3167 14 : *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
3168 : LSA_POLICY_MODE_NETWORK;
3169 :
3170 14 : return NT_STATUS_OK;
3171 : }
3172 :
3173 : /***************************************************************************
3174 : update the systemaccount information
3175 : ***************************************************************************/
3176 :
3177 0 : NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
3178 : struct lsa_SetSystemAccessAccount *r)
3179 : {
3180 0 : struct lsa_info *info=NULL;
3181 0 : NTSTATUS status;
3182 0 : GROUP_MAP *map;
3183 :
3184 : /* find the connection policy handle. */
3185 0 : info = find_policy_by_hnd(p,
3186 : r->in.handle,
3187 : LSA_HANDLE_ACCOUNT_TYPE,
3188 : struct lsa_info,
3189 0 : &status);
3190 0 : if (!NT_STATUS_IS_OK(status)) {
3191 0 : return NT_STATUS_INVALID_HANDLE;
3192 : }
3193 :
3194 0 : if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
3195 0 : return NT_STATUS_ACCESS_DENIED;
3196 : }
3197 :
3198 0 : map = talloc_zero(p->mem_ctx, GROUP_MAP);
3199 0 : if (!map) {
3200 0 : return NT_STATUS_NO_MEMORY;
3201 : }
3202 :
3203 0 : if (!pdb_getgrsid(map, info->sid)) {
3204 0 : TALLOC_FREE(map);
3205 0 : return NT_STATUS_NO_SUCH_GROUP;
3206 : }
3207 :
3208 0 : status = pdb_update_group_mapping_entry(map);
3209 0 : TALLOC_FREE(map);
3210 0 : return status;
3211 : }
3212 :
3213 : /***************************************************************************
3214 : _lsa_AddPrivilegesToAccount
3215 : For a given SID, add some privileges.
3216 : ***************************************************************************/
3217 :
3218 2 : NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
3219 : struct lsa_AddPrivilegesToAccount *r)
3220 : {
3221 2 : struct lsa_info *info = NULL;
3222 2 : struct lsa_PrivilegeSet *set = NULL;
3223 0 : NTSTATUS status;
3224 :
3225 : /* find the connection policy handle. */
3226 2 : info = find_policy_by_hnd(p,
3227 : r->in.handle,
3228 : LSA_HANDLE_ACCOUNT_TYPE,
3229 : struct lsa_info,
3230 0 : &status);
3231 2 : if (!NT_STATUS_IS_OK(status)) {
3232 0 : return NT_STATUS_INVALID_HANDLE;
3233 : }
3234 :
3235 2 : if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3236 0 : return NT_STATUS_ACCESS_DENIED;
3237 : }
3238 :
3239 2 : set = r->in.privs;
3240 :
3241 2 : if ( !grant_privilege_set( &info->sid, set ) ) {
3242 0 : struct dom_sid_buf buf;
3243 0 : DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
3244 : dom_sid_str_buf(&info->sid, &buf)));
3245 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3246 : }
3247 :
3248 2 : return NT_STATUS_OK;
3249 : }
3250 :
3251 : /***************************************************************************
3252 : _lsa_RemovePrivilegesFromAccount
3253 : For a given SID, remove some privileges.
3254 : ***************************************************************************/
3255 :
3256 2 : NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
3257 : struct lsa_RemovePrivilegesFromAccount *r)
3258 : {
3259 2 : struct lsa_info *info = NULL;
3260 2 : struct lsa_PrivilegeSet *set = NULL;
3261 0 : NTSTATUS status;
3262 :
3263 : /* find the connection policy handle. */
3264 2 : info = find_policy_by_hnd(p,
3265 : r->in.handle,
3266 : LSA_HANDLE_ACCOUNT_TYPE,
3267 : struct lsa_info,
3268 0 : &status);
3269 2 : if (!NT_STATUS_IS_OK(status)) {
3270 0 : return NT_STATUS_INVALID_HANDLE;
3271 : }
3272 :
3273 2 : if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3274 0 : return NT_STATUS_ACCESS_DENIED;
3275 : }
3276 :
3277 2 : set = r->in.privs;
3278 :
3279 2 : if ( !revoke_privilege_set( &info->sid, set) ) {
3280 0 : struct dom_sid_buf buf;
3281 0 : DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
3282 : dom_sid_str_buf(&info->sid, &buf)));
3283 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3284 : }
3285 :
3286 2 : return NT_STATUS_OK;
3287 : }
3288 :
3289 : /***************************************************************************
3290 : _lsa_LookupPrivName
3291 : ***************************************************************************/
3292 :
3293 50 : NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
3294 : struct lsa_LookupPrivName *r)
3295 : {
3296 50 : struct lsa_info *info = NULL;
3297 0 : const char *name;
3298 0 : struct lsa_StringLarge *lsa_name;
3299 0 : NTSTATUS status;
3300 :
3301 : /* find the connection policy handle. */
3302 50 : info = find_policy_by_hnd(p,
3303 : r->in.handle,
3304 : LSA_HANDLE_POLICY_TYPE,
3305 : struct lsa_info,
3306 0 : &status);
3307 50 : if (!NT_STATUS_IS_OK(status)) {
3308 0 : return NT_STATUS_INVALID_HANDLE;
3309 : }
3310 :
3311 50 : if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
3312 0 : return NT_STATUS_ACCESS_DENIED;
3313 : }
3314 :
3315 50 : if (r->in.luid->high != 0) {
3316 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3317 : }
3318 :
3319 50 : name = sec_privilege_name(r->in.luid->low);
3320 50 : if (!name) {
3321 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3322 : }
3323 :
3324 50 : lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
3325 50 : if (!lsa_name) {
3326 0 : return NT_STATUS_NO_MEMORY;
3327 : }
3328 :
3329 50 : lsa_name->string = talloc_strdup(lsa_name, name);
3330 50 : if (!lsa_name->string) {
3331 0 : TALLOC_FREE(lsa_name);
3332 0 : return NT_STATUS_NO_MEMORY;
3333 : }
3334 :
3335 50 : *r->out.name = lsa_name;
3336 :
3337 50 : return NT_STATUS_OK;
3338 : }
3339 :
3340 : /***************************************************************************
3341 : _lsa_QuerySecurity
3342 : ***************************************************************************/
3343 :
3344 12 : NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
3345 : struct lsa_QuerySecurity *r)
3346 : {
3347 12 : struct lsa_info *handle=NULL;
3348 12 : struct security_descriptor *psd = NULL;
3349 12 : size_t sd_size = 0;
3350 0 : NTSTATUS status;
3351 :
3352 : /* find the connection policy handle. */
3353 12 : handle = find_policy_by_hnd(p,
3354 : r->in.handle,
3355 : DCESRV_HANDLE_ANY,
3356 : struct lsa_info,
3357 0 : &status);
3358 12 : if (!NT_STATUS_IS_OK(status)) {
3359 0 : return NT_STATUS_INVALID_HANDLE;
3360 : }
3361 :
3362 12 : switch (handle->type) {
3363 12 : case LSA_HANDLE_POLICY_TYPE:
3364 : case LSA_HANDLE_ACCOUNT_TYPE:
3365 : case LSA_HANDLE_TRUST_TYPE:
3366 : case LSA_HANDLE_SECRET_TYPE:
3367 12 : psd = handle->sd;
3368 12 : sd_size = ndr_size_security_descriptor(psd, 0);
3369 12 : status = NT_STATUS_OK;
3370 12 : break;
3371 0 : default:
3372 0 : status = NT_STATUS_INVALID_HANDLE;
3373 0 : break;
3374 : }
3375 :
3376 12 : if (!NT_STATUS_IS_OK(status)) {
3377 0 : return status;
3378 : }
3379 :
3380 12 : *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
3381 12 : if (!*r->out.sdbuf) {
3382 0 : return NT_STATUS_NO_MEMORY;
3383 : }
3384 :
3385 12 : return status;
3386 : }
3387 :
3388 : /***************************************************************************
3389 : _lsa_AddAccountRights
3390 : ***************************************************************************/
3391 :
3392 24 : NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
3393 : struct lsa_AddAccountRights *r)
3394 : {
3395 24 : struct dcesrv_call_state *dce_call = p->dce_call;
3396 0 : struct auth_session_info *session_info =
3397 24 : dcesrv_call_session_info(dce_call);
3398 24 : int i = 0;
3399 24 : uint32_t acc_granted = 0;
3400 24 : struct security_descriptor *psd = NULL;
3401 0 : size_t sd_size;
3402 0 : struct dom_sid sid;
3403 0 : NTSTATUS status;
3404 :
3405 : /* find the connection policy handle. */
3406 24 : (void)find_policy_by_hnd(p,
3407 : r->in.handle,
3408 : LSA_HANDLE_POLICY_TYPE,
3409 : struct lsa_info,
3410 0 : &status);
3411 24 : if (!NT_STATUS_IS_OK(status)) {
3412 0 : return NT_STATUS_INVALID_HANDLE;
3413 : }
3414 :
3415 : /* get the generic lsa account SD for this SID until we store it */
3416 24 : status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3417 : &lsa_account_mapping,
3418 : NULL, 0);
3419 24 : if (!NT_STATUS_IS_OK(status)) {
3420 0 : return status;
3421 : }
3422 :
3423 : /*
3424 : * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3425 : * on the policy handle. If it does, ask for
3426 : * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3427 : * on the account sid. We don't check here so just use the latter. JRA.
3428 : */
3429 :
3430 24 : status = access_check_object(psd, session_info->security_token,
3431 : SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3432 : LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3433 : &acc_granted, "_lsa_AddAccountRights" );
3434 24 : if (!NT_STATUS_IS_OK(status)) {
3435 0 : return status;
3436 : }
3437 :
3438 : /* according to an NT4 PDC, you can add privileges to SIDs even without
3439 : call_lsa_create_account() first. And you can use any arbitrary SID. */
3440 :
3441 24 : sid_copy( &sid, r->in.sid );
3442 :
3443 47 : for ( i=0; i < r->in.rights->count; i++ ) {
3444 :
3445 24 : const char *privname = r->in.rights->names[i].string;
3446 :
3447 : /* only try to add non-null strings */
3448 :
3449 24 : if ( !privname )
3450 0 : continue;
3451 :
3452 24 : if ( !grant_privilege_by_name( &sid, privname ) ) {
3453 1 : DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3454 : privname ));
3455 1 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3456 : }
3457 : }
3458 :
3459 23 : return NT_STATUS_OK;
3460 : }
3461 :
3462 : /***************************************************************************
3463 : _lsa_RemoveAccountRights
3464 : ***************************************************************************/
3465 :
3466 20 : NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
3467 : struct lsa_RemoveAccountRights *r)
3468 : {
3469 20 : struct dcesrv_call_state *dce_call = p->dce_call;
3470 0 : struct auth_session_info *session_info =
3471 20 : dcesrv_call_session_info(dce_call);
3472 20 : int i = 0;
3473 20 : struct security_descriptor *psd = NULL;
3474 0 : size_t sd_size;
3475 0 : struct dom_sid sid;
3476 20 : const char *privname = NULL;
3477 20 : uint32_t acc_granted = 0;
3478 0 : NTSTATUS status;
3479 :
3480 : /* find the connection policy handle. */
3481 20 : (void)find_policy_by_hnd(p,
3482 : r->in.handle,
3483 : LSA_HANDLE_POLICY_TYPE,
3484 : struct lsa_info,
3485 0 : &status);
3486 20 : if (!NT_STATUS_IS_OK(status)) {
3487 0 : return NT_STATUS_INVALID_HANDLE;
3488 : }
3489 :
3490 : /* get the generic lsa account SD for this SID until we store it */
3491 20 : status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3492 : &lsa_account_mapping,
3493 : NULL, 0);
3494 20 : if (!NT_STATUS_IS_OK(status)) {
3495 0 : return status;
3496 : }
3497 :
3498 : /*
3499 : * From the MS DOCs. We need
3500 : * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3501 : * and DELETE on the account sid.
3502 : */
3503 :
3504 20 : status = access_check_object(psd, session_info->security_token,
3505 : SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3506 : LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3507 : LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
3508 : &acc_granted, "_lsa_RemoveAccountRights");
3509 20 : if (!NT_STATUS_IS_OK(status)) {
3510 0 : return status;
3511 : }
3512 :
3513 20 : sid_copy( &sid, r->in.sid );
3514 :
3515 20 : if ( r->in.remove_all ) {
3516 0 : if ( !revoke_all_privileges( &sid ) )
3517 0 : return NT_STATUS_ACCESS_DENIED;
3518 :
3519 0 : return NT_STATUS_OK;
3520 : }
3521 :
3522 40 : for ( i=0; i < r->in.rights->count; i++ ) {
3523 :
3524 20 : privname = r->in.rights->names[i].string;
3525 :
3526 : /* only try to add non-null strings */
3527 :
3528 20 : if ( !privname )
3529 0 : continue;
3530 :
3531 20 : if ( !revoke_privilege_by_name( &sid, privname ) ) {
3532 0 : DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3533 : privname ));
3534 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3535 : }
3536 : }
3537 :
3538 20 : return NT_STATUS_OK;
3539 : }
3540 :
3541 : /*******************************************************************
3542 : ********************************************************************/
3543 :
3544 14 : static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3545 : struct lsa_RightSet *r,
3546 : PRIVILEGE_SET *privileges)
3547 : {
3548 0 : uint32_t i;
3549 0 : const char *privname;
3550 14 : const char **privname_array = NULL;
3551 14 : size_t num_priv = 0;
3552 :
3553 66 : for (i=0; i<privileges->count; i++) {
3554 52 : if (privileges->set[i].luid.high) {
3555 0 : continue;
3556 : }
3557 52 : privname = sec_privilege_name(privileges->set[i].luid.low);
3558 52 : if (privname) {
3559 52 : if (!add_string_to_array(mem_ctx, privname,
3560 : &privname_array, &num_priv)) {
3561 0 : return NT_STATUS_NO_MEMORY;
3562 : }
3563 : }
3564 : }
3565 :
3566 14 : if (num_priv) {
3567 :
3568 4 : r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3569 : num_priv);
3570 4 : if (!r->names) {
3571 0 : return NT_STATUS_NO_MEMORY;
3572 : }
3573 :
3574 56 : for (i=0; i<num_priv; i++) {
3575 52 : init_lsa_StringLarge(&r->names[i], privname_array[i]);
3576 : }
3577 :
3578 4 : r->count = num_priv;
3579 : }
3580 :
3581 14 : return NT_STATUS_OK;
3582 : }
3583 :
3584 : /***************************************************************************
3585 : _lsa_EnumAccountRights
3586 : ***************************************************************************/
3587 :
3588 112 : NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3589 : struct lsa_EnumAccountRights *r)
3590 : {
3591 0 : NTSTATUS status;
3592 112 : struct lsa_info *info = NULL;
3593 0 : PRIVILEGE_SET *privileges;
3594 0 : struct dom_sid_buf buf;
3595 :
3596 : /* find the connection policy handle. */
3597 :
3598 112 : info = find_policy_by_hnd(p,
3599 : r->in.handle,
3600 : LSA_HANDLE_POLICY_TYPE,
3601 : struct lsa_info,
3602 0 : &status);
3603 112 : if (!NT_STATUS_IS_OK(status)) {
3604 0 : return NT_STATUS_INVALID_HANDLE;
3605 : }
3606 :
3607 112 : if (!(info->access & LSA_ACCOUNT_VIEW)) {
3608 0 : return NT_STATUS_ACCESS_DENIED;
3609 : }
3610 :
3611 : /* according to an NT4 PDC, you can add privileges to SIDs even without
3612 : call_lsa_create_account() first. And you can use any arbitrary SID. */
3613 :
3614 : /* according to MS-LSAD 3.1.4.5.10 it is required to return
3615 : * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3616 : * the lsa database */
3617 :
3618 112 : status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3619 112 : if (!NT_STATUS_IS_OK(status)) {
3620 98 : return status;
3621 : }
3622 :
3623 14 : DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3624 : dom_sid_str_buf(r->in.sid, &buf),
3625 : privileges->count));
3626 :
3627 14 : status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3628 :
3629 14 : return status;
3630 : }
3631 :
3632 : /***************************************************************************
3633 : _lsa_LookupPrivValue
3634 : ***************************************************************************/
3635 :
3636 20 : NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3637 : struct lsa_LookupPrivValue *r)
3638 : {
3639 20 : struct lsa_info *info = NULL;
3640 20 : const char *name = NULL;
3641 0 : NTSTATUS status;
3642 :
3643 : /* find the connection policy handle. */
3644 :
3645 20 : info = find_policy_by_hnd(p,
3646 : r->in.handle,
3647 : LSA_HANDLE_POLICY_TYPE,
3648 : struct lsa_info,
3649 0 : &status);
3650 20 : if (!NT_STATUS_IS_OK(status)) {
3651 0 : return NT_STATUS_INVALID_HANDLE;
3652 : }
3653 :
3654 20 : if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3655 0 : return NT_STATUS_ACCESS_DENIED;
3656 :
3657 20 : name = r->in.name->string;
3658 :
3659 20 : DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3660 :
3661 20 : r->out.luid->low = sec_privilege_id(name);
3662 20 : r->out.luid->high = 0;
3663 20 : if (r->out.luid->low == SEC_PRIV_INVALID) {
3664 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3665 : }
3666 20 : return NT_STATUS_OK;
3667 : }
3668 :
3669 : /***************************************************************************
3670 : _lsa_EnumAccountsWithUserRight
3671 : ***************************************************************************/
3672 :
3673 18 : NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3674 : struct lsa_EnumAccountsWithUserRight *r)
3675 : {
3676 0 : NTSTATUS status;
3677 18 : struct lsa_info *info = NULL;
3678 18 : struct dom_sid *sids = NULL;
3679 18 : int num_sids = 0;
3680 0 : uint32_t i;
3681 0 : enum sec_privilege privilege;
3682 :
3683 18 : info = find_policy_by_hnd(p,
3684 : r->in.handle,
3685 : LSA_HANDLE_POLICY_TYPE,
3686 : struct lsa_info,
3687 0 : &status);
3688 18 : if (!NT_STATUS_IS_OK(status)) {
3689 0 : return NT_STATUS_INVALID_HANDLE;
3690 : }
3691 :
3692 18 : if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3693 0 : return NT_STATUS_ACCESS_DENIED;
3694 : }
3695 :
3696 18 : if (!r->in.name || !r->in.name->string) {
3697 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3698 : }
3699 :
3700 18 : privilege = sec_privilege_id(r->in.name->string);
3701 18 : if (privilege == SEC_PRIV_INVALID) {
3702 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3703 : }
3704 :
3705 18 : status = privilege_enum_sids(privilege, p->mem_ctx,
3706 : &sids, &num_sids);
3707 18 : if (!NT_STATUS_IS_OK(status)) {
3708 0 : return status;
3709 : }
3710 :
3711 18 : r->out.sids->num_sids = num_sids;
3712 18 : r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3713 : r->out.sids->num_sids);
3714 :
3715 36 : for (i=0; i < r->out.sids->num_sids; i++) {
3716 36 : r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3717 18 : &sids[i]);
3718 18 : if (!r->out.sids->sids[i].sid) {
3719 0 : TALLOC_FREE(r->out.sids->sids);
3720 0 : r->out.sids->num_sids = 0;
3721 0 : return NT_STATUS_NO_MEMORY;
3722 : }
3723 : }
3724 :
3725 18 : return NT_STATUS_OK;
3726 : }
3727 :
3728 : /***************************************************************************
3729 : _lsa_Delete
3730 : ***************************************************************************/
3731 :
3732 8 : NTSTATUS _lsa_Delete(struct pipes_struct *p,
3733 : struct lsa_Delete *r)
3734 : {
3735 8 : return NT_STATUS_NOT_SUPPORTED;
3736 : }
3737 :
3738 0 : static NTSTATUS info_ex_2_pdb_trusted_domain(
3739 : struct lsa_TrustDomainInfoInfoEx *info_ex,
3740 : struct pdb_trusted_domain *td)
3741 : {
3742 0 : if (info_ex->domain_name.string == NULL ||
3743 0 : info_ex->netbios_name.string == NULL ||
3744 0 : info_ex->sid == NULL) {
3745 0 : return NT_STATUS_INVALID_PARAMETER;
3746 : }
3747 :
3748 0 : td->domain_name = talloc_strdup(td, info_ex->domain_name.string);
3749 0 : td->netbios_name = talloc_strdup(td, info_ex->netbios_name.string);
3750 0 : sid_copy(&td->security_identifier, info_ex->sid);
3751 0 : if (td->domain_name == NULL ||
3752 0 : td->netbios_name == NULL ||
3753 0 : is_null_sid(&td->security_identifier)) {
3754 0 : return NT_STATUS_NO_MEMORY;
3755 : }
3756 0 : td->trust_direction = info_ex->trust_direction;
3757 0 : td->trust_type = info_ex->trust_type;
3758 0 : td->trust_attributes = info_ex->trust_attributes;
3759 :
3760 0 : return NT_STATUS_OK;
3761 : }
3762 :
3763 0 : static NTSTATUS setInfoTrustedDomain_base(struct pipes_struct *p,
3764 : TALLOC_CTX *mem_ctx,
3765 : struct lsa_info *policy,
3766 : enum lsa_TrustDomInfoEnum level,
3767 : union lsa_TrustedDomainInfo *info)
3768 : {
3769 0 : struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
3770 0 : DATA_BLOB auth_blob;
3771 0 : struct trustDomainPasswords auth_struct;
3772 0 : NTSTATUS nt_status;
3773 :
3774 0 : struct pdb_trusted_domain *td;
3775 0 : struct pdb_trusted_domain *orig_td;
3776 :
3777 0 : td = talloc_zero(mem_ctx, struct pdb_trusted_domain);
3778 0 : if (td == NULL) {
3779 0 : return NT_STATUS_NO_MEMORY;
3780 : }
3781 :
3782 0 : switch (level) {
3783 0 : case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
3784 0 : if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3785 0 : return NT_STATUS_ACCESS_DENIED;
3786 : }
3787 0 : td->trust_posix_offset = &info->posix_offset.posix_offset;
3788 0 : break;
3789 0 : case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
3790 0 : if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3791 0 : return NT_STATUS_ACCESS_DENIED;
3792 : }
3793 0 : nt_status = info_ex_2_pdb_trusted_domain(&info->info_ex, td);
3794 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3795 0 : return nt_status;
3796 : }
3797 0 : break;
3798 0 : case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
3799 0 : if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3800 0 : return NT_STATUS_ACCESS_DENIED;
3801 : }
3802 0 : nt_status = auth_info_2_auth_blob(td, &info->auth_info,
3803 : &td->trust_auth_incoming,
3804 : &td->trust_auth_outgoing);
3805 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3806 0 : return nt_status;
3807 : }
3808 0 : break;
3809 0 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
3810 0 : if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3811 0 : return NT_STATUS_ACCESS_DENIED;
3812 : }
3813 0 : td->trust_posix_offset = &info->full_info.posix_offset.posix_offset;
3814 0 : nt_status = info_ex_2_pdb_trusted_domain(&info->full_info.info_ex,
3815 : td);
3816 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3817 0 : return nt_status;
3818 : }
3819 0 : nt_status = auth_info_2_auth_blob(td,
3820 : &info->full_info.auth_info,
3821 : &td->trust_auth_incoming,
3822 : &td->trust_auth_outgoing);
3823 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3824 0 : return nt_status;
3825 : }
3826 0 : break;
3827 0 : case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
3828 0 : if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3829 0 : return NT_STATUS_ACCESS_DENIED;
3830 : }
3831 0 : auth_info_int = &info->auth_info_internal;
3832 0 : break;
3833 0 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
3834 0 : if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3835 0 : return NT_STATUS_ACCESS_DENIED;
3836 : }
3837 0 : td->trust_posix_offset = &info->full_info_internal.posix_offset.posix_offset;
3838 0 : nt_status = info_ex_2_pdb_trusted_domain(&info->full_info_internal.info_ex,
3839 : td);
3840 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3841 0 : return nt_status;
3842 : }
3843 0 : auth_info_int = &info->full_info_internal.auth_info;
3844 0 : break;
3845 0 : case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
3846 0 : if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3847 0 : return NT_STATUS_ACCESS_DENIED;
3848 : }
3849 0 : td->supported_enc_type = &info->enc_types.enc_types;
3850 0 : break;
3851 0 : default:
3852 0 : return NT_STATUS_INVALID_PARAMETER;
3853 : }
3854 :
3855 : /* decode auth_info_int if set */
3856 0 : if (auth_info_int) {
3857 :
3858 : /* now decrypt blob */
3859 0 : auth_blob = data_blob_const(auth_info_int->auth_blob.data,
3860 0 : auth_info_int->auth_blob.size);
3861 :
3862 0 : nt_status = get_trustdom_auth_blob(p, mem_ctx,
3863 : &auth_blob, &auth_struct);
3864 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3865 0 : return nt_status;
3866 : }
3867 : } else {
3868 0 : memset(&auth_struct, 0, sizeof(auth_struct));
3869 : }
3870 :
3871 : /* TODO: verify only one object matches the dns/netbios/sid triplet and that
3872 : * this is the one we already have */
3873 :
3874 : /* TODO: check if the trust direction is changed and we need to add or remove
3875 : * auth data */
3876 :
3877 : /* TODO: check if trust type shall be changed and return an error in this case
3878 : * */
3879 0 : nt_status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &policy->sid,
3880 : &orig_td);
3881 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3882 0 : return nt_status;
3883 : }
3884 :
3885 :
3886 : /* TODO: should we fetch previous values from the existing entry
3887 : * and append them ? */
3888 0 : if (auth_struct.incoming.count) {
3889 0 : nt_status = get_trustauth_inout_blob(mem_ctx,
3890 : &auth_struct.incoming,
3891 : &td->trust_auth_incoming);
3892 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3893 0 : return nt_status;
3894 : }
3895 : } else {
3896 0 : ZERO_STRUCT(td->trust_auth_incoming);
3897 : }
3898 :
3899 0 : if (auth_struct.outgoing.count) {
3900 0 : nt_status = get_trustauth_inout_blob(mem_ctx,
3901 : &auth_struct.outgoing,
3902 : &td->trust_auth_outgoing);
3903 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3904 0 : return nt_status;
3905 : }
3906 : } else {
3907 0 : ZERO_STRUCT(td->trust_auth_outgoing);
3908 : }
3909 :
3910 0 : nt_status = pdb_set_trusted_domain(orig_td->domain_name, td);
3911 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3912 0 : return nt_status;
3913 : }
3914 :
3915 0 : return NT_STATUS_OK;
3916 : }
3917 :
3918 0 : NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3919 : struct lsa_SetTrustedDomainInfo *r)
3920 : {
3921 0 : NTSTATUS status;
3922 0 : struct policy_handle trustdom_handle;
3923 0 : struct lsa_OpenTrustedDomain o;
3924 0 : struct lsa_SetInformationTrustedDomain s;
3925 0 : struct lsa_Close c;
3926 :
3927 0 : o.in.handle = r->in.handle;
3928 0 : o.in.sid = r->in.dom_sid;
3929 0 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3930 0 : o.out.trustdom_handle = &trustdom_handle;
3931 :
3932 0 : status = _lsa_OpenTrustedDomain(p, &o);
3933 0 : if (!NT_STATUS_IS_OK(status)) {
3934 0 : return status;
3935 : }
3936 :
3937 0 : s.in.trustdom_handle = &trustdom_handle;
3938 0 : s.in.level = r->in.level;
3939 0 : s.in.info = r->in.info;
3940 :
3941 0 : status = _lsa_SetInformationTrustedDomain(p, &s);
3942 0 : if (!NT_STATUS_IS_OK(status)) {
3943 0 : return status;
3944 : }
3945 :
3946 0 : c.in.handle = &trustdom_handle;
3947 0 : c.out.handle = &trustdom_handle;
3948 :
3949 0 : return _lsa_Close(p, &c);
3950 : }
3951 :
3952 0 : NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3953 : struct lsa_SetTrustedDomainInfoByName *r)
3954 : {
3955 0 : NTSTATUS status;
3956 0 : struct policy_handle trustdom_handle;
3957 0 : struct lsa_OpenTrustedDomainByName o;
3958 0 : struct lsa_SetInformationTrustedDomain s;
3959 0 : struct lsa_Close c;
3960 :
3961 0 : o.in.handle = r->in.handle;
3962 0 : o.in.name.string = r->in.trusted_domain->string;
3963 0 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3964 0 : o.out.trustdom_handle = &trustdom_handle;
3965 :
3966 0 : status = _lsa_OpenTrustedDomainByName(p, &o);
3967 0 : if (!NT_STATUS_IS_OK(status)) {
3968 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
3969 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3970 : }
3971 0 : return status;
3972 : }
3973 :
3974 0 : s.in.trustdom_handle = &trustdom_handle;
3975 0 : s.in.level = r->in.level;
3976 0 : s.in.info = r->in.info;
3977 :
3978 0 : status = _lsa_SetInformationTrustedDomain(p, &s);
3979 0 : if (!NT_STATUS_IS_OK(status)) {
3980 0 : return status;
3981 : }
3982 :
3983 0 : c.in.handle = &trustdom_handle;
3984 0 : c.out.handle = &trustdom_handle;
3985 :
3986 0 : return _lsa_Close(p, &c);
3987 : }
3988 :
3989 0 : NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3990 : struct lsa_SetInformationTrustedDomain *r)
3991 : {
3992 0 : struct lsa_info *policy;
3993 0 : NTSTATUS status;
3994 :
3995 0 : policy = find_policy_by_hnd(p,
3996 : r->in.trustdom_handle,
3997 : LSA_HANDLE_TRUST_TYPE,
3998 : struct lsa_info,
3999 0 : &status);
4000 0 : if (!NT_STATUS_IS_OK(status)) {
4001 0 : return NT_STATUS_INVALID_HANDLE;
4002 : }
4003 :
4004 0 : return setInfoTrustedDomain_base(p, p->mem_ctx, policy,
4005 : r->in.level, r->in.info);
4006 : }
4007 :
4008 :
4009 : /*
4010 : * From here on the server routines are just dummy ones to make smbd link with
4011 : * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
4012 : * pulling the server stubs across one by one.
4013 : */
4014 :
4015 0 : NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
4016 : {
4017 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4018 0 : return NT_STATUS_NOT_IMPLEMENTED;
4019 : }
4020 :
4021 0 : NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
4022 : struct lsa_ChangePassword *r)
4023 : {
4024 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4025 0 : return NT_STATUS_NOT_IMPLEMENTED;
4026 : }
4027 :
4028 0 : NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
4029 : {
4030 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4031 0 : return NT_STATUS_NOT_IMPLEMENTED;
4032 : }
4033 :
4034 0 : NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
4035 : {
4036 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4037 0 : return NT_STATUS_NOT_IMPLEMENTED;
4038 : }
4039 :
4040 0 : NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
4041 : struct lsa_GetQuotasForAccount *r)
4042 : {
4043 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4044 0 : return NT_STATUS_NOT_IMPLEMENTED;
4045 : }
4046 :
4047 0 : NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
4048 : struct lsa_SetQuotasForAccount *r)
4049 : {
4050 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4051 0 : return NT_STATUS_NOT_IMPLEMENTED;
4052 : }
4053 :
4054 0 : NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
4055 : struct lsa_StorePrivateData *r)
4056 : {
4057 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4058 0 : return NT_STATUS_NOT_IMPLEMENTED;
4059 : }
4060 :
4061 0 : NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
4062 : struct lsa_RetrievePrivateData *r)
4063 : {
4064 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4065 0 : return NT_STATUS_NOT_IMPLEMENTED;
4066 : }
4067 :
4068 0 : NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
4069 : struct lsa_SetInfoPolicy2 *r)
4070 : {
4071 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4072 0 : return NT_STATUS_NOT_IMPLEMENTED;
4073 : }
4074 :
4075 0 : NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
4076 : struct lsa_EnumTrustedDomainsEx *r)
4077 : {
4078 0 : struct lsa_info *info;
4079 0 : uint32_t count;
4080 0 : struct pdb_trusted_domain **domains;
4081 0 : struct lsa_TrustDomainInfoInfoEx *entries;
4082 0 : int i;
4083 0 : NTSTATUS nt_status;
4084 :
4085 : /* bail out early if pdb backend is not capable of ex trusted domains,
4086 : * if we don't do that, the client might not call
4087 : * _lsa_EnumTrustedDomains() afterwards - gd */
4088 :
4089 0 : if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
4090 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4091 0 : return NT_STATUS_NOT_IMPLEMENTED;
4092 : }
4093 :
4094 0 : info = find_policy_by_hnd(p,
4095 : r->in.handle,
4096 : LSA_HANDLE_POLICY_TYPE,
4097 : struct lsa_info,
4098 0 : &nt_status);
4099 0 : if (!NT_STATUS_IS_OK(nt_status)) {
4100 0 : return NT_STATUS_INVALID_HANDLE;
4101 : }
4102 :
4103 : /* check if the user has enough rights */
4104 0 : if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
4105 0 : return NT_STATUS_ACCESS_DENIED;
4106 :
4107 0 : become_root();
4108 0 : nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
4109 0 : unbecome_root();
4110 :
4111 0 : if (!NT_STATUS_IS_OK(nt_status)) {
4112 0 : return nt_status;
4113 : }
4114 :
4115 0 : entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
4116 : count);
4117 0 : if (!entries) {
4118 0 : return NT_STATUS_NO_MEMORY;
4119 : }
4120 :
4121 0 : for (i=0; i<count; i++) {
4122 0 : init_lsa_StringLarge(&entries[i].domain_name,
4123 0 : domains[i]->domain_name);
4124 0 : init_lsa_StringLarge(&entries[i].netbios_name,
4125 0 : domains[i]->netbios_name);
4126 0 : entries[i].sid = &domains[i]->security_identifier;
4127 0 : entries[i].trust_direction = domains[i]->trust_direction;
4128 0 : entries[i].trust_type = domains[i]->trust_type;
4129 0 : entries[i].trust_attributes = domains[i]->trust_attributes;
4130 : }
4131 :
4132 0 : if (*r->in.resume_handle >= count) {
4133 0 : *r->out.resume_handle = -1;
4134 0 : TALLOC_FREE(entries);
4135 0 : return NT_STATUS_NO_MORE_ENTRIES;
4136 : }
4137 :
4138 : /* return the rest, limit by max_size. Note that we
4139 : use the w2k3 element size value of 60 */
4140 0 : r->out.domains->count = count - *r->in.resume_handle;
4141 0 : r->out.domains->count = MIN(r->out.domains->count,
4142 : (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
4143 :
4144 0 : r->out.domains->domains = entries + *r->in.resume_handle;
4145 :
4146 0 : if (r->out.domains->count < count - *r->in.resume_handle) {
4147 0 : *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
4148 0 : return STATUS_MORE_ENTRIES;
4149 : }
4150 :
4151 : /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
4152 : * always be larger than the previous input resume handle, in
4153 : * particular when hitting the last query it is vital to set the
4154 : * resume handle correctly to avoid infinite client loops, as
4155 : * seen e.g. with Windows XP SP3 when resume handle is 0 and
4156 : * status is NT_STATUS_OK - gd */
4157 :
4158 0 : *r->out.resume_handle = (uint32_t)-1;
4159 :
4160 0 : return NT_STATUS_OK;
4161 : }
4162 :
4163 0 : NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
4164 : struct lsa_QueryDomainInformationPolicy *r)
4165 : {
4166 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4167 0 : return NT_STATUS_NOT_IMPLEMENTED;
4168 : }
4169 :
4170 0 : NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
4171 : struct lsa_SetDomainInformationPolicy *r)
4172 : {
4173 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4174 0 : return NT_STATUS_NOT_IMPLEMENTED;
4175 : }
4176 :
4177 0 : NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
4178 : {
4179 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4180 0 : return NT_STATUS_NOT_IMPLEMENTED;
4181 : }
4182 :
4183 0 : NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
4184 : {
4185 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4186 0 : return NT_STATUS_NOT_IMPLEMENTED;
4187 : }
4188 :
4189 0 : NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
4190 : {
4191 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4192 0 : return NT_STATUS_NOT_IMPLEMENTED;
4193 : }
4194 :
4195 0 : NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
4196 : {
4197 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4198 0 : return NT_STATUS_NOT_IMPLEMENTED;
4199 : }
4200 :
4201 0 : NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
4202 : struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
4203 : {
4204 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4205 0 : return NT_STATUS_NOT_IMPLEMENTED;
4206 : }
4207 :
4208 0 : NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
4209 : struct lsa_CREDRREADDOMAINCREDENTIALS *r)
4210 : {
4211 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4212 0 : return NT_STATUS_NOT_IMPLEMENTED;
4213 : }
4214 :
4215 0 : NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
4216 : {
4217 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4218 0 : return NT_STATUS_NOT_IMPLEMENTED;
4219 : }
4220 :
4221 0 : NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
4222 : struct lsa_CREDRGETTARGETINFO *r)
4223 : {
4224 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4225 0 : return NT_STATUS_NOT_IMPLEMENTED;
4226 : }
4227 :
4228 0 : NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
4229 : struct lsa_CREDRPROFILELOADED *r)
4230 : {
4231 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4232 0 : return NT_STATUS_NOT_IMPLEMENTED;
4233 : }
4234 :
4235 0 : NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
4236 : struct lsa_CREDRGETSESSIONTYPES *r)
4237 : {
4238 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4239 0 : return NT_STATUS_NOT_IMPLEMENTED;
4240 : }
4241 :
4242 0 : NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
4243 : struct lsa_LSARREGISTERAUDITEVENT *r)
4244 : {
4245 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4246 0 : return NT_STATUS_NOT_IMPLEMENTED;
4247 : }
4248 :
4249 0 : NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
4250 : struct lsa_LSARGENAUDITEVENT *r)
4251 : {
4252 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4253 0 : return NT_STATUS_NOT_IMPLEMENTED;
4254 : }
4255 :
4256 0 : NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
4257 : struct lsa_LSARUNREGISTERAUDITEVENT *r)
4258 : {
4259 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4260 0 : return NT_STATUS_NOT_IMPLEMENTED;
4261 : }
4262 :
4263 0 : NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
4264 : struct lsa_lsaRQueryForestTrustInformation *r)
4265 : {
4266 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4267 0 : return NT_STATUS_NOT_IMPLEMENTED;
4268 : }
4269 :
4270 : #define DNS_CMP_MATCH 0
4271 : #define DNS_CMP_FIRST_IS_CHILD 1
4272 : #define DNS_CMP_SECOND_IS_CHILD 2
4273 : #define DNS_CMP_NO_MATCH 3
4274 :
4275 : /* this function assumes names are well formed DNS names.
4276 : * it doesn't validate them */
4277 0 : static int dns_cmp(const char *s1, size_t l1,
4278 : const char *s2, size_t l2)
4279 : {
4280 0 : const char *p1, *p2;
4281 0 : size_t t1, t2;
4282 0 : int cret;
4283 :
4284 0 : if (l1 == l2) {
4285 0 : if (strcasecmp_m(s1, s2) == 0) {
4286 0 : return DNS_CMP_MATCH;
4287 : }
4288 0 : return DNS_CMP_NO_MATCH;
4289 : }
4290 :
4291 0 : if (l1 > l2) {
4292 0 : p1 = s1;
4293 0 : p2 = s2;
4294 0 : t1 = l1;
4295 0 : t2 = l2;
4296 0 : cret = DNS_CMP_FIRST_IS_CHILD;
4297 : } else {
4298 0 : p1 = s2;
4299 0 : p2 = s1;
4300 0 : t1 = l2;
4301 0 : t2 = l1;
4302 0 : cret = DNS_CMP_SECOND_IS_CHILD;
4303 : }
4304 :
4305 0 : if (p1[t1 - t2 - 1] != '.') {
4306 0 : return DNS_CMP_NO_MATCH;
4307 : }
4308 :
4309 0 : if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
4310 0 : return cret;
4311 : }
4312 :
4313 0 : return DNS_CMP_NO_MATCH;
4314 : }
4315 :
4316 0 : static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
4317 : struct lsa_ForestTrustInformation *lfti,
4318 : struct ForestTrustInfo *fti)
4319 : {
4320 0 : struct lsa_ForestTrustRecord *lrec;
4321 0 : struct ForestTrustInfoRecord *rec;
4322 0 : struct lsa_StringLarge *tln;
4323 0 : struct lsa_ForestTrustDomainInfo *info;
4324 0 : uint32_t i;
4325 :
4326 0 : fti->version = 1;
4327 0 : fti->count = lfti->count;
4328 0 : fti->records = talloc_array(mem_ctx,
4329 : struct ForestTrustInfoRecordArmor,
4330 : fti->count);
4331 0 : if (!fti->records) {
4332 0 : return NT_STATUS_NO_MEMORY;
4333 : }
4334 0 : for (i = 0; i < fti->count; i++) {
4335 0 : lrec = lfti->entries[i];
4336 0 : rec = &fti->records[i].record;
4337 :
4338 0 : rec->flags = lrec->flags;
4339 0 : rec->timestamp = lrec->time;
4340 0 : rec->type = (enum ForestTrustInfoRecordType)lrec->type;
4341 :
4342 0 : switch (lrec->type) {
4343 0 : case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
4344 : case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4345 0 : tln = &lrec->forest_trust_data.top_level_name;
4346 0 : rec->data.name.string =
4347 0 : talloc_strdup(mem_ctx, tln->string);
4348 0 : if (!rec->data.name.string) {
4349 0 : return NT_STATUS_NO_MEMORY;
4350 : }
4351 0 : rec->data.name.size = strlen(rec->data.name.string);
4352 0 : break;
4353 0 : case LSA_FOREST_TRUST_DOMAIN_INFO:
4354 0 : info = &lrec->forest_trust_data.domain_info;
4355 0 : rec->data.info.sid = *info->domain_sid;
4356 0 : rec->data.info.dns_name.string =
4357 0 : talloc_strdup(mem_ctx,
4358 : info->dns_domain_name.string);
4359 0 : if (!rec->data.info.dns_name.string) {
4360 0 : return NT_STATUS_NO_MEMORY;
4361 : }
4362 0 : rec->data.info.dns_name.size =
4363 0 : strlen(rec->data.info.dns_name.string);
4364 0 : rec->data.info.netbios_name.string =
4365 0 : talloc_strdup(mem_ctx,
4366 : info->netbios_domain_name.string);
4367 0 : if (!rec->data.info.netbios_name.string) {
4368 0 : return NT_STATUS_NO_MEMORY;
4369 : }
4370 0 : rec->data.info.netbios_name.size =
4371 0 : strlen(rec->data.info.netbios_name.string);
4372 0 : break;
4373 0 : default:
4374 0 : return NT_STATUS_INVALID_DOMAIN_STATE;
4375 : }
4376 : }
4377 :
4378 0 : return NT_STATUS_OK;
4379 : }
4380 :
4381 : static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4382 : uint32_t index, uint32_t collision_type,
4383 : uint32_t conflict_type, const char *tdo_name);
4384 :
4385 0 : static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
4386 : const char *tdo_name,
4387 : struct ForestTrustInfo *tdo_fti,
4388 : struct ForestTrustInfo *new_fti,
4389 : struct lsa_ForestTrustCollisionInfo *c_info)
4390 : {
4391 0 : struct ForestTrustInfoRecord *nrec;
4392 0 : struct ForestTrustInfoRecord *trec;
4393 0 : const char *dns_name;
4394 0 : const char *nb_name = NULL;
4395 0 : struct dom_sid *sid = NULL;
4396 0 : const char *tname = NULL;
4397 0 : size_t dns_len = 0;
4398 0 : size_t tlen = 0;
4399 0 : uint32_t new_fti_idx;
4400 0 : uint32_t i;
4401 : /* use always TDO type, until we understand when Xref can be used */
4402 0 : uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
4403 0 : bool tln_conflict;
4404 0 : bool sid_conflict;
4405 0 : bool nb_conflict;
4406 0 : bool exclusion;
4407 0 : bool ex_rule = false;
4408 0 : int ret;
4409 :
4410 0 : for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
4411 :
4412 0 : nrec = &new_fti->records[new_fti_idx].record;
4413 0 : dns_name = NULL;
4414 0 : tln_conflict = false;
4415 0 : sid_conflict = false;
4416 0 : nb_conflict = false;
4417 0 : exclusion = false;
4418 :
4419 0 : switch (nrec->type) {
4420 0 : case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4421 : /* exclusions do not conflict by definition */
4422 0 : break;
4423 :
4424 0 : case FOREST_TRUST_TOP_LEVEL_NAME:
4425 0 : dns_name = nrec->data.name.string;
4426 0 : dns_len = nrec->data.name.size;
4427 0 : break;
4428 :
4429 0 : case LSA_FOREST_TRUST_DOMAIN_INFO:
4430 0 : dns_name = nrec->data.info.dns_name.string;
4431 0 : dns_len = nrec->data.info.dns_name.size;
4432 0 : nb_name = nrec->data.info.netbios_name.string;
4433 0 : sid = &nrec->data.info.sid;
4434 0 : break;
4435 : }
4436 :
4437 0 : if (!dns_name) continue;
4438 :
4439 : /* check if this is already taken and not excluded */
4440 0 : for (i = 0; i < tdo_fti->count; i++) {
4441 0 : trec = &tdo_fti->records[i].record;
4442 :
4443 0 : switch (trec->type) {
4444 0 : case FOREST_TRUST_TOP_LEVEL_NAME:
4445 0 : ex_rule = false;
4446 0 : tname = trec->data.name.string;
4447 0 : tlen = trec->data.name.size;
4448 0 : break;
4449 0 : case FOREST_TRUST_TOP_LEVEL_NAME_EX:
4450 0 : ex_rule = true;
4451 0 : tname = trec->data.name.string;
4452 0 : tlen = trec->data.name.size;
4453 0 : break;
4454 0 : case FOREST_TRUST_DOMAIN_INFO:
4455 0 : ex_rule = false;
4456 0 : tname = trec->data.info.dns_name.string;
4457 0 : tlen = trec->data.info.dns_name.size;
4458 0 : break;
4459 0 : default:
4460 0 : return NT_STATUS_INVALID_PARAMETER;
4461 : }
4462 0 : ret = dns_cmp(dns_name, dns_len, tname, tlen);
4463 0 : switch (ret) {
4464 0 : case DNS_CMP_MATCH:
4465 : /* if it matches exclusion,
4466 : * it doesn't conflict */
4467 0 : if (ex_rule) {
4468 0 : exclusion = true;
4469 0 : break;
4470 : }
4471 :
4472 0 : FALL_THROUGH;
4473 : case DNS_CMP_FIRST_IS_CHILD:
4474 : case DNS_CMP_SECOND_IS_CHILD:
4475 0 : tln_conflict = true;
4476 :
4477 : FALL_THROUGH;
4478 0 : default:
4479 0 : break;
4480 : }
4481 :
4482 : /* explicit exclusion, no dns name conflict here */
4483 0 : if (exclusion) {
4484 0 : tln_conflict = false;
4485 : }
4486 :
4487 0 : if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
4488 0 : continue;
4489 : }
4490 :
4491 : /* also test for domain info */
4492 0 : if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
4493 0 : dom_sid_compare(&trec->data.info.sid, sid) == 0) {
4494 0 : sid_conflict = true;
4495 : }
4496 0 : if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
4497 0 : strcasecmp_m(trec->data.info.netbios_name.string,
4498 : nb_name) == 0) {
4499 0 : nb_conflict = true;
4500 : }
4501 : }
4502 :
4503 0 : if (tln_conflict) {
4504 0 : (void)add_collision(c_info, new_fti_idx,
4505 : collision_type,
4506 : LSA_TLN_DISABLED_CONFLICT,
4507 : tdo_name);
4508 : }
4509 0 : if (sid_conflict) {
4510 0 : (void)add_collision(c_info, new_fti_idx,
4511 : collision_type,
4512 : LSA_SID_DISABLED_CONFLICT,
4513 : tdo_name);
4514 : }
4515 0 : if (nb_conflict) {
4516 0 : (void)add_collision(c_info, new_fti_idx,
4517 : collision_type,
4518 : LSA_NB_DISABLED_CONFLICT,
4519 : tdo_name);
4520 : }
4521 : }
4522 :
4523 0 : return NT_STATUS_OK;
4524 : }
4525 :
4526 0 : static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4527 : uint32_t idx, uint32_t collision_type,
4528 : uint32_t conflict_type, const char *tdo_name)
4529 : {
4530 0 : struct lsa_ForestTrustCollisionRecord **es;
4531 0 : uint32_t i = c_info->count;
4532 :
4533 0 : es = talloc_realloc(c_info, c_info->entries,
4534 : struct lsa_ForestTrustCollisionRecord *, i + 1);
4535 0 : if (!es) {
4536 0 : return NT_STATUS_NO_MEMORY;
4537 : }
4538 0 : c_info->entries = es;
4539 0 : c_info->count = i + 1;
4540 :
4541 0 : es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4542 0 : if (!es[i]) {
4543 0 : return NT_STATUS_NO_MEMORY;
4544 : }
4545 :
4546 0 : es[i]->index = idx;
4547 0 : es[i]->type = collision_type;
4548 0 : es[i]->flags = conflict_type;
4549 0 : es[i]->name.string = talloc_strdup(es[i], tdo_name);
4550 0 : if (!es[i]->name.string) {
4551 0 : return NT_STATUS_NO_MEMORY;
4552 : }
4553 0 : es[i]->name.size = strlen(es[i]->name.string);
4554 :
4555 0 : return NT_STATUS_OK;
4556 : }
4557 :
4558 0 : static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
4559 : struct pdb_trusted_domain *td,
4560 : struct ForestTrustInfo *info)
4561 : {
4562 0 : enum ndr_err_code ndr_err;
4563 :
4564 0 : if (td->trust_forest_trust_info.length == 0 ||
4565 0 : td->trust_forest_trust_info.data == NULL) {
4566 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4567 : }
4568 0 : ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
4569 : info,
4570 : (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
4571 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4572 0 : return NT_STATUS_INVALID_DOMAIN_STATE;
4573 : }
4574 :
4575 0 : return NT_STATUS_OK;
4576 : }
4577 :
4578 0 : static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
4579 : struct ForestTrustInfo *fti)
4580 : {
4581 0 : struct ForestTrustDataDomainInfo *info;
4582 0 : struct ForestTrustInfoRecord *rec;
4583 :
4584 0 : fti->version = 1;
4585 0 : fti->count = 2;
4586 0 : fti->records = talloc_array(fti,
4587 : struct ForestTrustInfoRecordArmor, 2);
4588 0 : if (!fti->records) {
4589 0 : return NT_STATUS_NO_MEMORY;
4590 : }
4591 :
4592 : /* TLN info */
4593 0 : rec = &fti->records[0].record;
4594 :
4595 0 : rec->flags = 0;
4596 0 : rec->timestamp = 0;
4597 0 : rec->type = FOREST_TRUST_TOP_LEVEL_NAME;
4598 :
4599 0 : rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
4600 0 : if (!rec->data.name.string) {
4601 0 : return NT_STATUS_NO_MEMORY;
4602 : }
4603 0 : rec->data.name.size = strlen(rec->data.name.string);
4604 :
4605 : /* DOMAIN info */
4606 0 : rec = &fti->records[1].record;
4607 :
4608 0 : rec->flags = 0;
4609 0 : rec->timestamp = 0;
4610 0 : rec->type = FOREST_TRUST_DOMAIN_INFO;
4611 :
4612 0 : info = &rec->data.info;
4613 :
4614 0 : info->sid = dom_info->sid;
4615 0 : info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
4616 0 : if (!info->dns_name.string) {
4617 0 : return NT_STATUS_NO_MEMORY;
4618 : }
4619 0 : info->dns_name.size = strlen(info->dns_name.string);
4620 0 : info->netbios_name.string = talloc_strdup(fti, dom_info->name);
4621 0 : if (!info->netbios_name.string) {
4622 0 : return NT_STATUS_NO_MEMORY;
4623 : }
4624 0 : info->netbios_name.size = strlen(info->netbios_name.string);
4625 :
4626 0 : return NT_STATUS_OK;
4627 : }
4628 :
4629 0 : NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
4630 : struct lsa_lsaRSetForestTrustInformation *r)
4631 : {
4632 0 : NTSTATUS status;
4633 0 : int i;
4634 0 : int j;
4635 0 : struct lsa_info *handle;
4636 0 : uint32_t num_domains;
4637 0 : struct pdb_trusted_domain **domains;
4638 0 : struct ForestTrustInfo *nfti;
4639 0 : struct ForestTrustInfo *fti;
4640 0 : struct lsa_ForestTrustCollisionInfo *c_info;
4641 0 : struct pdb_domain_info *dom_info;
4642 0 : enum ndr_err_code ndr_err;
4643 :
4644 0 : if (!IS_DC) {
4645 0 : return NT_STATUS_NOT_SUPPORTED;
4646 : }
4647 :
4648 0 : handle = find_policy_by_hnd(p,
4649 : r->in.handle,
4650 : LSA_HANDLE_TRUST_TYPE,
4651 : struct lsa_info,
4652 0 : &status);
4653 0 : if (!NT_STATUS_IS_OK(status)) {
4654 0 : return NT_STATUS_INVALID_HANDLE;
4655 : }
4656 :
4657 0 : if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
4658 0 : return NT_STATUS_ACCESS_DENIED;
4659 : }
4660 :
4661 0 : status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
4662 0 : if (!NT_STATUS_IS_OK(status)) {
4663 0 : return status;
4664 : }
4665 0 : if (num_domains == 0) {
4666 0 : return NT_STATUS_NO_SUCH_DOMAIN;
4667 : }
4668 :
4669 0 : for (i = 0; i < num_domains; i++) {
4670 0 : if (domains[i]->domain_name == NULL) {
4671 0 : return NT_STATUS_INVALID_DOMAIN_STATE;
4672 : }
4673 0 : if (strcasecmp_m(domains[i]->domain_name,
4674 0 : r->in.trusted_domain_name->string) == 0) {
4675 0 : break;
4676 : }
4677 : }
4678 0 : if (i >= num_domains) {
4679 0 : return NT_STATUS_NO_SUCH_DOMAIN;
4680 : }
4681 :
4682 0 : if (!(domains[i]->trust_attributes &
4683 : LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4684 0 : return NT_STATUS_INVALID_PARAMETER;
4685 : }
4686 :
4687 0 : if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4688 0 : return NT_STATUS_INVALID_PARAMETER;
4689 : }
4690 :
4691 : /* The following section until COPY_END is a copy from
4692 : * source4/rpmc_server/lsa/scesrc_lsa.c */
4693 0 : nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
4694 0 : if (!nfti) {
4695 0 : return NT_STATUS_NO_MEMORY;
4696 : }
4697 :
4698 0 : status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4699 0 : if (!NT_STATUS_IS_OK(status)) {
4700 0 : return status;
4701 : }
4702 :
4703 0 : c_info = talloc_zero(r->out.collision_info,
4704 : struct lsa_ForestTrustCollisionInfo);
4705 0 : if (!c_info) {
4706 0 : return NT_STATUS_NO_MEMORY;
4707 : }
4708 :
4709 : /* first check own info, then other domains */
4710 0 : fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4711 0 : if (!fti) {
4712 0 : return NT_STATUS_NO_MEMORY;
4713 : }
4714 :
4715 0 : dom_info = pdb_get_domain_info(p->mem_ctx);
4716 :
4717 0 : status = own_ft_info(dom_info, fti);
4718 0 : if (!NT_STATUS_IS_OK(status)) {
4719 0 : return status;
4720 : }
4721 :
4722 0 : status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
4723 0 : if (!NT_STATUS_IS_OK(status)) {
4724 0 : return status;
4725 : }
4726 :
4727 0 : for (j = 0; j < num_domains; j++) {
4728 0 : fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4729 0 : if (!fti) {
4730 0 : return NT_STATUS_NO_MEMORY;
4731 : }
4732 :
4733 0 : status = get_ft_info(p->mem_ctx, domains[j], fti);
4734 0 : if (!NT_STATUS_IS_OK(status)) {
4735 0 : if (NT_STATUS_EQUAL(status,
4736 : NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4737 0 : continue;
4738 : }
4739 0 : return status;
4740 : }
4741 :
4742 0 : if (domains[j]->domain_name == NULL) {
4743 0 : return NT_STATUS_INVALID_DOMAIN_STATE;
4744 : }
4745 :
4746 0 : status = check_ft_info(c_info, domains[j]->domain_name,
4747 : fti, nfti, c_info);
4748 0 : if (!NT_STATUS_IS_OK(status)) {
4749 0 : return status;
4750 : }
4751 : }
4752 :
4753 0 : if (c_info->count != 0) {
4754 0 : *r->out.collision_info = c_info;
4755 : }
4756 :
4757 0 : if (r->in.check_only != 0) {
4758 0 : return NT_STATUS_OK;
4759 : }
4760 :
4761 : /* COPY_END */
4762 :
4763 0 : ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
4764 : p->mem_ctx, nfti,
4765 : (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4766 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4767 0 : return NT_STATUS_INVALID_PARAMETER;
4768 : }
4769 :
4770 0 : status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
4771 0 : if (!NT_STATUS_IS_OK(status)) {
4772 0 : return status;
4773 : }
4774 :
4775 0 : return NT_STATUS_OK;
4776 : }
4777 :
4778 0 : NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
4779 : struct lsa_CREDRRENAME *r)
4780 : {
4781 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4782 0 : return NT_STATUS_NOT_IMPLEMENTED;
4783 : }
4784 :
4785 0 : NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
4786 : struct lsa_LSAROPENPOLICYSCE *r)
4787 : {
4788 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4789 0 : return NT_STATUS_NOT_IMPLEMENTED;
4790 : }
4791 :
4792 0 : NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4793 : struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4794 : {
4795 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4796 0 : return NT_STATUS_NOT_IMPLEMENTED;
4797 : }
4798 :
4799 0 : NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4800 : struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4801 : {
4802 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4803 0 : return NT_STATUS_NOT_IMPLEMENTED;
4804 : }
4805 :
4806 0 : NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4807 : struct lsa_LSARADTREPORTSECURITYEVENT *r)
4808 : {
4809 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4810 0 : return NT_STATUS_NOT_IMPLEMENTED;
4811 : }
4812 :
4813 : #include "librpc/rpc/dcesrv_core.h"
4814 :
4815 : #define DCESRV_INTERFACE_LSARPC_BIND(context, iface) \
4816 : dcesrv_interface_lsarpc_bind(context, iface)
4817 :
4818 2290 : static NTSTATUS dcesrv_interface_lsarpc_bind(
4819 : struct dcesrv_connection_context *context,
4820 : const struct dcesrv_interface *iface)
4821 : {
4822 2290 : return dcesrv_interface_bind_reject_connect(context, iface);
4823 : }
4824 :
4825 : static NTSTATUS lsarpc__op_init_server(struct dcesrv_context *dce_ctx,
4826 : const struct dcesrv_endpoint_server *ep_server);
4827 : static const struct dcesrv_interface dcesrv_lsarpc_interface;
4828 :
4829 : #define NCACN_NP_PIPE_NETLOGON "ncacn_np:[\\pipe\\netlogon]"
4830 : #define NCACN_NP_PIPE_LSASS "ncacn_np:[\\pipe\\lsass]"
4831 :
4832 : #define DCESRV_INTERFACE_LSARPC_NCACN_NP_SECONDARY_ENDPOINT \
4833 : NCACN_NP_PIPE_LSASS
4834 :
4835 : #define DCESRV_INTERFACE_LSARPC_INIT_SERVER \
4836 : dcesrv_interface_lsarpc_init_server
4837 :
4838 206 : static NTSTATUS dcesrv_interface_lsarpc_init_server(
4839 : struct dcesrv_context *dce_ctx,
4840 : const struct dcesrv_endpoint_server *ep_server)
4841 : {
4842 206 : NTSTATUS ret = dcesrv_interface_register(dce_ctx,
4843 : NCACN_NP_PIPE_NETLOGON,
4844 : NCACN_NP_PIPE_LSASS,
4845 : &dcesrv_lsarpc_interface,
4846 : NULL);
4847 206 : if (!NT_STATUS_IS_OK(ret)) {
4848 0 : DBG_ERR("Failed to register endpoint "
4849 : "'\\pipe\\netlogon'\n");
4850 0 : return ret;
4851 : }
4852 :
4853 206 : return lsarpc__op_init_server(dce_ctx, ep_server);
4854 : }
4855 :
4856 : /* include the generated boilerplate */
4857 : #include "librpc/gen_ndr/ndr_lsa_scompat.c"
|