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