spoolss: fill in IDL for JobNamedProperty calls.
[Samba.git] / source3 / rpc_server / lsa / srv_lsa_nt.c
blobf4dc4afd57fa19997b3c65b34cd82e02a8a196af
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 p->auth.auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1131 DEBUG(1, ("_lsa_LookupSids3: The client %s is not using "
1132 "a secure connection over netlogon\n",
1133 get_remote_machine_name() ));
1134 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1135 return NT_STATUS_ACCESS_DENIED;
1138 q.in.handle = NULL;
1139 q.in.sids = r->in.sids;
1140 q.in.level = r->in.level;
1141 q.in.lookup_options = r->in.lookup_options;
1142 q.in.client_revision = r->in.client_revision;
1143 q.in.names = r->in.names;
1144 q.in.count = r->in.count;
1146 q.out.domains = r->out.domains;
1147 q.out.names = r->out.names;
1148 q.out.count = r->out.count;
1150 return _lsa_LookupSids_common(p, &q);
1153 /***************************************************************************
1154 ***************************************************************************/
1156 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1158 int flags;
1160 switch (level) {
1161 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1162 flags = LOOKUP_NAME_ALL;
1163 break;
1164 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1165 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1166 break;
1167 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1168 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1169 break;
1170 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1171 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1172 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1173 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1174 default:
1175 flags = LOOKUP_NAME_NONE;
1176 break;
1179 return flags;
1182 /***************************************************************************
1183 _lsa_LookupNames
1184 ***************************************************************************/
1186 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1187 struct lsa_LookupNames *r)
1189 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1190 struct lsa_info *handle;
1191 struct lsa_String *names = r->in.names;
1192 uint32 num_entries = r->in.num_names;
1193 struct lsa_RefDomainList *domains = NULL;
1194 struct lsa_TranslatedSid *rids = NULL;
1195 uint32 mapped_count = 0;
1196 int flags = 0;
1198 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1199 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1200 return NT_STATUS_ACCESS_DENIED;
1203 if (num_entries > MAX_LOOKUP_SIDS) {
1204 num_entries = MAX_LOOKUP_SIDS;
1205 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1206 num_entries));
1209 flags = lsa_lookup_level_to_flags(r->in.level);
1211 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1212 if (!domains) {
1213 return NT_STATUS_NO_MEMORY;
1216 if (num_entries) {
1217 rids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid,
1218 num_entries);
1219 if (!rids) {
1220 return NT_STATUS_NO_MEMORY;
1222 } else {
1223 rids = NULL;
1226 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1227 status = NT_STATUS_INVALID_HANDLE;
1228 goto done;
1231 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1232 return NT_STATUS_INVALID_HANDLE;
1235 /* check if the user has enough rights */
1236 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1237 status = NT_STATUS_ACCESS_DENIED;
1238 goto done;
1241 /* set up the LSA Lookup RIDs response */
1242 become_root(); /* lookup_name can require root privs */
1243 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1244 names, flags, &mapped_count);
1245 unbecome_root();
1247 done:
1249 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1250 if (mapped_count == 0) {
1251 status = NT_STATUS_NONE_MAPPED;
1252 } else if (mapped_count != num_entries) {
1253 status = STATUS_SOME_UNMAPPED;
1257 *r->out.count = mapped_count;
1258 *r->out.domains = domains;
1259 r->out.sids->sids = rids;
1260 r->out.sids->count = num_entries;
1262 return status;
1265 /***************************************************************************
1266 _lsa_LookupNames2
1267 ***************************************************************************/
1269 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1270 struct lsa_LookupNames2 *r)
1272 NTSTATUS status;
1273 struct lsa_LookupNames q;
1274 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1275 struct lsa_TransSidArray *sid_array = NULL;
1276 uint32_t i;
1278 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1279 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1280 return NT_STATUS_ACCESS_DENIED;
1283 sid_array = talloc_zero(p->mem_ctx, struct lsa_TransSidArray);
1284 if (!sid_array) {
1285 return NT_STATUS_NO_MEMORY;
1288 q.in.handle = r->in.handle;
1289 q.in.num_names = r->in.num_names;
1290 q.in.names = r->in.names;
1291 q.in.level = r->in.level;
1292 q.in.sids = sid_array;
1293 q.in.count = r->in.count;
1294 /* we do not know what this is for */
1295 /* = r->in.unknown1; */
1296 /* = r->in.unknown2; */
1298 q.out.domains = r->out.domains;
1299 q.out.sids = sid_array;
1300 q.out.count = r->out.count;
1302 status = _lsa_LookupNames(p, &q);
1304 sid_array2->count = sid_array->count;
1305 sid_array2->sids = talloc_array(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1306 if (!sid_array2->sids) {
1307 return NT_STATUS_NO_MEMORY;
1310 for (i=0; i<sid_array->count; i++) {
1311 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1312 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1313 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1314 sid_array2->sids[i].unknown = 0;
1317 r->out.sids = sid_array2;
1319 return status;
1322 static NTSTATUS _lsa_LookupNames_common(struct pipes_struct *p,
1323 struct lsa_LookupNames3 *r)
1325 NTSTATUS status;
1326 struct lsa_info *handle;
1327 struct lsa_String *names = r->in.names;
1328 uint32 num_entries = r->in.num_names;
1329 struct lsa_RefDomainList *domains = NULL;
1330 struct lsa_TranslatedSid3 *trans_sids = NULL;
1331 uint32 mapped_count = 0;
1332 int flags = 0;
1333 bool check_policy = true;
1335 switch (p->opnum) {
1336 case NDR_LSA_LOOKUPNAMES4:
1337 check_policy = false;
1338 break;
1339 case NDR_LSA_LOOKUPNAMES3:
1340 default:
1341 check_policy = true;
1344 if (num_entries > MAX_LOOKUP_SIDS) {
1345 num_entries = MAX_LOOKUP_SIDS;
1346 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1349 flags = lsa_lookup_level_to_flags(r->in.level);
1351 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1352 if (!domains) {
1353 return NT_STATUS_NO_MEMORY;
1356 if (num_entries) {
1357 trans_sids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid3,
1358 num_entries);
1359 if (!trans_sids) {
1360 return NT_STATUS_NO_MEMORY;
1362 } else {
1363 trans_sids = NULL;
1366 if (check_policy) {
1368 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1369 status = NT_STATUS_INVALID_HANDLE;
1370 goto done;
1373 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1374 return NT_STATUS_INVALID_HANDLE;
1377 /* check if the user has enough rights */
1378 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1379 status = NT_STATUS_ACCESS_DENIED;
1380 goto done;
1384 /* set up the LSA Lookup SIDs response */
1385 become_root(); /* lookup_name can require root privs */
1386 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1387 names, flags, &mapped_count);
1388 unbecome_root();
1390 done:
1392 if (NT_STATUS_IS_OK(status)) {
1393 if (mapped_count == 0) {
1394 status = NT_STATUS_NONE_MAPPED;
1395 } else if (mapped_count != num_entries) {
1396 status = STATUS_SOME_UNMAPPED;
1400 *r->out.count = mapped_count;
1401 *r->out.domains = domains;
1402 r->out.sids->sids = trans_sids;
1403 r->out.sids->count = num_entries;
1405 return status;
1408 /***************************************************************************
1409 _lsa_LookupNames3
1410 ***************************************************************************/
1412 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1413 struct lsa_LookupNames3 *r)
1415 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1416 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1417 return NT_STATUS_ACCESS_DENIED;
1420 return _lsa_LookupNames_common(p, r);
1423 /***************************************************************************
1424 _lsa_LookupNames4
1425 ***************************************************************************/
1427 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1428 struct lsa_LookupNames4 *r)
1430 struct lsa_LookupNames3 q;
1432 if (p->transport != NCACN_IP_TCP) {
1433 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1434 return NT_STATUS_ACCESS_DENIED;
1437 /* No policy handle on this call. Restrict to crypto connections. */
1438 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
1439 p->auth.auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1440 DEBUG(1, ("_lsa_LookupNames4: The client %s is not using "
1441 "a secure connection over netlogon\n",
1442 get_remote_machine_name()));
1443 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1444 return NT_STATUS_ACCESS_DENIED;
1447 q.in.handle = NULL;
1448 q.in.num_names = r->in.num_names;
1449 q.in.names = r->in.names;
1450 q.in.level = r->in.level;
1451 q.in.lookup_options = r->in.lookup_options;
1452 q.in.client_revision = r->in.client_revision;
1453 q.in.sids = r->in.sids;
1454 q.in.count = r->in.count;
1456 q.out.domains = r->out.domains;
1457 q.out.sids = r->out.sids;
1458 q.out.count = r->out.count;
1460 return _lsa_LookupNames_common(p, &q);
1463 /***************************************************************************
1464 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1465 ***************************************************************************/
1467 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1469 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1470 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1471 return NT_STATUS_ACCESS_DENIED;
1474 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1475 return NT_STATUS_INVALID_HANDLE;
1478 close_policy_hnd(p, r->in.handle);
1479 ZERO_STRUCTP(r->out.handle);
1480 return NT_STATUS_OK;
1483 /***************************************************************************
1484 ***************************************************************************/
1486 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1487 const struct dom_sid *sid,
1488 struct trustdom_info **info)
1490 NTSTATUS status;
1491 uint32_t num_domains = 0;
1492 struct trustdom_info **domains = NULL;
1493 int i;
1495 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1496 if (!NT_STATUS_IS_OK(status)) {
1497 return status;
1500 for (i=0; i < num_domains; i++) {
1501 if (dom_sid_equal(&domains[i]->sid, sid)) {
1502 break;
1506 if (i == num_domains) {
1507 return NT_STATUS_INVALID_PARAMETER;
1510 *info = domains[i];
1512 return NT_STATUS_OK;
1515 /***************************************************************************
1516 ***************************************************************************/
1518 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1519 const char *netbios_domain_name,
1520 struct trustdom_info **info_p)
1522 NTSTATUS status;
1523 struct trustdom_info *info;
1524 struct pdb_trusted_domain *td;
1526 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1527 if (!NT_STATUS_IS_OK(status)) {
1528 return status;
1531 info = talloc(mem_ctx, struct trustdom_info);
1532 if (!info) {
1533 return NT_STATUS_NO_MEMORY;
1536 info->name = talloc_strdup(info, netbios_domain_name);
1537 NT_STATUS_HAVE_NO_MEMORY(info->name);
1539 sid_copy(&info->sid, &td->security_identifier);
1541 *info_p = info;
1543 return NT_STATUS_OK;
1546 /***************************************************************************
1547 _lsa_OpenSecret
1548 ***************************************************************************/
1550 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p,
1551 struct lsa_OpenSecret *r)
1553 struct lsa_info *handle;
1554 struct security_descriptor *psd;
1555 NTSTATUS status;
1556 uint32_t acc_granted;
1558 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1559 return NT_STATUS_INVALID_HANDLE;
1562 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1563 return NT_STATUS_INVALID_HANDLE;
1566 if (!r->in.name.string) {
1567 return NT_STATUS_INVALID_PARAMETER;
1570 /* Work out max allowed. */
1571 map_max_allowed_access(p->session_info->security_token,
1572 p->session_info->unix_token,
1573 &r->in.access_mask);
1575 /* map the generic bits to the lsa policy ones */
1576 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
1578 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
1579 NULL,
1580 NULL,
1581 NULL,
1582 NULL,
1583 &psd);
1584 if (!NT_STATUS_IS_OK(status)) {
1585 return status;
1588 status = access_check_object(psd, p->session_info->security_token,
1589 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1590 r->in.access_mask,
1591 &acc_granted, "_lsa_OpenSecret");
1592 if (!NT_STATUS_IS_OK(status)) {
1593 return status;
1596 status = create_lsa_policy_handle(p->mem_ctx, p,
1597 LSA_HANDLE_SECRET_TYPE,
1598 acc_granted,
1599 NULL,
1600 r->in.name.string,
1601 psd,
1602 r->out.sec_handle);
1603 if (!NT_STATUS_IS_OK(status)) {
1604 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1607 return NT_STATUS_OK;
1610 /***************************************************************************
1611 _lsa_OpenTrustedDomain_base
1612 ***************************************************************************/
1614 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1615 uint32_t access_mask,
1616 struct trustdom_info *info,
1617 struct policy_handle *handle)
1619 struct security_descriptor *psd = NULL;
1620 size_t sd_size;
1621 uint32_t acc_granted;
1622 NTSTATUS status;
1624 /* des_access is for the account here, not the policy
1625 * handle - so don't check against policy handle. */
1627 /* Work out max allowed. */
1628 map_max_allowed_access(p->session_info->security_token,
1629 p->session_info->unix_token,
1630 &access_mask);
1632 /* map the generic bits to the lsa account ones */
1633 se_map_generic(&access_mask, &lsa_trusted_domain_mapping);
1635 /* get the generic lsa account SD until we store it */
1636 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1637 &lsa_trusted_domain_mapping,
1638 NULL, 0);
1639 if (!NT_STATUS_IS_OK(status)) {
1640 return status;
1643 status = access_check_object(psd, p->session_info->security_token,
1644 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1645 access_mask, &acc_granted,
1646 "_lsa_OpenTrustedDomain");
1647 if (!NT_STATUS_IS_OK(status)) {
1648 return status;
1651 status = create_lsa_policy_handle(p->mem_ctx, p,
1652 LSA_HANDLE_TRUST_TYPE,
1653 acc_granted,
1654 &info->sid,
1655 info->name,
1656 psd,
1657 handle);
1658 if (!NT_STATUS_IS_OK(status)) {
1659 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1662 return NT_STATUS_OK;
1665 /***************************************************************************
1666 _lsa_OpenTrustedDomain
1667 ***************************************************************************/
1669 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1670 struct lsa_OpenTrustedDomain *r)
1672 struct lsa_info *handle = NULL;
1673 struct trustdom_info *info = NULL;
1674 NTSTATUS status;
1676 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1677 return NT_STATUS_INVALID_HANDLE;
1680 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1681 return NT_STATUS_INVALID_HANDLE;
1684 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1685 r->in.sid,
1686 &info);
1687 if (!NT_STATUS_IS_OK(status)) {
1688 return status;
1691 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1692 r->out.trustdom_handle);
1695 /***************************************************************************
1696 _lsa_OpenTrustedDomainByName
1697 ***************************************************************************/
1699 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1700 struct lsa_OpenTrustedDomainByName *r)
1702 struct lsa_info *handle = NULL;
1703 struct trustdom_info *info = NULL;
1704 NTSTATUS status;
1706 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1707 return NT_STATUS_INVALID_HANDLE;
1710 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1711 return NT_STATUS_INVALID_HANDLE;
1714 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1715 r->in.name.string,
1716 &info);
1717 if (!NT_STATUS_IS_OK(status)) {
1718 return status;
1721 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1722 r->out.trustdom_handle);
1725 static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
1726 TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
1727 struct trustDomainPasswords *auth_struct)
1729 enum ndr_err_code ndr_err;
1730 DATA_BLOB lsession_key;
1731 NTSTATUS status;
1733 status = session_extract_session_key(p->session_info, &lsession_key, KEY_USE_16BYTES);
1734 if (!NT_STATUS_IS_OK(status)) {
1735 return NT_STATUS_INVALID_PARAMETER;
1738 arcfour_crypt_blob(auth_blob->data, auth_blob->length, &lsession_key);
1739 ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
1740 auth_struct,
1741 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
1742 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1743 return NT_STATUS_INVALID_PARAMETER;
1746 return NT_STATUS_OK;
1749 static NTSTATUS get_trustauth_inout_blob(TALLOC_CTX *mem_ctx,
1750 struct trustAuthInOutBlob *iopw,
1751 DATA_BLOB *trustauth_blob)
1753 enum ndr_err_code ndr_err;
1755 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
1756 iopw,
1757 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
1758 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1759 return NT_STATUS_INVALID_PARAMETER;
1762 return NT_STATUS_OK;
1765 /***************************************************************************
1766 _lsa_CreateTrustedDomainEx2
1767 ***************************************************************************/
1769 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1770 struct lsa_CreateTrustedDomainEx2 *r)
1772 struct lsa_info *policy;
1773 NTSTATUS status;
1774 uint32_t acc_granted;
1775 struct security_descriptor *psd;
1776 size_t sd_size;
1777 struct pdb_trusted_domain td;
1778 struct trustDomainPasswords auth_struct;
1779 DATA_BLOB auth_blob;
1781 if (!IS_DC) {
1782 return NT_STATUS_NOT_SUPPORTED;
1785 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1786 return NT_STATUS_INVALID_HANDLE;
1789 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1790 return NT_STATUS_ACCESS_DENIED;
1793 if (p->session_info->unix_token->uid != sec_initial_uid() &&
1794 !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1795 return NT_STATUS_ACCESS_DENIED;
1798 /* Work out max allowed. */
1799 map_max_allowed_access(p->session_info->security_token,
1800 p->session_info->unix_token,
1801 &r->in.access_mask);
1803 /* map the generic bits to the lsa policy ones */
1804 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1806 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1807 &lsa_trusted_domain_mapping,
1808 NULL, 0);
1809 if (!NT_STATUS_IS_OK(status)) {
1810 return status;
1813 status = access_check_object(psd, p->session_info->security_token,
1814 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1815 r->in.access_mask, &acc_granted,
1816 "_lsa_CreateTrustedDomainEx2");
1817 if (!NT_STATUS_IS_OK(status)) {
1818 return status;
1821 ZERO_STRUCT(td);
1823 td.domain_name = talloc_strdup(p->mem_ctx,
1824 r->in.info->domain_name.string);
1825 if (td.domain_name == NULL) {
1826 return NT_STATUS_NO_MEMORY;
1828 td.netbios_name = talloc_strdup(p->mem_ctx,
1829 r->in.info->netbios_name.string);
1830 if (td.netbios_name == NULL) {
1831 return NT_STATUS_NO_MEMORY;
1833 sid_copy(&td.security_identifier, r->in.info->sid);
1834 td.trust_direction = r->in.info->trust_direction;
1835 td.trust_type = r->in.info->trust_type;
1836 td.trust_attributes = r->in.info->trust_attributes;
1838 if (r->in.auth_info_internal->auth_blob.size != 0) {
1839 auth_blob.length = r->in.auth_info_internal->auth_blob.size;
1840 auth_blob.data = r->in.auth_info_internal->auth_blob.data;
1842 status = get_trustdom_auth_blob(p, p->mem_ctx, &auth_blob, &auth_struct);
1843 if (!NT_STATUS_IS_OK(status)) {
1844 return NT_STATUS_UNSUCCESSFUL;
1847 status = get_trustauth_inout_blob(p->mem_ctx, &auth_struct.incoming, &td.trust_auth_incoming);
1848 if (!NT_STATUS_IS_OK(status)) {
1849 return NT_STATUS_UNSUCCESSFUL;
1852 status = get_trustauth_inout_blob(p->mem_ctx, &auth_struct.outgoing, &td.trust_auth_outgoing);
1853 if (!NT_STATUS_IS_OK(status)) {
1854 return NT_STATUS_UNSUCCESSFUL;
1856 } else {
1857 td.trust_auth_incoming.data = NULL;
1858 td.trust_auth_incoming.length = 0;
1859 td.trust_auth_outgoing.data = NULL;
1860 td.trust_auth_outgoing.length = 0;
1863 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1864 if (!NT_STATUS_IS_OK(status)) {
1865 return status;
1868 status = create_lsa_policy_handle(p->mem_ctx, p,
1869 LSA_HANDLE_TRUST_TYPE,
1870 acc_granted,
1871 r->in.info->sid,
1872 r->in.info->netbios_name.string,
1873 psd,
1874 r->out.trustdom_handle);
1875 if (!NT_STATUS_IS_OK(status)) {
1876 pdb_del_trusted_domain(r->in.info->netbios_name.string);
1877 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1880 return NT_STATUS_OK;
1883 /***************************************************************************
1884 _lsa_CreateTrustedDomainEx
1885 ***************************************************************************/
1887 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1888 struct lsa_CreateTrustedDomainEx *r)
1890 struct lsa_CreateTrustedDomainEx2 q;
1891 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1893 ZERO_STRUCT(auth_info);
1895 q.in.policy_handle = r->in.policy_handle;
1896 q.in.info = r->in.info;
1897 q.in.auth_info_internal = &auth_info;
1898 q.in.access_mask = r->in.access_mask;
1899 q.out.trustdom_handle = r->out.trustdom_handle;
1901 return _lsa_CreateTrustedDomainEx2(p, &q);
1904 /***************************************************************************
1905 _lsa_CreateTrustedDomain
1906 ***************************************************************************/
1908 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1909 struct lsa_CreateTrustedDomain *r)
1911 struct lsa_CreateTrustedDomainEx2 c;
1912 struct lsa_TrustDomainInfoInfoEx info;
1913 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1915 ZERO_STRUCT(auth_info);
1917 info.domain_name = r->in.info->name;
1918 info.netbios_name = r->in.info->name;
1919 info.sid = r->in.info->sid;
1920 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1921 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1922 info.trust_attributes = 0;
1924 c.in.policy_handle = r->in.policy_handle;
1925 c.in.info = &info;
1926 c.in.auth_info_internal = &auth_info;
1927 c.in.access_mask = r->in.access_mask;
1928 c.out.trustdom_handle = r->out.trustdom_handle;
1930 return _lsa_CreateTrustedDomainEx2(p, &c);
1933 /***************************************************************************
1934 _lsa_DeleteTrustedDomain
1935 ***************************************************************************/
1937 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1938 struct lsa_DeleteTrustedDomain *r)
1940 NTSTATUS status;
1941 struct lsa_info *handle;
1942 struct pdb_trusted_domain *td;
1944 /* find the connection policy handle. */
1945 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1946 return NT_STATUS_INVALID_HANDLE;
1949 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1950 return NT_STATUS_INVALID_HANDLE;
1953 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1954 return NT_STATUS_ACCESS_DENIED;
1957 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1958 if (!NT_STATUS_IS_OK(status)) {
1959 return status;
1962 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1963 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1964 sid_string_tos(r->in.dom_sid)));
1965 return NT_STATUS_UNSUCCESSFUL;
1968 status = pdb_del_trusted_domain(td->netbios_name);
1969 if (!NT_STATUS_IS_OK(status)) {
1970 return status;
1973 return NT_STATUS_OK;
1976 /***************************************************************************
1977 _lsa_CloseTrustedDomainEx
1978 ***************************************************************************/
1980 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1981 struct lsa_CloseTrustedDomainEx *r)
1983 return NT_STATUS_NOT_IMPLEMENTED;
1986 /***************************************************************************
1987 _lsa_QueryTrustedDomainInfo
1988 ***************************************************************************/
1990 static NTSTATUS pdb_trusted_domain_2_info_ex(TALLOC_CTX *mem_ctx,
1991 struct pdb_trusted_domain *td,
1992 struct lsa_TrustDomainInfoInfoEx *info_ex)
1994 if (td->domain_name == NULL ||
1995 td->netbios_name == NULL ||
1996 is_null_sid(&td->security_identifier)) {
1997 return NT_STATUS_INVALID_PARAMETER;
2000 info_ex->domain_name.string = talloc_strdup(mem_ctx, td->domain_name);
2001 info_ex->netbios_name.string = talloc_strdup(mem_ctx, td->netbios_name);
2002 info_ex->sid = dom_sid_dup(mem_ctx, &td->security_identifier);
2003 if (info_ex->domain_name.string == NULL ||
2004 info_ex->netbios_name.string == NULL ||
2005 info_ex->sid == NULL) {
2006 return NT_STATUS_NO_MEMORY;
2009 info_ex->trust_direction = td->trust_direction;
2010 info_ex->trust_type = td->trust_type;
2011 info_ex->trust_attributes = td->trust_attributes;
2013 return NT_STATUS_OK;
2016 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
2017 struct lsa_QueryTrustedDomainInfo *r)
2019 NTSTATUS status;
2020 struct lsa_info *handle;
2021 union lsa_TrustedDomainInfo *info;
2022 struct pdb_trusted_domain *td;
2023 uint32_t acc_required;
2025 /* find the connection policy handle. */
2026 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
2027 return NT_STATUS_INVALID_HANDLE;
2030 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
2031 return NT_STATUS_INVALID_HANDLE;
2034 switch (r->in.level) {
2035 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2036 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2037 break;
2038 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2039 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
2040 break;
2041 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2042 acc_required = LSA_TRUSTED_QUERY_POSIX;
2043 break;
2044 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2045 acc_required = LSA_TRUSTED_QUERY_AUTH;
2046 break;
2047 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2048 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2049 break;
2050 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2051 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2052 break;
2053 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2054 acc_required = LSA_TRUSTED_QUERY_AUTH;
2055 break;
2056 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2057 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2058 LSA_TRUSTED_QUERY_POSIX |
2059 LSA_TRUSTED_QUERY_AUTH;
2060 break;
2061 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2062 acc_required = LSA_TRUSTED_QUERY_AUTH;
2063 break;
2064 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2065 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2066 LSA_TRUSTED_QUERY_POSIX |
2067 LSA_TRUSTED_QUERY_AUTH;
2068 break;
2069 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2070 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2071 break;
2072 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2073 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2074 LSA_TRUSTED_QUERY_POSIX |
2075 LSA_TRUSTED_QUERY_AUTH;
2076 break;
2077 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2078 acc_required = LSA_TRUSTED_QUERY_POSIX;
2079 break;
2080 default:
2081 return NT_STATUS_INVALID_PARAMETER;
2084 if (!(handle->access & acc_required)) {
2085 return NT_STATUS_ACCESS_DENIED;
2088 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2089 if (!NT_STATUS_IS_OK(status)) {
2090 return status;
2093 info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
2094 if (!info) {
2095 return NT_STATUS_NO_MEMORY;
2098 switch (r->in.level) {
2099 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2100 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2101 break;
2102 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2103 return NT_STATUS_INVALID_PARAMETER;
2104 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2105 info->posix_offset.posix_offset = *td->trust_posix_offset;
2106 break;
2107 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2108 return NT_STATUS_INVALID_INFO_CLASS;
2109 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2110 return NT_STATUS_INVALID_PARAMETER;
2111 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2112 status = pdb_trusted_domain_2_info_ex(info, td, &info->info_ex);
2113 if (!NT_STATUS_IS_OK(status)) {
2114 return status;
2116 break;
2117 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2118 return NT_STATUS_INVALID_INFO_CLASS;
2119 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2120 status = pdb_trusted_domain_2_info_ex(info, td,
2121 &info->full_info.info_ex);
2122 if (!NT_STATUS_IS_OK(status)) {
2123 return status;
2125 info->full_info.posix_offset.posix_offset = *td->trust_posix_offset;
2126 status = auth_blob_2_auth_info(p->mem_ctx,
2127 td->trust_auth_incoming,
2128 td->trust_auth_outgoing,
2129 &info->full_info.auth_info);
2130 if (!NT_STATUS_IS_OK(status)) {
2131 return status;
2133 break;
2134 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2135 return NT_STATUS_INVALID_INFO_CLASS;
2136 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2137 return NT_STATUS_INVALID_INFO_CLASS;
2138 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2139 return NT_STATUS_INVALID_PARAMETER;
2140 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2141 info->full_info2_internal.posix_offset.posix_offset = *td->trust_posix_offset;
2142 status = auth_blob_2_auth_info(p->mem_ctx,
2143 td->trust_auth_incoming,
2144 td->trust_auth_outgoing,
2145 &info->full_info2_internal.auth_info);
2146 if (!NT_STATUS_IS_OK(status)) {
2147 return status;
2149 break;
2150 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2151 info->enc_types.enc_types = *td->supported_enc_type;
2152 break;
2153 default:
2154 return NT_STATUS_INVALID_PARAMETER;
2157 *r->out.info = info;
2159 return NT_STATUS_OK;
2162 /***************************************************************************
2163 _lsa_QueryTrustedDomainInfoBySid
2164 ***************************************************************************/
2166 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2167 struct lsa_QueryTrustedDomainInfoBySid *r)
2169 NTSTATUS status;
2170 struct policy_handle trustdom_handle;
2171 struct lsa_OpenTrustedDomain o;
2172 struct lsa_QueryTrustedDomainInfo q;
2173 struct lsa_Close c;
2175 o.in.handle = r->in.handle;
2176 o.in.sid = r->in.dom_sid;
2177 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2178 o.out.trustdom_handle = &trustdom_handle;
2180 status = _lsa_OpenTrustedDomain(p, &o);
2181 if (!NT_STATUS_IS_OK(status)) {
2182 return status;
2185 q.in.trustdom_handle = &trustdom_handle;
2186 q.in.level = r->in.level;
2187 q.out.info = r->out.info;
2189 status = _lsa_QueryTrustedDomainInfo(p, &q);
2190 if (!NT_STATUS_IS_OK(status)) {
2191 return status;
2194 c.in.handle = &trustdom_handle;
2195 c.out.handle = &trustdom_handle;
2197 return _lsa_Close(p, &c);
2200 /***************************************************************************
2201 _lsa_QueryTrustedDomainInfoByName
2202 ***************************************************************************/
2204 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2205 struct lsa_QueryTrustedDomainInfoByName *r)
2207 NTSTATUS status;
2208 struct policy_handle trustdom_handle;
2209 struct lsa_OpenTrustedDomainByName o;
2210 struct lsa_QueryTrustedDomainInfo q;
2211 struct lsa_Close c;
2213 o.in.handle = r->in.handle;
2214 o.in.name.string = r->in.trusted_domain->string;
2215 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2216 o.out.trustdom_handle = &trustdom_handle;
2218 status = _lsa_OpenTrustedDomainByName(p, &o);
2219 if (!NT_STATUS_IS_OK(status)) {
2220 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2221 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2223 return status;
2226 q.in.trustdom_handle = &trustdom_handle;
2227 q.in.level = r->in.level;
2228 q.out.info = r->out.info;
2230 status = _lsa_QueryTrustedDomainInfo(p, &q);
2231 if (!NT_STATUS_IS_OK(status)) {
2232 return status;
2235 c.in.handle = &trustdom_handle;
2236 c.out.handle = &trustdom_handle;
2238 return _lsa_Close(p, &c);
2241 /***************************************************************************
2242 _lsa_CreateSecret
2243 ***************************************************************************/
2245 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p,
2246 struct lsa_CreateSecret *r)
2248 NTSTATUS status;
2249 struct lsa_info *handle;
2250 uint32_t acc_granted;
2251 struct security_descriptor *psd;
2252 size_t sd_size;
2254 /* find the connection policy handle. */
2255 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
2256 return NT_STATUS_INVALID_HANDLE;
2259 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2260 return NT_STATUS_INVALID_HANDLE;
2263 /* check if the user has enough rights */
2265 if (!(handle->access & LSA_POLICY_CREATE_SECRET)) {
2266 return NT_STATUS_ACCESS_DENIED;
2269 /* Work out max allowed. */
2270 map_max_allowed_access(p->session_info->security_token,
2271 p->session_info->unix_token,
2272 &r->in.access_mask);
2274 /* map the generic bits to the lsa policy ones */
2275 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
2277 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2278 &lsa_secret_mapping,
2279 NULL, 0);
2280 if (!NT_STATUS_IS_OK(status)) {
2281 return status;
2284 status = access_check_object(psd, p->session_info->security_token,
2285 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2286 r->in.access_mask,
2287 &acc_granted, "_lsa_CreateSecret");
2288 if (!NT_STATUS_IS_OK(status)) {
2289 return status;
2292 if (!r->in.name.string) {
2293 return NT_STATUS_INVALID_PARAMETER;
2296 if (strlen(r->in.name.string) > 128) {
2297 return NT_STATUS_NAME_TOO_LONG;
2300 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
2301 NULL, NULL, NULL, NULL, NULL);
2302 if (NT_STATUS_IS_OK(status)) {
2303 return NT_STATUS_OBJECT_NAME_COLLISION;
2306 status = pdb_set_secret(r->in.name.string, NULL, NULL, psd);
2307 if (!NT_STATUS_IS_OK(status)) {
2308 return status;
2311 status = create_lsa_policy_handle(p->mem_ctx, p,
2312 LSA_HANDLE_SECRET_TYPE,
2313 acc_granted,
2314 NULL,
2315 r->in.name.string,
2316 psd,
2317 r->out.sec_handle);
2318 if (!NT_STATUS_IS_OK(status)) {
2319 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2322 return NT_STATUS_OK;
2325 /***************************************************************************
2326 _lsa_SetSecret
2327 ***************************************************************************/
2329 NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
2330 struct lsa_SetSecret *r)
2332 NTSTATUS status;
2333 struct lsa_info *info = NULL;
2334 DATA_BLOB blob_new, blob_old;
2335 DATA_BLOB cleartext_blob_new = data_blob_null;
2336 DATA_BLOB cleartext_blob_old = data_blob_null;
2337 DATA_BLOB *cleartext_blob_new_p = NULL;
2338 DATA_BLOB *cleartext_blob_old_p = NULL;
2339 DATA_BLOB session_key;
2341 if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
2342 return NT_STATUS_INVALID_HANDLE;
2345 if (info->type != LSA_HANDLE_SECRET_TYPE) {
2346 return NT_STATUS_INVALID_HANDLE;
2349 if (!(info->access & LSA_SECRET_SET_VALUE)) {
2350 return NT_STATUS_ACCESS_DENIED;
2353 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
2354 if(!NT_STATUS_IS_OK(status)) {
2355 return status;
2358 if (r->in.new_val) {
2359 blob_new = data_blob_const(r->in.new_val->data,
2360 r->in.new_val->length);
2362 status = sess_decrypt_blob(p->mem_ctx, &blob_new,
2363 &session_key,
2364 &cleartext_blob_new);
2365 if (!NT_STATUS_IS_OK(status)) {
2366 return status;
2369 cleartext_blob_new_p = &cleartext_blob_new;
2372 if (r->in.old_val) {
2373 blob_old = data_blob_const(r->in.old_val->data,
2374 r->in.old_val->length);
2376 status = sess_decrypt_blob(p->mem_ctx, &blob_old,
2377 &session_key,
2378 &cleartext_blob_old);
2379 if (!NT_STATUS_IS_OK(status)) {
2380 return status;
2383 cleartext_blob_old_p = &cleartext_blob_old;
2386 status = pdb_set_secret(info->name, cleartext_blob_new_p, cleartext_blob_old_p, NULL);
2387 if (!NT_STATUS_IS_OK(status)) {
2388 return status;
2391 #ifdef DEBUG_PASSWORD
2392 DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
2393 dump_data(10, cleartext_blob_new.data, cleartext_blob_new.length);
2394 DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
2395 dump_data(10, cleartext_blob_old.data, cleartext_blob_old.length);
2396 #endif
2398 return NT_STATUS_OK;
2401 /***************************************************************************
2402 _lsa_QuerySecret
2403 ***************************************************************************/
2405 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
2406 struct lsa_QuerySecret *r)
2408 struct lsa_info *info = NULL;
2409 DATA_BLOB blob_new, blob_old;
2410 DATA_BLOB blob_new_crypt, blob_old_crypt;
2411 DATA_BLOB session_key;
2412 NTTIME nttime_new, nttime_old;
2413 NTSTATUS status;
2415 if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
2416 return NT_STATUS_INVALID_HANDLE;
2419 if (info->type != LSA_HANDLE_SECRET_TYPE) {
2420 return NT_STATUS_INVALID_HANDLE;
2423 if (!(info->access & LSA_SECRET_QUERY_VALUE)) {
2424 return NT_STATUS_ACCESS_DENIED;
2427 status = pdb_get_secret(p->mem_ctx, info->name,
2428 &blob_new, &nttime_new,
2429 &blob_old, &nttime_old,
2430 NULL);
2431 if (!NT_STATUS_IS_OK(status)) {
2432 return status;
2435 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
2436 if(!NT_STATUS_IS_OK(status)) {
2437 return status;
2440 if (r->in.new_val) {
2441 if (blob_new.length) {
2442 if (!r->out.new_val->buf) {
2443 r->out.new_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2445 if (!r->out.new_val->buf) {
2446 return NT_STATUS_NO_MEMORY;
2449 blob_new_crypt = sess_encrypt_blob(p->mem_ctx, &blob_new,
2450 &session_key);
2451 if (!blob_new_crypt.length) {
2452 return NT_STATUS_NO_MEMORY;
2455 r->out.new_val->buf->data = blob_new_crypt.data;
2456 r->out.new_val->buf->length = blob_new_crypt.length;
2457 r->out.new_val->buf->size = blob_new_crypt.length;
2461 if (r->in.old_val) {
2462 if (blob_old.length) {
2463 if (!r->out.old_val->buf) {
2464 r->out.old_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2466 if (!r->out.old_val->buf) {
2467 return NT_STATUS_NO_MEMORY;
2470 blob_old_crypt = sess_encrypt_blob(p->mem_ctx, &blob_old,
2471 &session_key);
2472 if (!blob_old_crypt.length) {
2473 return NT_STATUS_NO_MEMORY;
2476 r->out.old_val->buf->data = blob_old_crypt.data;
2477 r->out.old_val->buf->length = blob_old_crypt.length;
2478 r->out.old_val->buf->size = blob_old_crypt.length;
2482 if (r->out.new_mtime) {
2483 *r->out.new_mtime = nttime_new;
2486 if (r->out.old_mtime) {
2487 *r->out.old_mtime = nttime_old;
2490 return NT_STATUS_OK;
2493 /***************************************************************************
2494 _lsa_DeleteObject
2495 ***************************************************************************/
2497 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2498 struct lsa_DeleteObject *r)
2500 NTSTATUS status;
2501 struct lsa_info *info = NULL;
2503 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2504 return NT_STATUS_INVALID_HANDLE;
2507 if (!(info->access & SEC_STD_DELETE)) {
2508 return NT_STATUS_ACCESS_DENIED;
2511 switch (info->type) {
2512 case LSA_HANDLE_ACCOUNT_TYPE:
2513 status = privilege_delete_account(&info->sid);
2514 if (!NT_STATUS_IS_OK(status)) {
2515 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2516 nt_errstr(status)));
2517 return status;
2519 break;
2520 case LSA_HANDLE_TRUST_TYPE:
2521 if (!pdb_del_trusteddom_pw(info->name)) {
2522 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2524 status = NT_STATUS_OK;
2525 break;
2526 case LSA_HANDLE_SECRET_TYPE:
2527 status = pdb_delete_secret(info->name);
2528 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2529 return NT_STATUS_INVALID_HANDLE;
2531 break;
2532 default:
2533 return NT_STATUS_INVALID_HANDLE;
2536 close_policy_hnd(p, r->in.handle);
2537 ZERO_STRUCTP(r->out.handle);
2539 return status;
2542 /***************************************************************************
2543 _lsa_EnumPrivs
2544 ***************************************************************************/
2546 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2547 struct lsa_EnumPrivs *r)
2549 struct lsa_info *handle;
2550 uint32 i;
2551 uint32 enum_context = *r->in.resume_handle;
2552 int num_privs = num_privileges_in_short_list();
2553 struct lsa_PrivEntry *entries = NULL;
2555 /* remember that the enum_context starts at 0 and not 1 */
2557 if ( enum_context >= num_privs )
2558 return NT_STATUS_NO_MORE_ENTRIES;
2560 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2561 enum_context, num_privs));
2563 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2564 return NT_STATUS_INVALID_HANDLE;
2566 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2567 return NT_STATUS_INVALID_HANDLE;
2570 /* check if the user has enough rights
2571 I don't know if it's the right one. not documented. */
2573 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2574 return NT_STATUS_ACCESS_DENIED;
2576 if (num_privs) {
2577 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2578 if (!entries) {
2579 return NT_STATUS_NO_MEMORY;
2581 } else {
2582 entries = NULL;
2585 for (i = 0; i < num_privs; i++) {
2586 if( i < enum_context) {
2588 init_lsa_StringLarge(&entries[i].name, NULL);
2590 entries[i].luid.low = 0;
2591 entries[i].luid.high = 0;
2592 } else {
2594 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2596 entries[i].luid.low = sec_privilege_from_index(i);
2597 entries[i].luid.high = 0;
2601 enum_context = num_privs;
2603 *r->out.resume_handle = enum_context;
2604 r->out.privs->count = num_privs;
2605 r->out.privs->privs = entries;
2607 return NT_STATUS_OK;
2610 /***************************************************************************
2611 _lsa_LookupPrivDisplayName
2612 ***************************************************************************/
2614 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2615 struct lsa_LookupPrivDisplayName *r)
2617 struct lsa_info *handle;
2618 const char *description;
2619 struct lsa_StringLarge *lsa_name;
2621 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2622 return NT_STATUS_INVALID_HANDLE;
2624 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2625 return NT_STATUS_INVALID_HANDLE;
2628 /* check if the user has enough rights */
2631 * I don't know if it's the right one. not documented.
2633 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2634 return NT_STATUS_ACCESS_DENIED;
2636 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2638 description = get_privilege_dispname(r->in.name->string);
2639 if (!description) {
2640 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2641 return NT_STATUS_NO_SUCH_PRIVILEGE;
2644 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2646 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2647 if (!lsa_name) {
2648 return NT_STATUS_NO_MEMORY;
2651 init_lsa_StringLarge(lsa_name, description);
2653 *r->out.returned_language_id = r->in.language_id;
2654 *r->out.disp_name = lsa_name;
2656 return NT_STATUS_OK;
2659 /***************************************************************************
2660 _lsa_EnumAccounts
2661 ***************************************************************************/
2663 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2664 struct lsa_EnumAccounts *r)
2666 struct lsa_info *handle;
2667 struct dom_sid *sid_list;
2668 int i, j, num_entries;
2669 NTSTATUS status;
2670 struct lsa_SidPtr *sids = NULL;
2672 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2673 return NT_STATUS_INVALID_HANDLE;
2675 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2676 return NT_STATUS_INVALID_HANDLE;
2679 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2680 return NT_STATUS_ACCESS_DENIED;
2682 sid_list = NULL;
2683 num_entries = 0;
2685 /* The only way we can currently find out all the SIDs that have been
2686 privileged is to scan all privileges */
2688 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2689 if (!NT_STATUS_IS_OK(status)) {
2690 return status;
2693 if (*r->in.resume_handle >= num_entries) {
2694 return NT_STATUS_NO_MORE_ENTRIES;
2697 if (num_entries - *r->in.resume_handle) {
2698 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2699 num_entries - *r->in.resume_handle);
2700 if (!sids) {
2701 talloc_free(sid_list);
2702 return NT_STATUS_NO_MEMORY;
2705 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2706 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2707 if (!sids[j].sid) {
2708 talloc_free(sid_list);
2709 return NT_STATUS_NO_MEMORY;
2714 talloc_free(sid_list);
2716 *r->out.resume_handle = num_entries;
2717 r->out.sids->num_sids = num_entries;
2718 r->out.sids->sids = sids;
2720 return NT_STATUS_OK;
2723 /***************************************************************************
2724 _lsa_GetUserName
2725 ***************************************************************************/
2727 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2728 struct lsa_GetUserName *r)
2730 const char *username, *domname;
2731 struct lsa_String *account_name = NULL;
2732 struct lsa_String *authority_name = NULL;
2734 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
2735 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
2736 return NT_STATUS_ACCESS_DENIED;
2739 if (r->in.account_name &&
2740 *r->in.account_name) {
2741 return NT_STATUS_INVALID_PARAMETER;
2744 if (r->in.authority_name &&
2745 *r->in.authority_name) {
2746 return NT_STATUS_INVALID_PARAMETER;
2749 if (security_session_user_level(p->session_info, NULL) < SECURITY_USER) {
2751 * I'm 99% sure this is not the right place to do this,
2752 * global_sid_Anonymous should probably be put into the token
2753 * instead of the guest id -- vl
2755 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2756 &domname, &username, NULL)) {
2757 return NT_STATUS_NO_MEMORY;
2759 } else {
2760 username = p->session_info->unix_info->sanitized_username;
2761 domname = p->session_info->info->domain_name;
2764 account_name = talloc(p->mem_ctx, struct lsa_String);
2765 if (!account_name) {
2766 return NT_STATUS_NO_MEMORY;
2768 init_lsa_String(account_name, username);
2770 if (r->out.authority_name) {
2771 authority_name = talloc(p->mem_ctx, struct lsa_String);
2772 if (!authority_name) {
2773 return NT_STATUS_NO_MEMORY;
2775 init_lsa_String(authority_name, domname);
2778 *r->out.account_name = account_name;
2779 if (r->out.authority_name) {
2780 *r->out.authority_name = authority_name;
2783 return NT_STATUS_OK;
2786 /***************************************************************************
2787 _lsa_CreateAccount
2788 ***************************************************************************/
2790 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2791 struct lsa_CreateAccount *r)
2793 NTSTATUS status;
2794 struct lsa_info *handle;
2795 uint32_t acc_granted;
2796 struct security_descriptor *psd;
2797 size_t sd_size;
2798 uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
2799 ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
2800 LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2801 SEC_STD_DELETE));
2803 /* find the connection policy handle. */
2804 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2805 return NT_STATUS_INVALID_HANDLE;
2807 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2808 return NT_STATUS_INVALID_HANDLE;
2811 /* check if the user has enough rights */
2813 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2814 return NT_STATUS_ACCESS_DENIED;
2817 /* Work out max allowed. */
2818 map_max_allowed_access(p->session_info->security_token,
2819 p->session_info->unix_token,
2820 &r->in.access_mask);
2822 /* map the generic bits to the lsa policy ones */
2823 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2825 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2826 &lsa_account_mapping,
2827 r->in.sid, owner_access);
2828 if (!NT_STATUS_IS_OK(status)) {
2829 return status;
2832 status = access_check_object(psd, p->session_info->security_token,
2833 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2834 &acc_granted, "_lsa_CreateAccount");
2835 if (!NT_STATUS_IS_OK(status)) {
2836 return status;
2839 if ( is_privileged_sid( r->in.sid ) )
2840 return NT_STATUS_OBJECT_NAME_COLLISION;
2842 status = create_lsa_policy_handle(p->mem_ctx, p,
2843 LSA_HANDLE_ACCOUNT_TYPE,
2844 acc_granted,
2845 r->in.sid,
2846 NULL,
2847 psd,
2848 r->out.acct_handle);
2849 if (!NT_STATUS_IS_OK(status)) {
2850 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2853 return privilege_create_account(r->in.sid);
2856 /***************************************************************************
2857 _lsa_OpenAccount
2858 ***************************************************************************/
2860 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2861 struct lsa_OpenAccount *r)
2863 struct lsa_info *handle;
2864 struct security_descriptor *psd = NULL;
2865 size_t sd_size;
2866 uint32_t des_access = r->in.access_mask;
2867 uint32_t acc_granted;
2868 uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
2869 ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
2870 LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2871 SEC_STD_DELETE));
2872 NTSTATUS status;
2874 /* find the connection policy handle. */
2875 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2876 return NT_STATUS_INVALID_HANDLE;
2878 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2879 return NT_STATUS_INVALID_HANDLE;
2882 /* des_access is for the account here, not the policy
2883 * handle - so don't check against policy handle. */
2885 /* Work out max allowed. */
2886 map_max_allowed_access(p->session_info->security_token,
2887 p->session_info->unix_token,
2888 &des_access);
2890 /* map the generic bits to the lsa account ones */
2891 se_map_generic(&des_access, &lsa_account_mapping);
2893 /* get the generic lsa account SD until we store it */
2894 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2895 &lsa_account_mapping,
2896 r->in.sid, owner_access);
2897 if (!NT_STATUS_IS_OK(status)) {
2898 return status;
2901 status = access_check_object(psd, p->session_info->security_token,
2902 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2903 &acc_granted, "_lsa_OpenAccount" );
2904 if (!NT_STATUS_IS_OK(status)) {
2905 return status;
2908 /* TODO: Fis the parsing routine before reenabling this check! */
2909 #if 0
2910 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2911 return NT_STATUS_ACCESS_DENIED;
2912 #endif
2914 status = create_lsa_policy_handle(p->mem_ctx, p,
2915 LSA_HANDLE_ACCOUNT_TYPE,
2916 acc_granted,
2917 r->in.sid,
2918 NULL,
2919 psd,
2920 r->out.acct_handle);
2921 if (!NT_STATUS_IS_OK(status)) {
2922 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2925 return NT_STATUS_OK;
2928 /***************************************************************************
2929 _lsa_EnumPrivsAccount
2930 For a given SID, enumerate all the privilege this account has.
2931 ***************************************************************************/
2933 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2934 struct lsa_EnumPrivsAccount *r)
2936 NTSTATUS status = NT_STATUS_OK;
2937 struct lsa_info *info=NULL;
2938 PRIVILEGE_SET *privileges;
2939 struct lsa_PrivilegeSet *priv_set = NULL;
2941 /* find the connection policy handle. */
2942 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2943 return NT_STATUS_INVALID_HANDLE;
2945 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2946 return NT_STATUS_INVALID_HANDLE;
2949 if (!(info->access & LSA_ACCOUNT_VIEW))
2950 return NT_STATUS_ACCESS_DENIED;
2952 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2953 if (!NT_STATUS_IS_OK(status)) {
2954 return status;
2957 *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2958 if (!priv_set) {
2959 return NT_STATUS_NO_MEMORY;
2962 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2963 sid_string_dbg(&info->sid),
2964 privileges->count));
2966 priv_set->count = privileges->count;
2967 priv_set->unknown = 0;
2968 priv_set->set = talloc_move(priv_set, &privileges->set);
2970 return status;
2973 /***************************************************************************
2974 _lsa_GetSystemAccessAccount
2975 ***************************************************************************/
2977 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2978 struct lsa_GetSystemAccessAccount *r)
2980 NTSTATUS status;
2981 struct lsa_info *info = NULL;
2982 struct lsa_EnumPrivsAccount e;
2983 struct lsa_PrivilegeSet *privset;
2985 /* find the connection policy handle. */
2987 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2988 return NT_STATUS_INVALID_HANDLE;
2990 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2991 return NT_STATUS_INVALID_HANDLE;
2994 if (!(info->access & LSA_ACCOUNT_VIEW))
2995 return NT_STATUS_ACCESS_DENIED;
2997 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2998 if (!privset) {
2999 return NT_STATUS_NO_MEMORY;
3002 e.in.handle = r->in.handle;
3003 e.out.privs = &privset;
3005 status = _lsa_EnumPrivsAccount(p, &e);
3006 if (!NT_STATUS_IS_OK(status)) {
3007 DEBUG(10,("_lsa_GetSystemAccessAccount: "
3008 "failed to call _lsa_EnumPrivsAccount(): %s\n",
3009 nt_errstr(status)));
3010 return status;
3013 /* Samba4 would iterate over the privset to merge the policy mode bits,
3014 * not sure samba3 can do the same here, so just return what we did in
3015 * the past - gd */
3018 0x01 -> Log on locally
3019 0x02 -> Access this computer from network
3020 0x04 -> Log on as a batch job
3021 0x10 -> Log on as a service
3023 they can be ORed together
3026 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
3027 LSA_POLICY_MODE_NETWORK;
3029 return NT_STATUS_OK;
3032 /***************************************************************************
3033 update the systemaccount information
3034 ***************************************************************************/
3036 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
3037 struct lsa_SetSystemAccessAccount *r)
3039 struct lsa_info *info=NULL;
3040 NTSTATUS status;
3041 GROUP_MAP *map;
3043 /* find the connection policy handle. */
3044 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3045 return NT_STATUS_INVALID_HANDLE;
3047 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3048 return NT_STATUS_INVALID_HANDLE;
3051 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
3052 return NT_STATUS_ACCESS_DENIED;
3055 map = talloc_zero(p->mem_ctx, GROUP_MAP);
3056 if (!map) {
3057 return NT_STATUS_NO_MEMORY;
3060 if (!pdb_getgrsid(map, info->sid)) {
3061 TALLOC_FREE(map);
3062 return NT_STATUS_NO_SUCH_GROUP;
3065 status = pdb_update_group_mapping_entry(map);
3066 TALLOC_FREE(map);
3067 return status;
3070 /***************************************************************************
3071 _lsa_AddPrivilegesToAccount
3072 For a given SID, add some privileges.
3073 ***************************************************************************/
3075 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
3076 struct lsa_AddPrivilegesToAccount *r)
3078 struct lsa_info *info = NULL;
3079 struct lsa_PrivilegeSet *set = NULL;
3081 /* find the connection policy handle. */
3082 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3083 return NT_STATUS_INVALID_HANDLE;
3085 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3086 return NT_STATUS_INVALID_HANDLE;
3089 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3090 return NT_STATUS_ACCESS_DENIED;
3093 set = r->in.privs;
3095 if ( !grant_privilege_set( &info->sid, set ) ) {
3096 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
3097 sid_string_dbg(&info->sid) ));
3098 return NT_STATUS_NO_SUCH_PRIVILEGE;
3101 return NT_STATUS_OK;
3104 /***************************************************************************
3105 _lsa_RemovePrivilegesFromAccount
3106 For a given SID, remove some privileges.
3107 ***************************************************************************/
3109 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
3110 struct lsa_RemovePrivilegesFromAccount *r)
3112 struct lsa_info *info = NULL;
3113 struct lsa_PrivilegeSet *set = NULL;
3115 /* find the connection policy handle. */
3116 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3117 return NT_STATUS_INVALID_HANDLE;
3119 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3120 return NT_STATUS_INVALID_HANDLE;
3123 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3124 return NT_STATUS_ACCESS_DENIED;
3127 set = r->in.privs;
3129 if ( !revoke_privilege_set( &info->sid, set) ) {
3130 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
3131 sid_string_dbg(&info->sid) ));
3132 return NT_STATUS_NO_SUCH_PRIVILEGE;
3135 return NT_STATUS_OK;
3138 /***************************************************************************
3139 _lsa_LookupPrivName
3140 ***************************************************************************/
3142 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
3143 struct lsa_LookupPrivName *r)
3145 struct lsa_info *info = NULL;
3146 const char *name;
3147 struct lsa_StringLarge *lsa_name;
3149 /* find the connection policy handle. */
3150 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3151 return NT_STATUS_INVALID_HANDLE;
3154 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3155 return NT_STATUS_INVALID_HANDLE;
3158 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
3159 return NT_STATUS_ACCESS_DENIED;
3162 if (r->in.luid->high != 0) {
3163 return NT_STATUS_NO_SUCH_PRIVILEGE;
3166 name = sec_privilege_name(r->in.luid->low);
3167 if (!name) {
3168 return NT_STATUS_NO_SUCH_PRIVILEGE;
3171 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
3172 if (!lsa_name) {
3173 return NT_STATUS_NO_MEMORY;
3176 lsa_name->string = talloc_strdup(lsa_name, name);
3177 if (!lsa_name->string) {
3178 TALLOC_FREE(lsa_name);
3179 return NT_STATUS_NO_MEMORY;
3182 *r->out.name = lsa_name;
3184 return NT_STATUS_OK;
3187 /***************************************************************************
3188 _lsa_QuerySecurity
3189 ***************************************************************************/
3191 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
3192 struct lsa_QuerySecurity *r)
3194 struct lsa_info *handle=NULL;
3195 struct security_descriptor *psd = NULL;
3196 size_t sd_size = 0;
3197 NTSTATUS status;
3199 /* find the connection policy handle. */
3200 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
3201 return NT_STATUS_INVALID_HANDLE;
3203 switch (handle->type) {
3204 case LSA_HANDLE_POLICY_TYPE:
3205 case LSA_HANDLE_ACCOUNT_TYPE:
3206 case LSA_HANDLE_TRUST_TYPE:
3207 case LSA_HANDLE_SECRET_TYPE:
3208 psd = handle->sd;
3209 sd_size = ndr_size_security_descriptor(psd, 0);
3210 status = NT_STATUS_OK;
3211 break;
3212 default:
3213 status = NT_STATUS_INVALID_HANDLE;
3214 break;
3217 if (!NT_STATUS_IS_OK(status)) {
3218 return status;
3221 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
3222 if (!*r->out.sdbuf) {
3223 return NT_STATUS_NO_MEMORY;
3226 return status;
3229 /***************************************************************************
3230 _lsa_AddAccountRights
3231 ***************************************************************************/
3233 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
3234 struct lsa_AddAccountRights *r)
3236 struct lsa_info *info = NULL;
3237 int i = 0;
3238 uint32_t acc_granted = 0;
3239 struct security_descriptor *psd = NULL;
3240 size_t sd_size;
3241 struct dom_sid sid;
3242 NTSTATUS status;
3244 /* find the connection policy handle. */
3245 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3246 return NT_STATUS_INVALID_HANDLE;
3248 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3249 return NT_STATUS_INVALID_HANDLE;
3252 /* get the generic lsa account SD for this SID until we store it */
3253 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3254 &lsa_account_mapping,
3255 NULL, 0);
3256 if (!NT_STATUS_IS_OK(status)) {
3257 return status;
3261 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3262 * on the policy handle. If it does, ask for
3263 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3264 * on the account sid. We don't check here so just use the latter. JRA.
3267 status = access_check_object(psd, p->session_info->security_token,
3268 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3269 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3270 &acc_granted, "_lsa_AddAccountRights" );
3271 if (!NT_STATUS_IS_OK(status)) {
3272 return status;
3275 /* according to an NT4 PDC, you can add privileges to SIDs even without
3276 call_lsa_create_account() first. And you can use any arbitrary SID. */
3278 sid_copy( &sid, r->in.sid );
3280 for ( i=0; i < r->in.rights->count; i++ ) {
3282 const char *privname = r->in.rights->names[i].string;
3284 /* only try to add non-null strings */
3286 if ( !privname )
3287 continue;
3289 if ( !grant_privilege_by_name( &sid, privname ) ) {
3290 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3291 privname ));
3292 return NT_STATUS_NO_SUCH_PRIVILEGE;
3296 return NT_STATUS_OK;
3299 /***************************************************************************
3300 _lsa_RemoveAccountRights
3301 ***************************************************************************/
3303 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
3304 struct lsa_RemoveAccountRights *r)
3306 struct lsa_info *info = NULL;
3307 int i = 0;
3308 struct security_descriptor *psd = NULL;
3309 size_t sd_size;
3310 struct dom_sid sid;
3311 const char *privname = NULL;
3312 uint32_t acc_granted = 0;
3313 NTSTATUS status;
3315 /* find the connection policy handle. */
3316 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3317 return NT_STATUS_INVALID_HANDLE;
3319 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3320 return NT_STATUS_INVALID_HANDLE;
3323 /* get the generic lsa account SD for this SID until we store it */
3324 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3325 &lsa_account_mapping,
3326 NULL, 0);
3327 if (!NT_STATUS_IS_OK(status)) {
3328 return status;
3332 * From the MS DOCs. We need
3333 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3334 * and DELETE on the account sid.
3337 status = access_check_object(psd, p->session_info->security_token,
3338 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3339 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3340 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
3341 &acc_granted, "_lsa_RemoveAccountRights");
3342 if (!NT_STATUS_IS_OK(status)) {
3343 return status;
3346 sid_copy( &sid, r->in.sid );
3348 if ( r->in.remove_all ) {
3349 if ( !revoke_all_privileges( &sid ) )
3350 return NT_STATUS_ACCESS_DENIED;
3352 return NT_STATUS_OK;
3355 for ( i=0; i < r->in.rights->count; i++ ) {
3357 privname = r->in.rights->names[i].string;
3359 /* only try to add non-null strings */
3361 if ( !privname )
3362 continue;
3364 if ( !revoke_privilege_by_name( &sid, privname ) ) {
3365 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3366 privname ));
3367 return NT_STATUS_NO_SUCH_PRIVILEGE;
3371 return NT_STATUS_OK;
3374 /*******************************************************************
3375 ********************************************************************/
3377 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3378 struct lsa_RightSet *r,
3379 PRIVILEGE_SET *privileges)
3381 uint32 i;
3382 const char *privname;
3383 const char **privname_array = NULL;
3384 int num_priv = 0;
3386 for (i=0; i<privileges->count; i++) {
3387 if (privileges->set[i].luid.high) {
3388 continue;
3390 privname = sec_privilege_name(privileges->set[i].luid.low);
3391 if (privname) {
3392 if (!add_string_to_array(mem_ctx, privname,
3393 &privname_array, &num_priv)) {
3394 return NT_STATUS_NO_MEMORY;
3399 if (num_priv) {
3401 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3402 num_priv);
3403 if (!r->names) {
3404 return NT_STATUS_NO_MEMORY;
3407 for (i=0; i<num_priv; i++) {
3408 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3411 r->count = num_priv;
3414 return NT_STATUS_OK;
3417 /***************************************************************************
3418 _lsa_EnumAccountRights
3419 ***************************************************************************/
3421 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3422 struct lsa_EnumAccountRights *r)
3424 NTSTATUS status;
3425 struct lsa_info *info = NULL;
3426 PRIVILEGE_SET *privileges;
3428 /* find the connection policy handle. */
3430 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3431 return NT_STATUS_INVALID_HANDLE;
3433 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3434 return NT_STATUS_INVALID_HANDLE;
3437 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3438 return NT_STATUS_ACCESS_DENIED;
3441 /* according to an NT4 PDC, you can add privileges to SIDs even without
3442 call_lsa_create_account() first. And you can use any arbitrary SID. */
3444 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3445 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3446 * the lsa database */
3448 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3449 if (!NT_STATUS_IS_OK(status)) {
3450 return status;
3453 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3454 sid_string_dbg(r->in.sid), privileges->count));
3456 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3458 return status;
3461 /***************************************************************************
3462 _lsa_LookupPrivValue
3463 ***************************************************************************/
3465 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3466 struct lsa_LookupPrivValue *r)
3468 struct lsa_info *info = NULL;
3469 const char *name = NULL;
3471 /* find the connection policy handle. */
3473 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3474 return NT_STATUS_INVALID_HANDLE;
3476 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3477 return NT_STATUS_INVALID_HANDLE;
3480 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3481 return NT_STATUS_ACCESS_DENIED;
3483 name = r->in.name->string;
3485 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3487 r->out.luid->low = sec_privilege_id(name);
3488 r->out.luid->high = 0;
3489 if (r->out.luid->low == SEC_PRIV_INVALID) {
3490 return NT_STATUS_NO_SUCH_PRIVILEGE;
3492 return NT_STATUS_OK;
3495 /***************************************************************************
3496 _lsa_EnumAccountsWithUserRight
3497 ***************************************************************************/
3499 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3500 struct lsa_EnumAccountsWithUserRight *r)
3502 NTSTATUS status;
3503 struct lsa_info *info = NULL;
3504 struct dom_sid *sids = NULL;
3505 int num_sids = 0;
3506 uint32_t i;
3507 enum sec_privilege privilege;
3509 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3510 return NT_STATUS_INVALID_HANDLE;
3513 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3514 return NT_STATUS_INVALID_HANDLE;
3517 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3518 return NT_STATUS_ACCESS_DENIED;
3521 if (!r->in.name || !r->in.name->string) {
3522 return NT_STATUS_NO_SUCH_PRIVILEGE;
3525 privilege = sec_privilege_id(r->in.name->string);
3526 if (privilege == SEC_PRIV_INVALID) {
3527 return NT_STATUS_NO_SUCH_PRIVILEGE;
3530 status = privilege_enum_sids(privilege, p->mem_ctx,
3531 &sids, &num_sids);
3532 if (!NT_STATUS_IS_OK(status)) {
3533 return status;
3536 r->out.sids->num_sids = num_sids;
3537 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3538 r->out.sids->num_sids);
3540 for (i=0; i < r->out.sids->num_sids; i++) {
3541 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3542 &sids[i]);
3543 if (!r->out.sids->sids[i].sid) {
3544 TALLOC_FREE(r->out.sids->sids);
3545 r->out.sids->num_sids = 0;
3546 return NT_STATUS_NO_MEMORY;
3550 return NT_STATUS_OK;
3553 /***************************************************************************
3554 _lsa_Delete
3555 ***************************************************************************/
3557 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3558 struct lsa_Delete *r)
3560 return NT_STATUS_NOT_SUPPORTED;
3563 static NTSTATUS info_ex_2_pdb_trusted_domain(
3564 struct lsa_TrustDomainInfoInfoEx *info_ex,
3565 struct pdb_trusted_domain *td)
3567 if (info_ex->domain_name.string == NULL ||
3568 info_ex->netbios_name.string == NULL ||
3569 info_ex->sid == NULL) {
3570 return NT_STATUS_INVALID_PARAMETER;
3573 td->domain_name = talloc_strdup(td, info_ex->domain_name.string);
3574 td->netbios_name = talloc_strdup(td, info_ex->netbios_name.string);
3575 sid_copy(&td->security_identifier, info_ex->sid);
3576 if (td->domain_name == NULL ||
3577 td->netbios_name == NULL ||
3578 is_null_sid(&td->security_identifier)) {
3579 return NT_STATUS_NO_MEMORY;
3581 td->trust_direction = info_ex->trust_direction;
3582 td->trust_type = info_ex->trust_type;
3583 td->trust_attributes = info_ex->trust_attributes;
3585 return NT_STATUS_OK;
3588 static NTSTATUS setInfoTrustedDomain_base(struct pipes_struct *p,
3589 TALLOC_CTX *mem_ctx,
3590 struct lsa_info *policy,
3591 enum lsa_TrustDomInfoEnum level,
3592 union lsa_TrustedDomainInfo *info)
3594 struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
3595 DATA_BLOB auth_blob;
3596 struct trustDomainPasswords auth_struct;
3597 NTSTATUS nt_status;
3599 struct pdb_trusted_domain *td;
3600 struct pdb_trusted_domain *orig_td;
3602 td = talloc_zero(mem_ctx, struct pdb_trusted_domain);
3603 if (td == NULL) {
3604 return NT_STATUS_NO_MEMORY;
3607 switch (level) {
3608 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
3609 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3610 return NT_STATUS_ACCESS_DENIED;
3612 td->trust_posix_offset = &info->posix_offset.posix_offset;
3613 break;
3614 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
3615 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3616 return NT_STATUS_ACCESS_DENIED;
3618 nt_status = info_ex_2_pdb_trusted_domain(&info->info_ex, td);
3619 if (!NT_STATUS_IS_OK(nt_status)) {
3620 return nt_status;
3622 break;
3623 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
3624 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3625 return NT_STATUS_ACCESS_DENIED;
3627 nt_status = auth_info_2_auth_blob(td, &info->auth_info,
3628 &td->trust_auth_incoming,
3629 &td->trust_auth_outgoing);
3630 if (!NT_STATUS_IS_OK(nt_status)) {
3631 return nt_status;
3633 break;
3634 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
3635 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3636 return NT_STATUS_ACCESS_DENIED;
3638 td->trust_posix_offset = &info->full_info.posix_offset.posix_offset;
3639 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info.info_ex,
3640 td);
3641 if (!NT_STATUS_IS_OK(nt_status)) {
3642 return nt_status;
3644 nt_status = auth_info_2_auth_blob(td,
3645 &info->full_info.auth_info,
3646 &td->trust_auth_incoming,
3647 &td->trust_auth_outgoing);
3648 if (!NT_STATUS_IS_OK(nt_status)) {
3649 return nt_status;
3651 break;
3652 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
3653 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3654 return NT_STATUS_ACCESS_DENIED;
3656 auth_info_int = &info->auth_info_internal;
3657 break;
3658 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
3659 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3660 return NT_STATUS_ACCESS_DENIED;
3662 td->trust_posix_offset = &info->full_info_internal.posix_offset.posix_offset;
3663 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info_internal.info_ex,
3664 td);
3665 if (!NT_STATUS_IS_OK(nt_status)) {
3666 return nt_status;
3668 auth_info_int = &info->full_info_internal.auth_info;
3669 break;
3670 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
3671 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3672 return NT_STATUS_ACCESS_DENIED;
3674 td->supported_enc_type = &info->enc_types.enc_types;
3675 break;
3676 default:
3677 return NT_STATUS_INVALID_PARAMETER;
3680 /* decode auth_info_int if set */
3681 if (auth_info_int) {
3683 /* now decrypt blob */
3684 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
3685 auth_info_int->auth_blob.size);
3687 nt_status = get_trustdom_auth_blob(p, mem_ctx,
3688 &auth_blob, &auth_struct);
3689 if (!NT_STATUS_IS_OK(nt_status)) {
3690 return nt_status;
3692 } else {
3693 memset(&auth_struct, 0, sizeof(auth_struct));
3696 /* TODO: verify only one object matches the dns/netbios/sid triplet and that
3697 * this is the one we already have */
3699 /* TODO: check if the trust direction is changed and we need to add or remove
3700 * auth data */
3702 /* TODO: check if trust type shall be changed and return an error in this case
3703 * */
3704 nt_status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &policy->sid,
3705 &orig_td);
3706 if (!NT_STATUS_IS_OK(nt_status)) {
3707 return nt_status;
3711 /* TODO: should we fetch previous values from the existing entry
3712 * and append them ? */
3713 if (auth_struct.incoming.count) {
3714 nt_status = get_trustauth_inout_blob(mem_ctx,
3715 &auth_struct.incoming,
3716 &td->trust_auth_incoming);
3717 if (!NT_STATUS_IS_OK(nt_status)) {
3718 return nt_status;
3720 } else {
3721 ZERO_STRUCT(td->trust_auth_incoming);
3724 if (auth_struct.outgoing.count) {
3725 nt_status = get_trustauth_inout_blob(mem_ctx,
3726 &auth_struct.outgoing,
3727 &td->trust_auth_outgoing);
3728 if (!NT_STATUS_IS_OK(nt_status)) {
3729 return nt_status;
3731 } else {
3732 ZERO_STRUCT(td->trust_auth_outgoing);
3735 nt_status = pdb_set_trusted_domain(orig_td->domain_name, td);
3736 if (!NT_STATUS_IS_OK(nt_status)) {
3737 return nt_status;
3740 return NT_STATUS_OK;
3743 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3744 struct lsa_SetTrustedDomainInfo *r)
3746 NTSTATUS status;
3747 struct policy_handle trustdom_handle;
3748 struct lsa_OpenTrustedDomain o;
3749 struct lsa_SetInformationTrustedDomain s;
3750 struct lsa_Close c;
3752 o.in.handle = r->in.handle;
3753 o.in.sid = r->in.dom_sid;
3754 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3755 o.out.trustdom_handle = &trustdom_handle;
3757 status = _lsa_OpenTrustedDomain(p, &o);
3758 if (!NT_STATUS_IS_OK(status)) {
3759 return status;
3762 s.in.trustdom_handle = &trustdom_handle;
3763 s.in.level = r->in.level;
3764 s.in.info = r->in.info;
3766 status = _lsa_SetInformationTrustedDomain(p, &s);
3767 if (!NT_STATUS_IS_OK(status)) {
3768 return status;
3771 c.in.handle = &trustdom_handle;
3772 c.out.handle = &trustdom_handle;
3774 return _lsa_Close(p, &c);
3777 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3778 struct lsa_SetTrustedDomainInfoByName *r)
3780 NTSTATUS status;
3781 struct policy_handle trustdom_handle;
3782 struct lsa_OpenTrustedDomainByName o;
3783 struct lsa_SetInformationTrustedDomain s;
3784 struct lsa_Close c;
3786 o.in.handle = r->in.handle;
3787 o.in.name.string = r->in.trusted_domain->string;
3788 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3789 o.out.trustdom_handle = &trustdom_handle;
3791 status = _lsa_OpenTrustedDomainByName(p, &o);
3792 if (!NT_STATUS_IS_OK(status)) {
3793 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
3794 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3796 return status;
3799 s.in.trustdom_handle = &trustdom_handle;
3800 s.in.level = r->in.level;
3801 s.in.info = r->in.info;
3803 status = _lsa_SetInformationTrustedDomain(p, &s);
3804 if (!NT_STATUS_IS_OK(status)) {
3805 return status;
3808 c.in.handle = &trustdom_handle;
3809 c.out.handle = &trustdom_handle;
3811 return _lsa_Close(p, &c);
3814 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3815 struct lsa_SetInformationTrustedDomain *r)
3817 struct lsa_info *policy;
3819 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&policy)) {
3820 return NT_STATUS_INVALID_HANDLE;
3823 if (policy->type != LSA_HANDLE_TRUST_TYPE) {
3824 return NT_STATUS_INVALID_HANDLE;
3827 return setInfoTrustedDomain_base(p, p->mem_ctx, policy,
3828 r->in.level, r->in.info);
3833 * From here on the server routines are just dummy ones to make smbd link with
3834 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3835 * pulling the server stubs across one by one.
3838 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3840 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3841 return NT_STATUS_NOT_IMPLEMENTED;
3844 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3845 struct lsa_ChangePassword *r)
3847 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3848 return NT_STATUS_NOT_IMPLEMENTED;
3851 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3853 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3854 return NT_STATUS_NOT_IMPLEMENTED;
3857 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3859 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3860 return NT_STATUS_NOT_IMPLEMENTED;
3863 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3864 struct lsa_GetQuotasForAccount *r)
3866 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3867 return NT_STATUS_NOT_IMPLEMENTED;
3870 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3871 struct lsa_SetQuotasForAccount *r)
3873 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3874 return NT_STATUS_NOT_IMPLEMENTED;
3877 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3878 struct lsa_StorePrivateData *r)
3880 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3881 return NT_STATUS_NOT_IMPLEMENTED;
3884 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3885 struct lsa_RetrievePrivateData *r)
3887 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3888 return NT_STATUS_NOT_IMPLEMENTED;
3891 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3892 struct lsa_SetInfoPolicy2 *r)
3894 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3895 return NT_STATUS_NOT_IMPLEMENTED;
3898 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3899 struct lsa_EnumTrustedDomainsEx *r)
3901 struct lsa_info *info;
3902 uint32_t count;
3903 struct pdb_trusted_domain **domains;
3904 struct lsa_TrustDomainInfoInfoEx *entries;
3905 int i;
3906 NTSTATUS nt_status;
3908 /* bail out early if pdb backend is not capable of ex trusted domains,
3909 * if we dont do that, the client might not call
3910 * _lsa_EnumTrustedDomains() afterwards - gd */
3912 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3913 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3914 return NT_STATUS_NOT_IMPLEMENTED;
3917 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3918 return NT_STATUS_INVALID_HANDLE;
3920 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3921 return NT_STATUS_INVALID_HANDLE;
3924 /* check if the user has enough rights */
3925 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3926 return NT_STATUS_ACCESS_DENIED;
3928 become_root();
3929 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3930 unbecome_root();
3932 if (!NT_STATUS_IS_OK(nt_status)) {
3933 return nt_status;
3936 entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3937 count);
3938 if (!entries) {
3939 return NT_STATUS_NO_MEMORY;
3942 for (i=0; i<count; i++) {
3943 init_lsa_StringLarge(&entries[i].domain_name,
3944 domains[i]->domain_name);
3945 init_lsa_StringLarge(&entries[i].netbios_name,
3946 domains[i]->netbios_name);
3947 entries[i].sid = &domains[i]->security_identifier;
3948 entries[i].trust_direction = domains[i]->trust_direction;
3949 entries[i].trust_type = domains[i]->trust_type;
3950 entries[i].trust_attributes = domains[i]->trust_attributes;
3953 if (*r->in.resume_handle >= count) {
3954 *r->out.resume_handle = -1;
3955 TALLOC_FREE(entries);
3956 return NT_STATUS_NO_MORE_ENTRIES;
3959 /* return the rest, limit by max_size. Note that we
3960 use the w2k3 element size value of 60 */
3961 r->out.domains->count = count - *r->in.resume_handle;
3962 r->out.domains->count = MIN(r->out.domains->count,
3963 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3965 r->out.domains->domains = entries + *r->in.resume_handle;
3967 if (r->out.domains->count < count - *r->in.resume_handle) {
3968 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3969 return STATUS_MORE_ENTRIES;
3972 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3973 * always be larger than the previous input resume handle, in
3974 * particular when hitting the last query it is vital to set the
3975 * resume handle correctly to avoid infinite client loops, as
3976 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3977 * status is NT_STATUS_OK - gd */
3979 *r->out.resume_handle = (uint32_t)-1;
3981 return NT_STATUS_OK;
3984 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3985 struct lsa_QueryDomainInformationPolicy *r)
3987 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3988 return NT_STATUS_NOT_IMPLEMENTED;
3991 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3992 struct lsa_SetDomainInformationPolicy *r)
3994 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3995 return NT_STATUS_NOT_IMPLEMENTED;
3998 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
4000 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4001 return NT_STATUS_NOT_IMPLEMENTED;
4004 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
4006 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4007 return NT_STATUS_NOT_IMPLEMENTED;
4010 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
4012 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4013 return NT_STATUS_NOT_IMPLEMENTED;
4016 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
4018 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4019 return NT_STATUS_NOT_IMPLEMENTED;
4022 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
4023 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
4025 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4026 return NT_STATUS_NOT_IMPLEMENTED;
4029 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
4030 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
4032 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4033 return NT_STATUS_NOT_IMPLEMENTED;
4036 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
4038 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4039 return NT_STATUS_NOT_IMPLEMENTED;
4042 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
4043 struct lsa_CREDRGETTARGETINFO *r)
4045 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4046 return NT_STATUS_NOT_IMPLEMENTED;
4049 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
4050 struct lsa_CREDRPROFILELOADED *r)
4052 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4053 return NT_STATUS_NOT_IMPLEMENTED;
4056 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
4057 struct lsa_CREDRGETSESSIONTYPES *r)
4059 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4060 return NT_STATUS_NOT_IMPLEMENTED;
4063 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
4064 struct lsa_LSARREGISTERAUDITEVENT *r)
4066 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4067 return NT_STATUS_NOT_IMPLEMENTED;
4070 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
4071 struct lsa_LSARGENAUDITEVENT *r)
4073 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4074 return NT_STATUS_NOT_IMPLEMENTED;
4077 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
4078 struct lsa_LSARUNREGISTERAUDITEVENT *r)
4080 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4081 return NT_STATUS_NOT_IMPLEMENTED;
4084 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
4085 struct lsa_lsaRQueryForestTrustInformation *r)
4087 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4088 return NT_STATUS_NOT_IMPLEMENTED;
4091 #define DNS_CMP_MATCH 0
4092 #define DNS_CMP_FIRST_IS_CHILD 1
4093 #define DNS_CMP_SECOND_IS_CHILD 2
4094 #define DNS_CMP_NO_MATCH 3
4096 /* this function assumes names are well formed DNS names.
4097 * it doesn't validate them */
4098 static int dns_cmp(const char *s1, size_t l1,
4099 const char *s2, size_t l2)
4101 const char *p1, *p2;
4102 size_t t1, t2;
4103 int cret;
4105 if (l1 == l2) {
4106 if (strcasecmp_m(s1, s2) == 0) {
4107 return DNS_CMP_MATCH;
4109 return DNS_CMP_NO_MATCH;
4112 if (l1 > l2) {
4113 p1 = s1;
4114 p2 = s2;
4115 t1 = l1;
4116 t2 = l2;
4117 cret = DNS_CMP_FIRST_IS_CHILD;
4118 } else {
4119 p1 = s2;
4120 p2 = s1;
4121 t1 = l2;
4122 t2 = l1;
4123 cret = DNS_CMP_SECOND_IS_CHILD;
4126 if (p1[t1 - t2 - 1] != '.') {
4127 return DNS_CMP_NO_MATCH;
4130 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
4131 return cret;
4134 return DNS_CMP_NO_MATCH;
4137 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
4138 struct lsa_ForestTrustInformation *lfti,
4139 struct ForestTrustInfo *fti)
4141 struct lsa_ForestTrustRecord *lrec;
4142 struct ForestTrustInfoRecord *rec;
4143 struct lsa_StringLarge *tln;
4144 struct lsa_ForestTrustDomainInfo *info;
4145 uint32_t i;
4147 fti->version = 1;
4148 fti->count = lfti->count;
4149 fti->records = talloc_array(mem_ctx,
4150 struct ForestTrustInfoRecordArmor,
4151 fti->count);
4152 if (!fti->records) {
4153 return NT_STATUS_NO_MEMORY;
4155 for (i = 0; i < fti->count; i++) {
4156 lrec = lfti->entries[i];
4157 rec = &fti->records[i].record;
4159 rec->flags = lrec->flags;
4160 rec->timestamp = lrec->time;
4161 rec->type = lrec->type;
4163 switch (lrec->type) {
4164 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
4165 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4166 tln = &lrec->forest_trust_data.top_level_name;
4167 rec->data.name.string =
4168 talloc_strdup(mem_ctx, tln->string);
4169 if (!rec->data.name.string) {
4170 return NT_STATUS_NO_MEMORY;
4172 rec->data.name.size = strlen(rec->data.name.string);
4173 break;
4174 case LSA_FOREST_TRUST_DOMAIN_INFO:
4175 info = &lrec->forest_trust_data.domain_info;
4176 rec->data.info.sid = *info->domain_sid;
4177 rec->data.info.dns_name.string =
4178 talloc_strdup(mem_ctx,
4179 info->dns_domain_name.string);
4180 if (!rec->data.info.dns_name.string) {
4181 return NT_STATUS_NO_MEMORY;
4183 rec->data.info.dns_name.size =
4184 strlen(rec->data.info.dns_name.string);
4185 rec->data.info.netbios_name.string =
4186 talloc_strdup(mem_ctx,
4187 info->netbios_domain_name.string);
4188 if (!rec->data.info.netbios_name.string) {
4189 return NT_STATUS_NO_MEMORY;
4191 rec->data.info.netbios_name.size =
4192 strlen(rec->data.info.netbios_name.string);
4193 break;
4194 default:
4195 return NT_STATUS_INVALID_DOMAIN_STATE;
4199 return NT_STATUS_OK;
4202 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4203 uint32_t index, uint32_t collision_type,
4204 uint32_t conflict_type, const char *tdo_name);
4206 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
4207 const char *tdo_name,
4208 struct ForestTrustInfo *tdo_fti,
4209 struct ForestTrustInfo *new_fti,
4210 struct lsa_ForestTrustCollisionInfo *c_info)
4212 struct ForestTrustInfoRecord *nrec;
4213 struct ForestTrustInfoRecord *trec;
4214 const char *dns_name;
4215 const char *nb_name = NULL;
4216 struct dom_sid *sid = NULL;
4217 const char *tname = NULL;
4218 size_t dns_len = 0;
4219 size_t tlen = 0;
4220 uint32_t new_fti_idx;
4221 uint32_t i;
4222 /* use always TDO type, until we understand when Xref can be used */
4223 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
4224 bool tln_conflict;
4225 bool sid_conflict;
4226 bool nb_conflict;
4227 bool exclusion;
4228 bool ex_rule = false;
4229 int ret;
4231 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
4233 nrec = &new_fti->records[new_fti_idx].record;
4234 dns_name = NULL;
4235 tln_conflict = false;
4236 sid_conflict = false;
4237 nb_conflict = false;
4238 exclusion = false;
4240 switch (nrec->type) {
4241 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4242 /* exclusions do not conflict by definition */
4243 break;
4245 case FOREST_TRUST_TOP_LEVEL_NAME:
4246 dns_name = nrec->data.name.string;
4247 dns_len = nrec->data.name.size;
4248 break;
4250 case LSA_FOREST_TRUST_DOMAIN_INFO:
4251 dns_name = nrec->data.info.dns_name.string;
4252 dns_len = nrec->data.info.dns_name.size;
4253 nb_name = nrec->data.info.netbios_name.string;
4254 sid = &nrec->data.info.sid;
4255 break;
4258 if (!dns_name) continue;
4260 /* check if this is already taken and not excluded */
4261 for (i = 0; i < tdo_fti->count; i++) {
4262 trec = &tdo_fti->records[i].record;
4264 switch (trec->type) {
4265 case FOREST_TRUST_TOP_LEVEL_NAME:
4266 ex_rule = false;
4267 tname = trec->data.name.string;
4268 tlen = trec->data.name.size;
4269 break;
4270 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
4271 ex_rule = true;
4272 tname = trec->data.name.string;
4273 tlen = trec->data.name.size;
4274 break;
4275 case FOREST_TRUST_DOMAIN_INFO:
4276 ex_rule = false;
4277 tname = trec->data.info.dns_name.string;
4278 tlen = trec->data.info.dns_name.size;
4279 break;
4280 default:
4281 return NT_STATUS_INVALID_PARAMETER;
4283 ret = dns_cmp(dns_name, dns_len, tname, tlen);
4284 switch (ret) {
4285 case DNS_CMP_MATCH:
4286 /* if it matches exclusion,
4287 * it doesn't conflict */
4288 if (ex_rule) {
4289 exclusion = true;
4290 break;
4292 /* fall through */
4293 case DNS_CMP_FIRST_IS_CHILD:
4294 case DNS_CMP_SECOND_IS_CHILD:
4295 tln_conflict = true;
4296 /* fall through */
4297 default:
4298 break;
4301 /* explicit exclusion, no dns name conflict here */
4302 if (exclusion) {
4303 tln_conflict = false;
4306 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
4307 continue;
4310 /* also test for domain info */
4311 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
4312 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
4313 sid_conflict = true;
4315 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
4316 strcasecmp_m(trec->data.info.netbios_name.string,
4317 nb_name) == 0) {
4318 nb_conflict = true;
4322 if (tln_conflict) {
4323 (void)add_collision(c_info, new_fti_idx,
4324 collision_type,
4325 LSA_TLN_DISABLED_CONFLICT,
4326 tdo_name);
4328 if (sid_conflict) {
4329 (void)add_collision(c_info, new_fti_idx,
4330 collision_type,
4331 LSA_SID_DISABLED_CONFLICT,
4332 tdo_name);
4334 if (nb_conflict) {
4335 (void)add_collision(c_info, new_fti_idx,
4336 collision_type,
4337 LSA_NB_DISABLED_CONFLICT,
4338 tdo_name);
4342 return NT_STATUS_OK;
4345 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4346 uint32_t idx, uint32_t collision_type,
4347 uint32_t conflict_type, const char *tdo_name)
4349 struct lsa_ForestTrustCollisionRecord **es;
4350 uint32_t i = c_info->count;
4352 es = talloc_realloc(c_info, c_info->entries,
4353 struct lsa_ForestTrustCollisionRecord *, i + 1);
4354 if (!es) {
4355 return NT_STATUS_NO_MEMORY;
4357 c_info->entries = es;
4358 c_info->count = i + 1;
4360 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4361 if (!es[i]) {
4362 return NT_STATUS_NO_MEMORY;
4365 es[i]->index = idx;
4366 es[i]->type = collision_type;
4367 es[i]->flags.flags = conflict_type;
4368 es[i]->name.string = talloc_strdup(es[i], tdo_name);
4369 if (!es[i]->name.string) {
4370 return NT_STATUS_NO_MEMORY;
4372 es[i]->name.size = strlen(es[i]->name.string);
4374 return NT_STATUS_OK;
4377 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
4378 struct pdb_trusted_domain *td,
4379 struct ForestTrustInfo *info)
4381 enum ndr_err_code ndr_err;
4383 if (td->trust_forest_trust_info.length == 0 ||
4384 td->trust_forest_trust_info.data == NULL) {
4385 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4387 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
4388 info,
4389 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
4390 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4391 return NT_STATUS_INVALID_DOMAIN_STATE;
4394 return NT_STATUS_OK;
4397 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
4398 struct ForestTrustInfo *fti)
4400 struct ForestTrustDataDomainInfo *info;
4401 struct ForestTrustInfoRecord *rec;
4403 fti->version = 1;
4404 fti->count = 2;
4405 fti->records = talloc_array(fti,
4406 struct ForestTrustInfoRecordArmor, 2);
4407 if (!fti->records) {
4408 return NT_STATUS_NO_MEMORY;
4411 /* TLN info */
4412 rec = &fti->records[0].record;
4414 rec->flags = 0;
4415 rec->timestamp = 0;
4416 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
4418 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
4419 if (!rec->data.name.string) {
4420 return NT_STATUS_NO_MEMORY;
4422 rec->data.name.size = strlen(rec->data.name.string);
4424 /* DOMAIN info */
4425 rec = &fti->records[1].record;
4427 rec->flags = 0;
4428 rec->timestamp = 0;
4429 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
4431 info = &rec->data.info;
4433 info->sid = dom_info->sid;
4434 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
4435 if (!info->dns_name.string) {
4436 return NT_STATUS_NO_MEMORY;
4438 info->dns_name.size = strlen(info->dns_name.string);
4439 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
4440 if (!info->netbios_name.string) {
4441 return NT_STATUS_NO_MEMORY;
4443 info->netbios_name.size = strlen(info->netbios_name.string);
4445 return NT_STATUS_OK;
4448 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
4449 struct lsa_lsaRSetForestTrustInformation *r)
4451 NTSTATUS status;
4452 int i;
4453 int j;
4454 struct lsa_info *handle;
4455 uint32_t num_domains;
4456 struct pdb_trusted_domain **domains;
4457 struct ForestTrustInfo *nfti;
4458 struct ForestTrustInfo *fti;
4459 struct lsa_ForestTrustCollisionInfo *c_info;
4460 struct pdb_domain_info *dom_info;
4461 enum ndr_err_code ndr_err;
4463 if (!IS_DC) {
4464 return NT_STATUS_NOT_SUPPORTED;
4467 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
4468 return NT_STATUS_INVALID_HANDLE;
4471 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
4472 return NT_STATUS_INVALID_HANDLE;
4475 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
4476 return NT_STATUS_ACCESS_DENIED;
4479 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
4480 if (!NT_STATUS_IS_OK(status)) {
4481 return status;
4483 if (num_domains == 0) {
4484 return NT_STATUS_NO_SUCH_DOMAIN;
4487 for (i = 0; i < num_domains; i++) {
4488 if (domains[i]->domain_name == NULL) {
4489 return NT_STATUS_INVALID_DOMAIN_STATE;
4491 if (strcasecmp_m(domains[i]->domain_name,
4492 r->in.trusted_domain_name->string) == 0) {
4493 break;
4496 if (i >= num_domains) {
4497 return NT_STATUS_NO_SUCH_DOMAIN;
4500 if (!(domains[i]->trust_attributes &
4501 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4502 return NT_STATUS_INVALID_PARAMETER;
4505 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4506 return NT_STATUS_INVALID_PARAMETER;
4509 /* The following section until COPY_END is a copy from
4510 * source4/rpmc_server/lsa/scesrc_lsa.c */
4511 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
4512 if (!nfti) {
4513 return NT_STATUS_NO_MEMORY;
4516 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4517 if (!NT_STATUS_IS_OK(status)) {
4518 return status;
4521 c_info = talloc_zero(r->out.collision_info,
4522 struct lsa_ForestTrustCollisionInfo);
4523 if (!c_info) {
4524 return NT_STATUS_NO_MEMORY;
4527 /* first check own info, then other domains */
4528 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4529 if (!fti) {
4530 return NT_STATUS_NO_MEMORY;
4533 dom_info = pdb_get_domain_info(p->mem_ctx);
4535 status = own_ft_info(dom_info, fti);
4536 if (!NT_STATUS_IS_OK(status)) {
4537 return status;
4540 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
4541 if (!NT_STATUS_IS_OK(status)) {
4542 return status;
4545 for (j = 0; j < num_domains; j++) {
4546 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4547 if (!fti) {
4548 return NT_STATUS_NO_MEMORY;
4551 status = get_ft_info(p->mem_ctx, domains[j], fti);
4552 if (!NT_STATUS_IS_OK(status)) {
4553 if (NT_STATUS_EQUAL(status,
4554 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4555 continue;
4557 return status;
4560 if (domains[j]->domain_name == NULL) {
4561 return NT_STATUS_INVALID_DOMAIN_STATE;
4564 status = check_ft_info(c_info, domains[j]->domain_name,
4565 fti, nfti, c_info);
4566 if (!NT_STATUS_IS_OK(status)) {
4567 return status;
4571 *r->out.collision_info = c_info;
4573 if (r->in.check_only != 0) {
4574 return NT_STATUS_OK;
4577 /* COPY_END */
4579 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
4580 p->mem_ctx, nfti,
4581 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4582 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4583 return NT_STATUS_INVALID_PARAMETER;
4586 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
4587 if (!NT_STATUS_IS_OK(status)) {
4588 return status;
4591 return NT_STATUS_OK;
4594 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
4595 struct lsa_CREDRRENAME *r)
4597 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4598 return NT_STATUS_NOT_IMPLEMENTED;
4601 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
4602 struct lsa_LSAROPENPOLICYSCE *r)
4604 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4605 return NT_STATUS_NOT_IMPLEMENTED;
4608 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4609 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4611 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4612 return NT_STATUS_NOT_IMPLEMENTED;
4615 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4616 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4618 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4619 return NT_STATUS_NOT_IMPLEMENTED;
4622 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4623 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4625 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4626 return NT_STATUS_NOT_IMPLEMENTED;