s3-lsarpc: Restrict lsa_LookupSids3 to ncacn_ip_tcp connections.
[Samba/gbeck.git] / source3 / rpc_server / lsa / srv_lsa_nt.c
blobd74ed73fddf7d970e6957517d1533fc450b735e9
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.
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.
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.
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/>.
30 /* This is the implementation of the lsa server code. */
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 "../lib/crypto/arcfour.h"
43 #include "../libcli/security/dom_sid.h"
44 #include "../librpc/gen_ndr/ndr_security.h"
45 #include "passdb.h"
46 #include "auth.h"
47 #include "lib/privileges.h"
48 #include "rpc_server/srv_access_check.h"
49 #include "../librpc/gen_ndr/ndr_wkssvc.h"
50 #include "../libcli/auth/libcli_auth.h"
51 #include "../libcli/lsarpc/util_lsarpc.h"
53 #undef DBGC_CLASS
54 #define DBGC_CLASS DBGC_RPC_SRV
56 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
58 enum lsa_handle_type {
59 LSA_HANDLE_POLICY_TYPE = 1,
60 LSA_HANDLE_ACCOUNT_TYPE = 2,
61 LSA_HANDLE_TRUST_TYPE = 3,
62 LSA_HANDLE_SECRET_TYPE = 4};
64 struct lsa_info {
65 struct dom_sid sid;
66 const char *name;
67 uint32 access;
68 enum lsa_handle_type type;
69 struct security_descriptor *sd;
72 const struct generic_mapping lsa_account_mapping = {
73 LSA_ACCOUNT_READ,
74 LSA_ACCOUNT_WRITE,
75 LSA_ACCOUNT_EXECUTE,
76 LSA_ACCOUNT_ALL_ACCESS
79 const struct generic_mapping lsa_policy_mapping = {
80 LSA_POLICY_READ,
81 LSA_POLICY_WRITE,
82 LSA_POLICY_EXECUTE,
83 LSA_POLICY_ALL_ACCESS
86 const struct generic_mapping lsa_secret_mapping = {
87 LSA_SECRET_READ,
88 LSA_SECRET_WRITE,
89 LSA_SECRET_EXECUTE,
90 LSA_SECRET_ALL_ACCESS
93 const struct generic_mapping lsa_trusted_domain_mapping = {
94 LSA_TRUSTED_DOMAIN_READ,
95 LSA_TRUSTED_DOMAIN_WRITE,
96 LSA_TRUSTED_DOMAIN_EXECUTE,
97 LSA_TRUSTED_DOMAIN_ALL_ACCESS
100 /***************************************************************************
101 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
102 ***************************************************************************/
104 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
105 struct lsa_RefDomainList *ref,
106 const char *dom_name,
107 struct dom_sid *dom_sid)
109 int num = 0;
111 if (dom_name != NULL) {
112 for (num = 0; num < ref->count; num++) {
113 if (dom_sid_equal(dom_sid, ref->domains[num].sid)) {
114 return num;
117 } else {
118 num = ref->count;
121 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
122 /* index not found, already at maximum domain limit */
123 return -1;
126 ref->count = num + 1;
127 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
129 ref->domains = talloc_realloc(mem_ctx, ref->domains,
130 struct lsa_DomainInfo, ref->count);
131 if (!ref->domains) {
132 return -1;
135 ZERO_STRUCT(ref->domains[num]);
137 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
138 ref->domains[num].sid = dom_sid_dup(mem_ctx, dom_sid);
139 if (!ref->domains[num].sid) {
140 return -1;
143 return num;
147 /***************************************************************************
148 initialize a lsa_DomainInfo structure.
149 ***************************************************************************/
151 static void init_dom_query_3(struct lsa_DomainInfo *r,
152 const char *name,
153 struct dom_sid *sid)
155 init_lsa_StringLarge(&r->name, name);
156 r->sid = sid;
159 /***************************************************************************
160 initialize a lsa_DomainInfo structure.
161 ***************************************************************************/
163 static void init_dom_query_5(struct lsa_DomainInfo *r,
164 const char *name,
165 struct dom_sid *sid)
167 init_lsa_StringLarge(&r->name, name);
168 r->sid = sid;
171 /***************************************************************************
172 lookup_lsa_rids. Must be called as root for lookup_name to work.
173 ***************************************************************************/
175 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
176 struct lsa_RefDomainList *ref,
177 struct lsa_TranslatedSid *prid,
178 uint32_t num_entries,
179 struct lsa_String *name,
180 int flags,
181 uint32_t *pmapped_count)
183 uint32 mapped_count, i;
185 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
187 mapped_count = 0;
188 *pmapped_count = 0;
190 for (i = 0; i < num_entries; i++) {
191 struct dom_sid sid;
192 uint32 rid;
193 int dom_idx;
194 const char *full_name;
195 const char *domain;
196 enum lsa_SidType type;
198 /* Split name into domain and user component */
200 /* follow w2k8 behavior and return the builtin domain when no
201 * input has been passed in */
203 if (name[i].string) {
204 full_name = name[i].string;
205 } else {
206 full_name = "BUILTIN";
209 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
211 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
212 &sid, &type)) {
213 type = SID_NAME_UNKNOWN;
216 switch (type) {
217 case SID_NAME_USER:
218 case SID_NAME_DOM_GRP:
219 case SID_NAME_DOMAIN:
220 case SID_NAME_ALIAS:
221 case SID_NAME_WKN_GRP:
222 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
223 /* Leave these unchanged */
224 break;
225 default:
226 /* Don't hand out anything but the list above */
227 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
228 type = SID_NAME_UNKNOWN;
229 break;
232 rid = 0;
233 dom_idx = -1;
235 if (type != SID_NAME_UNKNOWN) {
236 if (type == SID_NAME_DOMAIN) {
237 rid = (uint32_t)-1;
238 } else {
239 sid_split_rid(&sid, &rid);
241 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
242 mapped_count++;
245 prid[i].sid_type = type;
246 prid[i].rid = rid;
247 prid[i].sid_index = dom_idx;
250 *pmapped_count = mapped_count;
251 return NT_STATUS_OK;
254 /***************************************************************************
255 lookup_lsa_sids. Must be called as root for lookup_name to work.
256 ***************************************************************************/
258 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
259 struct lsa_RefDomainList *ref,
260 struct lsa_TranslatedSid3 *trans_sids,
261 uint32_t num_entries,
262 struct lsa_String *name,
263 int flags,
264 uint32 *pmapped_count)
266 uint32 mapped_count, i;
268 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
270 mapped_count = 0;
271 *pmapped_count = 0;
273 for (i = 0; i < num_entries; i++) {
274 struct dom_sid sid;
275 uint32 rid;
276 int dom_idx;
277 const char *full_name;
278 const char *domain;
279 enum lsa_SidType type;
281 ZERO_STRUCT(sid);
283 /* Split name into domain and user component */
285 full_name = name[i].string;
286 if (full_name == NULL) {
287 return NT_STATUS_NO_MEMORY;
290 DEBUG(5, ("lookup_lsa_sids: looking up name %s\n", full_name));
292 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
293 &sid, &type)) {
294 type = SID_NAME_UNKNOWN;
297 switch (type) {
298 case SID_NAME_USER:
299 case SID_NAME_DOM_GRP:
300 case SID_NAME_DOMAIN:
301 case SID_NAME_ALIAS:
302 case SID_NAME_WKN_GRP:
303 DEBUG(5, ("lookup_lsa_sids: %s found\n", full_name));
304 /* Leave these unchanged */
305 break;
306 default:
307 /* Don't hand out anything but the list above */
308 DEBUG(5, ("lookup_lsa_sids: %s not found\n", full_name));
309 type = SID_NAME_UNKNOWN;
310 break;
313 rid = 0;
314 dom_idx = -1;
316 if (type != SID_NAME_UNKNOWN) {
317 struct dom_sid domain_sid;
318 sid_copy(&domain_sid, &sid);
319 sid_split_rid(&domain_sid, &rid);
320 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
321 mapped_count++;
324 /* Initialize the lsa_TranslatedSid3 return. */
325 trans_sids[i].sid_type = type;
326 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
327 trans_sids[i].sid_index = dom_idx;
330 *pmapped_count = mapped_count;
331 return NT_STATUS_OK;
334 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
335 const struct generic_mapping *map,
336 struct dom_sid *sid, uint32_t sid_access)
338 struct dom_sid adm_sid;
339 struct security_ace ace[5];
340 size_t i = 0;
342 struct security_acl *psa = NULL;
344 /* READ|EXECUTE access for Everyone */
346 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
347 map->generic_execute | map->generic_read, 0);
349 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
351 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
352 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
353 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
354 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
356 /* Add Full Access for Domain Admins */
357 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
358 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
359 map->generic_all, 0);
361 /* If we have a sid, give it some special access */
363 if (sid) {
364 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
365 sid_access, 0);
368 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
369 return NT_STATUS_NO_MEMORY;
371 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
372 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
373 psa, sd_size)) == NULL)
374 return NT_STATUS_NO_MEMORY;
376 return NT_STATUS_OK;
379 /***************************************************************************
380 ***************************************************************************/
382 static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
383 struct pipes_struct *p,
384 enum lsa_handle_type type,
385 uint32_t acc_granted,
386 struct dom_sid *sid,
387 const char *name,
388 const struct security_descriptor *sd,
389 struct policy_handle *handle)
391 struct lsa_info *info;
393 ZERO_STRUCTP(handle);
395 info = talloc_zero(mem_ctx, struct lsa_info);
396 if (!info) {
397 return NT_STATUS_NO_MEMORY;
400 info->type = type;
401 info->access = acc_granted;
403 if (sid) {
404 sid_copy(&info->sid, sid);
407 info->name = talloc_strdup(info, name);
409 if (sd) {
410 info->sd = dup_sec_desc(info, sd);
411 if (!info->sd) {
412 talloc_free(info);
413 return NT_STATUS_NO_MEMORY;
417 if (!create_policy_hnd(p, handle, info)) {
418 talloc_free(info);
419 ZERO_STRUCTP(handle);
420 return NT_STATUS_NO_MEMORY;
423 return NT_STATUS_OK;
426 /***************************************************************************
427 _lsa_OpenPolicy2
428 ***************************************************************************/
430 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
431 struct lsa_OpenPolicy2 *r)
433 struct security_descriptor *psd = NULL;
434 size_t sd_size;
435 uint32 des_access = r->in.access_mask;
436 uint32 acc_granted;
437 NTSTATUS status;
439 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
440 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
441 return NT_STATUS_ACCESS_DENIED;
444 /* Work out max allowed. */
445 map_max_allowed_access(p->session_info->security_token,
446 p->session_info->unix_token,
447 &des_access);
449 /* map the generic bits to the lsa policy ones */
450 se_map_generic(&des_access, &lsa_policy_mapping);
452 /* get the generic lsa policy SD until we store it */
453 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
454 NULL, 0);
455 if (!NT_STATUS_IS_OK(status)) {
456 return status;
459 status = access_check_object(psd, p->session_info->security_token,
460 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
461 &acc_granted, "_lsa_OpenPolicy2" );
462 if (!NT_STATUS_IS_OK(status)) {
463 return status;
466 status = create_lsa_policy_handle(p->mem_ctx, p,
467 LSA_HANDLE_POLICY_TYPE,
468 acc_granted,
469 get_global_sam_sid(),
470 NULL,
471 psd,
472 r->out.handle);
473 if (!NT_STATUS_IS_OK(status)) {
474 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
477 return NT_STATUS_OK;
480 /***************************************************************************
481 _lsa_OpenPolicy
482 ***************************************************************************/
484 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
485 struct lsa_OpenPolicy *r)
487 struct lsa_OpenPolicy2 o;
489 /* _lsa_OpenPolicy2 will check if this is a NCACN_NP connection */
491 o.in.system_name = NULL; /* should be ignored */
492 o.in.attr = r->in.attr;
493 o.in.access_mask = r->in.access_mask;
495 o.out.handle = r->out.handle;
497 return _lsa_OpenPolicy2(p, &o);
500 /***************************************************************************
501 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
502 ufff, done :) mimir
503 ***************************************************************************/
505 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
506 struct lsa_EnumTrustDom *r)
508 struct lsa_info *info;
509 uint32_t count;
510 struct trustdom_info **domains;
511 struct lsa_DomainInfo *entries;
512 int i;
513 NTSTATUS nt_status;
515 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
516 return NT_STATUS_INVALID_HANDLE;
518 if (info->type != LSA_HANDLE_POLICY_TYPE) {
519 return NT_STATUS_INVALID_HANDLE;
522 /* check if the user has enough rights */
523 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
524 return NT_STATUS_ACCESS_DENIED;
526 become_root();
527 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
528 unbecome_root();
530 if (!NT_STATUS_IS_OK(nt_status)) {
531 return nt_status;
534 entries = talloc_zero_array(p->mem_ctx, struct lsa_DomainInfo, count);
535 if (!entries) {
536 return NT_STATUS_NO_MEMORY;
539 for (i=0; i<count; i++) {
540 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
541 entries[i].sid = &domains[i]->sid;
544 if (*r->in.resume_handle >= count) {
545 *r->out.resume_handle = -1;
546 TALLOC_FREE(entries);
547 return NT_STATUS_NO_MORE_ENTRIES;
550 /* return the rest, limit by max_size. Note that we
551 use the w2k3 element size value of 60 */
552 r->out.domains->count = count - *r->in.resume_handle;
553 r->out.domains->count = MIN(r->out.domains->count,
554 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
556 r->out.domains->domains = entries + *r->in.resume_handle;
558 if (r->out.domains->count < count - *r->in.resume_handle) {
559 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
560 return STATUS_MORE_ENTRIES;
563 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
564 * always be larger than the previous input resume handle, in
565 * particular when hitting the last query it is vital to set the
566 * resume handle correctly to avoid infinite client loops, as
567 * seen e.g. with Windows XP SP3 when resume handle is 0 and
568 * status is NT_STATUS_OK - gd */
570 *r->out.resume_handle = (uint32_t)-1;
572 return NT_STATUS_OK;
575 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
576 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
577 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
579 /***************************************************************************
580 _lsa_QueryInfoPolicy
581 ***************************************************************************/
583 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
584 struct lsa_QueryInfoPolicy *r)
586 NTSTATUS status = NT_STATUS_OK;
587 struct lsa_info *handle;
588 struct dom_sid domain_sid;
589 const char *name;
590 struct dom_sid *sid = NULL;
591 union lsa_PolicyInformation *info = NULL;
592 uint32_t acc_required = 0;
594 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
595 return NT_STATUS_INVALID_HANDLE;
597 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
598 return NT_STATUS_INVALID_HANDLE;
601 switch (r->in.level) {
602 case LSA_POLICY_INFO_AUDIT_LOG:
603 case LSA_POLICY_INFO_AUDIT_EVENTS:
604 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
605 break;
606 case LSA_POLICY_INFO_DOMAIN:
607 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
608 break;
609 case LSA_POLICY_INFO_PD:
610 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
611 break;
612 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
613 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
614 break;
615 case LSA_POLICY_INFO_ROLE:
616 case LSA_POLICY_INFO_REPLICA:
617 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
618 break;
619 case LSA_POLICY_INFO_QUOTA:
620 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
621 break;
622 case LSA_POLICY_INFO_MOD:
623 case LSA_POLICY_INFO_AUDIT_FULL_SET:
624 /* according to MS-LSAD 3.1.4.4.3 */
625 return NT_STATUS_INVALID_PARAMETER;
626 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
627 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
628 break;
629 case LSA_POLICY_INFO_DNS:
630 case LSA_POLICY_INFO_DNS_INT:
631 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
632 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
633 break;
634 default:
635 break;
638 if (!(handle->access & acc_required)) {
639 /* return NT_STATUS_ACCESS_DENIED; */
642 info = talloc_zero(p->mem_ctx, union lsa_PolicyInformation);
643 if (!info) {
644 return NT_STATUS_NO_MEMORY;
647 switch (r->in.level) {
648 /* according to MS-LSAD 3.1.4.4.3 */
649 case LSA_POLICY_INFO_MOD:
650 case LSA_POLICY_INFO_AUDIT_FULL_SET:
651 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
652 return NT_STATUS_INVALID_PARAMETER;
653 case LSA_POLICY_INFO_AUDIT_LOG:
654 info->audit_log.percent_full = 0;
655 info->audit_log.maximum_log_size = 0;
656 info->audit_log.retention_time = 0;
657 info->audit_log.shutdown_in_progress = 0;
658 info->audit_log.time_to_shutdown = 0;
659 info->audit_log.next_audit_record = 0;
660 status = NT_STATUS_OK;
661 break;
662 case LSA_POLICY_INFO_PD:
663 info->pd.name.string = NULL;
664 status = NT_STATUS_OK;
665 break;
666 case LSA_POLICY_INFO_REPLICA:
667 info->replica.source.string = NULL;
668 info->replica.account.string = NULL;
669 status = NT_STATUS_OK;
670 break;
671 case LSA_POLICY_INFO_QUOTA:
672 info->quota.paged_pool = 0;
673 info->quota.non_paged_pool = 0;
674 info->quota.min_wss = 0;
675 info->quota.max_wss = 0;
676 info->quota.pagefile = 0;
677 info->quota.unknown = 0;
678 status = NT_STATUS_OK;
679 break;
680 case LSA_POLICY_INFO_AUDIT_EVENTS:
683 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
685 /* check if the user has enough rights */
686 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
687 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
688 return NT_STATUS_ACCESS_DENIED;
691 /* fake info: We audit everything. ;) */
693 info->audit_events.auditing_mode = true;
694 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
695 info->audit_events.settings = talloc_zero_array(p->mem_ctx,
696 enum lsa_PolicyAuditPolicy,
697 info->audit_events.count);
698 if (!info->audit_events.settings) {
699 return NT_STATUS_NO_MEMORY;
702 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
703 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
704 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
705 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
706 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
707 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
708 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
710 break;
712 case LSA_POLICY_INFO_DOMAIN:
713 /* check if the user has enough rights */
714 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
715 return NT_STATUS_ACCESS_DENIED;
717 /* Request PolicyPrimaryDomainInformation. */
718 switch (lp_server_role()) {
719 case ROLE_DOMAIN_PDC:
720 case ROLE_DOMAIN_BDC:
721 name = get_global_sam_name();
722 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
723 if (!sid) {
724 return NT_STATUS_NO_MEMORY;
726 break;
727 case ROLE_DOMAIN_MEMBER:
728 name = lp_workgroup();
729 /* We need to return the Domain SID here. */
730 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
731 sid = dom_sid_dup(p->mem_ctx, &domain_sid);
732 if (!sid) {
733 return NT_STATUS_NO_MEMORY;
735 } else {
736 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
738 break;
739 case ROLE_STANDALONE:
740 name = lp_workgroup();
741 sid = NULL;
742 break;
743 default:
744 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
746 init_dom_query_3(&info->domain, name, sid);
747 break;
748 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
749 /* check if the user has enough rights */
750 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
751 return NT_STATUS_ACCESS_DENIED;
753 /* Request PolicyAccountDomainInformation. */
754 name = get_global_sam_name();
755 sid = get_global_sam_sid();
757 init_dom_query_5(&info->account_domain, name, sid);
758 break;
759 case LSA_POLICY_INFO_ROLE:
760 /* check if the user has enough rights */
761 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
762 return NT_STATUS_ACCESS_DENIED;
764 switch (lp_server_role()) {
765 case ROLE_DOMAIN_BDC:
767 * only a BDC is a backup controller
768 * of the domain, it controls.
770 info->role.role = LSA_ROLE_BACKUP;
771 break;
772 default:
774 * any other role is a primary
775 * of the domain, it controls.
777 info->role.role = LSA_ROLE_PRIMARY;
778 break;
780 break;
781 case LSA_POLICY_INFO_DNS:
782 case LSA_POLICY_INFO_DNS_INT: {
783 struct pdb_domain_info *dominfo;
785 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
786 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
787 "without ADS passdb backend\n"));
788 status = NT_STATUS_INVALID_INFO_CLASS;
789 break;
792 dominfo = pdb_get_domain_info(info);
793 if (dominfo == NULL) {
794 status = NT_STATUS_NO_MEMORY;
795 break;
798 init_lsa_StringLarge(&info->dns.name,
799 dominfo->name);
800 init_lsa_StringLarge(&info->dns.dns_domain,
801 dominfo->dns_domain);
802 init_lsa_StringLarge(&info->dns.dns_forest,
803 dominfo->dns_forest);
804 info->dns.domain_guid = dominfo->guid;
805 info->dns.sid = &dominfo->sid;
806 break;
808 default:
809 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
810 r->in.level));
811 status = NT_STATUS_INVALID_INFO_CLASS;
812 break;
815 *r->out.info = info;
817 return status;
820 /***************************************************************************
821 _lsa_QueryInfoPolicy2
822 ***************************************************************************/
824 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
825 struct lsa_QueryInfoPolicy2 *r2)
827 struct lsa_QueryInfoPolicy r;
829 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
830 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
831 return NT_STATUS_NOT_IMPLEMENTED;
834 ZERO_STRUCT(r);
835 r.in.handle = r2->in.handle;
836 r.in.level = r2->in.level;
837 r.out.info = r2->out.info;
839 return _lsa_QueryInfoPolicy(p, &r);
842 /***************************************************************************
843 _lsa_lookup_sids_internal
844 ***************************************************************************/
846 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
847 TALLOC_CTX *mem_ctx,
848 uint16_t level, /* input */
849 int num_sids, /* input */
850 struct lsa_SidPtr *sid, /* input */
851 struct lsa_RefDomainList **pp_ref, /* input/output */
852 struct lsa_TranslatedName2 **pp_names,/* input/output */
853 uint32_t *pp_mapped_count) /* input/output */
855 NTSTATUS status;
856 int i;
857 const struct dom_sid **sids = NULL;
858 struct lsa_RefDomainList *ref = NULL;
859 uint32 mapped_count = 0;
860 struct lsa_dom_info *dom_infos = NULL;
861 struct lsa_name_info *name_infos = NULL;
862 struct lsa_TranslatedName2 *names = NULL;
864 *pp_mapped_count = 0;
865 *pp_names = NULL;
866 *pp_ref = NULL;
868 if (num_sids == 0) {
869 return NT_STATUS_OK;
872 sids = talloc_array(p->mem_ctx, const struct dom_sid *, num_sids);
873 ref = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
875 if (sids == NULL || ref == NULL) {
876 return NT_STATUS_NO_MEMORY;
879 for (i=0; i<num_sids; i++) {
880 sids[i] = sid[i].sid;
883 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
884 &dom_infos, &name_infos);
886 if (!NT_STATUS_IS_OK(status)) {
887 return status;
890 names = talloc_array(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
891 if (names == NULL) {
892 return NT_STATUS_NO_MEMORY;
895 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
897 if (!dom_infos[i].valid) {
898 break;
901 if (init_lsa_ref_domain_list(mem_ctx, ref,
902 dom_infos[i].name,
903 &dom_infos[i].sid) != i) {
904 DEBUG(0, ("Domain %s mentioned twice??\n",
905 dom_infos[i].name));
906 return NT_STATUS_INTERNAL_ERROR;
910 for (i=0; i<num_sids; i++) {
911 struct lsa_name_info *name = &name_infos[i];
913 if (name->type == SID_NAME_UNKNOWN) {
914 name->dom_idx = -1;
915 /* Unknown sids should return the string
916 * representation of the SID. Windows 2003 behaves
917 * rather erratic here, in many cases it returns the
918 * RID as 8 bytes hex, in others it returns the full
919 * SID. We (Jerry/VL) could not figure out which the
920 * hard cases are, so leave it with the SID. */
921 name->name = dom_sid_string(p->mem_ctx, sids[i]);
922 if (name->name == NULL) {
923 return NT_STATUS_NO_MEMORY;
925 } else {
926 mapped_count += 1;
929 names[i].sid_type = name->type;
930 names[i].name.string = name->name;
931 names[i].sid_index = name->dom_idx;
932 names[i].unknown = 0;
935 status = NT_STATUS_NONE_MAPPED;
936 if (mapped_count > 0) {
937 status = (mapped_count < num_sids) ?
938 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
941 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
942 num_sids, mapped_count, nt_errstr(status)));
944 *pp_mapped_count = mapped_count;
945 *pp_names = names;
946 *pp_ref = ref;
948 return status;
951 /***************************************************************************
952 _lsa_LookupSids
953 ***************************************************************************/
955 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
956 struct lsa_LookupSids *r)
958 NTSTATUS status;
959 struct lsa_info *handle;
960 int num_sids = r->in.sids->num_sids;
961 uint32 mapped_count = 0;
962 struct lsa_RefDomainList *domains = NULL;
963 struct lsa_TranslatedName *names_out = NULL;
964 struct lsa_TranslatedName2 *names = NULL;
965 int i;
967 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
968 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
969 return NT_STATUS_ACCESS_DENIED;
972 if ((r->in.level < 1) || (r->in.level > 6)) {
973 return NT_STATUS_INVALID_PARAMETER;
976 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
977 return NT_STATUS_INVALID_HANDLE;
980 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
981 return NT_STATUS_INVALID_HANDLE;
984 /* check if the user has enough rights */
985 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
986 return NT_STATUS_ACCESS_DENIED;
989 if (num_sids > MAX_LOOKUP_SIDS) {
990 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
991 MAX_LOOKUP_SIDS, num_sids));
992 return NT_STATUS_NONE_MAPPED;
995 status = _lsa_lookup_sids_internal(p,
996 p->mem_ctx,
997 r->in.level,
998 num_sids,
999 r->in.sids->sids,
1000 &domains,
1001 &names,
1002 &mapped_count);
1004 /* Only return here when there is a real error.
1005 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
1006 the requested sids could be resolved. Older versions of XP (pre SP3)
1007 rely that we return with the string representations of those SIDs in
1008 that case. If we don't, XP crashes - Guenther
1011 if (NT_STATUS_IS_ERR(status) &&
1012 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1013 return status;
1016 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
1017 names_out = talloc_array(p->mem_ctx, struct lsa_TranslatedName,
1018 num_sids);
1019 if (!names_out) {
1020 return NT_STATUS_NO_MEMORY;
1023 for (i=0; i<num_sids; i++) {
1024 names_out[i].sid_type = names[i].sid_type;
1025 names_out[i].name = names[i].name;
1026 names_out[i].sid_index = names[i].sid_index;
1029 *r->out.domains = domains;
1030 r->out.names->count = num_sids;
1031 r->out.names->names = names_out;
1032 *r->out.count = mapped_count;
1034 return status;
1037 static NTSTATUS _lsa_LookupSids_common(struct pipes_struct *p,
1038 struct lsa_LookupSids2 *r)
1040 NTSTATUS status;
1041 struct lsa_info *handle;
1042 int num_sids = r->in.sids->num_sids;
1043 uint32 mapped_count = 0;
1044 struct lsa_RefDomainList *domains = NULL;
1045 struct lsa_TranslatedName2 *names = NULL;
1046 bool check_policy = true;
1048 switch (p->opnum) {
1049 case NDR_LSA_LOOKUPSIDS3:
1050 check_policy = false;
1051 break;
1052 case NDR_LSA_LOOKUPSIDS2:
1053 default:
1054 check_policy = true;
1057 if ((r->in.level < 1) || (r->in.level > 6)) {
1058 return NT_STATUS_INVALID_PARAMETER;
1061 if (check_policy) {
1062 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1063 return NT_STATUS_INVALID_HANDLE;
1066 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1067 return NT_STATUS_INVALID_HANDLE;
1070 /* check if the user has enough rights */
1071 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1072 return NT_STATUS_ACCESS_DENIED;
1076 if (num_sids > MAX_LOOKUP_SIDS) {
1077 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1078 MAX_LOOKUP_SIDS, num_sids));
1079 return NT_STATUS_NONE_MAPPED;
1082 status = _lsa_lookup_sids_internal(p,
1083 p->mem_ctx,
1084 r->in.level,
1085 num_sids,
1086 r->in.sids->sids,
1087 &domains,
1088 &names,
1089 &mapped_count);
1091 *r->out.domains = domains;
1092 r->out.names->count = num_sids;
1093 r->out.names->names = names;
1094 *r->out.count = mapped_count;
1096 return status;
1099 /***************************************************************************
1100 _lsa_LookupSids2
1101 ***************************************************************************/
1103 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1104 struct lsa_LookupSids2 *r)
1106 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1107 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1108 return NT_STATUS_ACCESS_DENIED;
1111 return _lsa_LookupSids_common(p, r);
1114 /***************************************************************************
1115 _lsa_LookupSids3
1116 ***************************************************************************/
1118 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1119 struct lsa_LookupSids3 *r)
1121 struct lsa_LookupSids2 q;
1123 if (p->transport != NCACN_IP_TCP) {
1124 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1125 return NT_STATUS_ACCESS_DENIED;
1128 /* No policy handle on this call. Restrict to crypto connections. */
1129 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1130 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1131 get_remote_machine_name() ));
1132 return NT_STATUS_INVALID_PARAMETER;
1135 q.in.handle = NULL;
1136 q.in.sids = r->in.sids;
1137 q.in.level = r->in.level;
1138 q.in.lookup_options = r->in.lookup_options;
1139 q.in.client_revision = r->in.client_revision;
1140 q.in.names = r->in.names;
1141 q.in.count = r->in.count;
1143 q.out.domains = r->out.domains;
1144 q.out.names = r->out.names;
1145 q.out.count = r->out.count;
1147 return _lsa_LookupSids_common(p, &q);
1150 /***************************************************************************
1151 ***************************************************************************/
1153 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1155 int flags;
1157 switch (level) {
1158 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1159 flags = LOOKUP_NAME_ALL;
1160 break;
1161 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1162 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1163 break;
1164 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1165 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1166 break;
1167 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1168 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1169 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1170 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1171 default:
1172 flags = LOOKUP_NAME_NONE;
1173 break;
1176 return flags;
1179 /***************************************************************************
1180 _lsa_LookupNames
1181 ***************************************************************************/
1183 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1184 struct lsa_LookupNames *r)
1186 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1187 struct lsa_info *handle;
1188 struct lsa_String *names = r->in.names;
1189 uint32 num_entries = r->in.num_names;
1190 struct lsa_RefDomainList *domains = NULL;
1191 struct lsa_TranslatedSid *rids = NULL;
1192 uint32 mapped_count = 0;
1193 int flags = 0;
1195 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1196 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1197 return NT_STATUS_ACCESS_DENIED;
1200 if (num_entries > MAX_LOOKUP_SIDS) {
1201 num_entries = MAX_LOOKUP_SIDS;
1202 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1203 num_entries));
1206 flags = lsa_lookup_level_to_flags(r->in.level);
1208 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1209 if (!domains) {
1210 return NT_STATUS_NO_MEMORY;
1213 if (num_entries) {
1214 rids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid,
1215 num_entries);
1216 if (!rids) {
1217 return NT_STATUS_NO_MEMORY;
1219 } else {
1220 rids = NULL;
1223 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1224 status = NT_STATUS_INVALID_HANDLE;
1225 goto done;
1228 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1229 return NT_STATUS_INVALID_HANDLE;
1232 /* check if the user has enough rights */
1233 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1234 status = NT_STATUS_ACCESS_DENIED;
1235 goto done;
1238 /* set up the LSA Lookup RIDs response */
1239 become_root(); /* lookup_name can require root privs */
1240 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1241 names, flags, &mapped_count);
1242 unbecome_root();
1244 done:
1246 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1247 if (mapped_count == 0) {
1248 status = NT_STATUS_NONE_MAPPED;
1249 } else if (mapped_count != num_entries) {
1250 status = STATUS_SOME_UNMAPPED;
1254 *r->out.count = mapped_count;
1255 *r->out.domains = domains;
1256 r->out.sids->sids = rids;
1257 r->out.sids->count = num_entries;
1259 return status;
1262 /***************************************************************************
1263 _lsa_LookupNames2
1264 ***************************************************************************/
1266 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1267 struct lsa_LookupNames2 *r)
1269 NTSTATUS status;
1270 struct lsa_LookupNames q;
1271 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1272 struct lsa_TransSidArray *sid_array = NULL;
1273 uint32_t i;
1275 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1276 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1277 return NT_STATUS_ACCESS_DENIED;
1280 sid_array = talloc_zero(p->mem_ctx, struct lsa_TransSidArray);
1281 if (!sid_array) {
1282 return NT_STATUS_NO_MEMORY;
1285 q.in.handle = r->in.handle;
1286 q.in.num_names = r->in.num_names;
1287 q.in.names = r->in.names;
1288 q.in.level = r->in.level;
1289 q.in.sids = sid_array;
1290 q.in.count = r->in.count;
1291 /* we do not know what this is for */
1292 /* = r->in.unknown1; */
1293 /* = r->in.unknown2; */
1295 q.out.domains = r->out.domains;
1296 q.out.sids = sid_array;
1297 q.out.count = r->out.count;
1299 status = _lsa_LookupNames(p, &q);
1301 sid_array2->count = sid_array->count;
1302 sid_array2->sids = talloc_array(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1303 if (!sid_array2->sids) {
1304 return NT_STATUS_NO_MEMORY;
1307 for (i=0; i<sid_array->count; i++) {
1308 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1309 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1310 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1311 sid_array2->sids[i].unknown = 0;
1314 r->out.sids = sid_array2;
1316 return status;
1319 /***************************************************************************
1320 _lsa_LookupNames3
1321 ***************************************************************************/
1323 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1324 struct lsa_LookupNames3 *r)
1326 NTSTATUS status;
1327 struct lsa_info *handle;
1328 struct lsa_String *names = r->in.names;
1329 uint32 num_entries = r->in.num_names;
1330 struct lsa_RefDomainList *domains = NULL;
1331 struct lsa_TranslatedSid3 *trans_sids = NULL;
1332 uint32 mapped_count = 0;
1333 int flags = 0;
1334 bool check_policy = true;
1336 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1337 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1338 return NT_STATUS_ACCESS_DENIED;
1341 switch (p->opnum) {
1342 case NDR_LSA_LOOKUPNAMES4:
1343 check_policy = false;
1344 break;
1345 case NDR_LSA_LOOKUPNAMES3:
1346 default:
1347 check_policy = true;
1350 if (num_entries > MAX_LOOKUP_SIDS) {
1351 num_entries = MAX_LOOKUP_SIDS;
1352 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1355 flags = lsa_lookup_level_to_flags(r->in.level);
1357 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1358 if (!domains) {
1359 return NT_STATUS_NO_MEMORY;
1362 if (num_entries) {
1363 trans_sids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid3,
1364 num_entries);
1365 if (!trans_sids) {
1366 return NT_STATUS_NO_MEMORY;
1368 } else {
1369 trans_sids = NULL;
1372 if (check_policy) {
1374 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1375 status = NT_STATUS_INVALID_HANDLE;
1376 goto done;
1379 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1380 return NT_STATUS_INVALID_HANDLE;
1383 /* check if the user has enough rights */
1384 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1385 status = NT_STATUS_ACCESS_DENIED;
1386 goto done;
1390 /* set up the LSA Lookup SIDs response */
1391 become_root(); /* lookup_name can require root privs */
1392 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1393 names, flags, &mapped_count);
1394 unbecome_root();
1396 done:
1398 if (NT_STATUS_IS_OK(status)) {
1399 if (mapped_count == 0) {
1400 status = NT_STATUS_NONE_MAPPED;
1401 } else if (mapped_count != num_entries) {
1402 status = STATUS_SOME_UNMAPPED;
1406 *r->out.count = mapped_count;
1407 *r->out.domains = domains;
1408 r->out.sids->sids = trans_sids;
1409 r->out.sids->count = num_entries;
1411 return status;
1414 /***************************************************************************
1415 _lsa_LookupNames4
1416 ***************************************************************************/
1418 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1419 struct lsa_LookupNames4 *r)
1421 struct lsa_LookupNames3 q;
1423 /* No policy handle on this call. Restrict to crypto connections. */
1424 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1425 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1426 get_remote_machine_name() ));
1427 return NT_STATUS_INVALID_PARAMETER;
1430 q.in.handle = NULL;
1431 q.in.num_names = r->in.num_names;
1432 q.in.names = r->in.names;
1433 q.in.level = r->in.level;
1434 q.in.lookup_options = r->in.lookup_options;
1435 q.in.client_revision = r->in.client_revision;
1436 q.in.sids = r->in.sids;
1437 q.in.count = r->in.count;
1439 q.out.domains = r->out.domains;
1440 q.out.sids = r->out.sids;
1441 q.out.count = r->out.count;
1443 return _lsa_LookupNames3(p, &q);
1446 /***************************************************************************
1447 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1448 ***************************************************************************/
1450 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1452 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1453 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1454 return NT_STATUS_ACCESS_DENIED;
1457 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1458 return NT_STATUS_INVALID_HANDLE;
1461 close_policy_hnd(p, r->in.handle);
1462 ZERO_STRUCTP(r->out.handle);
1463 return NT_STATUS_OK;
1466 /***************************************************************************
1467 ***************************************************************************/
1469 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1470 const struct dom_sid *sid,
1471 struct trustdom_info **info)
1473 NTSTATUS status;
1474 uint32_t num_domains = 0;
1475 struct trustdom_info **domains = NULL;
1476 int i;
1478 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1479 if (!NT_STATUS_IS_OK(status)) {
1480 return status;
1483 for (i=0; i < num_domains; i++) {
1484 if (dom_sid_equal(&domains[i]->sid, sid)) {
1485 break;
1489 if (i == num_domains) {
1490 return NT_STATUS_INVALID_PARAMETER;
1493 *info = domains[i];
1495 return NT_STATUS_OK;
1498 /***************************************************************************
1499 ***************************************************************************/
1501 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1502 const char *netbios_domain_name,
1503 struct trustdom_info **info_p)
1505 NTSTATUS status;
1506 struct trustdom_info *info;
1507 struct pdb_trusted_domain *td;
1509 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1510 if (!NT_STATUS_IS_OK(status)) {
1511 return status;
1514 info = talloc(mem_ctx, struct trustdom_info);
1515 if (!info) {
1516 return NT_STATUS_NO_MEMORY;
1519 info->name = talloc_strdup(info, netbios_domain_name);
1520 NT_STATUS_HAVE_NO_MEMORY(info->name);
1522 sid_copy(&info->sid, &td->security_identifier);
1524 *info_p = info;
1526 return NT_STATUS_OK;
1529 /***************************************************************************
1530 _lsa_OpenSecret
1531 ***************************************************************************/
1533 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p,
1534 struct lsa_OpenSecret *r)
1536 struct lsa_info *handle;
1537 struct security_descriptor *psd;
1538 NTSTATUS status;
1539 uint32_t acc_granted;
1541 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1542 return NT_STATUS_INVALID_HANDLE;
1545 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1546 return NT_STATUS_INVALID_HANDLE;
1549 if (!r->in.name.string) {
1550 return NT_STATUS_INVALID_PARAMETER;
1553 /* Work out max allowed. */
1554 map_max_allowed_access(p->session_info->security_token,
1555 p->session_info->unix_token,
1556 &r->in.access_mask);
1558 /* map the generic bits to the lsa policy ones */
1559 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
1561 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
1562 NULL,
1563 NULL,
1564 NULL,
1565 NULL,
1566 &psd);
1567 if (!NT_STATUS_IS_OK(status)) {
1568 return status;
1571 status = access_check_object(psd, p->session_info->security_token,
1572 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1573 r->in.access_mask,
1574 &acc_granted, "_lsa_OpenSecret");
1575 if (!NT_STATUS_IS_OK(status)) {
1576 return status;
1579 status = create_lsa_policy_handle(p->mem_ctx, p,
1580 LSA_HANDLE_SECRET_TYPE,
1581 acc_granted,
1582 NULL,
1583 r->in.name.string,
1584 psd,
1585 r->out.sec_handle);
1586 if (!NT_STATUS_IS_OK(status)) {
1587 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1590 return NT_STATUS_OK;
1593 /***************************************************************************
1594 _lsa_OpenTrustedDomain_base
1595 ***************************************************************************/
1597 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1598 uint32_t access_mask,
1599 struct trustdom_info *info,
1600 struct policy_handle *handle)
1602 struct security_descriptor *psd = NULL;
1603 size_t sd_size;
1604 uint32_t acc_granted;
1605 NTSTATUS status;
1607 /* des_access is for the account here, not the policy
1608 * handle - so don't check against policy handle. */
1610 /* Work out max allowed. */
1611 map_max_allowed_access(p->session_info->security_token,
1612 p->session_info->unix_token,
1613 &access_mask);
1615 /* map the generic bits to the lsa account ones */
1616 se_map_generic(&access_mask, &lsa_trusted_domain_mapping);
1618 /* get the generic lsa account SD until we store it */
1619 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1620 &lsa_trusted_domain_mapping,
1621 NULL, 0);
1622 if (!NT_STATUS_IS_OK(status)) {
1623 return status;
1626 status = access_check_object(psd, p->session_info->security_token,
1627 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1628 access_mask, &acc_granted,
1629 "_lsa_OpenTrustedDomain");
1630 if (!NT_STATUS_IS_OK(status)) {
1631 return status;
1634 status = create_lsa_policy_handle(p->mem_ctx, p,
1635 LSA_HANDLE_TRUST_TYPE,
1636 acc_granted,
1637 &info->sid,
1638 info->name,
1639 psd,
1640 handle);
1641 if (!NT_STATUS_IS_OK(status)) {
1642 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1645 return NT_STATUS_OK;
1648 /***************************************************************************
1649 _lsa_OpenTrustedDomain
1650 ***************************************************************************/
1652 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1653 struct lsa_OpenTrustedDomain *r)
1655 struct lsa_info *handle = NULL;
1656 struct trustdom_info *info = NULL;
1657 NTSTATUS status;
1659 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1660 return NT_STATUS_INVALID_HANDLE;
1663 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1664 return NT_STATUS_INVALID_HANDLE;
1667 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1668 r->in.sid,
1669 &info);
1670 if (!NT_STATUS_IS_OK(status)) {
1671 return status;
1674 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1675 r->out.trustdom_handle);
1678 /***************************************************************************
1679 _lsa_OpenTrustedDomainByName
1680 ***************************************************************************/
1682 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1683 struct lsa_OpenTrustedDomainByName *r)
1685 struct lsa_info *handle = NULL;
1686 struct trustdom_info *info = NULL;
1687 NTSTATUS status;
1689 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1690 return NT_STATUS_INVALID_HANDLE;
1693 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1694 return NT_STATUS_INVALID_HANDLE;
1697 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1698 r->in.name.string,
1699 &info);
1700 if (!NT_STATUS_IS_OK(status)) {
1701 return status;
1704 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1705 r->out.trustdom_handle);
1708 static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
1709 TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
1710 struct trustDomainPasswords *auth_struct)
1712 enum ndr_err_code ndr_err;
1713 DATA_BLOB lsession_key;
1714 NTSTATUS status;
1716 status = session_extract_session_key(p->session_info, &lsession_key, KEY_USE_16BYTES);
1717 if (!NT_STATUS_IS_OK(status)) {
1718 return NT_STATUS_INVALID_PARAMETER;
1721 arcfour_crypt_blob(auth_blob->data, auth_blob->length, &lsession_key);
1722 ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
1723 auth_struct,
1724 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
1725 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1726 return NT_STATUS_INVALID_PARAMETER;
1729 return NT_STATUS_OK;
1732 static NTSTATUS get_trustauth_inout_blob(TALLOC_CTX *mem_ctx,
1733 struct trustAuthInOutBlob *iopw,
1734 DATA_BLOB *trustauth_blob)
1736 enum ndr_err_code ndr_err;
1738 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
1739 iopw,
1740 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
1741 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1742 return NT_STATUS_INVALID_PARAMETER;
1745 return NT_STATUS_OK;
1748 /***************************************************************************
1749 _lsa_CreateTrustedDomainEx2
1750 ***************************************************************************/
1752 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1753 struct lsa_CreateTrustedDomainEx2 *r)
1755 struct lsa_info *policy;
1756 NTSTATUS status;
1757 uint32_t acc_granted;
1758 struct security_descriptor *psd;
1759 size_t sd_size;
1760 struct pdb_trusted_domain td;
1761 struct trustDomainPasswords auth_struct;
1762 DATA_BLOB auth_blob;
1764 if (!IS_DC) {
1765 return NT_STATUS_NOT_SUPPORTED;
1768 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1769 return NT_STATUS_INVALID_HANDLE;
1772 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1773 return NT_STATUS_ACCESS_DENIED;
1776 if (p->session_info->unix_token->uid != sec_initial_uid() &&
1777 !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1778 return NT_STATUS_ACCESS_DENIED;
1781 /* Work out max allowed. */
1782 map_max_allowed_access(p->session_info->security_token,
1783 p->session_info->unix_token,
1784 &r->in.access_mask);
1786 /* map the generic bits to the lsa policy ones */
1787 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1789 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1790 &lsa_trusted_domain_mapping,
1791 NULL, 0);
1792 if (!NT_STATUS_IS_OK(status)) {
1793 return status;
1796 status = access_check_object(psd, p->session_info->security_token,
1797 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1798 r->in.access_mask, &acc_granted,
1799 "_lsa_CreateTrustedDomainEx2");
1800 if (!NT_STATUS_IS_OK(status)) {
1801 return status;
1804 ZERO_STRUCT(td);
1806 td.domain_name = talloc_strdup(p->mem_ctx,
1807 r->in.info->domain_name.string);
1808 if (td.domain_name == NULL) {
1809 return NT_STATUS_NO_MEMORY;
1811 td.netbios_name = talloc_strdup(p->mem_ctx,
1812 r->in.info->netbios_name.string);
1813 if (td.netbios_name == NULL) {
1814 return NT_STATUS_NO_MEMORY;
1816 sid_copy(&td.security_identifier, r->in.info->sid);
1817 td.trust_direction = r->in.info->trust_direction;
1818 td.trust_type = r->in.info->trust_type;
1819 td.trust_attributes = r->in.info->trust_attributes;
1821 if (r->in.auth_info_internal->auth_blob.size != 0) {
1822 auth_blob.length = r->in.auth_info_internal->auth_blob.size;
1823 auth_blob.data = r->in.auth_info_internal->auth_blob.data;
1825 status = get_trustdom_auth_blob(p, p->mem_ctx, &auth_blob, &auth_struct);
1826 if (!NT_STATUS_IS_OK(status)) {
1827 return NT_STATUS_UNSUCCESSFUL;
1830 status = get_trustauth_inout_blob(p->mem_ctx, &auth_struct.incoming, &td.trust_auth_incoming);
1831 if (!NT_STATUS_IS_OK(status)) {
1832 return NT_STATUS_UNSUCCESSFUL;
1835 status = get_trustauth_inout_blob(p->mem_ctx, &auth_struct.outgoing, &td.trust_auth_outgoing);
1836 if (!NT_STATUS_IS_OK(status)) {
1837 return NT_STATUS_UNSUCCESSFUL;
1839 } else {
1840 td.trust_auth_incoming.data = NULL;
1841 td.trust_auth_incoming.length = 0;
1842 td.trust_auth_outgoing.data = NULL;
1843 td.trust_auth_outgoing.length = 0;
1846 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1847 if (!NT_STATUS_IS_OK(status)) {
1848 return status;
1851 status = create_lsa_policy_handle(p->mem_ctx, p,
1852 LSA_HANDLE_TRUST_TYPE,
1853 acc_granted,
1854 r->in.info->sid,
1855 r->in.info->netbios_name.string,
1856 psd,
1857 r->out.trustdom_handle);
1858 if (!NT_STATUS_IS_OK(status)) {
1859 pdb_del_trusted_domain(r->in.info->netbios_name.string);
1860 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1863 return NT_STATUS_OK;
1866 /***************************************************************************
1867 _lsa_CreateTrustedDomainEx
1868 ***************************************************************************/
1870 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1871 struct lsa_CreateTrustedDomainEx *r)
1873 struct lsa_CreateTrustedDomainEx2 q;
1874 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1876 ZERO_STRUCT(auth_info);
1878 q.in.policy_handle = r->in.policy_handle;
1879 q.in.info = r->in.info;
1880 q.in.auth_info_internal = &auth_info;
1881 q.in.access_mask = r->in.access_mask;
1882 q.out.trustdom_handle = r->out.trustdom_handle;
1884 return _lsa_CreateTrustedDomainEx2(p, &q);
1887 /***************************************************************************
1888 _lsa_CreateTrustedDomain
1889 ***************************************************************************/
1891 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1892 struct lsa_CreateTrustedDomain *r)
1894 struct lsa_CreateTrustedDomainEx2 c;
1895 struct lsa_TrustDomainInfoInfoEx info;
1896 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1898 ZERO_STRUCT(auth_info);
1900 info.domain_name = r->in.info->name;
1901 info.netbios_name = r->in.info->name;
1902 info.sid = r->in.info->sid;
1903 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1904 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1905 info.trust_attributes = 0;
1907 c.in.policy_handle = r->in.policy_handle;
1908 c.in.info = &info;
1909 c.in.auth_info_internal = &auth_info;
1910 c.in.access_mask = r->in.access_mask;
1911 c.out.trustdom_handle = r->out.trustdom_handle;
1913 return _lsa_CreateTrustedDomainEx2(p, &c);
1916 /***************************************************************************
1917 _lsa_DeleteTrustedDomain
1918 ***************************************************************************/
1920 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1921 struct lsa_DeleteTrustedDomain *r)
1923 NTSTATUS status;
1924 struct lsa_info *handle;
1925 struct pdb_trusted_domain *td;
1927 /* find the connection policy handle. */
1928 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1929 return NT_STATUS_INVALID_HANDLE;
1932 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1933 return NT_STATUS_INVALID_HANDLE;
1936 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1937 return NT_STATUS_ACCESS_DENIED;
1940 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1941 if (!NT_STATUS_IS_OK(status)) {
1942 return status;
1945 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1946 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1947 sid_string_tos(r->in.dom_sid)));
1948 return NT_STATUS_UNSUCCESSFUL;
1951 status = pdb_del_trusted_domain(td->netbios_name);
1952 if (!NT_STATUS_IS_OK(status)) {
1953 return status;
1956 return NT_STATUS_OK;
1959 /***************************************************************************
1960 _lsa_CloseTrustedDomainEx
1961 ***************************************************************************/
1963 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1964 struct lsa_CloseTrustedDomainEx *r)
1966 return NT_STATUS_NOT_IMPLEMENTED;
1969 /***************************************************************************
1970 _lsa_QueryTrustedDomainInfo
1971 ***************************************************************************/
1973 static NTSTATUS pdb_trusted_domain_2_info_ex(TALLOC_CTX *mem_ctx,
1974 struct pdb_trusted_domain *td,
1975 struct lsa_TrustDomainInfoInfoEx *info_ex)
1977 if (td->domain_name == NULL ||
1978 td->netbios_name == NULL ||
1979 is_null_sid(&td->security_identifier)) {
1980 return NT_STATUS_INVALID_PARAMETER;
1983 info_ex->domain_name.string = talloc_strdup(mem_ctx, td->domain_name);
1984 info_ex->netbios_name.string = talloc_strdup(mem_ctx, td->netbios_name);
1985 info_ex->sid = dom_sid_dup(mem_ctx, &td->security_identifier);
1986 if (info_ex->domain_name.string == NULL ||
1987 info_ex->netbios_name.string == NULL ||
1988 info_ex->sid == NULL) {
1989 return NT_STATUS_NO_MEMORY;
1992 info_ex->trust_direction = td->trust_direction;
1993 info_ex->trust_type = td->trust_type;
1994 info_ex->trust_attributes = td->trust_attributes;
1996 return NT_STATUS_OK;
1999 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
2000 struct lsa_QueryTrustedDomainInfo *r)
2002 NTSTATUS status;
2003 struct lsa_info *handle;
2004 union lsa_TrustedDomainInfo *info;
2005 struct pdb_trusted_domain *td;
2006 uint32_t acc_required;
2008 /* find the connection policy handle. */
2009 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
2010 return NT_STATUS_INVALID_HANDLE;
2013 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
2014 return NT_STATUS_INVALID_HANDLE;
2017 switch (r->in.level) {
2018 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2019 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2020 break;
2021 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2022 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
2023 break;
2024 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2025 acc_required = LSA_TRUSTED_QUERY_POSIX;
2026 break;
2027 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2028 acc_required = LSA_TRUSTED_QUERY_AUTH;
2029 break;
2030 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2031 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2032 break;
2033 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2034 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2035 break;
2036 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2037 acc_required = LSA_TRUSTED_QUERY_AUTH;
2038 break;
2039 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2040 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2041 LSA_TRUSTED_QUERY_POSIX |
2042 LSA_TRUSTED_QUERY_AUTH;
2043 break;
2044 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2045 acc_required = LSA_TRUSTED_QUERY_AUTH;
2046 break;
2047 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2048 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2049 LSA_TRUSTED_QUERY_POSIX |
2050 LSA_TRUSTED_QUERY_AUTH;
2051 break;
2052 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2053 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2054 break;
2055 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2056 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2057 LSA_TRUSTED_QUERY_POSIX |
2058 LSA_TRUSTED_QUERY_AUTH;
2059 break;
2060 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2061 acc_required = LSA_TRUSTED_QUERY_POSIX;
2062 break;
2063 default:
2064 return NT_STATUS_INVALID_PARAMETER;
2067 if (!(handle->access & acc_required)) {
2068 return NT_STATUS_ACCESS_DENIED;
2071 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2072 if (!NT_STATUS_IS_OK(status)) {
2073 return status;
2076 info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
2077 if (!info) {
2078 return NT_STATUS_NO_MEMORY;
2081 switch (r->in.level) {
2082 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2083 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2084 break;
2085 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2086 return NT_STATUS_INVALID_PARAMETER;
2087 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2088 info->posix_offset.posix_offset = *td->trust_posix_offset;
2089 break;
2090 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2091 return NT_STATUS_INVALID_INFO_CLASS;
2092 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2093 return NT_STATUS_INVALID_PARAMETER;
2094 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2095 status = pdb_trusted_domain_2_info_ex(info, td, &info->info_ex);
2096 if (!NT_STATUS_IS_OK(status)) {
2097 return status;
2099 break;
2100 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2101 return NT_STATUS_INVALID_INFO_CLASS;
2102 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2103 status = pdb_trusted_domain_2_info_ex(info, td,
2104 &info->full_info.info_ex);
2105 if (!NT_STATUS_IS_OK(status)) {
2106 return status;
2108 info->full_info.posix_offset.posix_offset = *td->trust_posix_offset;
2109 status = auth_blob_2_auth_info(p->mem_ctx,
2110 td->trust_auth_incoming,
2111 td->trust_auth_outgoing,
2112 &info->full_info.auth_info);
2113 if (!NT_STATUS_IS_OK(status)) {
2114 return status;
2116 break;
2117 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2118 return NT_STATUS_INVALID_INFO_CLASS;
2119 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2120 return NT_STATUS_INVALID_INFO_CLASS;
2121 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2122 return NT_STATUS_INVALID_PARAMETER;
2123 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2124 info->full_info2_internal.posix_offset.posix_offset = *td->trust_posix_offset;
2125 status = auth_blob_2_auth_info(p->mem_ctx,
2126 td->trust_auth_incoming,
2127 td->trust_auth_outgoing,
2128 &info->full_info2_internal.auth_info);
2129 if (!NT_STATUS_IS_OK(status)) {
2130 return status;
2132 break;
2133 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2134 info->enc_types.enc_types = *td->supported_enc_type;
2135 break;
2136 default:
2137 return NT_STATUS_INVALID_PARAMETER;
2140 *r->out.info = info;
2142 return NT_STATUS_OK;
2145 /***************************************************************************
2146 _lsa_QueryTrustedDomainInfoBySid
2147 ***************************************************************************/
2149 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2150 struct lsa_QueryTrustedDomainInfoBySid *r)
2152 NTSTATUS status;
2153 struct policy_handle trustdom_handle;
2154 struct lsa_OpenTrustedDomain o;
2155 struct lsa_QueryTrustedDomainInfo q;
2156 struct lsa_Close c;
2158 o.in.handle = r->in.handle;
2159 o.in.sid = r->in.dom_sid;
2160 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2161 o.out.trustdom_handle = &trustdom_handle;
2163 status = _lsa_OpenTrustedDomain(p, &o);
2164 if (!NT_STATUS_IS_OK(status)) {
2165 return status;
2168 q.in.trustdom_handle = &trustdom_handle;
2169 q.in.level = r->in.level;
2170 q.out.info = r->out.info;
2172 status = _lsa_QueryTrustedDomainInfo(p, &q);
2173 if (!NT_STATUS_IS_OK(status)) {
2174 return status;
2177 c.in.handle = &trustdom_handle;
2178 c.out.handle = &trustdom_handle;
2180 return _lsa_Close(p, &c);
2183 /***************************************************************************
2184 _lsa_QueryTrustedDomainInfoByName
2185 ***************************************************************************/
2187 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2188 struct lsa_QueryTrustedDomainInfoByName *r)
2190 NTSTATUS status;
2191 struct policy_handle trustdom_handle;
2192 struct lsa_OpenTrustedDomainByName o;
2193 struct lsa_QueryTrustedDomainInfo q;
2194 struct lsa_Close c;
2196 o.in.handle = r->in.handle;
2197 o.in.name.string = r->in.trusted_domain->string;
2198 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2199 o.out.trustdom_handle = &trustdom_handle;
2201 status = _lsa_OpenTrustedDomainByName(p, &o);
2202 if (!NT_STATUS_IS_OK(status)) {
2203 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2204 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2206 return status;
2209 q.in.trustdom_handle = &trustdom_handle;
2210 q.in.level = r->in.level;
2211 q.out.info = r->out.info;
2213 status = _lsa_QueryTrustedDomainInfo(p, &q);
2214 if (!NT_STATUS_IS_OK(status)) {
2215 return status;
2218 c.in.handle = &trustdom_handle;
2219 c.out.handle = &trustdom_handle;
2221 return _lsa_Close(p, &c);
2224 /***************************************************************************
2225 _lsa_CreateSecret
2226 ***************************************************************************/
2228 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p,
2229 struct lsa_CreateSecret *r)
2231 NTSTATUS status;
2232 struct lsa_info *handle;
2233 uint32_t acc_granted;
2234 struct security_descriptor *psd;
2235 size_t sd_size;
2237 /* find the connection policy handle. */
2238 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
2239 return NT_STATUS_INVALID_HANDLE;
2242 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2243 return NT_STATUS_INVALID_HANDLE;
2246 /* check if the user has enough rights */
2248 if (!(handle->access & LSA_POLICY_CREATE_SECRET)) {
2249 return NT_STATUS_ACCESS_DENIED;
2252 /* Work out max allowed. */
2253 map_max_allowed_access(p->session_info->security_token,
2254 p->session_info->unix_token,
2255 &r->in.access_mask);
2257 /* map the generic bits to the lsa policy ones */
2258 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
2260 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2261 &lsa_secret_mapping,
2262 NULL, 0);
2263 if (!NT_STATUS_IS_OK(status)) {
2264 return status;
2267 status = access_check_object(psd, p->session_info->security_token,
2268 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2269 r->in.access_mask,
2270 &acc_granted, "_lsa_CreateSecret");
2271 if (!NT_STATUS_IS_OK(status)) {
2272 return status;
2275 if (!r->in.name.string) {
2276 return NT_STATUS_INVALID_PARAMETER;
2279 if (strlen(r->in.name.string) > 128) {
2280 return NT_STATUS_NAME_TOO_LONG;
2283 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
2284 NULL, NULL, NULL, NULL, NULL);
2285 if (NT_STATUS_IS_OK(status)) {
2286 return NT_STATUS_OBJECT_NAME_COLLISION;
2289 status = pdb_set_secret(r->in.name.string, NULL, NULL, psd);
2290 if (!NT_STATUS_IS_OK(status)) {
2291 return status;
2294 status = create_lsa_policy_handle(p->mem_ctx, p,
2295 LSA_HANDLE_SECRET_TYPE,
2296 acc_granted,
2297 NULL,
2298 r->in.name.string,
2299 psd,
2300 r->out.sec_handle);
2301 if (!NT_STATUS_IS_OK(status)) {
2302 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2305 return NT_STATUS_OK;
2308 /***************************************************************************
2309 _lsa_SetSecret
2310 ***************************************************************************/
2312 NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
2313 struct lsa_SetSecret *r)
2315 NTSTATUS status;
2316 struct lsa_info *info = NULL;
2317 DATA_BLOB blob_new, blob_old;
2318 DATA_BLOB cleartext_blob_new = data_blob_null;
2319 DATA_BLOB cleartext_blob_old = data_blob_null;
2320 DATA_BLOB *cleartext_blob_new_p = NULL;
2321 DATA_BLOB *cleartext_blob_old_p = NULL;
2322 DATA_BLOB session_key;
2324 if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
2325 return NT_STATUS_INVALID_HANDLE;
2328 if (info->type != LSA_HANDLE_SECRET_TYPE) {
2329 return NT_STATUS_INVALID_HANDLE;
2332 if (!(info->access & LSA_SECRET_SET_VALUE)) {
2333 return NT_STATUS_ACCESS_DENIED;
2336 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
2337 if(!NT_STATUS_IS_OK(status)) {
2338 return status;
2341 if (r->in.new_val) {
2342 blob_new = data_blob_const(r->in.new_val->data,
2343 r->in.new_val->length);
2345 status = sess_decrypt_blob(p->mem_ctx, &blob_new,
2346 &session_key,
2347 &cleartext_blob_new);
2348 if (!NT_STATUS_IS_OK(status)) {
2349 return status;
2352 cleartext_blob_new_p = &cleartext_blob_new;
2355 if (r->in.old_val) {
2356 blob_old = data_blob_const(r->in.old_val->data,
2357 r->in.old_val->length);
2359 status = sess_decrypt_blob(p->mem_ctx, &blob_old,
2360 &session_key,
2361 &cleartext_blob_old);
2362 if (!NT_STATUS_IS_OK(status)) {
2363 return status;
2366 cleartext_blob_old_p = &cleartext_blob_old;
2369 status = pdb_set_secret(info->name, cleartext_blob_new_p, cleartext_blob_old_p, NULL);
2370 if (!NT_STATUS_IS_OK(status)) {
2371 return status;
2374 #ifdef DEBUG_PASSWORD
2375 DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
2376 dump_data(10, cleartext_blob_new.data, cleartext_blob_new.length);
2377 DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
2378 dump_data(10, cleartext_blob_old.data, cleartext_blob_old.length);
2379 #endif
2381 return NT_STATUS_OK;
2384 /***************************************************************************
2385 _lsa_QuerySecret
2386 ***************************************************************************/
2388 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
2389 struct lsa_QuerySecret *r)
2391 struct lsa_info *info = NULL;
2392 DATA_BLOB blob_new, blob_old;
2393 DATA_BLOB blob_new_crypt, blob_old_crypt;
2394 DATA_BLOB session_key;
2395 NTTIME nttime_new, nttime_old;
2396 NTSTATUS status;
2398 if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
2399 return NT_STATUS_INVALID_HANDLE;
2402 if (info->type != LSA_HANDLE_SECRET_TYPE) {
2403 return NT_STATUS_INVALID_HANDLE;
2406 if (!(info->access & LSA_SECRET_QUERY_VALUE)) {
2407 return NT_STATUS_ACCESS_DENIED;
2410 status = pdb_get_secret(p->mem_ctx, info->name,
2411 &blob_new, &nttime_new,
2412 &blob_old, &nttime_old,
2413 NULL);
2414 if (!NT_STATUS_IS_OK(status)) {
2415 return status;
2418 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
2419 if(!NT_STATUS_IS_OK(status)) {
2420 return status;
2423 if (r->in.new_val) {
2424 if (blob_new.length) {
2425 if (!r->out.new_val->buf) {
2426 r->out.new_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2428 if (!r->out.new_val->buf) {
2429 return NT_STATUS_NO_MEMORY;
2432 blob_new_crypt = sess_encrypt_blob(p->mem_ctx, &blob_new,
2433 &session_key);
2434 if (!blob_new_crypt.length) {
2435 return NT_STATUS_NO_MEMORY;
2438 r->out.new_val->buf->data = blob_new_crypt.data;
2439 r->out.new_val->buf->length = blob_new_crypt.length;
2440 r->out.new_val->buf->size = blob_new_crypt.length;
2444 if (r->in.old_val) {
2445 if (blob_old.length) {
2446 if (!r->out.old_val->buf) {
2447 r->out.old_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2449 if (!r->out.old_val->buf) {
2450 return NT_STATUS_NO_MEMORY;
2453 blob_old_crypt = sess_encrypt_blob(p->mem_ctx, &blob_old,
2454 &session_key);
2455 if (!blob_old_crypt.length) {
2456 return NT_STATUS_NO_MEMORY;
2459 r->out.old_val->buf->data = blob_old_crypt.data;
2460 r->out.old_val->buf->length = blob_old_crypt.length;
2461 r->out.old_val->buf->size = blob_old_crypt.length;
2465 if (r->out.new_mtime) {
2466 *r->out.new_mtime = nttime_new;
2469 if (r->out.old_mtime) {
2470 *r->out.old_mtime = nttime_old;
2473 return NT_STATUS_OK;
2476 /***************************************************************************
2477 _lsa_DeleteObject
2478 ***************************************************************************/
2480 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2481 struct lsa_DeleteObject *r)
2483 NTSTATUS status;
2484 struct lsa_info *info = NULL;
2486 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2487 return NT_STATUS_INVALID_HANDLE;
2490 if (!(info->access & SEC_STD_DELETE)) {
2491 return NT_STATUS_ACCESS_DENIED;
2494 switch (info->type) {
2495 case LSA_HANDLE_ACCOUNT_TYPE:
2496 status = privilege_delete_account(&info->sid);
2497 if (!NT_STATUS_IS_OK(status)) {
2498 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2499 nt_errstr(status)));
2500 return status;
2502 break;
2503 case LSA_HANDLE_TRUST_TYPE:
2504 if (!pdb_del_trusteddom_pw(info->name)) {
2505 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2507 status = NT_STATUS_OK;
2508 break;
2509 case LSA_HANDLE_SECRET_TYPE:
2510 status = pdb_delete_secret(info->name);
2511 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2512 return NT_STATUS_INVALID_HANDLE;
2514 break;
2515 default:
2516 return NT_STATUS_INVALID_HANDLE;
2519 close_policy_hnd(p, r->in.handle);
2520 ZERO_STRUCTP(r->out.handle);
2522 return status;
2525 /***************************************************************************
2526 _lsa_EnumPrivs
2527 ***************************************************************************/
2529 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2530 struct lsa_EnumPrivs *r)
2532 struct lsa_info *handle;
2533 uint32 i;
2534 uint32 enum_context = *r->in.resume_handle;
2535 int num_privs = num_privileges_in_short_list();
2536 struct lsa_PrivEntry *entries = NULL;
2538 /* remember that the enum_context starts at 0 and not 1 */
2540 if ( enum_context >= num_privs )
2541 return NT_STATUS_NO_MORE_ENTRIES;
2543 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2544 enum_context, num_privs));
2546 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2547 return NT_STATUS_INVALID_HANDLE;
2549 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2550 return NT_STATUS_INVALID_HANDLE;
2553 /* check if the user has enough rights
2554 I don't know if it's the right one. not documented. */
2556 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2557 return NT_STATUS_ACCESS_DENIED;
2559 if (num_privs) {
2560 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2561 if (!entries) {
2562 return NT_STATUS_NO_MEMORY;
2564 } else {
2565 entries = NULL;
2568 for (i = 0; i < num_privs; i++) {
2569 if( i < enum_context) {
2571 init_lsa_StringLarge(&entries[i].name, NULL);
2573 entries[i].luid.low = 0;
2574 entries[i].luid.high = 0;
2575 } else {
2577 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2579 entries[i].luid.low = sec_privilege_from_index(i);
2580 entries[i].luid.high = 0;
2584 enum_context = num_privs;
2586 *r->out.resume_handle = enum_context;
2587 r->out.privs->count = num_privs;
2588 r->out.privs->privs = entries;
2590 return NT_STATUS_OK;
2593 /***************************************************************************
2594 _lsa_LookupPrivDisplayName
2595 ***************************************************************************/
2597 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2598 struct lsa_LookupPrivDisplayName *r)
2600 struct lsa_info *handle;
2601 const char *description;
2602 struct lsa_StringLarge *lsa_name;
2604 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2605 return NT_STATUS_INVALID_HANDLE;
2607 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2608 return NT_STATUS_INVALID_HANDLE;
2611 /* check if the user has enough rights */
2614 * I don't know if it's the right one. not documented.
2616 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2617 return NT_STATUS_ACCESS_DENIED;
2619 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2621 description = get_privilege_dispname(r->in.name->string);
2622 if (!description) {
2623 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2624 return NT_STATUS_NO_SUCH_PRIVILEGE;
2627 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2629 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2630 if (!lsa_name) {
2631 return NT_STATUS_NO_MEMORY;
2634 init_lsa_StringLarge(lsa_name, description);
2636 *r->out.returned_language_id = r->in.language_id;
2637 *r->out.disp_name = lsa_name;
2639 return NT_STATUS_OK;
2642 /***************************************************************************
2643 _lsa_EnumAccounts
2644 ***************************************************************************/
2646 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2647 struct lsa_EnumAccounts *r)
2649 struct lsa_info *handle;
2650 struct dom_sid *sid_list;
2651 int i, j, num_entries;
2652 NTSTATUS status;
2653 struct lsa_SidPtr *sids = NULL;
2655 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2656 return NT_STATUS_INVALID_HANDLE;
2658 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2659 return NT_STATUS_INVALID_HANDLE;
2662 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2663 return NT_STATUS_ACCESS_DENIED;
2665 sid_list = NULL;
2666 num_entries = 0;
2668 /* The only way we can currently find out all the SIDs that have been
2669 privileged is to scan all privileges */
2671 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2672 if (!NT_STATUS_IS_OK(status)) {
2673 return status;
2676 if (*r->in.resume_handle >= num_entries) {
2677 return NT_STATUS_NO_MORE_ENTRIES;
2680 if (num_entries - *r->in.resume_handle) {
2681 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2682 num_entries - *r->in.resume_handle);
2683 if (!sids) {
2684 talloc_free(sid_list);
2685 return NT_STATUS_NO_MEMORY;
2688 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2689 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2690 if (!sids[j].sid) {
2691 talloc_free(sid_list);
2692 return NT_STATUS_NO_MEMORY;
2697 talloc_free(sid_list);
2699 *r->out.resume_handle = num_entries;
2700 r->out.sids->num_sids = num_entries;
2701 r->out.sids->sids = sids;
2703 return NT_STATUS_OK;
2706 /***************************************************************************
2707 _lsa_GetUserName
2708 ***************************************************************************/
2710 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2711 struct lsa_GetUserName *r)
2713 const char *username, *domname;
2714 struct lsa_String *account_name = NULL;
2715 struct lsa_String *authority_name = NULL;
2717 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
2718 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
2719 return NT_STATUS_ACCESS_DENIED;
2722 if (r->in.account_name &&
2723 *r->in.account_name) {
2724 return NT_STATUS_INVALID_PARAMETER;
2727 if (r->in.authority_name &&
2728 *r->in.authority_name) {
2729 return NT_STATUS_INVALID_PARAMETER;
2732 if (security_session_user_level(p->session_info, NULL) < SECURITY_USER) {
2734 * I'm 99% sure this is not the right place to do this,
2735 * global_sid_Anonymous should probably be put into the token
2736 * instead of the guest id -- vl
2738 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2739 &domname, &username, NULL)) {
2740 return NT_STATUS_NO_MEMORY;
2742 } else {
2743 username = p->session_info->unix_info->sanitized_username;
2744 domname = p->session_info->info->domain_name;
2747 account_name = talloc(p->mem_ctx, struct lsa_String);
2748 if (!account_name) {
2749 return NT_STATUS_NO_MEMORY;
2751 init_lsa_String(account_name, username);
2753 if (r->out.authority_name) {
2754 authority_name = talloc(p->mem_ctx, struct lsa_String);
2755 if (!authority_name) {
2756 return NT_STATUS_NO_MEMORY;
2758 init_lsa_String(authority_name, domname);
2761 *r->out.account_name = account_name;
2762 if (r->out.authority_name) {
2763 *r->out.authority_name = authority_name;
2766 return NT_STATUS_OK;
2769 /***************************************************************************
2770 _lsa_CreateAccount
2771 ***************************************************************************/
2773 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2774 struct lsa_CreateAccount *r)
2776 NTSTATUS status;
2777 struct lsa_info *handle;
2778 uint32_t acc_granted;
2779 struct security_descriptor *psd;
2780 size_t sd_size;
2781 uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
2782 ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
2783 LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2784 SEC_STD_DELETE));
2786 /* find the connection policy handle. */
2787 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2788 return NT_STATUS_INVALID_HANDLE;
2790 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2791 return NT_STATUS_INVALID_HANDLE;
2794 /* check if the user has enough rights */
2796 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2797 return NT_STATUS_ACCESS_DENIED;
2800 /* Work out max allowed. */
2801 map_max_allowed_access(p->session_info->security_token,
2802 p->session_info->unix_token,
2803 &r->in.access_mask);
2805 /* map the generic bits to the lsa policy ones */
2806 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2808 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2809 &lsa_account_mapping,
2810 r->in.sid, owner_access);
2811 if (!NT_STATUS_IS_OK(status)) {
2812 return status;
2815 status = access_check_object(psd, p->session_info->security_token,
2816 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2817 &acc_granted, "_lsa_CreateAccount");
2818 if (!NT_STATUS_IS_OK(status)) {
2819 return status;
2822 if ( is_privileged_sid( r->in.sid ) )
2823 return NT_STATUS_OBJECT_NAME_COLLISION;
2825 status = create_lsa_policy_handle(p->mem_ctx, p,
2826 LSA_HANDLE_ACCOUNT_TYPE,
2827 acc_granted,
2828 r->in.sid,
2829 NULL,
2830 psd,
2831 r->out.acct_handle);
2832 if (!NT_STATUS_IS_OK(status)) {
2833 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2836 return privilege_create_account(r->in.sid);
2839 /***************************************************************************
2840 _lsa_OpenAccount
2841 ***************************************************************************/
2843 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2844 struct lsa_OpenAccount *r)
2846 struct lsa_info *handle;
2847 struct security_descriptor *psd = NULL;
2848 size_t sd_size;
2849 uint32_t des_access = r->in.access_mask;
2850 uint32_t acc_granted;
2851 uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
2852 ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
2853 LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2854 SEC_STD_DELETE));
2855 NTSTATUS status;
2857 /* find the connection policy handle. */
2858 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2859 return NT_STATUS_INVALID_HANDLE;
2861 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2862 return NT_STATUS_INVALID_HANDLE;
2865 /* des_access is for the account here, not the policy
2866 * handle - so don't check against policy handle. */
2868 /* Work out max allowed. */
2869 map_max_allowed_access(p->session_info->security_token,
2870 p->session_info->unix_token,
2871 &des_access);
2873 /* map the generic bits to the lsa account ones */
2874 se_map_generic(&des_access, &lsa_account_mapping);
2876 /* get the generic lsa account SD until we store it */
2877 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2878 &lsa_account_mapping,
2879 r->in.sid, owner_access);
2880 if (!NT_STATUS_IS_OK(status)) {
2881 return status;
2884 status = access_check_object(psd, p->session_info->security_token,
2885 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2886 &acc_granted, "_lsa_OpenAccount" );
2887 if (!NT_STATUS_IS_OK(status)) {
2888 return status;
2891 /* TODO: Fis the parsing routine before reenabling this check! */
2892 #if 0
2893 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2894 return NT_STATUS_ACCESS_DENIED;
2895 #endif
2897 status = create_lsa_policy_handle(p->mem_ctx, p,
2898 LSA_HANDLE_ACCOUNT_TYPE,
2899 acc_granted,
2900 r->in.sid,
2901 NULL,
2902 psd,
2903 r->out.acct_handle);
2904 if (!NT_STATUS_IS_OK(status)) {
2905 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2908 return NT_STATUS_OK;
2911 /***************************************************************************
2912 _lsa_EnumPrivsAccount
2913 For a given SID, enumerate all the privilege this account has.
2914 ***************************************************************************/
2916 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2917 struct lsa_EnumPrivsAccount *r)
2919 NTSTATUS status = NT_STATUS_OK;
2920 struct lsa_info *info=NULL;
2921 PRIVILEGE_SET *privileges;
2922 struct lsa_PrivilegeSet *priv_set = NULL;
2924 /* find the connection policy handle. */
2925 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2926 return NT_STATUS_INVALID_HANDLE;
2928 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2929 return NT_STATUS_INVALID_HANDLE;
2932 if (!(info->access & LSA_ACCOUNT_VIEW))
2933 return NT_STATUS_ACCESS_DENIED;
2935 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2936 if (!NT_STATUS_IS_OK(status)) {
2937 return status;
2940 *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2941 if (!priv_set) {
2942 return NT_STATUS_NO_MEMORY;
2945 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2946 sid_string_dbg(&info->sid),
2947 privileges->count));
2949 priv_set->count = privileges->count;
2950 priv_set->unknown = 0;
2951 priv_set->set = talloc_move(priv_set, &privileges->set);
2953 return status;
2956 /***************************************************************************
2957 _lsa_GetSystemAccessAccount
2958 ***************************************************************************/
2960 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2961 struct lsa_GetSystemAccessAccount *r)
2963 NTSTATUS status;
2964 struct lsa_info *info = NULL;
2965 struct lsa_EnumPrivsAccount e;
2966 struct lsa_PrivilegeSet *privset;
2968 /* find the connection policy handle. */
2970 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2971 return NT_STATUS_INVALID_HANDLE;
2973 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2974 return NT_STATUS_INVALID_HANDLE;
2977 if (!(info->access & LSA_ACCOUNT_VIEW))
2978 return NT_STATUS_ACCESS_DENIED;
2980 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2981 if (!privset) {
2982 return NT_STATUS_NO_MEMORY;
2985 e.in.handle = r->in.handle;
2986 e.out.privs = &privset;
2988 status = _lsa_EnumPrivsAccount(p, &e);
2989 if (!NT_STATUS_IS_OK(status)) {
2990 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2991 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2992 nt_errstr(status)));
2993 return status;
2996 /* Samba4 would iterate over the privset to merge the policy mode bits,
2997 * not sure samba3 can do the same here, so just return what we did in
2998 * the past - gd */
3001 0x01 -> Log on locally
3002 0x02 -> Access this computer from network
3003 0x04 -> Log on as a batch job
3004 0x10 -> Log on as a service
3006 they can be ORed together
3009 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
3010 LSA_POLICY_MODE_NETWORK;
3012 return NT_STATUS_OK;
3015 /***************************************************************************
3016 update the systemaccount information
3017 ***************************************************************************/
3019 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
3020 struct lsa_SetSystemAccessAccount *r)
3022 struct lsa_info *info=NULL;
3023 NTSTATUS status;
3024 GROUP_MAP *map;
3026 /* find the connection policy handle. */
3027 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3028 return NT_STATUS_INVALID_HANDLE;
3030 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3031 return NT_STATUS_INVALID_HANDLE;
3034 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
3035 return NT_STATUS_ACCESS_DENIED;
3038 map = talloc_zero(p->mem_ctx, GROUP_MAP);
3039 if (!map) {
3040 return NT_STATUS_NO_MEMORY;
3043 if (!pdb_getgrsid(map, info->sid)) {
3044 TALLOC_FREE(map);
3045 return NT_STATUS_NO_SUCH_GROUP;
3048 status = pdb_update_group_mapping_entry(map);
3049 TALLOC_FREE(map);
3050 return status;
3053 /***************************************************************************
3054 _lsa_AddPrivilegesToAccount
3055 For a given SID, add some privileges.
3056 ***************************************************************************/
3058 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
3059 struct lsa_AddPrivilegesToAccount *r)
3061 struct lsa_info *info = NULL;
3062 struct lsa_PrivilegeSet *set = NULL;
3064 /* find the connection policy handle. */
3065 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3066 return NT_STATUS_INVALID_HANDLE;
3068 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3069 return NT_STATUS_INVALID_HANDLE;
3072 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3073 return NT_STATUS_ACCESS_DENIED;
3076 set = r->in.privs;
3078 if ( !grant_privilege_set( &info->sid, set ) ) {
3079 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
3080 sid_string_dbg(&info->sid) ));
3081 return NT_STATUS_NO_SUCH_PRIVILEGE;
3084 return NT_STATUS_OK;
3087 /***************************************************************************
3088 _lsa_RemovePrivilegesFromAccount
3089 For a given SID, remove some privileges.
3090 ***************************************************************************/
3092 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
3093 struct lsa_RemovePrivilegesFromAccount *r)
3095 struct lsa_info *info = NULL;
3096 struct lsa_PrivilegeSet *set = NULL;
3098 /* find the connection policy handle. */
3099 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3100 return NT_STATUS_INVALID_HANDLE;
3102 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3103 return NT_STATUS_INVALID_HANDLE;
3106 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3107 return NT_STATUS_ACCESS_DENIED;
3110 set = r->in.privs;
3112 if ( !revoke_privilege_set( &info->sid, set) ) {
3113 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
3114 sid_string_dbg(&info->sid) ));
3115 return NT_STATUS_NO_SUCH_PRIVILEGE;
3118 return NT_STATUS_OK;
3121 /***************************************************************************
3122 _lsa_LookupPrivName
3123 ***************************************************************************/
3125 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
3126 struct lsa_LookupPrivName *r)
3128 struct lsa_info *info = NULL;
3129 const char *name;
3130 struct lsa_StringLarge *lsa_name;
3132 /* find the connection policy handle. */
3133 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3134 return NT_STATUS_INVALID_HANDLE;
3137 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3138 return NT_STATUS_INVALID_HANDLE;
3141 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
3142 return NT_STATUS_ACCESS_DENIED;
3145 if (r->in.luid->high != 0) {
3146 return NT_STATUS_NO_SUCH_PRIVILEGE;
3149 name = sec_privilege_name(r->in.luid->low);
3150 if (!name) {
3151 return NT_STATUS_NO_SUCH_PRIVILEGE;
3154 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
3155 if (!lsa_name) {
3156 return NT_STATUS_NO_MEMORY;
3159 lsa_name->string = talloc_strdup(lsa_name, name);
3160 if (!lsa_name->string) {
3161 TALLOC_FREE(lsa_name);
3162 return NT_STATUS_NO_MEMORY;
3165 *r->out.name = lsa_name;
3167 return NT_STATUS_OK;
3170 /***************************************************************************
3171 _lsa_QuerySecurity
3172 ***************************************************************************/
3174 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
3175 struct lsa_QuerySecurity *r)
3177 struct lsa_info *handle=NULL;
3178 struct security_descriptor *psd = NULL;
3179 size_t sd_size = 0;
3180 NTSTATUS status;
3182 /* find the connection policy handle. */
3183 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
3184 return NT_STATUS_INVALID_HANDLE;
3186 switch (handle->type) {
3187 case LSA_HANDLE_POLICY_TYPE:
3188 case LSA_HANDLE_ACCOUNT_TYPE:
3189 case LSA_HANDLE_TRUST_TYPE:
3190 case LSA_HANDLE_SECRET_TYPE:
3191 psd = handle->sd;
3192 sd_size = ndr_size_security_descriptor(psd, 0);
3193 status = NT_STATUS_OK;
3194 break;
3195 default:
3196 status = NT_STATUS_INVALID_HANDLE;
3197 break;
3200 if (!NT_STATUS_IS_OK(status)) {
3201 return status;
3204 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
3205 if (!*r->out.sdbuf) {
3206 return NT_STATUS_NO_MEMORY;
3209 return status;
3212 /***************************************************************************
3213 _lsa_AddAccountRights
3214 ***************************************************************************/
3216 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
3217 struct lsa_AddAccountRights *r)
3219 struct lsa_info *info = NULL;
3220 int i = 0;
3221 uint32_t acc_granted = 0;
3222 struct security_descriptor *psd = NULL;
3223 size_t sd_size;
3224 struct dom_sid sid;
3225 NTSTATUS status;
3227 /* find the connection policy handle. */
3228 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3229 return NT_STATUS_INVALID_HANDLE;
3231 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3232 return NT_STATUS_INVALID_HANDLE;
3235 /* get the generic lsa account SD for this SID until we store it */
3236 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3237 &lsa_account_mapping,
3238 NULL, 0);
3239 if (!NT_STATUS_IS_OK(status)) {
3240 return status;
3244 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3245 * on the policy handle. If it does, ask for
3246 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3247 * on the account sid. We don't check here so just use the latter. JRA.
3250 status = access_check_object(psd, p->session_info->security_token,
3251 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3252 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3253 &acc_granted, "_lsa_AddAccountRights" );
3254 if (!NT_STATUS_IS_OK(status)) {
3255 return status;
3258 /* according to an NT4 PDC, you can add privileges to SIDs even without
3259 call_lsa_create_account() first. And you can use any arbitrary SID. */
3261 sid_copy( &sid, r->in.sid );
3263 for ( i=0; i < r->in.rights->count; i++ ) {
3265 const char *privname = r->in.rights->names[i].string;
3267 /* only try to add non-null strings */
3269 if ( !privname )
3270 continue;
3272 if ( !grant_privilege_by_name( &sid, privname ) ) {
3273 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3274 privname ));
3275 return NT_STATUS_NO_SUCH_PRIVILEGE;
3279 return NT_STATUS_OK;
3282 /***************************************************************************
3283 _lsa_RemoveAccountRights
3284 ***************************************************************************/
3286 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
3287 struct lsa_RemoveAccountRights *r)
3289 struct lsa_info *info = NULL;
3290 int i = 0;
3291 struct security_descriptor *psd = NULL;
3292 size_t sd_size;
3293 struct dom_sid sid;
3294 const char *privname = NULL;
3295 uint32_t acc_granted = 0;
3296 NTSTATUS status;
3298 /* find the connection policy handle. */
3299 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3300 return NT_STATUS_INVALID_HANDLE;
3302 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3303 return NT_STATUS_INVALID_HANDLE;
3306 /* get the generic lsa account SD for this SID until we store it */
3307 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3308 &lsa_account_mapping,
3309 NULL, 0);
3310 if (!NT_STATUS_IS_OK(status)) {
3311 return status;
3315 * From the MS DOCs. We need
3316 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3317 * and DELETE on the account sid.
3320 status = access_check_object(psd, p->session_info->security_token,
3321 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3322 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3323 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
3324 &acc_granted, "_lsa_RemoveAccountRights");
3325 if (!NT_STATUS_IS_OK(status)) {
3326 return status;
3329 sid_copy( &sid, r->in.sid );
3331 if ( r->in.remove_all ) {
3332 if ( !revoke_all_privileges( &sid ) )
3333 return NT_STATUS_ACCESS_DENIED;
3335 return NT_STATUS_OK;
3338 for ( i=0; i < r->in.rights->count; i++ ) {
3340 privname = r->in.rights->names[i].string;
3342 /* only try to add non-null strings */
3344 if ( !privname )
3345 continue;
3347 if ( !revoke_privilege_by_name( &sid, privname ) ) {
3348 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3349 privname ));
3350 return NT_STATUS_NO_SUCH_PRIVILEGE;
3354 return NT_STATUS_OK;
3357 /*******************************************************************
3358 ********************************************************************/
3360 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3361 struct lsa_RightSet *r,
3362 PRIVILEGE_SET *privileges)
3364 uint32 i;
3365 const char *privname;
3366 const char **privname_array = NULL;
3367 int num_priv = 0;
3369 for (i=0; i<privileges->count; i++) {
3370 if (privileges->set[i].luid.high) {
3371 continue;
3373 privname = sec_privilege_name(privileges->set[i].luid.low);
3374 if (privname) {
3375 if (!add_string_to_array(mem_ctx, privname,
3376 &privname_array, &num_priv)) {
3377 return NT_STATUS_NO_MEMORY;
3382 if (num_priv) {
3384 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3385 num_priv);
3386 if (!r->names) {
3387 return NT_STATUS_NO_MEMORY;
3390 for (i=0; i<num_priv; i++) {
3391 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3394 r->count = num_priv;
3397 return NT_STATUS_OK;
3400 /***************************************************************************
3401 _lsa_EnumAccountRights
3402 ***************************************************************************/
3404 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3405 struct lsa_EnumAccountRights *r)
3407 NTSTATUS status;
3408 struct lsa_info *info = NULL;
3409 PRIVILEGE_SET *privileges;
3411 /* find the connection policy handle. */
3413 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3414 return NT_STATUS_INVALID_HANDLE;
3416 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3417 return NT_STATUS_INVALID_HANDLE;
3420 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3421 return NT_STATUS_ACCESS_DENIED;
3424 /* according to an NT4 PDC, you can add privileges to SIDs even without
3425 call_lsa_create_account() first. And you can use any arbitrary SID. */
3427 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3428 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3429 * the lsa database */
3431 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3432 if (!NT_STATUS_IS_OK(status)) {
3433 return status;
3436 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3437 sid_string_dbg(r->in.sid), privileges->count));
3439 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3441 return status;
3444 /***************************************************************************
3445 _lsa_LookupPrivValue
3446 ***************************************************************************/
3448 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3449 struct lsa_LookupPrivValue *r)
3451 struct lsa_info *info = NULL;
3452 const char *name = NULL;
3454 /* find the connection policy handle. */
3456 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3457 return NT_STATUS_INVALID_HANDLE;
3459 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3460 return NT_STATUS_INVALID_HANDLE;
3463 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3464 return NT_STATUS_ACCESS_DENIED;
3466 name = r->in.name->string;
3468 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3470 r->out.luid->low = sec_privilege_id(name);
3471 r->out.luid->high = 0;
3472 if (r->out.luid->low == SEC_PRIV_INVALID) {
3473 return NT_STATUS_NO_SUCH_PRIVILEGE;
3475 return NT_STATUS_OK;
3478 /***************************************************************************
3479 _lsa_EnumAccountsWithUserRight
3480 ***************************************************************************/
3482 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3483 struct lsa_EnumAccountsWithUserRight *r)
3485 NTSTATUS status;
3486 struct lsa_info *info = NULL;
3487 struct dom_sid *sids = NULL;
3488 int num_sids = 0;
3489 uint32_t i;
3490 enum sec_privilege privilege;
3492 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3493 return NT_STATUS_INVALID_HANDLE;
3496 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3497 return NT_STATUS_INVALID_HANDLE;
3500 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3501 return NT_STATUS_ACCESS_DENIED;
3504 if (!r->in.name || !r->in.name->string) {
3505 return NT_STATUS_NO_SUCH_PRIVILEGE;
3508 privilege = sec_privilege_id(r->in.name->string);
3509 if (privilege == SEC_PRIV_INVALID) {
3510 return NT_STATUS_NO_SUCH_PRIVILEGE;
3513 status = privilege_enum_sids(privilege, p->mem_ctx,
3514 &sids, &num_sids);
3515 if (!NT_STATUS_IS_OK(status)) {
3516 return status;
3519 r->out.sids->num_sids = num_sids;
3520 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3521 r->out.sids->num_sids);
3523 for (i=0; i < r->out.sids->num_sids; i++) {
3524 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3525 &sids[i]);
3526 if (!r->out.sids->sids[i].sid) {
3527 TALLOC_FREE(r->out.sids->sids);
3528 r->out.sids->num_sids = 0;
3529 return NT_STATUS_NO_MEMORY;
3533 return NT_STATUS_OK;
3536 /***************************************************************************
3537 _lsa_Delete
3538 ***************************************************************************/
3540 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3541 struct lsa_Delete *r)
3543 return NT_STATUS_NOT_SUPPORTED;
3546 static NTSTATUS info_ex_2_pdb_trusted_domain(
3547 struct lsa_TrustDomainInfoInfoEx *info_ex,
3548 struct pdb_trusted_domain *td)
3550 if (info_ex->domain_name.string == NULL ||
3551 info_ex->netbios_name.string == NULL ||
3552 info_ex->sid == NULL) {
3553 return NT_STATUS_INVALID_PARAMETER;
3556 td->domain_name = talloc_strdup(td, info_ex->domain_name.string);
3557 td->netbios_name = talloc_strdup(td, info_ex->netbios_name.string);
3558 sid_copy(&td->security_identifier, info_ex->sid);
3559 if (td->domain_name == NULL ||
3560 td->netbios_name == NULL ||
3561 is_null_sid(&td->security_identifier)) {
3562 return NT_STATUS_NO_MEMORY;
3564 td->trust_direction = info_ex->trust_direction;
3565 td->trust_type = info_ex->trust_type;
3566 td->trust_attributes = info_ex->trust_attributes;
3568 return NT_STATUS_OK;
3571 static NTSTATUS setInfoTrustedDomain_base(struct pipes_struct *p,
3572 TALLOC_CTX *mem_ctx,
3573 struct lsa_info *policy,
3574 enum lsa_TrustDomInfoEnum level,
3575 union lsa_TrustedDomainInfo *info)
3577 struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
3578 DATA_BLOB auth_blob;
3579 struct trustDomainPasswords auth_struct;
3580 NTSTATUS nt_status;
3582 struct pdb_trusted_domain *td;
3583 struct pdb_trusted_domain *orig_td;
3585 td = talloc_zero(mem_ctx, struct pdb_trusted_domain);
3586 if (td == NULL) {
3587 return NT_STATUS_NO_MEMORY;
3590 switch (level) {
3591 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
3592 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3593 return NT_STATUS_ACCESS_DENIED;
3595 td->trust_posix_offset = &info->posix_offset.posix_offset;
3596 break;
3597 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
3598 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3599 return NT_STATUS_ACCESS_DENIED;
3601 nt_status = info_ex_2_pdb_trusted_domain(&info->info_ex, td);
3602 if (!NT_STATUS_IS_OK(nt_status)) {
3603 return nt_status;
3605 break;
3606 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
3607 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3608 return NT_STATUS_ACCESS_DENIED;
3610 nt_status = auth_info_2_auth_blob(td, &info->auth_info,
3611 &td->trust_auth_incoming,
3612 &td->trust_auth_outgoing);
3613 if (!NT_STATUS_IS_OK(nt_status)) {
3614 return nt_status;
3616 break;
3617 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
3618 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3619 return NT_STATUS_ACCESS_DENIED;
3621 td->trust_posix_offset = &info->full_info.posix_offset.posix_offset;
3622 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info.info_ex,
3623 td);
3624 if (!NT_STATUS_IS_OK(nt_status)) {
3625 return nt_status;
3627 nt_status = auth_info_2_auth_blob(td,
3628 &info->full_info.auth_info,
3629 &td->trust_auth_incoming,
3630 &td->trust_auth_outgoing);
3631 if (!NT_STATUS_IS_OK(nt_status)) {
3632 return nt_status;
3634 break;
3635 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
3636 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3637 return NT_STATUS_ACCESS_DENIED;
3639 auth_info_int = &info->auth_info_internal;
3640 break;
3641 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
3642 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3643 return NT_STATUS_ACCESS_DENIED;
3645 td->trust_posix_offset = &info->full_info_internal.posix_offset.posix_offset;
3646 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info_internal.info_ex,
3647 td);
3648 if (!NT_STATUS_IS_OK(nt_status)) {
3649 return nt_status;
3651 auth_info_int = &info->full_info_internal.auth_info;
3652 break;
3653 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
3654 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3655 return NT_STATUS_ACCESS_DENIED;
3657 td->supported_enc_type = &info->enc_types.enc_types;
3658 break;
3659 default:
3660 return NT_STATUS_INVALID_PARAMETER;
3663 /* decode auth_info_int if set */
3664 if (auth_info_int) {
3666 /* now decrypt blob */
3667 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
3668 auth_info_int->auth_blob.size);
3670 nt_status = get_trustdom_auth_blob(p, mem_ctx,
3671 &auth_blob, &auth_struct);
3672 if (!NT_STATUS_IS_OK(nt_status)) {
3673 return nt_status;
3675 } else {
3676 memset(&auth_struct, 0, sizeof(auth_struct));
3679 /* TODO: verify only one object matches the dns/netbios/sid triplet and that
3680 * this is the one we already have */
3682 /* TODO: check if the trust direction is changed and we need to add or remove
3683 * auth data */
3685 /* TODO: check if trust type shall be changed and return an error in this case
3686 * */
3687 nt_status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &policy->sid,
3688 &orig_td);
3689 if (!NT_STATUS_IS_OK(nt_status)) {
3690 return nt_status;
3694 /* TODO: should we fetch previous values from the existing entry
3695 * and append them ? */
3696 if (auth_struct.incoming.count) {
3697 nt_status = get_trustauth_inout_blob(mem_ctx,
3698 &auth_struct.incoming,
3699 &td->trust_auth_incoming);
3700 if (!NT_STATUS_IS_OK(nt_status)) {
3701 return nt_status;
3703 } else {
3704 ZERO_STRUCT(td->trust_auth_incoming);
3707 if (auth_struct.outgoing.count) {
3708 nt_status = get_trustauth_inout_blob(mem_ctx,
3709 &auth_struct.outgoing,
3710 &td->trust_auth_outgoing);
3711 if (!NT_STATUS_IS_OK(nt_status)) {
3712 return nt_status;
3714 } else {
3715 ZERO_STRUCT(td->trust_auth_outgoing);
3718 nt_status = pdb_set_trusted_domain(orig_td->domain_name, td);
3719 if (!NT_STATUS_IS_OK(nt_status)) {
3720 return nt_status;
3723 return NT_STATUS_OK;
3726 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3727 struct lsa_SetTrustedDomainInfo *r)
3729 NTSTATUS status;
3730 struct policy_handle trustdom_handle;
3731 struct lsa_OpenTrustedDomain o;
3732 struct lsa_SetInformationTrustedDomain s;
3733 struct lsa_Close c;
3735 o.in.handle = r->in.handle;
3736 o.in.sid = r->in.dom_sid;
3737 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3738 o.out.trustdom_handle = &trustdom_handle;
3740 status = _lsa_OpenTrustedDomain(p, &o);
3741 if (!NT_STATUS_IS_OK(status)) {
3742 return status;
3745 s.in.trustdom_handle = &trustdom_handle;
3746 s.in.level = r->in.level;
3747 s.in.info = r->in.info;
3749 status = _lsa_SetInformationTrustedDomain(p, &s);
3750 if (!NT_STATUS_IS_OK(status)) {
3751 return status;
3754 c.in.handle = &trustdom_handle;
3755 c.out.handle = &trustdom_handle;
3757 return _lsa_Close(p, &c);
3760 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3761 struct lsa_SetTrustedDomainInfoByName *r)
3763 NTSTATUS status;
3764 struct policy_handle trustdom_handle;
3765 struct lsa_OpenTrustedDomainByName o;
3766 struct lsa_SetInformationTrustedDomain s;
3767 struct lsa_Close c;
3769 o.in.handle = r->in.handle;
3770 o.in.name.string = r->in.trusted_domain->string;
3771 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3772 o.out.trustdom_handle = &trustdom_handle;
3774 status = _lsa_OpenTrustedDomainByName(p, &o);
3775 if (!NT_STATUS_IS_OK(status)) {
3776 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
3777 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3779 return status;
3782 s.in.trustdom_handle = &trustdom_handle;
3783 s.in.level = r->in.level;
3784 s.in.info = r->in.info;
3786 status = _lsa_SetInformationTrustedDomain(p, &s);
3787 if (!NT_STATUS_IS_OK(status)) {
3788 return status;
3791 c.in.handle = &trustdom_handle;
3792 c.out.handle = &trustdom_handle;
3794 return _lsa_Close(p, &c);
3797 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3798 struct lsa_SetInformationTrustedDomain *r)
3800 struct lsa_info *policy;
3802 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&policy)) {
3803 return NT_STATUS_INVALID_HANDLE;
3806 if (policy->type != LSA_HANDLE_TRUST_TYPE) {
3807 return NT_STATUS_INVALID_HANDLE;
3810 return setInfoTrustedDomain_base(p, p->mem_ctx, policy,
3811 r->in.level, r->in.info);
3816 * From here on the server routines are just dummy ones to make smbd link with
3817 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3818 * pulling the server stubs across one by one.
3821 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3823 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3824 return NT_STATUS_NOT_IMPLEMENTED;
3827 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3828 struct lsa_ChangePassword *r)
3830 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3831 return NT_STATUS_NOT_IMPLEMENTED;
3834 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3836 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3837 return NT_STATUS_NOT_IMPLEMENTED;
3840 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3842 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3843 return NT_STATUS_NOT_IMPLEMENTED;
3846 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3847 struct lsa_GetQuotasForAccount *r)
3849 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3850 return NT_STATUS_NOT_IMPLEMENTED;
3853 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3854 struct lsa_SetQuotasForAccount *r)
3856 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3857 return NT_STATUS_NOT_IMPLEMENTED;
3860 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3861 struct lsa_StorePrivateData *r)
3863 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3864 return NT_STATUS_NOT_IMPLEMENTED;
3867 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3868 struct lsa_RetrievePrivateData *r)
3870 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3871 return NT_STATUS_NOT_IMPLEMENTED;
3874 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3875 struct lsa_SetInfoPolicy2 *r)
3877 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3878 return NT_STATUS_NOT_IMPLEMENTED;
3881 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3882 struct lsa_EnumTrustedDomainsEx *r)
3884 struct lsa_info *info;
3885 uint32_t count;
3886 struct pdb_trusted_domain **domains;
3887 struct lsa_TrustDomainInfoInfoEx *entries;
3888 int i;
3889 NTSTATUS nt_status;
3891 /* bail out early if pdb backend is not capable of ex trusted domains,
3892 * if we dont do that, the client might not call
3893 * _lsa_EnumTrustedDomains() afterwards - gd */
3895 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3896 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3897 return NT_STATUS_NOT_IMPLEMENTED;
3900 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3901 return NT_STATUS_INVALID_HANDLE;
3903 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3904 return NT_STATUS_INVALID_HANDLE;
3907 /* check if the user has enough rights */
3908 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3909 return NT_STATUS_ACCESS_DENIED;
3911 become_root();
3912 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3913 unbecome_root();
3915 if (!NT_STATUS_IS_OK(nt_status)) {
3916 return nt_status;
3919 entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3920 count);
3921 if (!entries) {
3922 return NT_STATUS_NO_MEMORY;
3925 for (i=0; i<count; i++) {
3926 init_lsa_StringLarge(&entries[i].netbios_name,
3927 domains[i]->netbios_name);
3928 entries[i].sid = &domains[i]->security_identifier;
3931 if (*r->in.resume_handle >= count) {
3932 *r->out.resume_handle = -1;
3933 TALLOC_FREE(entries);
3934 return NT_STATUS_NO_MORE_ENTRIES;
3937 /* return the rest, limit by max_size. Note that we
3938 use the w2k3 element size value of 60 */
3939 r->out.domains->count = count - *r->in.resume_handle;
3940 r->out.domains->count = MIN(r->out.domains->count,
3941 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3943 r->out.domains->domains = entries + *r->in.resume_handle;
3945 if (r->out.domains->count < count - *r->in.resume_handle) {
3946 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3947 return STATUS_MORE_ENTRIES;
3950 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3951 * always be larger than the previous input resume handle, in
3952 * particular when hitting the last query it is vital to set the
3953 * resume handle correctly to avoid infinite client loops, as
3954 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3955 * status is NT_STATUS_OK - gd */
3957 *r->out.resume_handle = (uint32_t)-1;
3959 return NT_STATUS_OK;
3962 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3963 struct lsa_QueryDomainInformationPolicy *r)
3965 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3966 return NT_STATUS_NOT_IMPLEMENTED;
3969 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3970 struct lsa_SetDomainInformationPolicy *r)
3972 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3973 return NT_STATUS_NOT_IMPLEMENTED;
3976 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3978 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3979 return NT_STATUS_NOT_IMPLEMENTED;
3982 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3984 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3985 return NT_STATUS_NOT_IMPLEMENTED;
3988 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3990 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3991 return NT_STATUS_NOT_IMPLEMENTED;
3994 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3996 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3997 return NT_STATUS_NOT_IMPLEMENTED;
4000 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
4001 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
4003 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4004 return NT_STATUS_NOT_IMPLEMENTED;
4007 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
4008 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
4010 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4011 return NT_STATUS_NOT_IMPLEMENTED;
4014 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
4016 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4017 return NT_STATUS_NOT_IMPLEMENTED;
4020 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
4021 struct lsa_CREDRGETTARGETINFO *r)
4023 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4024 return NT_STATUS_NOT_IMPLEMENTED;
4027 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
4028 struct lsa_CREDRPROFILELOADED *r)
4030 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4031 return NT_STATUS_NOT_IMPLEMENTED;
4034 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
4035 struct lsa_CREDRGETSESSIONTYPES *r)
4037 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4038 return NT_STATUS_NOT_IMPLEMENTED;
4041 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
4042 struct lsa_LSARREGISTERAUDITEVENT *r)
4044 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4045 return NT_STATUS_NOT_IMPLEMENTED;
4048 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
4049 struct lsa_LSARGENAUDITEVENT *r)
4051 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4052 return NT_STATUS_NOT_IMPLEMENTED;
4055 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
4056 struct lsa_LSARUNREGISTERAUDITEVENT *r)
4058 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4059 return NT_STATUS_NOT_IMPLEMENTED;
4062 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
4063 struct lsa_lsaRQueryForestTrustInformation *r)
4065 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4066 return NT_STATUS_NOT_IMPLEMENTED;
4069 #define DNS_CMP_MATCH 0
4070 #define DNS_CMP_FIRST_IS_CHILD 1
4071 #define DNS_CMP_SECOND_IS_CHILD 2
4072 #define DNS_CMP_NO_MATCH 3
4074 /* this function assumes names are well formed DNS names.
4075 * it doesn't validate them */
4076 static int dns_cmp(const char *s1, size_t l1,
4077 const char *s2, size_t l2)
4079 const char *p1, *p2;
4080 size_t t1, t2;
4081 int cret;
4083 if (l1 == l2) {
4084 if (strcasecmp_m(s1, s2) == 0) {
4085 return DNS_CMP_MATCH;
4087 return DNS_CMP_NO_MATCH;
4090 if (l1 > l2) {
4091 p1 = s1;
4092 p2 = s2;
4093 t1 = l1;
4094 t2 = l2;
4095 cret = DNS_CMP_FIRST_IS_CHILD;
4096 } else {
4097 p1 = s2;
4098 p2 = s1;
4099 t1 = l2;
4100 t2 = l1;
4101 cret = DNS_CMP_SECOND_IS_CHILD;
4104 if (p1[t1 - t2 - 1] != '.') {
4105 return DNS_CMP_NO_MATCH;
4108 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
4109 return cret;
4112 return DNS_CMP_NO_MATCH;
4115 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
4116 struct lsa_ForestTrustInformation *lfti,
4117 struct ForestTrustInfo *fti)
4119 struct lsa_ForestTrustRecord *lrec;
4120 struct ForestTrustInfoRecord *rec;
4121 struct lsa_StringLarge *tln;
4122 struct lsa_ForestTrustDomainInfo *info;
4123 uint32_t i;
4125 fti->version = 1;
4126 fti->count = lfti->count;
4127 fti->records = talloc_array(mem_ctx,
4128 struct ForestTrustInfoRecordArmor,
4129 fti->count);
4130 if (!fti->records) {
4131 return NT_STATUS_NO_MEMORY;
4133 for (i = 0; i < fti->count; i++) {
4134 lrec = lfti->entries[i];
4135 rec = &fti->records[i].record;
4137 rec->flags = lrec->flags;
4138 rec->timestamp = lrec->time;
4139 rec->type = lrec->type;
4141 switch (lrec->type) {
4142 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
4143 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4144 tln = &lrec->forest_trust_data.top_level_name;
4145 rec->data.name.string =
4146 talloc_strdup(mem_ctx, tln->string);
4147 if (!rec->data.name.string) {
4148 return NT_STATUS_NO_MEMORY;
4150 rec->data.name.size = strlen(rec->data.name.string);
4151 break;
4152 case LSA_FOREST_TRUST_DOMAIN_INFO:
4153 info = &lrec->forest_trust_data.domain_info;
4154 rec->data.info.sid = *info->domain_sid;
4155 rec->data.info.dns_name.string =
4156 talloc_strdup(mem_ctx,
4157 info->dns_domain_name.string);
4158 if (!rec->data.info.dns_name.string) {
4159 return NT_STATUS_NO_MEMORY;
4161 rec->data.info.dns_name.size =
4162 strlen(rec->data.info.dns_name.string);
4163 rec->data.info.netbios_name.string =
4164 talloc_strdup(mem_ctx,
4165 info->netbios_domain_name.string);
4166 if (!rec->data.info.netbios_name.string) {
4167 return NT_STATUS_NO_MEMORY;
4169 rec->data.info.netbios_name.size =
4170 strlen(rec->data.info.netbios_name.string);
4171 break;
4172 default:
4173 return NT_STATUS_INVALID_DOMAIN_STATE;
4177 return NT_STATUS_OK;
4180 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4181 uint32_t index, uint32_t collision_type,
4182 uint32_t conflict_type, const char *tdo_name);
4184 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
4185 const char *tdo_name,
4186 struct ForestTrustInfo *tdo_fti,
4187 struct ForestTrustInfo *new_fti,
4188 struct lsa_ForestTrustCollisionInfo *c_info)
4190 struct ForestTrustInfoRecord *nrec;
4191 struct ForestTrustInfoRecord *trec;
4192 const char *dns_name;
4193 const char *nb_name = NULL;
4194 struct dom_sid *sid = NULL;
4195 const char *tname = NULL;
4196 size_t dns_len = 0;
4197 size_t tlen = 0;
4198 uint32_t new_fti_idx;
4199 uint32_t i;
4200 /* use always TDO type, until we understand when Xref can be used */
4201 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
4202 bool tln_conflict;
4203 bool sid_conflict;
4204 bool nb_conflict;
4205 bool exclusion;
4206 bool ex_rule = false;
4207 int ret;
4209 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
4211 nrec = &new_fti->records[new_fti_idx].record;
4212 dns_name = NULL;
4213 tln_conflict = false;
4214 sid_conflict = false;
4215 nb_conflict = false;
4216 exclusion = false;
4218 switch (nrec->type) {
4219 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4220 /* exclusions do not conflict by definition */
4221 break;
4223 case FOREST_TRUST_TOP_LEVEL_NAME:
4224 dns_name = nrec->data.name.string;
4225 dns_len = nrec->data.name.size;
4226 break;
4228 case LSA_FOREST_TRUST_DOMAIN_INFO:
4229 dns_name = nrec->data.info.dns_name.string;
4230 dns_len = nrec->data.info.dns_name.size;
4231 nb_name = nrec->data.info.netbios_name.string;
4232 sid = &nrec->data.info.sid;
4233 break;
4236 if (!dns_name) continue;
4238 /* check if this is already taken and not excluded */
4239 for (i = 0; i < tdo_fti->count; i++) {
4240 trec = &tdo_fti->records[i].record;
4242 switch (trec->type) {
4243 case FOREST_TRUST_TOP_LEVEL_NAME:
4244 ex_rule = false;
4245 tname = trec->data.name.string;
4246 tlen = trec->data.name.size;
4247 break;
4248 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
4249 ex_rule = true;
4250 tname = trec->data.name.string;
4251 tlen = trec->data.name.size;
4252 break;
4253 case FOREST_TRUST_DOMAIN_INFO:
4254 ex_rule = false;
4255 tname = trec->data.info.dns_name.string;
4256 tlen = trec->data.info.dns_name.size;
4257 break;
4258 default:
4259 return NT_STATUS_INVALID_PARAMETER;
4261 ret = dns_cmp(dns_name, dns_len, tname, tlen);
4262 switch (ret) {
4263 case DNS_CMP_MATCH:
4264 /* if it matches exclusion,
4265 * it doesn't conflict */
4266 if (ex_rule) {
4267 exclusion = true;
4268 break;
4270 /* fall through */
4271 case DNS_CMP_FIRST_IS_CHILD:
4272 case DNS_CMP_SECOND_IS_CHILD:
4273 tln_conflict = true;
4274 /* fall through */
4275 default:
4276 break;
4279 /* explicit exclusion, no dns name conflict here */
4280 if (exclusion) {
4281 tln_conflict = false;
4284 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
4285 continue;
4288 /* also test for domain info */
4289 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
4290 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
4291 sid_conflict = true;
4293 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
4294 strcasecmp_m(trec->data.info.netbios_name.string,
4295 nb_name) == 0) {
4296 nb_conflict = true;
4300 if (tln_conflict) {
4301 (void)add_collision(c_info, new_fti_idx,
4302 collision_type,
4303 LSA_TLN_DISABLED_CONFLICT,
4304 tdo_name);
4306 if (sid_conflict) {
4307 (void)add_collision(c_info, new_fti_idx,
4308 collision_type,
4309 LSA_SID_DISABLED_CONFLICT,
4310 tdo_name);
4312 if (nb_conflict) {
4313 (void)add_collision(c_info, new_fti_idx,
4314 collision_type,
4315 LSA_NB_DISABLED_CONFLICT,
4316 tdo_name);
4320 return NT_STATUS_OK;
4323 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4324 uint32_t idx, uint32_t collision_type,
4325 uint32_t conflict_type, const char *tdo_name)
4327 struct lsa_ForestTrustCollisionRecord **es;
4328 uint32_t i = c_info->count;
4330 es = talloc_realloc(c_info, c_info->entries,
4331 struct lsa_ForestTrustCollisionRecord *, i + 1);
4332 if (!es) {
4333 return NT_STATUS_NO_MEMORY;
4335 c_info->entries = es;
4336 c_info->count = i + 1;
4338 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4339 if (!es[i]) {
4340 return NT_STATUS_NO_MEMORY;
4343 es[i]->index = idx;
4344 es[i]->type = collision_type;
4345 es[i]->flags.flags = conflict_type;
4346 es[i]->name.string = talloc_strdup(es[i], tdo_name);
4347 if (!es[i]->name.string) {
4348 return NT_STATUS_NO_MEMORY;
4350 es[i]->name.size = strlen(es[i]->name.string);
4352 return NT_STATUS_OK;
4355 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
4356 struct pdb_trusted_domain *td,
4357 struct ForestTrustInfo *info)
4359 enum ndr_err_code ndr_err;
4361 if (td->trust_forest_trust_info.length == 0 ||
4362 td->trust_forest_trust_info.data == NULL) {
4363 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4365 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
4366 info,
4367 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
4368 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4369 return NT_STATUS_INVALID_DOMAIN_STATE;
4372 return NT_STATUS_OK;
4375 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
4376 struct ForestTrustInfo *fti)
4378 struct ForestTrustDataDomainInfo *info;
4379 struct ForestTrustInfoRecord *rec;
4381 fti->version = 1;
4382 fti->count = 2;
4383 fti->records = talloc_array(fti,
4384 struct ForestTrustInfoRecordArmor, 2);
4385 if (!fti->records) {
4386 return NT_STATUS_NO_MEMORY;
4389 /* TLN info */
4390 rec = &fti->records[0].record;
4392 rec->flags = 0;
4393 rec->timestamp = 0;
4394 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
4396 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
4397 if (!rec->data.name.string) {
4398 return NT_STATUS_NO_MEMORY;
4400 rec->data.name.size = strlen(rec->data.name.string);
4402 /* DOMAIN info */
4403 rec = &fti->records[1].record;
4405 rec->flags = 0;
4406 rec->timestamp = 0;
4407 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
4409 info = &rec->data.info;
4411 info->sid = dom_info->sid;
4412 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
4413 if (!info->dns_name.string) {
4414 return NT_STATUS_NO_MEMORY;
4416 info->dns_name.size = strlen(info->dns_name.string);
4417 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
4418 if (!info->netbios_name.string) {
4419 return NT_STATUS_NO_MEMORY;
4421 info->netbios_name.size = strlen(info->netbios_name.string);
4423 return NT_STATUS_OK;
4426 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
4427 struct lsa_lsaRSetForestTrustInformation *r)
4429 NTSTATUS status;
4430 int i;
4431 int j;
4432 struct lsa_info *handle;
4433 uint32_t num_domains;
4434 struct pdb_trusted_domain **domains;
4435 struct ForestTrustInfo *nfti;
4436 struct ForestTrustInfo *fti;
4437 struct lsa_ForestTrustCollisionInfo *c_info;
4438 struct pdb_domain_info *dom_info;
4439 enum ndr_err_code ndr_err;
4441 if (!IS_DC) {
4442 return NT_STATUS_NOT_SUPPORTED;
4445 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
4446 return NT_STATUS_INVALID_HANDLE;
4449 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
4450 return NT_STATUS_INVALID_HANDLE;
4453 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
4454 return NT_STATUS_ACCESS_DENIED;
4457 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
4458 if (!NT_STATUS_IS_OK(status)) {
4459 return status;
4461 if (num_domains == 0) {
4462 return NT_STATUS_NO_SUCH_DOMAIN;
4465 for (i = 0; i < num_domains; i++) {
4466 if (domains[i]->domain_name == NULL) {
4467 return NT_STATUS_INVALID_DOMAIN_STATE;
4469 if (strcasecmp_m(domains[i]->domain_name,
4470 r->in.trusted_domain_name->string) == 0) {
4471 break;
4474 if (i >= num_domains) {
4475 return NT_STATUS_NO_SUCH_DOMAIN;
4478 if (!(domains[i]->trust_attributes &
4479 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4480 return NT_STATUS_INVALID_PARAMETER;
4483 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4484 return NT_STATUS_INVALID_PARAMETER;
4487 /* The following section until COPY_END is a copy from
4488 * source4/rpmc_server/lsa/scesrc_lsa.c */
4489 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
4490 if (!nfti) {
4491 return NT_STATUS_NO_MEMORY;
4494 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4495 if (!NT_STATUS_IS_OK(status)) {
4496 return status;
4499 c_info = talloc_zero(r->out.collision_info,
4500 struct lsa_ForestTrustCollisionInfo);
4501 if (!c_info) {
4502 return NT_STATUS_NO_MEMORY;
4505 /* first check own info, then other domains */
4506 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4507 if (!fti) {
4508 return NT_STATUS_NO_MEMORY;
4511 dom_info = pdb_get_domain_info(p->mem_ctx);
4513 status = own_ft_info(dom_info, fti);
4514 if (!NT_STATUS_IS_OK(status)) {
4515 return status;
4518 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
4519 if (!NT_STATUS_IS_OK(status)) {
4520 return status;
4523 for (j = 0; j < num_domains; j++) {
4524 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4525 if (!fti) {
4526 return NT_STATUS_NO_MEMORY;
4529 status = get_ft_info(p->mem_ctx, domains[j], fti);
4530 if (!NT_STATUS_IS_OK(status)) {
4531 if (NT_STATUS_EQUAL(status,
4532 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4533 continue;
4535 return status;
4538 if (domains[j]->domain_name == NULL) {
4539 return NT_STATUS_INVALID_DOMAIN_STATE;
4542 status = check_ft_info(c_info, domains[j]->domain_name,
4543 fti, nfti, c_info);
4544 if (!NT_STATUS_IS_OK(status)) {
4545 return status;
4549 *r->out.collision_info = c_info;
4551 if (r->in.check_only != 0) {
4552 return NT_STATUS_OK;
4555 /* COPY_END */
4557 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
4558 p->mem_ctx, nfti,
4559 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4560 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4561 return NT_STATUS_INVALID_PARAMETER;
4564 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
4565 if (!NT_STATUS_IS_OK(status)) {
4566 return status;
4569 return NT_STATUS_OK;
4572 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
4573 struct lsa_CREDRRENAME *r)
4575 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4576 return NT_STATUS_NOT_IMPLEMENTED;
4579 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
4580 struct lsa_LSAROPENPOLICYSCE *r)
4582 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4583 return NT_STATUS_NOT_IMPLEMENTED;
4586 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4587 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4589 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4590 return NT_STATUS_NOT_IMPLEMENTED;
4593 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4594 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4596 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4597 return NT_STATUS_NOT_IMPLEMENTED;
4600 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4601 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4603 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4604 return NT_STATUS_NOT_IMPLEMENTED;