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. */
34 #include "../librpc/gen_ndr/srv_lsa.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"
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"
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};
68 enum lsa_handle_type type;
69 struct security_descriptor *sd;
72 const struct generic_mapping lsa_account_mapping = {
76 LSA_ACCOUNT_ALL_ACCESS
79 const struct generic_mapping lsa_policy_mapping = {
86 const struct generic_mapping lsa_secret_mapping = {
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)
111 if (dom_name != NULL) {
112 for (num = 0; num < ref->count; num++) {
113 if (dom_sid_equal(dom_sid, ref->domains[num].sid)) {
121 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
122 /* index not found, already at maximum domain limit */
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);
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) {
147 /***************************************************************************
148 initialize a lsa_DomainInfo structure.
149 ***************************************************************************/
151 static void init_dom_query_3(struct lsa_DomainInfo *r,
155 init_lsa_StringLarge(&r->name, name);
159 /***************************************************************************
160 initialize a lsa_DomainInfo structure.
161 ***************************************************************************/
163 static void init_dom_query_5(struct lsa_DomainInfo *r,
167 init_lsa_StringLarge(&r->name, name);
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,
181 uint32_t *pmapped_count)
183 uint32 mapped_count, i;
185 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
190 for (i = 0; i < num_entries; i++) {
194 const char *full_name;
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;
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,
213 type = SID_NAME_UNKNOWN;
218 case SID_NAME_DOM_GRP:
219 case SID_NAME_DOMAIN:
221 case SID_NAME_WKN_GRP:
222 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
223 /* Leave these unchanged */
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;
235 if (type != SID_NAME_UNKNOWN) {
236 if (type == SID_NAME_DOMAIN) {
239 sid_split_rid(&sid, &rid);
241 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
245 prid[i].sid_type = type;
247 prid[i].sid_index = dom_idx;
250 *pmapped_count = mapped_count;
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,
264 uint32 *pmapped_count)
266 uint32 mapped_count, i;
268 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
273 for (i = 0; i < num_entries; i++) {
277 const char *full_name;
279 enum lsa_SidType type;
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,
294 type = SID_NAME_UNKNOWN;
299 case SID_NAME_DOM_GRP:
300 case SID_NAME_DOMAIN:
302 case SID_NAME_WKN_GRP:
303 DEBUG(5, ("lookup_lsa_sids: %s found\n", full_name));
304 /* Leave these unchanged */
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;
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);
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;
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];
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 */
364 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
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;
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,
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);
397 return NT_STATUS_NO_MEMORY;
401 info->access = acc_granted;
404 sid_copy(&info->sid, sid);
407 info->name = talloc_strdup(info, name);
410 info->sd = dup_sec_desc(info, sd);
413 return NT_STATUS_NO_MEMORY;
417 if (!create_policy_hnd(p, handle, info)) {
419 ZERO_STRUCTP(handle);
420 return NT_STATUS_NO_MEMORY;
426 /***************************************************************************
428 ***************************************************************************/
430 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
431 struct lsa_OpenPolicy2 *r)
433 struct security_descriptor *psd = NULL;
435 uint32 des_access = r->in.access_mask;
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,
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,
455 if (!NT_STATUS_IS_OK(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)) {
466 status = create_lsa_policy_handle(p->mem_ctx, p,
467 LSA_HANDLE_POLICY_TYPE,
469 get_global_sam_sid(),
473 if (!NT_STATUS_IS_OK(status)) {
474 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
480 /***************************************************************************
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.
503 ***************************************************************************/
505 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
506 struct lsa_EnumTrustDom *r)
508 struct lsa_info *info;
510 struct trustdom_info **domains;
511 struct lsa_DomainInfo *entries;
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;
527 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
530 if (!NT_STATUS_IS_OK(nt_status)) {
534 entries = talloc_zero_array(p->mem_ctx, struct lsa_DomainInfo, count);
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;
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 /***************************************************************************
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;
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;
606 case LSA_POLICY_INFO_DOMAIN:
607 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
609 case LSA_POLICY_INFO_PD:
610 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
612 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
613 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
615 case LSA_POLICY_INFO_ROLE:
616 case LSA_POLICY_INFO_REPLICA:
617 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
619 case LSA_POLICY_INFO_QUOTA:
620 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
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;
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;
638 if (!(handle->access & acc_required)) {
639 /* return NT_STATUS_ACCESS_DENIED; */
642 info = talloc_zero(p->mem_ctx, union lsa_PolicyInformation);
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;
662 case LSA_POLICY_INFO_PD:
663 info->pd.name.string = NULL;
664 status = NT_STATUS_OK;
666 case LSA_POLICY_INFO_REPLICA:
667 info->replica.source.string = NULL;
668 info->replica.account.string = NULL;
669 status = NT_STATUS_OK;
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;
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;
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());
724 return NT_STATUS_NO_MEMORY;
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);
733 return NT_STATUS_NO_MEMORY;
736 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
739 case ROLE_STANDALONE:
740 name = lp_workgroup();
744 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
746 init_dom_query_3(&info->domain, name, sid);
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);
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;
774 * any other role is a primary
775 * of the domain, it controls.
777 info->role.role = LSA_ROLE_PRIMARY;
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;
792 dominfo = pdb_get_domain_info(info);
793 if (dominfo == NULL) {
794 status = NT_STATUS_NO_MEMORY;
798 init_lsa_StringLarge(&info->dns.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;
809 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
811 status = NT_STATUS_INVALID_INFO_CLASS;
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;
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,
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 */
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;
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)) {
890 names = talloc_array(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
892 return NT_STATUS_NO_MEMORY;
895 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
897 if (!dom_infos[i].valid) {
901 if (init_lsa_ref_domain_list(mem_ctx, ref,
903 &dom_infos[i].sid) != i) {
904 DEBUG(0, ("Domain %s mentioned twice??\n",
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) {
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;
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;
951 /***************************************************************************
953 ***************************************************************************/
955 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
956 struct lsa_LookupSids *r)
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;
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,
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)) {
1016 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
1017 names_out = talloc_array(p->mem_ctx, struct lsa_TranslatedName,
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;
1037 static NTSTATUS _lsa_LookupSids_common(struct pipes_struct *p,
1038 struct lsa_LookupSids2 *r)
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;
1049 case NDR_LSA_LOOKUPSIDS3:
1050 check_policy = false;
1052 case NDR_LSA_LOOKUPSIDS2:
1054 check_policy = true;
1057 if ((r->in.level < 1) || (r->in.level > 6)) {
1058 return NT_STATUS_INVALID_PARAMETER;
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,
1091 *r->out.domains = domains;
1092 r->out.names->count = num_sids;
1093 r->out.names->names = names;
1094 *r->out.count = mapped_count;
1099 /***************************************************************************
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 /***************************************************************************
1116 ***************************************************************************/
1118 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1119 struct lsa_LookupSids3 *r)
1121 struct lsa_LookupSids2 q;
1123 if (p->transport != NCACN_IP_TCP) {
1124 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1125 return NT_STATUS_ACCESS_DENIED;
1128 /* No policy handle on this call. Restrict to crypto connections. */
1129 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1130 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1131 get_remote_machine_name() ));
1132 return NT_STATUS_INVALID_PARAMETER;
1136 q.in.sids = r->in.sids;
1137 q.in.level = r->in.level;
1138 q.in.lookup_options = r->in.lookup_options;
1139 q.in.client_revision = r->in.client_revision;
1140 q.in.names = r->in.names;
1141 q.in.count = r->in.count;
1143 q.out.domains = r->out.domains;
1144 q.out.names = r->out.names;
1145 q.out.count = r->out.count;
1147 return _lsa_LookupSids_common(p, &q);
1150 /***************************************************************************
1151 ***************************************************************************/
1153 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1158 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1159 flags = LOOKUP_NAME_ALL;
1161 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1162 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1164 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1165 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1167 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1168 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1169 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1170 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1172 flags = LOOKUP_NAME_NONE;
1179 /***************************************************************************
1181 ***************************************************************************/
1183 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1184 struct lsa_LookupNames *r)
1186 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1187 struct lsa_info *handle;
1188 struct lsa_String *names = r->in.names;
1189 uint32 num_entries = r->in.num_names;
1190 struct lsa_RefDomainList *domains = NULL;
1191 struct lsa_TranslatedSid *rids = NULL;
1192 uint32 mapped_count = 0;
1195 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1196 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1197 return NT_STATUS_ACCESS_DENIED;
1200 if (num_entries > MAX_LOOKUP_SIDS) {
1201 num_entries = MAX_LOOKUP_SIDS;
1202 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1206 flags = lsa_lookup_level_to_flags(r->in.level);
1208 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1210 return NT_STATUS_NO_MEMORY;
1214 rids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid,
1217 return NT_STATUS_NO_MEMORY;
1223 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1224 status = NT_STATUS_INVALID_HANDLE;
1228 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1229 return NT_STATUS_INVALID_HANDLE;
1232 /* check if the user has enough rights */
1233 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1234 status = NT_STATUS_ACCESS_DENIED;
1238 /* set up the LSA Lookup RIDs response */
1239 become_root(); /* lookup_name can require root privs */
1240 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1241 names, flags, &mapped_count);
1246 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1247 if (mapped_count == 0) {
1248 status = NT_STATUS_NONE_MAPPED;
1249 } else if (mapped_count != num_entries) {
1250 status = STATUS_SOME_UNMAPPED;
1254 *r->out.count = mapped_count;
1255 *r->out.domains = domains;
1256 r->out.sids->sids = rids;
1257 r->out.sids->count = num_entries;
1262 /***************************************************************************
1264 ***************************************************************************/
1266 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1267 struct lsa_LookupNames2 *r)
1270 struct lsa_LookupNames q;
1271 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1272 struct lsa_TransSidArray *sid_array = NULL;
1275 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1276 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1277 return NT_STATUS_ACCESS_DENIED;
1280 sid_array = talloc_zero(p->mem_ctx, struct lsa_TransSidArray);
1282 return NT_STATUS_NO_MEMORY;
1285 q.in.handle = r->in.handle;
1286 q.in.num_names = r->in.num_names;
1287 q.in.names = r->in.names;
1288 q.in.level = r->in.level;
1289 q.in.sids = sid_array;
1290 q.in.count = r->in.count;
1291 /* we do not know what this is for */
1292 /* = r->in.unknown1; */
1293 /* = r->in.unknown2; */
1295 q.out.domains = r->out.domains;
1296 q.out.sids = sid_array;
1297 q.out.count = r->out.count;
1299 status = _lsa_LookupNames(p, &q);
1301 sid_array2->count = sid_array->count;
1302 sid_array2->sids = talloc_array(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1303 if (!sid_array2->sids) {
1304 return NT_STATUS_NO_MEMORY;
1307 for (i=0; i<sid_array->count; i++) {
1308 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1309 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1310 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1311 sid_array2->sids[i].unknown = 0;
1314 r->out.sids = sid_array2;
1319 static NTSTATUS _lsa_LookupNames_common(struct pipes_struct *p,
1320 struct lsa_LookupNames3 *r)
1323 struct lsa_info *handle;
1324 struct lsa_String *names = r->in.names;
1325 uint32 num_entries = r->in.num_names;
1326 struct lsa_RefDomainList *domains = NULL;
1327 struct lsa_TranslatedSid3 *trans_sids = NULL;
1328 uint32 mapped_count = 0;
1330 bool check_policy = true;
1333 case NDR_LSA_LOOKUPNAMES4:
1334 check_policy = false;
1336 case NDR_LSA_LOOKUPNAMES3:
1338 check_policy = true;
1341 if (num_entries > MAX_LOOKUP_SIDS) {
1342 num_entries = MAX_LOOKUP_SIDS;
1343 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1346 flags = lsa_lookup_level_to_flags(r->in.level);
1348 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1350 return NT_STATUS_NO_MEMORY;
1354 trans_sids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid3,
1357 return NT_STATUS_NO_MEMORY;
1365 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1366 status = NT_STATUS_INVALID_HANDLE;
1370 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1371 return NT_STATUS_INVALID_HANDLE;
1374 /* check if the user has enough rights */
1375 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1376 status = NT_STATUS_ACCESS_DENIED;
1381 /* set up the LSA Lookup SIDs response */
1382 become_root(); /* lookup_name can require root privs */
1383 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1384 names, flags, &mapped_count);
1389 if (NT_STATUS_IS_OK(status)) {
1390 if (mapped_count == 0) {
1391 status = NT_STATUS_NONE_MAPPED;
1392 } else if (mapped_count != num_entries) {
1393 status = STATUS_SOME_UNMAPPED;
1397 *r->out.count = mapped_count;
1398 *r->out.domains = domains;
1399 r->out.sids->sids = trans_sids;
1400 r->out.sids->count = num_entries;
1405 /***************************************************************************
1407 ***************************************************************************/
1409 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1410 struct lsa_LookupNames3 *r)
1412 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1413 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1414 return NT_STATUS_ACCESS_DENIED;
1417 return _lsa_LookupNames_common(p, r);
1420 /***************************************************************************
1422 ***************************************************************************/
1424 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1425 struct lsa_LookupNames4 *r)
1427 struct lsa_LookupNames3 q;
1429 if (p->transport != NCACN_IP_TCP) {
1430 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1431 return NT_STATUS_ACCESS_DENIED;
1434 /* No policy handle on this call. Restrict to crypto connections. */
1435 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1436 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1437 get_remote_machine_name() ));
1438 return NT_STATUS_INVALID_PARAMETER;
1442 q.in.num_names = r->in.num_names;
1443 q.in.names = r->in.names;
1444 q.in.level = r->in.level;
1445 q.in.lookup_options = r->in.lookup_options;
1446 q.in.client_revision = r->in.client_revision;
1447 q.in.sids = r->in.sids;
1448 q.in.count = r->in.count;
1450 q.out.domains = r->out.domains;
1451 q.out.sids = r->out.sids;
1452 q.out.count = r->out.count;
1454 return _lsa_LookupNames_common(p, &q);
1457 /***************************************************************************
1458 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1459 ***************************************************************************/
1461 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1463 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1464 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1465 return NT_STATUS_ACCESS_DENIED;
1468 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1469 return NT_STATUS_INVALID_HANDLE;
1472 close_policy_hnd(p, r->in.handle);
1473 ZERO_STRUCTP(r->out.handle);
1474 return NT_STATUS_OK;
1477 /***************************************************************************
1478 ***************************************************************************/
1480 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1481 const struct dom_sid *sid,
1482 struct trustdom_info **info)
1485 uint32_t num_domains = 0;
1486 struct trustdom_info **domains = NULL;
1489 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1490 if (!NT_STATUS_IS_OK(status)) {
1494 for (i=0; i < num_domains; i++) {
1495 if (dom_sid_equal(&domains[i]->sid, sid)) {
1500 if (i == num_domains) {
1501 return NT_STATUS_INVALID_PARAMETER;
1506 return NT_STATUS_OK;
1509 /***************************************************************************
1510 ***************************************************************************/
1512 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1513 const char *netbios_domain_name,
1514 struct trustdom_info **info_p)
1517 struct trustdom_info *info;
1518 struct pdb_trusted_domain *td;
1520 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1521 if (!NT_STATUS_IS_OK(status)) {
1525 info = talloc(mem_ctx, struct trustdom_info);
1527 return NT_STATUS_NO_MEMORY;
1530 info->name = talloc_strdup(info, netbios_domain_name);
1531 NT_STATUS_HAVE_NO_MEMORY(info->name);
1533 sid_copy(&info->sid, &td->security_identifier);
1537 return NT_STATUS_OK;
1540 /***************************************************************************
1542 ***************************************************************************/
1544 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p,
1545 struct lsa_OpenSecret *r)
1547 struct lsa_info *handle;
1548 struct security_descriptor *psd;
1550 uint32_t acc_granted;
1552 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1553 return NT_STATUS_INVALID_HANDLE;
1556 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1557 return NT_STATUS_INVALID_HANDLE;
1560 if (!r->in.name.string) {
1561 return NT_STATUS_INVALID_PARAMETER;
1564 /* Work out max allowed. */
1565 map_max_allowed_access(p->session_info->security_token,
1566 p->session_info->unix_token,
1567 &r->in.access_mask);
1569 /* map the generic bits to the lsa policy ones */
1570 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
1572 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
1578 if (!NT_STATUS_IS_OK(status)) {
1582 status = access_check_object(psd, p->session_info->security_token,
1583 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1585 &acc_granted, "_lsa_OpenSecret");
1586 if (!NT_STATUS_IS_OK(status)) {
1590 status = create_lsa_policy_handle(p->mem_ctx, p,
1591 LSA_HANDLE_SECRET_TYPE,
1597 if (!NT_STATUS_IS_OK(status)) {
1598 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1601 return NT_STATUS_OK;
1604 /***************************************************************************
1605 _lsa_OpenTrustedDomain_base
1606 ***************************************************************************/
1608 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1609 uint32_t access_mask,
1610 struct trustdom_info *info,
1611 struct policy_handle *handle)
1613 struct security_descriptor *psd = NULL;
1615 uint32_t acc_granted;
1618 /* des_access is for the account here, not the policy
1619 * handle - so don't check against policy handle. */
1621 /* Work out max allowed. */
1622 map_max_allowed_access(p->session_info->security_token,
1623 p->session_info->unix_token,
1626 /* map the generic bits to the lsa account ones */
1627 se_map_generic(&access_mask, &lsa_trusted_domain_mapping);
1629 /* get the generic lsa account SD until we store it */
1630 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1631 &lsa_trusted_domain_mapping,
1633 if (!NT_STATUS_IS_OK(status)) {
1637 status = access_check_object(psd, p->session_info->security_token,
1638 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1639 access_mask, &acc_granted,
1640 "_lsa_OpenTrustedDomain");
1641 if (!NT_STATUS_IS_OK(status)) {
1645 status = create_lsa_policy_handle(p->mem_ctx, p,
1646 LSA_HANDLE_TRUST_TYPE,
1652 if (!NT_STATUS_IS_OK(status)) {
1653 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1656 return NT_STATUS_OK;
1659 /***************************************************************************
1660 _lsa_OpenTrustedDomain
1661 ***************************************************************************/
1663 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1664 struct lsa_OpenTrustedDomain *r)
1666 struct lsa_info *handle = NULL;
1667 struct trustdom_info *info = NULL;
1670 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1671 return NT_STATUS_INVALID_HANDLE;
1674 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1675 return NT_STATUS_INVALID_HANDLE;
1678 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1681 if (!NT_STATUS_IS_OK(status)) {
1685 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1686 r->out.trustdom_handle);
1689 /***************************************************************************
1690 _lsa_OpenTrustedDomainByName
1691 ***************************************************************************/
1693 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1694 struct lsa_OpenTrustedDomainByName *r)
1696 struct lsa_info *handle = NULL;
1697 struct trustdom_info *info = NULL;
1700 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1701 return NT_STATUS_INVALID_HANDLE;
1704 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1705 return NT_STATUS_INVALID_HANDLE;
1708 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1711 if (!NT_STATUS_IS_OK(status)) {
1715 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1716 r->out.trustdom_handle);
1719 static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
1720 TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
1721 struct trustDomainPasswords *auth_struct)
1723 enum ndr_err_code ndr_err;
1724 DATA_BLOB lsession_key;
1727 status = session_extract_session_key(p->session_info, &lsession_key, KEY_USE_16BYTES);
1728 if (!NT_STATUS_IS_OK(status)) {
1729 return NT_STATUS_INVALID_PARAMETER;
1732 arcfour_crypt_blob(auth_blob->data, auth_blob->length, &lsession_key);
1733 ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
1735 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
1736 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1737 return NT_STATUS_INVALID_PARAMETER;
1740 return NT_STATUS_OK;
1743 static NTSTATUS get_trustauth_inout_blob(TALLOC_CTX *mem_ctx,
1744 struct trustAuthInOutBlob *iopw,
1745 DATA_BLOB *trustauth_blob)
1747 enum ndr_err_code ndr_err;
1749 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
1751 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
1752 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1753 return NT_STATUS_INVALID_PARAMETER;
1756 return NT_STATUS_OK;
1759 /***************************************************************************
1760 _lsa_CreateTrustedDomainEx2
1761 ***************************************************************************/
1763 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1764 struct lsa_CreateTrustedDomainEx2 *r)
1766 struct lsa_info *policy;
1768 uint32_t acc_granted;
1769 struct security_descriptor *psd;
1771 struct pdb_trusted_domain td;
1772 struct trustDomainPasswords auth_struct;
1773 DATA_BLOB auth_blob;
1776 return NT_STATUS_NOT_SUPPORTED;
1779 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1780 return NT_STATUS_INVALID_HANDLE;
1783 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1784 return NT_STATUS_ACCESS_DENIED;
1787 if (p->session_info->unix_token->uid != sec_initial_uid() &&
1788 !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1789 return NT_STATUS_ACCESS_DENIED;
1792 /* Work out max allowed. */
1793 map_max_allowed_access(p->session_info->security_token,
1794 p->session_info->unix_token,
1795 &r->in.access_mask);
1797 /* map the generic bits to the lsa policy ones */
1798 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1800 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1801 &lsa_trusted_domain_mapping,
1803 if (!NT_STATUS_IS_OK(status)) {
1807 status = access_check_object(psd, p->session_info->security_token,
1808 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1809 r->in.access_mask, &acc_granted,
1810 "_lsa_CreateTrustedDomainEx2");
1811 if (!NT_STATUS_IS_OK(status)) {
1817 td.domain_name = talloc_strdup(p->mem_ctx,
1818 r->in.info->domain_name.string);
1819 if (td.domain_name == NULL) {
1820 return NT_STATUS_NO_MEMORY;
1822 td.netbios_name = talloc_strdup(p->mem_ctx,
1823 r->in.info->netbios_name.string);
1824 if (td.netbios_name == NULL) {
1825 return NT_STATUS_NO_MEMORY;
1827 sid_copy(&td.security_identifier, r->in.info->sid);
1828 td.trust_direction = r->in.info->trust_direction;
1829 td.trust_type = r->in.info->trust_type;
1830 td.trust_attributes = r->in.info->trust_attributes;
1832 if (r->in.auth_info_internal->auth_blob.size != 0) {
1833 auth_blob.length = r->in.auth_info_internal->auth_blob.size;
1834 auth_blob.data = r->in.auth_info_internal->auth_blob.data;
1836 status = get_trustdom_auth_blob(p, p->mem_ctx, &auth_blob, &auth_struct);
1837 if (!NT_STATUS_IS_OK(status)) {
1838 return NT_STATUS_UNSUCCESSFUL;
1841 status = get_trustauth_inout_blob(p->mem_ctx, &auth_struct.incoming, &td.trust_auth_incoming);
1842 if (!NT_STATUS_IS_OK(status)) {
1843 return NT_STATUS_UNSUCCESSFUL;
1846 status = get_trustauth_inout_blob(p->mem_ctx, &auth_struct.outgoing, &td.trust_auth_outgoing);
1847 if (!NT_STATUS_IS_OK(status)) {
1848 return NT_STATUS_UNSUCCESSFUL;
1851 td.trust_auth_incoming.data = NULL;
1852 td.trust_auth_incoming.length = 0;
1853 td.trust_auth_outgoing.data = NULL;
1854 td.trust_auth_outgoing.length = 0;
1857 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1858 if (!NT_STATUS_IS_OK(status)) {
1862 status = create_lsa_policy_handle(p->mem_ctx, p,
1863 LSA_HANDLE_TRUST_TYPE,
1866 r->in.info->netbios_name.string,
1868 r->out.trustdom_handle);
1869 if (!NT_STATUS_IS_OK(status)) {
1870 pdb_del_trusted_domain(r->in.info->netbios_name.string);
1871 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1874 return NT_STATUS_OK;
1877 /***************************************************************************
1878 _lsa_CreateTrustedDomainEx
1879 ***************************************************************************/
1881 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1882 struct lsa_CreateTrustedDomainEx *r)
1884 struct lsa_CreateTrustedDomainEx2 q;
1885 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1887 ZERO_STRUCT(auth_info);
1889 q.in.policy_handle = r->in.policy_handle;
1890 q.in.info = r->in.info;
1891 q.in.auth_info_internal = &auth_info;
1892 q.in.access_mask = r->in.access_mask;
1893 q.out.trustdom_handle = r->out.trustdom_handle;
1895 return _lsa_CreateTrustedDomainEx2(p, &q);
1898 /***************************************************************************
1899 _lsa_CreateTrustedDomain
1900 ***************************************************************************/
1902 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1903 struct lsa_CreateTrustedDomain *r)
1905 struct lsa_CreateTrustedDomainEx2 c;
1906 struct lsa_TrustDomainInfoInfoEx info;
1907 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1909 ZERO_STRUCT(auth_info);
1911 info.domain_name = r->in.info->name;
1912 info.netbios_name = r->in.info->name;
1913 info.sid = r->in.info->sid;
1914 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1915 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1916 info.trust_attributes = 0;
1918 c.in.policy_handle = r->in.policy_handle;
1920 c.in.auth_info_internal = &auth_info;
1921 c.in.access_mask = r->in.access_mask;
1922 c.out.trustdom_handle = r->out.trustdom_handle;
1924 return _lsa_CreateTrustedDomainEx2(p, &c);
1927 /***************************************************************************
1928 _lsa_DeleteTrustedDomain
1929 ***************************************************************************/
1931 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1932 struct lsa_DeleteTrustedDomain *r)
1935 struct lsa_info *handle;
1936 struct pdb_trusted_domain *td;
1938 /* find the connection policy handle. */
1939 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1940 return NT_STATUS_INVALID_HANDLE;
1943 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1944 return NT_STATUS_INVALID_HANDLE;
1947 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1948 return NT_STATUS_ACCESS_DENIED;
1951 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1952 if (!NT_STATUS_IS_OK(status)) {
1956 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1957 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1958 sid_string_tos(r->in.dom_sid)));
1959 return NT_STATUS_UNSUCCESSFUL;
1962 status = pdb_del_trusted_domain(td->netbios_name);
1963 if (!NT_STATUS_IS_OK(status)) {
1967 return NT_STATUS_OK;
1970 /***************************************************************************
1971 _lsa_CloseTrustedDomainEx
1972 ***************************************************************************/
1974 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1975 struct lsa_CloseTrustedDomainEx *r)
1977 return NT_STATUS_NOT_IMPLEMENTED;
1980 /***************************************************************************
1981 _lsa_QueryTrustedDomainInfo
1982 ***************************************************************************/
1984 static NTSTATUS pdb_trusted_domain_2_info_ex(TALLOC_CTX *mem_ctx,
1985 struct pdb_trusted_domain *td,
1986 struct lsa_TrustDomainInfoInfoEx *info_ex)
1988 if (td->domain_name == NULL ||
1989 td->netbios_name == NULL ||
1990 is_null_sid(&td->security_identifier)) {
1991 return NT_STATUS_INVALID_PARAMETER;
1994 info_ex->domain_name.string = talloc_strdup(mem_ctx, td->domain_name);
1995 info_ex->netbios_name.string = talloc_strdup(mem_ctx, td->netbios_name);
1996 info_ex->sid = dom_sid_dup(mem_ctx, &td->security_identifier);
1997 if (info_ex->domain_name.string == NULL ||
1998 info_ex->netbios_name.string == NULL ||
1999 info_ex->sid == NULL) {
2000 return NT_STATUS_NO_MEMORY;
2003 info_ex->trust_direction = td->trust_direction;
2004 info_ex->trust_type = td->trust_type;
2005 info_ex->trust_attributes = td->trust_attributes;
2007 return NT_STATUS_OK;
2010 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
2011 struct lsa_QueryTrustedDomainInfo *r)
2014 struct lsa_info *handle;
2015 union lsa_TrustedDomainInfo *info;
2016 struct pdb_trusted_domain *td;
2017 uint32_t acc_required;
2019 /* find the connection policy handle. */
2020 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
2021 return NT_STATUS_INVALID_HANDLE;
2024 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
2025 return NT_STATUS_INVALID_HANDLE;
2028 switch (r->in.level) {
2029 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2030 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2032 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2033 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
2035 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2036 acc_required = LSA_TRUSTED_QUERY_POSIX;
2038 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2039 acc_required = LSA_TRUSTED_QUERY_AUTH;
2041 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2042 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2044 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2045 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2047 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2048 acc_required = LSA_TRUSTED_QUERY_AUTH;
2050 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2051 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2052 LSA_TRUSTED_QUERY_POSIX |
2053 LSA_TRUSTED_QUERY_AUTH;
2055 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2056 acc_required = LSA_TRUSTED_QUERY_AUTH;
2058 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2059 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2060 LSA_TRUSTED_QUERY_POSIX |
2061 LSA_TRUSTED_QUERY_AUTH;
2063 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2064 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2066 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2067 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2068 LSA_TRUSTED_QUERY_POSIX |
2069 LSA_TRUSTED_QUERY_AUTH;
2071 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2072 acc_required = LSA_TRUSTED_QUERY_POSIX;
2075 return NT_STATUS_INVALID_PARAMETER;
2078 if (!(handle->access & acc_required)) {
2079 return NT_STATUS_ACCESS_DENIED;
2082 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2083 if (!NT_STATUS_IS_OK(status)) {
2087 info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
2089 return NT_STATUS_NO_MEMORY;
2092 switch (r->in.level) {
2093 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2094 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2096 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2097 return NT_STATUS_INVALID_PARAMETER;
2098 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2099 info->posix_offset.posix_offset = *td->trust_posix_offset;
2101 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2102 return NT_STATUS_INVALID_INFO_CLASS;
2103 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2104 return NT_STATUS_INVALID_PARAMETER;
2105 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2106 status = pdb_trusted_domain_2_info_ex(info, td, &info->info_ex);
2107 if (!NT_STATUS_IS_OK(status)) {
2111 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2112 return NT_STATUS_INVALID_INFO_CLASS;
2113 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2114 status = pdb_trusted_domain_2_info_ex(info, td,
2115 &info->full_info.info_ex);
2116 if (!NT_STATUS_IS_OK(status)) {
2119 info->full_info.posix_offset.posix_offset = *td->trust_posix_offset;
2120 status = auth_blob_2_auth_info(p->mem_ctx,
2121 td->trust_auth_incoming,
2122 td->trust_auth_outgoing,
2123 &info->full_info.auth_info);
2124 if (!NT_STATUS_IS_OK(status)) {
2128 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2129 return NT_STATUS_INVALID_INFO_CLASS;
2130 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2131 return NT_STATUS_INVALID_INFO_CLASS;
2132 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2133 return NT_STATUS_INVALID_PARAMETER;
2134 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2135 info->full_info2_internal.posix_offset.posix_offset = *td->trust_posix_offset;
2136 status = auth_blob_2_auth_info(p->mem_ctx,
2137 td->trust_auth_incoming,
2138 td->trust_auth_outgoing,
2139 &info->full_info2_internal.auth_info);
2140 if (!NT_STATUS_IS_OK(status)) {
2144 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2145 info->enc_types.enc_types = *td->supported_enc_type;
2148 return NT_STATUS_INVALID_PARAMETER;
2151 *r->out.info = info;
2153 return NT_STATUS_OK;
2156 /***************************************************************************
2157 _lsa_QueryTrustedDomainInfoBySid
2158 ***************************************************************************/
2160 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2161 struct lsa_QueryTrustedDomainInfoBySid *r)
2164 struct policy_handle trustdom_handle;
2165 struct lsa_OpenTrustedDomain o;
2166 struct lsa_QueryTrustedDomainInfo q;
2169 o.in.handle = r->in.handle;
2170 o.in.sid = r->in.dom_sid;
2171 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2172 o.out.trustdom_handle = &trustdom_handle;
2174 status = _lsa_OpenTrustedDomain(p, &o);
2175 if (!NT_STATUS_IS_OK(status)) {
2179 q.in.trustdom_handle = &trustdom_handle;
2180 q.in.level = r->in.level;
2181 q.out.info = r->out.info;
2183 status = _lsa_QueryTrustedDomainInfo(p, &q);
2184 if (!NT_STATUS_IS_OK(status)) {
2188 c.in.handle = &trustdom_handle;
2189 c.out.handle = &trustdom_handle;
2191 return _lsa_Close(p, &c);
2194 /***************************************************************************
2195 _lsa_QueryTrustedDomainInfoByName
2196 ***************************************************************************/
2198 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2199 struct lsa_QueryTrustedDomainInfoByName *r)
2202 struct policy_handle trustdom_handle;
2203 struct lsa_OpenTrustedDomainByName o;
2204 struct lsa_QueryTrustedDomainInfo q;
2207 o.in.handle = r->in.handle;
2208 o.in.name.string = r->in.trusted_domain->string;
2209 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2210 o.out.trustdom_handle = &trustdom_handle;
2212 status = _lsa_OpenTrustedDomainByName(p, &o);
2213 if (!NT_STATUS_IS_OK(status)) {
2214 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2215 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2220 q.in.trustdom_handle = &trustdom_handle;
2221 q.in.level = r->in.level;
2222 q.out.info = r->out.info;
2224 status = _lsa_QueryTrustedDomainInfo(p, &q);
2225 if (!NT_STATUS_IS_OK(status)) {
2229 c.in.handle = &trustdom_handle;
2230 c.out.handle = &trustdom_handle;
2232 return _lsa_Close(p, &c);
2235 /***************************************************************************
2237 ***************************************************************************/
2239 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p,
2240 struct lsa_CreateSecret *r)
2243 struct lsa_info *handle;
2244 uint32_t acc_granted;
2245 struct security_descriptor *psd;
2248 /* find the connection policy handle. */
2249 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
2250 return NT_STATUS_INVALID_HANDLE;
2253 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2254 return NT_STATUS_INVALID_HANDLE;
2257 /* check if the user has enough rights */
2259 if (!(handle->access & LSA_POLICY_CREATE_SECRET)) {
2260 return NT_STATUS_ACCESS_DENIED;
2263 /* Work out max allowed. */
2264 map_max_allowed_access(p->session_info->security_token,
2265 p->session_info->unix_token,
2266 &r->in.access_mask);
2268 /* map the generic bits to the lsa policy ones */
2269 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
2271 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2272 &lsa_secret_mapping,
2274 if (!NT_STATUS_IS_OK(status)) {
2278 status = access_check_object(psd, p->session_info->security_token,
2279 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2281 &acc_granted, "_lsa_CreateSecret");
2282 if (!NT_STATUS_IS_OK(status)) {
2286 if (!r->in.name.string) {
2287 return NT_STATUS_INVALID_PARAMETER;
2290 if (strlen(r->in.name.string) > 128) {
2291 return NT_STATUS_NAME_TOO_LONG;
2294 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
2295 NULL, NULL, NULL, NULL, NULL);
2296 if (NT_STATUS_IS_OK(status)) {
2297 return NT_STATUS_OBJECT_NAME_COLLISION;
2300 status = pdb_set_secret(r->in.name.string, NULL, NULL, psd);
2301 if (!NT_STATUS_IS_OK(status)) {
2305 status = create_lsa_policy_handle(p->mem_ctx, p,
2306 LSA_HANDLE_SECRET_TYPE,
2312 if (!NT_STATUS_IS_OK(status)) {
2313 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2316 return NT_STATUS_OK;
2319 /***************************************************************************
2321 ***************************************************************************/
2323 NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
2324 struct lsa_SetSecret *r)
2327 struct lsa_info *info = NULL;
2328 DATA_BLOB blob_new, blob_old;
2329 DATA_BLOB cleartext_blob_new = data_blob_null;
2330 DATA_BLOB cleartext_blob_old = data_blob_null;
2331 DATA_BLOB *cleartext_blob_new_p = NULL;
2332 DATA_BLOB *cleartext_blob_old_p = NULL;
2333 DATA_BLOB session_key;
2335 if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
2336 return NT_STATUS_INVALID_HANDLE;
2339 if (info->type != LSA_HANDLE_SECRET_TYPE) {
2340 return NT_STATUS_INVALID_HANDLE;
2343 if (!(info->access & LSA_SECRET_SET_VALUE)) {
2344 return NT_STATUS_ACCESS_DENIED;
2347 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
2348 if(!NT_STATUS_IS_OK(status)) {
2352 if (r->in.new_val) {
2353 blob_new = data_blob_const(r->in.new_val->data,
2354 r->in.new_val->length);
2356 status = sess_decrypt_blob(p->mem_ctx, &blob_new,
2358 &cleartext_blob_new);
2359 if (!NT_STATUS_IS_OK(status)) {
2363 cleartext_blob_new_p = &cleartext_blob_new;
2366 if (r->in.old_val) {
2367 blob_old = data_blob_const(r->in.old_val->data,
2368 r->in.old_val->length);
2370 status = sess_decrypt_blob(p->mem_ctx, &blob_old,
2372 &cleartext_blob_old);
2373 if (!NT_STATUS_IS_OK(status)) {
2377 cleartext_blob_old_p = &cleartext_blob_old;
2380 status = pdb_set_secret(info->name, cleartext_blob_new_p, cleartext_blob_old_p, NULL);
2381 if (!NT_STATUS_IS_OK(status)) {
2385 #ifdef DEBUG_PASSWORD
2386 DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
2387 dump_data(10, cleartext_blob_new.data, cleartext_blob_new.length);
2388 DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
2389 dump_data(10, cleartext_blob_old.data, cleartext_blob_old.length);
2392 return NT_STATUS_OK;
2395 /***************************************************************************
2397 ***************************************************************************/
2399 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
2400 struct lsa_QuerySecret *r)
2402 struct lsa_info *info = NULL;
2403 DATA_BLOB blob_new, blob_old;
2404 DATA_BLOB blob_new_crypt, blob_old_crypt;
2405 DATA_BLOB session_key;
2406 NTTIME nttime_new, nttime_old;
2409 if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
2410 return NT_STATUS_INVALID_HANDLE;
2413 if (info->type != LSA_HANDLE_SECRET_TYPE) {
2414 return NT_STATUS_INVALID_HANDLE;
2417 if (!(info->access & LSA_SECRET_QUERY_VALUE)) {
2418 return NT_STATUS_ACCESS_DENIED;
2421 status = pdb_get_secret(p->mem_ctx, info->name,
2422 &blob_new, &nttime_new,
2423 &blob_old, &nttime_old,
2425 if (!NT_STATUS_IS_OK(status)) {
2429 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
2430 if(!NT_STATUS_IS_OK(status)) {
2434 if (r->in.new_val) {
2435 if (blob_new.length) {
2436 if (!r->out.new_val->buf) {
2437 r->out.new_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2439 if (!r->out.new_val->buf) {
2440 return NT_STATUS_NO_MEMORY;
2443 blob_new_crypt = sess_encrypt_blob(p->mem_ctx, &blob_new,
2445 if (!blob_new_crypt.length) {
2446 return NT_STATUS_NO_MEMORY;
2449 r->out.new_val->buf->data = blob_new_crypt.data;
2450 r->out.new_val->buf->length = blob_new_crypt.length;
2451 r->out.new_val->buf->size = blob_new_crypt.length;
2455 if (r->in.old_val) {
2456 if (blob_old.length) {
2457 if (!r->out.old_val->buf) {
2458 r->out.old_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2460 if (!r->out.old_val->buf) {
2461 return NT_STATUS_NO_MEMORY;
2464 blob_old_crypt = sess_encrypt_blob(p->mem_ctx, &blob_old,
2466 if (!blob_old_crypt.length) {
2467 return NT_STATUS_NO_MEMORY;
2470 r->out.old_val->buf->data = blob_old_crypt.data;
2471 r->out.old_val->buf->length = blob_old_crypt.length;
2472 r->out.old_val->buf->size = blob_old_crypt.length;
2476 if (r->out.new_mtime) {
2477 *r->out.new_mtime = nttime_new;
2480 if (r->out.old_mtime) {
2481 *r->out.old_mtime = nttime_old;
2484 return NT_STATUS_OK;
2487 /***************************************************************************
2489 ***************************************************************************/
2491 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2492 struct lsa_DeleteObject *r)
2495 struct lsa_info *info = NULL;
2497 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2498 return NT_STATUS_INVALID_HANDLE;
2501 if (!(info->access & SEC_STD_DELETE)) {
2502 return NT_STATUS_ACCESS_DENIED;
2505 switch (info->type) {
2506 case LSA_HANDLE_ACCOUNT_TYPE:
2507 status = privilege_delete_account(&info->sid);
2508 if (!NT_STATUS_IS_OK(status)) {
2509 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2510 nt_errstr(status)));
2514 case LSA_HANDLE_TRUST_TYPE:
2515 if (!pdb_del_trusteddom_pw(info->name)) {
2516 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2518 status = NT_STATUS_OK;
2520 case LSA_HANDLE_SECRET_TYPE:
2521 status = pdb_delete_secret(info->name);
2522 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2523 return NT_STATUS_INVALID_HANDLE;
2527 return NT_STATUS_INVALID_HANDLE;
2530 close_policy_hnd(p, r->in.handle);
2531 ZERO_STRUCTP(r->out.handle);
2536 /***************************************************************************
2538 ***************************************************************************/
2540 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2541 struct lsa_EnumPrivs *r)
2543 struct lsa_info *handle;
2545 uint32 enum_context = *r->in.resume_handle;
2546 int num_privs = num_privileges_in_short_list();
2547 struct lsa_PrivEntry *entries = NULL;
2549 /* remember that the enum_context starts at 0 and not 1 */
2551 if ( enum_context >= num_privs )
2552 return NT_STATUS_NO_MORE_ENTRIES;
2554 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2555 enum_context, num_privs));
2557 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2558 return NT_STATUS_INVALID_HANDLE;
2560 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2561 return NT_STATUS_INVALID_HANDLE;
2564 /* check if the user has enough rights
2565 I don't know if it's the right one. not documented. */
2567 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2568 return NT_STATUS_ACCESS_DENIED;
2571 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2573 return NT_STATUS_NO_MEMORY;
2579 for (i = 0; i < num_privs; i++) {
2580 if( i < enum_context) {
2582 init_lsa_StringLarge(&entries[i].name, NULL);
2584 entries[i].luid.low = 0;
2585 entries[i].luid.high = 0;
2588 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2590 entries[i].luid.low = sec_privilege_from_index(i);
2591 entries[i].luid.high = 0;
2595 enum_context = num_privs;
2597 *r->out.resume_handle = enum_context;
2598 r->out.privs->count = num_privs;
2599 r->out.privs->privs = entries;
2601 return NT_STATUS_OK;
2604 /***************************************************************************
2605 _lsa_LookupPrivDisplayName
2606 ***************************************************************************/
2608 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2609 struct lsa_LookupPrivDisplayName *r)
2611 struct lsa_info *handle;
2612 const char *description;
2613 struct lsa_StringLarge *lsa_name;
2615 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2616 return NT_STATUS_INVALID_HANDLE;
2618 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2619 return NT_STATUS_INVALID_HANDLE;
2622 /* check if the user has enough rights */
2625 * I don't know if it's the right one. not documented.
2627 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2628 return NT_STATUS_ACCESS_DENIED;
2630 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2632 description = get_privilege_dispname(r->in.name->string);
2634 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2635 return NT_STATUS_NO_SUCH_PRIVILEGE;
2638 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2640 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2642 return NT_STATUS_NO_MEMORY;
2645 init_lsa_StringLarge(lsa_name, description);
2647 *r->out.returned_language_id = r->in.language_id;
2648 *r->out.disp_name = lsa_name;
2650 return NT_STATUS_OK;
2653 /***************************************************************************
2655 ***************************************************************************/
2657 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2658 struct lsa_EnumAccounts *r)
2660 struct lsa_info *handle;
2661 struct dom_sid *sid_list;
2662 int i, j, num_entries;
2664 struct lsa_SidPtr *sids = NULL;
2666 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2667 return NT_STATUS_INVALID_HANDLE;
2669 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2670 return NT_STATUS_INVALID_HANDLE;
2673 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2674 return NT_STATUS_ACCESS_DENIED;
2679 /* The only way we can currently find out all the SIDs that have been
2680 privileged is to scan all privileges */
2682 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2683 if (!NT_STATUS_IS_OK(status)) {
2687 if (*r->in.resume_handle >= num_entries) {
2688 return NT_STATUS_NO_MORE_ENTRIES;
2691 if (num_entries - *r->in.resume_handle) {
2692 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2693 num_entries - *r->in.resume_handle);
2695 talloc_free(sid_list);
2696 return NT_STATUS_NO_MEMORY;
2699 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2700 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2702 talloc_free(sid_list);
2703 return NT_STATUS_NO_MEMORY;
2708 talloc_free(sid_list);
2710 *r->out.resume_handle = num_entries;
2711 r->out.sids->num_sids = num_entries;
2712 r->out.sids->sids = sids;
2714 return NT_STATUS_OK;
2717 /***************************************************************************
2719 ***************************************************************************/
2721 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2722 struct lsa_GetUserName *r)
2724 const char *username, *domname;
2725 struct lsa_String *account_name = NULL;
2726 struct lsa_String *authority_name = NULL;
2728 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
2729 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
2730 return NT_STATUS_ACCESS_DENIED;
2733 if (r->in.account_name &&
2734 *r->in.account_name) {
2735 return NT_STATUS_INVALID_PARAMETER;
2738 if (r->in.authority_name &&
2739 *r->in.authority_name) {
2740 return NT_STATUS_INVALID_PARAMETER;
2743 if (security_session_user_level(p->session_info, NULL) < SECURITY_USER) {
2745 * I'm 99% sure this is not the right place to do this,
2746 * global_sid_Anonymous should probably be put into the token
2747 * instead of the guest id -- vl
2749 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2750 &domname, &username, NULL)) {
2751 return NT_STATUS_NO_MEMORY;
2754 username = p->session_info->unix_info->sanitized_username;
2755 domname = p->session_info->info->domain_name;
2758 account_name = talloc(p->mem_ctx, struct lsa_String);
2759 if (!account_name) {
2760 return NT_STATUS_NO_MEMORY;
2762 init_lsa_String(account_name, username);
2764 if (r->out.authority_name) {
2765 authority_name = talloc(p->mem_ctx, struct lsa_String);
2766 if (!authority_name) {
2767 return NT_STATUS_NO_MEMORY;
2769 init_lsa_String(authority_name, domname);
2772 *r->out.account_name = account_name;
2773 if (r->out.authority_name) {
2774 *r->out.authority_name = authority_name;
2777 return NT_STATUS_OK;
2780 /***************************************************************************
2782 ***************************************************************************/
2784 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2785 struct lsa_CreateAccount *r)
2788 struct lsa_info *handle;
2789 uint32_t acc_granted;
2790 struct security_descriptor *psd;
2792 uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
2793 ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
2794 LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2797 /* find the connection policy handle. */
2798 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2799 return NT_STATUS_INVALID_HANDLE;
2801 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2802 return NT_STATUS_INVALID_HANDLE;
2805 /* check if the user has enough rights */
2807 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2808 return NT_STATUS_ACCESS_DENIED;
2811 /* Work out max allowed. */
2812 map_max_allowed_access(p->session_info->security_token,
2813 p->session_info->unix_token,
2814 &r->in.access_mask);
2816 /* map the generic bits to the lsa policy ones */
2817 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2819 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2820 &lsa_account_mapping,
2821 r->in.sid, owner_access);
2822 if (!NT_STATUS_IS_OK(status)) {
2826 status = access_check_object(psd, p->session_info->security_token,
2827 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2828 &acc_granted, "_lsa_CreateAccount");
2829 if (!NT_STATUS_IS_OK(status)) {
2833 if ( is_privileged_sid( r->in.sid ) )
2834 return NT_STATUS_OBJECT_NAME_COLLISION;
2836 status = create_lsa_policy_handle(p->mem_ctx, p,
2837 LSA_HANDLE_ACCOUNT_TYPE,
2842 r->out.acct_handle);
2843 if (!NT_STATUS_IS_OK(status)) {
2844 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2847 return privilege_create_account(r->in.sid);
2850 /***************************************************************************
2852 ***************************************************************************/
2854 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2855 struct lsa_OpenAccount *r)
2857 struct lsa_info *handle;
2858 struct security_descriptor *psd = NULL;
2860 uint32_t des_access = r->in.access_mask;
2861 uint32_t acc_granted;
2862 uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
2863 ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
2864 LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2868 /* find the connection policy handle. */
2869 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2870 return NT_STATUS_INVALID_HANDLE;
2872 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2873 return NT_STATUS_INVALID_HANDLE;
2876 /* des_access is for the account here, not the policy
2877 * handle - so don't check against policy handle. */
2879 /* Work out max allowed. */
2880 map_max_allowed_access(p->session_info->security_token,
2881 p->session_info->unix_token,
2884 /* map the generic bits to the lsa account ones */
2885 se_map_generic(&des_access, &lsa_account_mapping);
2887 /* get the generic lsa account SD until we store it */
2888 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2889 &lsa_account_mapping,
2890 r->in.sid, owner_access);
2891 if (!NT_STATUS_IS_OK(status)) {
2895 status = access_check_object(psd, p->session_info->security_token,
2896 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2897 &acc_granted, "_lsa_OpenAccount" );
2898 if (!NT_STATUS_IS_OK(status)) {
2902 /* TODO: Fis the parsing routine before reenabling this check! */
2904 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2905 return NT_STATUS_ACCESS_DENIED;
2908 status = create_lsa_policy_handle(p->mem_ctx, p,
2909 LSA_HANDLE_ACCOUNT_TYPE,
2914 r->out.acct_handle);
2915 if (!NT_STATUS_IS_OK(status)) {
2916 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2919 return NT_STATUS_OK;
2922 /***************************************************************************
2923 _lsa_EnumPrivsAccount
2924 For a given SID, enumerate all the privilege this account has.
2925 ***************************************************************************/
2927 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2928 struct lsa_EnumPrivsAccount *r)
2930 NTSTATUS status = NT_STATUS_OK;
2931 struct lsa_info *info=NULL;
2932 PRIVILEGE_SET *privileges;
2933 struct lsa_PrivilegeSet *priv_set = NULL;
2935 /* find the connection policy handle. */
2936 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2937 return NT_STATUS_INVALID_HANDLE;
2939 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2940 return NT_STATUS_INVALID_HANDLE;
2943 if (!(info->access & LSA_ACCOUNT_VIEW))
2944 return NT_STATUS_ACCESS_DENIED;
2946 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2947 if (!NT_STATUS_IS_OK(status)) {
2951 *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2953 return NT_STATUS_NO_MEMORY;
2956 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2957 sid_string_dbg(&info->sid),
2958 privileges->count));
2960 priv_set->count = privileges->count;
2961 priv_set->unknown = 0;
2962 priv_set->set = talloc_move(priv_set, &privileges->set);
2967 /***************************************************************************
2968 _lsa_GetSystemAccessAccount
2969 ***************************************************************************/
2971 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2972 struct lsa_GetSystemAccessAccount *r)
2975 struct lsa_info *info = NULL;
2976 struct lsa_EnumPrivsAccount e;
2977 struct lsa_PrivilegeSet *privset;
2979 /* find the connection policy handle. */
2981 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2982 return NT_STATUS_INVALID_HANDLE;
2984 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2985 return NT_STATUS_INVALID_HANDLE;
2988 if (!(info->access & LSA_ACCOUNT_VIEW))
2989 return NT_STATUS_ACCESS_DENIED;
2991 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2993 return NT_STATUS_NO_MEMORY;
2996 e.in.handle = r->in.handle;
2997 e.out.privs = &privset;
2999 status = _lsa_EnumPrivsAccount(p, &e);
3000 if (!NT_STATUS_IS_OK(status)) {
3001 DEBUG(10,("_lsa_GetSystemAccessAccount: "
3002 "failed to call _lsa_EnumPrivsAccount(): %s\n",
3003 nt_errstr(status)));
3007 /* Samba4 would iterate over the privset to merge the policy mode bits,
3008 * not sure samba3 can do the same here, so just return what we did in
3012 0x01 -> Log on locally
3013 0x02 -> Access this computer from network
3014 0x04 -> Log on as a batch job
3015 0x10 -> Log on as a service
3017 they can be ORed together
3020 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
3021 LSA_POLICY_MODE_NETWORK;
3023 return NT_STATUS_OK;
3026 /***************************************************************************
3027 update the systemaccount information
3028 ***************************************************************************/
3030 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
3031 struct lsa_SetSystemAccessAccount *r)
3033 struct lsa_info *info=NULL;
3037 /* find the connection policy handle. */
3038 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3039 return NT_STATUS_INVALID_HANDLE;
3041 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3042 return NT_STATUS_INVALID_HANDLE;
3045 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
3046 return NT_STATUS_ACCESS_DENIED;
3049 map = talloc_zero(p->mem_ctx, GROUP_MAP);
3051 return NT_STATUS_NO_MEMORY;
3054 if (!pdb_getgrsid(map, info->sid)) {
3056 return NT_STATUS_NO_SUCH_GROUP;
3059 status = pdb_update_group_mapping_entry(map);
3064 /***************************************************************************
3065 _lsa_AddPrivilegesToAccount
3066 For a given SID, add some privileges.
3067 ***************************************************************************/
3069 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
3070 struct lsa_AddPrivilegesToAccount *r)
3072 struct lsa_info *info = NULL;
3073 struct lsa_PrivilegeSet *set = NULL;
3075 /* find the connection policy handle. */
3076 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3077 return NT_STATUS_INVALID_HANDLE;
3079 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3080 return NT_STATUS_INVALID_HANDLE;
3083 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3084 return NT_STATUS_ACCESS_DENIED;
3089 if ( !grant_privilege_set( &info->sid, set ) ) {
3090 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
3091 sid_string_dbg(&info->sid) ));
3092 return NT_STATUS_NO_SUCH_PRIVILEGE;
3095 return NT_STATUS_OK;
3098 /***************************************************************************
3099 _lsa_RemovePrivilegesFromAccount
3100 For a given SID, remove some privileges.
3101 ***************************************************************************/
3103 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
3104 struct lsa_RemovePrivilegesFromAccount *r)
3106 struct lsa_info *info = NULL;
3107 struct lsa_PrivilegeSet *set = NULL;
3109 /* find the connection policy handle. */
3110 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3111 return NT_STATUS_INVALID_HANDLE;
3113 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3114 return NT_STATUS_INVALID_HANDLE;
3117 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3118 return NT_STATUS_ACCESS_DENIED;
3123 if ( !revoke_privilege_set( &info->sid, set) ) {
3124 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
3125 sid_string_dbg(&info->sid) ));
3126 return NT_STATUS_NO_SUCH_PRIVILEGE;
3129 return NT_STATUS_OK;
3132 /***************************************************************************
3134 ***************************************************************************/
3136 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
3137 struct lsa_LookupPrivName *r)
3139 struct lsa_info *info = NULL;
3141 struct lsa_StringLarge *lsa_name;
3143 /* find the connection policy handle. */
3144 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3145 return NT_STATUS_INVALID_HANDLE;
3148 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3149 return NT_STATUS_INVALID_HANDLE;
3152 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
3153 return NT_STATUS_ACCESS_DENIED;
3156 if (r->in.luid->high != 0) {
3157 return NT_STATUS_NO_SUCH_PRIVILEGE;
3160 name = sec_privilege_name(r->in.luid->low);
3162 return NT_STATUS_NO_SUCH_PRIVILEGE;
3165 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
3167 return NT_STATUS_NO_MEMORY;
3170 lsa_name->string = talloc_strdup(lsa_name, name);
3171 if (!lsa_name->string) {
3172 TALLOC_FREE(lsa_name);
3173 return NT_STATUS_NO_MEMORY;
3176 *r->out.name = lsa_name;
3178 return NT_STATUS_OK;
3181 /***************************************************************************
3183 ***************************************************************************/
3185 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
3186 struct lsa_QuerySecurity *r)
3188 struct lsa_info *handle=NULL;
3189 struct security_descriptor *psd = NULL;
3193 /* find the connection policy handle. */
3194 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
3195 return NT_STATUS_INVALID_HANDLE;
3197 switch (handle->type) {
3198 case LSA_HANDLE_POLICY_TYPE:
3199 case LSA_HANDLE_ACCOUNT_TYPE:
3200 case LSA_HANDLE_TRUST_TYPE:
3201 case LSA_HANDLE_SECRET_TYPE:
3203 sd_size = ndr_size_security_descriptor(psd, 0);
3204 status = NT_STATUS_OK;
3207 status = NT_STATUS_INVALID_HANDLE;
3211 if (!NT_STATUS_IS_OK(status)) {
3215 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
3216 if (!*r->out.sdbuf) {
3217 return NT_STATUS_NO_MEMORY;
3223 /***************************************************************************
3224 _lsa_AddAccountRights
3225 ***************************************************************************/
3227 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
3228 struct lsa_AddAccountRights *r)
3230 struct lsa_info *info = NULL;
3232 uint32_t acc_granted = 0;
3233 struct security_descriptor *psd = NULL;
3238 /* find the connection policy handle. */
3239 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3240 return NT_STATUS_INVALID_HANDLE;
3242 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3243 return NT_STATUS_INVALID_HANDLE;
3246 /* get the generic lsa account SD for this SID until we store it */
3247 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3248 &lsa_account_mapping,
3250 if (!NT_STATUS_IS_OK(status)) {
3255 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3256 * on the policy handle. If it does, ask for
3257 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3258 * on the account sid. We don't check here so just use the latter. JRA.
3261 status = access_check_object(psd, p->session_info->security_token,
3262 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3263 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3264 &acc_granted, "_lsa_AddAccountRights" );
3265 if (!NT_STATUS_IS_OK(status)) {
3269 /* according to an NT4 PDC, you can add privileges to SIDs even without
3270 call_lsa_create_account() first. And you can use any arbitrary SID. */
3272 sid_copy( &sid, r->in.sid );
3274 for ( i=0; i < r->in.rights->count; i++ ) {
3276 const char *privname = r->in.rights->names[i].string;
3278 /* only try to add non-null strings */
3283 if ( !grant_privilege_by_name( &sid, privname ) ) {
3284 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3286 return NT_STATUS_NO_SUCH_PRIVILEGE;
3290 return NT_STATUS_OK;
3293 /***************************************************************************
3294 _lsa_RemoveAccountRights
3295 ***************************************************************************/
3297 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
3298 struct lsa_RemoveAccountRights *r)
3300 struct lsa_info *info = NULL;
3302 struct security_descriptor *psd = NULL;
3305 const char *privname = NULL;
3306 uint32_t acc_granted = 0;
3309 /* find the connection policy handle. */
3310 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3311 return NT_STATUS_INVALID_HANDLE;
3313 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3314 return NT_STATUS_INVALID_HANDLE;
3317 /* get the generic lsa account SD for this SID until we store it */
3318 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3319 &lsa_account_mapping,
3321 if (!NT_STATUS_IS_OK(status)) {
3326 * From the MS DOCs. We need
3327 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3328 * and DELETE on the account sid.
3331 status = access_check_object(psd, p->session_info->security_token,
3332 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3333 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3334 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
3335 &acc_granted, "_lsa_RemoveAccountRights");
3336 if (!NT_STATUS_IS_OK(status)) {
3340 sid_copy( &sid, r->in.sid );
3342 if ( r->in.remove_all ) {
3343 if ( !revoke_all_privileges( &sid ) )
3344 return NT_STATUS_ACCESS_DENIED;
3346 return NT_STATUS_OK;
3349 for ( i=0; i < r->in.rights->count; i++ ) {
3351 privname = r->in.rights->names[i].string;
3353 /* only try to add non-null strings */
3358 if ( !revoke_privilege_by_name( &sid, privname ) ) {
3359 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3361 return NT_STATUS_NO_SUCH_PRIVILEGE;
3365 return NT_STATUS_OK;
3368 /*******************************************************************
3369 ********************************************************************/
3371 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3372 struct lsa_RightSet *r,
3373 PRIVILEGE_SET *privileges)
3376 const char *privname;
3377 const char **privname_array = NULL;
3380 for (i=0; i<privileges->count; i++) {
3381 if (privileges->set[i].luid.high) {
3384 privname = sec_privilege_name(privileges->set[i].luid.low);
3386 if (!add_string_to_array(mem_ctx, privname,
3387 &privname_array, &num_priv)) {
3388 return NT_STATUS_NO_MEMORY;
3395 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3398 return NT_STATUS_NO_MEMORY;
3401 for (i=0; i<num_priv; i++) {
3402 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3405 r->count = num_priv;
3408 return NT_STATUS_OK;
3411 /***************************************************************************
3412 _lsa_EnumAccountRights
3413 ***************************************************************************/
3415 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3416 struct lsa_EnumAccountRights *r)
3419 struct lsa_info *info = NULL;
3420 PRIVILEGE_SET *privileges;
3422 /* find the connection policy handle. */
3424 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3425 return NT_STATUS_INVALID_HANDLE;
3427 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3428 return NT_STATUS_INVALID_HANDLE;
3431 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3432 return NT_STATUS_ACCESS_DENIED;
3435 /* according to an NT4 PDC, you can add privileges to SIDs even without
3436 call_lsa_create_account() first. And you can use any arbitrary SID. */
3438 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3439 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3440 * the lsa database */
3442 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3443 if (!NT_STATUS_IS_OK(status)) {
3447 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3448 sid_string_dbg(r->in.sid), privileges->count));
3450 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3455 /***************************************************************************
3456 _lsa_LookupPrivValue
3457 ***************************************************************************/
3459 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3460 struct lsa_LookupPrivValue *r)
3462 struct lsa_info *info = NULL;
3463 const char *name = NULL;
3465 /* find the connection policy handle. */
3467 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3468 return NT_STATUS_INVALID_HANDLE;
3470 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3471 return NT_STATUS_INVALID_HANDLE;
3474 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3475 return NT_STATUS_ACCESS_DENIED;
3477 name = r->in.name->string;
3479 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3481 r->out.luid->low = sec_privilege_id(name);
3482 r->out.luid->high = 0;
3483 if (r->out.luid->low == SEC_PRIV_INVALID) {
3484 return NT_STATUS_NO_SUCH_PRIVILEGE;
3486 return NT_STATUS_OK;
3489 /***************************************************************************
3490 _lsa_EnumAccountsWithUserRight
3491 ***************************************************************************/
3493 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3494 struct lsa_EnumAccountsWithUserRight *r)
3497 struct lsa_info *info = NULL;
3498 struct dom_sid *sids = NULL;
3501 enum sec_privilege privilege;
3503 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3504 return NT_STATUS_INVALID_HANDLE;
3507 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3508 return NT_STATUS_INVALID_HANDLE;
3511 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3512 return NT_STATUS_ACCESS_DENIED;
3515 if (!r->in.name || !r->in.name->string) {
3516 return NT_STATUS_NO_SUCH_PRIVILEGE;
3519 privilege = sec_privilege_id(r->in.name->string);
3520 if (privilege == SEC_PRIV_INVALID) {
3521 return NT_STATUS_NO_SUCH_PRIVILEGE;
3524 status = privilege_enum_sids(privilege, p->mem_ctx,
3526 if (!NT_STATUS_IS_OK(status)) {
3530 r->out.sids->num_sids = num_sids;
3531 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3532 r->out.sids->num_sids);
3534 for (i=0; i < r->out.sids->num_sids; i++) {
3535 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3537 if (!r->out.sids->sids[i].sid) {
3538 TALLOC_FREE(r->out.sids->sids);
3539 r->out.sids->num_sids = 0;
3540 return NT_STATUS_NO_MEMORY;
3544 return NT_STATUS_OK;
3547 /***************************************************************************
3549 ***************************************************************************/
3551 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3552 struct lsa_Delete *r)
3554 return NT_STATUS_NOT_SUPPORTED;
3557 static NTSTATUS info_ex_2_pdb_trusted_domain(
3558 struct lsa_TrustDomainInfoInfoEx *info_ex,
3559 struct pdb_trusted_domain *td)
3561 if (info_ex->domain_name.string == NULL ||
3562 info_ex->netbios_name.string == NULL ||
3563 info_ex->sid == NULL) {
3564 return NT_STATUS_INVALID_PARAMETER;
3567 td->domain_name = talloc_strdup(td, info_ex->domain_name.string);
3568 td->netbios_name = talloc_strdup(td, info_ex->netbios_name.string);
3569 sid_copy(&td->security_identifier, info_ex->sid);
3570 if (td->domain_name == NULL ||
3571 td->netbios_name == NULL ||
3572 is_null_sid(&td->security_identifier)) {
3573 return NT_STATUS_NO_MEMORY;
3575 td->trust_direction = info_ex->trust_direction;
3576 td->trust_type = info_ex->trust_type;
3577 td->trust_attributes = info_ex->trust_attributes;
3579 return NT_STATUS_OK;
3582 static NTSTATUS setInfoTrustedDomain_base(struct pipes_struct *p,
3583 TALLOC_CTX *mem_ctx,
3584 struct lsa_info *policy,
3585 enum lsa_TrustDomInfoEnum level,
3586 union lsa_TrustedDomainInfo *info)
3588 struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
3589 DATA_BLOB auth_blob;
3590 struct trustDomainPasswords auth_struct;
3593 struct pdb_trusted_domain *td;
3594 struct pdb_trusted_domain *orig_td;
3596 td = talloc_zero(mem_ctx, struct pdb_trusted_domain);
3598 return NT_STATUS_NO_MEMORY;
3602 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
3603 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3604 return NT_STATUS_ACCESS_DENIED;
3606 td->trust_posix_offset = &info->posix_offset.posix_offset;
3608 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
3609 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3610 return NT_STATUS_ACCESS_DENIED;
3612 nt_status = info_ex_2_pdb_trusted_domain(&info->info_ex, td);
3613 if (!NT_STATUS_IS_OK(nt_status)) {
3617 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
3618 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3619 return NT_STATUS_ACCESS_DENIED;
3621 nt_status = auth_info_2_auth_blob(td, &info->auth_info,
3622 &td->trust_auth_incoming,
3623 &td->trust_auth_outgoing);
3624 if (!NT_STATUS_IS_OK(nt_status)) {
3628 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
3629 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3630 return NT_STATUS_ACCESS_DENIED;
3632 td->trust_posix_offset = &info->full_info.posix_offset.posix_offset;
3633 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info.info_ex,
3635 if (!NT_STATUS_IS_OK(nt_status)) {
3638 nt_status = auth_info_2_auth_blob(td,
3639 &info->full_info.auth_info,
3640 &td->trust_auth_incoming,
3641 &td->trust_auth_outgoing);
3642 if (!NT_STATUS_IS_OK(nt_status)) {
3646 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
3647 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3648 return NT_STATUS_ACCESS_DENIED;
3650 auth_info_int = &info->auth_info_internal;
3652 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
3653 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3654 return NT_STATUS_ACCESS_DENIED;
3656 td->trust_posix_offset = &info->full_info_internal.posix_offset.posix_offset;
3657 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info_internal.info_ex,
3659 if (!NT_STATUS_IS_OK(nt_status)) {
3662 auth_info_int = &info->full_info_internal.auth_info;
3664 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
3665 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3666 return NT_STATUS_ACCESS_DENIED;
3668 td->supported_enc_type = &info->enc_types.enc_types;
3671 return NT_STATUS_INVALID_PARAMETER;
3674 /* decode auth_info_int if set */
3675 if (auth_info_int) {
3677 /* now decrypt blob */
3678 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
3679 auth_info_int->auth_blob.size);
3681 nt_status = get_trustdom_auth_blob(p, mem_ctx,
3682 &auth_blob, &auth_struct);
3683 if (!NT_STATUS_IS_OK(nt_status)) {
3687 memset(&auth_struct, 0, sizeof(auth_struct));
3690 /* TODO: verify only one object matches the dns/netbios/sid triplet and that
3691 * this is the one we already have */
3693 /* TODO: check if the trust direction is changed and we need to add or remove
3696 /* TODO: check if trust type shall be changed and return an error in this case
3698 nt_status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &policy->sid,
3700 if (!NT_STATUS_IS_OK(nt_status)) {
3705 /* TODO: should we fetch previous values from the existing entry
3706 * and append them ? */
3707 if (auth_struct.incoming.count) {
3708 nt_status = get_trustauth_inout_blob(mem_ctx,
3709 &auth_struct.incoming,
3710 &td->trust_auth_incoming);
3711 if (!NT_STATUS_IS_OK(nt_status)) {
3715 ZERO_STRUCT(td->trust_auth_incoming);
3718 if (auth_struct.outgoing.count) {
3719 nt_status = get_trustauth_inout_blob(mem_ctx,
3720 &auth_struct.outgoing,
3721 &td->trust_auth_outgoing);
3722 if (!NT_STATUS_IS_OK(nt_status)) {
3726 ZERO_STRUCT(td->trust_auth_outgoing);
3729 nt_status = pdb_set_trusted_domain(orig_td->domain_name, td);
3730 if (!NT_STATUS_IS_OK(nt_status)) {
3734 return NT_STATUS_OK;
3737 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3738 struct lsa_SetTrustedDomainInfo *r)
3741 struct policy_handle trustdom_handle;
3742 struct lsa_OpenTrustedDomain o;
3743 struct lsa_SetInformationTrustedDomain s;
3746 o.in.handle = r->in.handle;
3747 o.in.sid = r->in.dom_sid;
3748 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3749 o.out.trustdom_handle = &trustdom_handle;
3751 status = _lsa_OpenTrustedDomain(p, &o);
3752 if (!NT_STATUS_IS_OK(status)) {
3756 s.in.trustdom_handle = &trustdom_handle;
3757 s.in.level = r->in.level;
3758 s.in.info = r->in.info;
3760 status = _lsa_SetInformationTrustedDomain(p, &s);
3761 if (!NT_STATUS_IS_OK(status)) {
3765 c.in.handle = &trustdom_handle;
3766 c.out.handle = &trustdom_handle;
3768 return _lsa_Close(p, &c);
3771 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3772 struct lsa_SetTrustedDomainInfoByName *r)
3775 struct policy_handle trustdom_handle;
3776 struct lsa_OpenTrustedDomainByName o;
3777 struct lsa_SetInformationTrustedDomain s;
3780 o.in.handle = r->in.handle;
3781 o.in.name.string = r->in.trusted_domain->string;
3782 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3783 o.out.trustdom_handle = &trustdom_handle;
3785 status = _lsa_OpenTrustedDomainByName(p, &o);
3786 if (!NT_STATUS_IS_OK(status)) {
3787 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
3788 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3793 s.in.trustdom_handle = &trustdom_handle;
3794 s.in.level = r->in.level;
3795 s.in.info = r->in.info;
3797 status = _lsa_SetInformationTrustedDomain(p, &s);
3798 if (!NT_STATUS_IS_OK(status)) {
3802 c.in.handle = &trustdom_handle;
3803 c.out.handle = &trustdom_handle;
3805 return _lsa_Close(p, &c);
3808 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3809 struct lsa_SetInformationTrustedDomain *r)
3811 struct lsa_info *policy;
3813 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&policy)) {
3814 return NT_STATUS_INVALID_HANDLE;
3817 if (policy->type != LSA_HANDLE_TRUST_TYPE) {
3818 return NT_STATUS_INVALID_HANDLE;
3821 return setInfoTrustedDomain_base(p, p->mem_ctx, policy,
3822 r->in.level, r->in.info);
3827 * From here on the server routines are just dummy ones to make smbd link with
3828 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3829 * pulling the server stubs across one by one.
3832 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3834 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3835 return NT_STATUS_NOT_IMPLEMENTED;
3838 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3839 struct lsa_ChangePassword *r)
3841 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3842 return NT_STATUS_NOT_IMPLEMENTED;
3845 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3847 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3848 return NT_STATUS_NOT_IMPLEMENTED;
3851 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3853 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3854 return NT_STATUS_NOT_IMPLEMENTED;
3857 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3858 struct lsa_GetQuotasForAccount *r)
3860 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3861 return NT_STATUS_NOT_IMPLEMENTED;
3864 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3865 struct lsa_SetQuotasForAccount *r)
3867 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3868 return NT_STATUS_NOT_IMPLEMENTED;
3871 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3872 struct lsa_StorePrivateData *r)
3874 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3875 return NT_STATUS_NOT_IMPLEMENTED;
3878 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3879 struct lsa_RetrievePrivateData *r)
3881 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3882 return NT_STATUS_NOT_IMPLEMENTED;
3885 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3886 struct lsa_SetInfoPolicy2 *r)
3888 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3889 return NT_STATUS_NOT_IMPLEMENTED;
3892 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3893 struct lsa_EnumTrustedDomainsEx *r)
3895 struct lsa_info *info;
3897 struct pdb_trusted_domain **domains;
3898 struct lsa_TrustDomainInfoInfoEx *entries;
3902 /* bail out early if pdb backend is not capable of ex trusted domains,
3903 * if we dont do that, the client might not call
3904 * _lsa_EnumTrustedDomains() afterwards - gd */
3906 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3907 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3908 return NT_STATUS_NOT_IMPLEMENTED;
3911 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3912 return NT_STATUS_INVALID_HANDLE;
3914 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3915 return NT_STATUS_INVALID_HANDLE;
3918 /* check if the user has enough rights */
3919 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3920 return NT_STATUS_ACCESS_DENIED;
3923 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3926 if (!NT_STATUS_IS_OK(nt_status)) {
3930 entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3933 return NT_STATUS_NO_MEMORY;
3936 for (i=0; i<count; i++) {
3937 init_lsa_StringLarge(&entries[i].netbios_name,
3938 domains[i]->netbios_name);
3939 entries[i].sid = &domains[i]->security_identifier;
3942 if (*r->in.resume_handle >= count) {
3943 *r->out.resume_handle = -1;
3944 TALLOC_FREE(entries);
3945 return NT_STATUS_NO_MORE_ENTRIES;
3948 /* return the rest, limit by max_size. Note that we
3949 use the w2k3 element size value of 60 */
3950 r->out.domains->count = count - *r->in.resume_handle;
3951 r->out.domains->count = MIN(r->out.domains->count,
3952 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3954 r->out.domains->domains = entries + *r->in.resume_handle;
3956 if (r->out.domains->count < count - *r->in.resume_handle) {
3957 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3958 return STATUS_MORE_ENTRIES;
3961 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3962 * always be larger than the previous input resume handle, in
3963 * particular when hitting the last query it is vital to set the
3964 * resume handle correctly to avoid infinite client loops, as
3965 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3966 * status is NT_STATUS_OK - gd */
3968 *r->out.resume_handle = (uint32_t)-1;
3970 return NT_STATUS_OK;
3973 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3974 struct lsa_QueryDomainInformationPolicy *r)
3976 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3977 return NT_STATUS_NOT_IMPLEMENTED;
3980 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3981 struct lsa_SetDomainInformationPolicy *r)
3983 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3984 return NT_STATUS_NOT_IMPLEMENTED;
3987 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3989 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3990 return NT_STATUS_NOT_IMPLEMENTED;
3993 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3995 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3996 return NT_STATUS_NOT_IMPLEMENTED;
3999 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
4001 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4002 return NT_STATUS_NOT_IMPLEMENTED;
4005 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
4007 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4008 return NT_STATUS_NOT_IMPLEMENTED;
4011 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
4012 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
4014 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4015 return NT_STATUS_NOT_IMPLEMENTED;
4018 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
4019 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
4021 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4022 return NT_STATUS_NOT_IMPLEMENTED;
4025 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
4027 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4028 return NT_STATUS_NOT_IMPLEMENTED;
4031 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
4032 struct lsa_CREDRGETTARGETINFO *r)
4034 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4035 return NT_STATUS_NOT_IMPLEMENTED;
4038 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
4039 struct lsa_CREDRPROFILELOADED *r)
4041 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4042 return NT_STATUS_NOT_IMPLEMENTED;
4045 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
4046 struct lsa_CREDRGETSESSIONTYPES *r)
4048 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4049 return NT_STATUS_NOT_IMPLEMENTED;
4052 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
4053 struct lsa_LSARREGISTERAUDITEVENT *r)
4055 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4056 return NT_STATUS_NOT_IMPLEMENTED;
4059 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
4060 struct lsa_LSARGENAUDITEVENT *r)
4062 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4063 return NT_STATUS_NOT_IMPLEMENTED;
4066 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
4067 struct lsa_LSARUNREGISTERAUDITEVENT *r)
4069 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4070 return NT_STATUS_NOT_IMPLEMENTED;
4073 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
4074 struct lsa_lsaRQueryForestTrustInformation *r)
4076 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4077 return NT_STATUS_NOT_IMPLEMENTED;
4080 #define DNS_CMP_MATCH 0
4081 #define DNS_CMP_FIRST_IS_CHILD 1
4082 #define DNS_CMP_SECOND_IS_CHILD 2
4083 #define DNS_CMP_NO_MATCH 3
4085 /* this function assumes names are well formed DNS names.
4086 * it doesn't validate them */
4087 static int dns_cmp(const char *s1, size_t l1,
4088 const char *s2, size_t l2)
4090 const char *p1, *p2;
4095 if (strcasecmp_m(s1, s2) == 0) {
4096 return DNS_CMP_MATCH;
4098 return DNS_CMP_NO_MATCH;
4106 cret = DNS_CMP_FIRST_IS_CHILD;
4112 cret = DNS_CMP_SECOND_IS_CHILD;
4115 if (p1[t1 - t2 - 1] != '.') {
4116 return DNS_CMP_NO_MATCH;
4119 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
4123 return DNS_CMP_NO_MATCH;
4126 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
4127 struct lsa_ForestTrustInformation *lfti,
4128 struct ForestTrustInfo *fti)
4130 struct lsa_ForestTrustRecord *lrec;
4131 struct ForestTrustInfoRecord *rec;
4132 struct lsa_StringLarge *tln;
4133 struct lsa_ForestTrustDomainInfo *info;
4137 fti->count = lfti->count;
4138 fti->records = talloc_array(mem_ctx,
4139 struct ForestTrustInfoRecordArmor,
4141 if (!fti->records) {
4142 return NT_STATUS_NO_MEMORY;
4144 for (i = 0; i < fti->count; i++) {
4145 lrec = lfti->entries[i];
4146 rec = &fti->records[i].record;
4148 rec->flags = lrec->flags;
4149 rec->timestamp = lrec->time;
4150 rec->type = lrec->type;
4152 switch (lrec->type) {
4153 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
4154 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4155 tln = &lrec->forest_trust_data.top_level_name;
4156 rec->data.name.string =
4157 talloc_strdup(mem_ctx, tln->string);
4158 if (!rec->data.name.string) {
4159 return NT_STATUS_NO_MEMORY;
4161 rec->data.name.size = strlen(rec->data.name.string);
4163 case LSA_FOREST_TRUST_DOMAIN_INFO:
4164 info = &lrec->forest_trust_data.domain_info;
4165 rec->data.info.sid = *info->domain_sid;
4166 rec->data.info.dns_name.string =
4167 talloc_strdup(mem_ctx,
4168 info->dns_domain_name.string);
4169 if (!rec->data.info.dns_name.string) {
4170 return NT_STATUS_NO_MEMORY;
4172 rec->data.info.dns_name.size =
4173 strlen(rec->data.info.dns_name.string);
4174 rec->data.info.netbios_name.string =
4175 talloc_strdup(mem_ctx,
4176 info->netbios_domain_name.string);
4177 if (!rec->data.info.netbios_name.string) {
4178 return NT_STATUS_NO_MEMORY;
4180 rec->data.info.netbios_name.size =
4181 strlen(rec->data.info.netbios_name.string);
4184 return NT_STATUS_INVALID_DOMAIN_STATE;
4188 return NT_STATUS_OK;
4191 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4192 uint32_t index, uint32_t collision_type,
4193 uint32_t conflict_type, const char *tdo_name);
4195 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
4196 const char *tdo_name,
4197 struct ForestTrustInfo *tdo_fti,
4198 struct ForestTrustInfo *new_fti,
4199 struct lsa_ForestTrustCollisionInfo *c_info)
4201 struct ForestTrustInfoRecord *nrec;
4202 struct ForestTrustInfoRecord *trec;
4203 const char *dns_name;
4204 const char *nb_name = NULL;
4205 struct dom_sid *sid = NULL;
4206 const char *tname = NULL;
4209 uint32_t new_fti_idx;
4211 /* use always TDO type, until we understand when Xref can be used */
4212 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
4217 bool ex_rule = false;
4220 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
4222 nrec = &new_fti->records[new_fti_idx].record;
4224 tln_conflict = false;
4225 sid_conflict = false;
4226 nb_conflict = false;
4229 switch (nrec->type) {
4230 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4231 /* exclusions do not conflict by definition */
4234 case FOREST_TRUST_TOP_LEVEL_NAME:
4235 dns_name = nrec->data.name.string;
4236 dns_len = nrec->data.name.size;
4239 case LSA_FOREST_TRUST_DOMAIN_INFO:
4240 dns_name = nrec->data.info.dns_name.string;
4241 dns_len = nrec->data.info.dns_name.size;
4242 nb_name = nrec->data.info.netbios_name.string;
4243 sid = &nrec->data.info.sid;
4247 if (!dns_name) continue;
4249 /* check if this is already taken and not excluded */
4250 for (i = 0; i < tdo_fti->count; i++) {
4251 trec = &tdo_fti->records[i].record;
4253 switch (trec->type) {
4254 case FOREST_TRUST_TOP_LEVEL_NAME:
4256 tname = trec->data.name.string;
4257 tlen = trec->data.name.size;
4259 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
4261 tname = trec->data.name.string;
4262 tlen = trec->data.name.size;
4264 case FOREST_TRUST_DOMAIN_INFO:
4266 tname = trec->data.info.dns_name.string;
4267 tlen = trec->data.info.dns_name.size;
4270 return NT_STATUS_INVALID_PARAMETER;
4272 ret = dns_cmp(dns_name, dns_len, tname, tlen);
4275 /* if it matches exclusion,
4276 * it doesn't conflict */
4282 case DNS_CMP_FIRST_IS_CHILD:
4283 case DNS_CMP_SECOND_IS_CHILD:
4284 tln_conflict = true;
4290 /* explicit exclusion, no dns name conflict here */
4292 tln_conflict = false;
4295 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
4299 /* also test for domain info */
4300 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
4301 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
4302 sid_conflict = true;
4304 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
4305 strcasecmp_m(trec->data.info.netbios_name.string,
4312 (void)add_collision(c_info, new_fti_idx,
4314 LSA_TLN_DISABLED_CONFLICT,
4318 (void)add_collision(c_info, new_fti_idx,
4320 LSA_SID_DISABLED_CONFLICT,
4324 (void)add_collision(c_info, new_fti_idx,
4326 LSA_NB_DISABLED_CONFLICT,
4331 return NT_STATUS_OK;
4334 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4335 uint32_t idx, uint32_t collision_type,
4336 uint32_t conflict_type, const char *tdo_name)
4338 struct lsa_ForestTrustCollisionRecord **es;
4339 uint32_t i = c_info->count;
4341 es = talloc_realloc(c_info, c_info->entries,
4342 struct lsa_ForestTrustCollisionRecord *, i + 1);
4344 return NT_STATUS_NO_MEMORY;
4346 c_info->entries = es;
4347 c_info->count = i + 1;
4349 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4351 return NT_STATUS_NO_MEMORY;
4355 es[i]->type = collision_type;
4356 es[i]->flags.flags = conflict_type;
4357 es[i]->name.string = talloc_strdup(es[i], tdo_name);
4358 if (!es[i]->name.string) {
4359 return NT_STATUS_NO_MEMORY;
4361 es[i]->name.size = strlen(es[i]->name.string);
4363 return NT_STATUS_OK;
4366 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
4367 struct pdb_trusted_domain *td,
4368 struct ForestTrustInfo *info)
4370 enum ndr_err_code ndr_err;
4372 if (td->trust_forest_trust_info.length == 0 ||
4373 td->trust_forest_trust_info.data == NULL) {
4374 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4376 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
4378 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
4379 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4380 return NT_STATUS_INVALID_DOMAIN_STATE;
4383 return NT_STATUS_OK;
4386 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
4387 struct ForestTrustInfo *fti)
4389 struct ForestTrustDataDomainInfo *info;
4390 struct ForestTrustInfoRecord *rec;
4394 fti->records = talloc_array(fti,
4395 struct ForestTrustInfoRecordArmor, 2);
4396 if (!fti->records) {
4397 return NT_STATUS_NO_MEMORY;
4401 rec = &fti->records[0].record;
4405 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
4407 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
4408 if (!rec->data.name.string) {
4409 return NT_STATUS_NO_MEMORY;
4411 rec->data.name.size = strlen(rec->data.name.string);
4414 rec = &fti->records[1].record;
4418 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
4420 info = &rec->data.info;
4422 info->sid = dom_info->sid;
4423 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
4424 if (!info->dns_name.string) {
4425 return NT_STATUS_NO_MEMORY;
4427 info->dns_name.size = strlen(info->dns_name.string);
4428 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
4429 if (!info->netbios_name.string) {
4430 return NT_STATUS_NO_MEMORY;
4432 info->netbios_name.size = strlen(info->netbios_name.string);
4434 return NT_STATUS_OK;
4437 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
4438 struct lsa_lsaRSetForestTrustInformation *r)
4443 struct lsa_info *handle;
4444 uint32_t num_domains;
4445 struct pdb_trusted_domain **domains;
4446 struct ForestTrustInfo *nfti;
4447 struct ForestTrustInfo *fti;
4448 struct lsa_ForestTrustCollisionInfo *c_info;
4449 struct pdb_domain_info *dom_info;
4450 enum ndr_err_code ndr_err;
4453 return NT_STATUS_NOT_SUPPORTED;
4456 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
4457 return NT_STATUS_INVALID_HANDLE;
4460 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
4461 return NT_STATUS_INVALID_HANDLE;
4464 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
4465 return NT_STATUS_ACCESS_DENIED;
4468 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
4469 if (!NT_STATUS_IS_OK(status)) {
4472 if (num_domains == 0) {
4473 return NT_STATUS_NO_SUCH_DOMAIN;
4476 for (i = 0; i < num_domains; i++) {
4477 if (domains[i]->domain_name == NULL) {
4478 return NT_STATUS_INVALID_DOMAIN_STATE;
4480 if (strcasecmp_m(domains[i]->domain_name,
4481 r->in.trusted_domain_name->string) == 0) {
4485 if (i >= num_domains) {
4486 return NT_STATUS_NO_SUCH_DOMAIN;
4489 if (!(domains[i]->trust_attributes &
4490 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4491 return NT_STATUS_INVALID_PARAMETER;
4494 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4495 return NT_STATUS_INVALID_PARAMETER;
4498 /* The following section until COPY_END is a copy from
4499 * source4/rpmc_server/lsa/scesrc_lsa.c */
4500 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
4502 return NT_STATUS_NO_MEMORY;
4505 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4506 if (!NT_STATUS_IS_OK(status)) {
4510 c_info = talloc_zero(r->out.collision_info,
4511 struct lsa_ForestTrustCollisionInfo);
4513 return NT_STATUS_NO_MEMORY;
4516 /* first check own info, then other domains */
4517 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4519 return NT_STATUS_NO_MEMORY;
4522 dom_info = pdb_get_domain_info(p->mem_ctx);
4524 status = own_ft_info(dom_info, fti);
4525 if (!NT_STATUS_IS_OK(status)) {
4529 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
4530 if (!NT_STATUS_IS_OK(status)) {
4534 for (j = 0; j < num_domains; j++) {
4535 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4537 return NT_STATUS_NO_MEMORY;
4540 status = get_ft_info(p->mem_ctx, domains[j], fti);
4541 if (!NT_STATUS_IS_OK(status)) {
4542 if (NT_STATUS_EQUAL(status,
4543 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4549 if (domains[j]->domain_name == NULL) {
4550 return NT_STATUS_INVALID_DOMAIN_STATE;
4553 status = check_ft_info(c_info, domains[j]->domain_name,
4555 if (!NT_STATUS_IS_OK(status)) {
4560 *r->out.collision_info = c_info;
4562 if (r->in.check_only != 0) {
4563 return NT_STATUS_OK;
4568 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
4570 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4571 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4572 return NT_STATUS_INVALID_PARAMETER;
4575 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
4576 if (!NT_STATUS_IS_OK(status)) {
4580 return NT_STATUS_OK;
4583 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
4584 struct lsa_CREDRRENAME *r)
4586 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4587 return NT_STATUS_NOT_IMPLEMENTED;
4590 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
4591 struct lsa_LSAROPENPOLICYSCE *r)
4593 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4594 return NT_STATUS_NOT_IMPLEMENTED;
4597 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4598 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4600 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4601 return NT_STATUS_NOT_IMPLEMENTED;
4604 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4605 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4607 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4608 return NT_STATUS_NOT_IMPLEMENTED;
4611 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4612 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4614 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4615 return NT_STATUS_NOT_IMPLEMENTED;