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 "rpc_client/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, ("init_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, ("init_lsa_sids: %s found\n", full_name));
304 /* Leave these unchanged */
307 /* Don't hand out anything but the list above */
308 DEBUG(5, ("init_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 /* Work out max allowed. */
440 map_max_allowed_access(p->session_info->security_token,
441 p->session_info->unix_token,
444 /* map the generic bits to the lsa policy ones */
445 se_map_generic(&des_access, &lsa_policy_mapping);
447 /* get the generic lsa policy SD until we store it */
448 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
450 if (!NT_STATUS_IS_OK(status)) {
454 status = access_check_object(psd, p->session_info->security_token,
455 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
456 &acc_granted, "_lsa_OpenPolicy2" );
457 if (!NT_STATUS_IS_OK(status)) {
461 status = create_lsa_policy_handle(p->mem_ctx, p,
462 LSA_HANDLE_POLICY_TYPE,
464 get_global_sam_sid(),
468 if (!NT_STATUS_IS_OK(status)) {
469 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
475 /***************************************************************************
477 ***************************************************************************/
479 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
480 struct lsa_OpenPolicy *r)
482 struct lsa_OpenPolicy2 o;
484 o.in.system_name = NULL; /* should be ignored */
485 o.in.attr = r->in.attr;
486 o.in.access_mask = r->in.access_mask;
488 o.out.handle = r->out.handle;
490 return _lsa_OpenPolicy2(p, &o);
493 /***************************************************************************
494 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
496 ***************************************************************************/
498 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
499 struct lsa_EnumTrustDom *r)
501 struct lsa_info *info;
503 struct trustdom_info **domains;
504 struct lsa_DomainInfo *entries;
508 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
509 return NT_STATUS_INVALID_HANDLE;
511 if (info->type != LSA_HANDLE_POLICY_TYPE) {
512 return NT_STATUS_INVALID_HANDLE;
515 /* check if the user has enough rights */
516 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
517 return NT_STATUS_ACCESS_DENIED;
520 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
523 if (!NT_STATUS_IS_OK(nt_status)) {
527 entries = talloc_zero_array(p->mem_ctx, struct lsa_DomainInfo, count);
529 return NT_STATUS_NO_MEMORY;
532 for (i=0; i<count; i++) {
533 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
534 entries[i].sid = &domains[i]->sid;
537 if (*r->in.resume_handle >= count) {
538 *r->out.resume_handle = -1;
539 TALLOC_FREE(entries);
540 return NT_STATUS_NO_MORE_ENTRIES;
543 /* return the rest, limit by max_size. Note that we
544 use the w2k3 element size value of 60 */
545 r->out.domains->count = count - *r->in.resume_handle;
546 r->out.domains->count = MIN(r->out.domains->count,
547 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
549 r->out.domains->domains = entries + *r->in.resume_handle;
551 if (r->out.domains->count < count - *r->in.resume_handle) {
552 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
553 return STATUS_MORE_ENTRIES;
556 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
557 * always be larger than the previous input resume handle, in
558 * particular when hitting the last query it is vital to set the
559 * resume handle correctly to avoid infinite client loops, as
560 * seen e.g. with Windows XP SP3 when resume handle is 0 and
561 * status is NT_STATUS_OK - gd */
563 *r->out.resume_handle = (uint32_t)-1;
568 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
569 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
570 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
572 /***************************************************************************
574 ***************************************************************************/
576 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
577 struct lsa_QueryInfoPolicy *r)
579 NTSTATUS status = NT_STATUS_OK;
580 struct lsa_info *handle;
581 struct dom_sid domain_sid;
583 struct dom_sid *sid = NULL;
584 union lsa_PolicyInformation *info = NULL;
585 uint32_t acc_required = 0;
587 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
588 return NT_STATUS_INVALID_HANDLE;
590 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
591 return NT_STATUS_INVALID_HANDLE;
594 switch (r->in.level) {
595 case LSA_POLICY_INFO_AUDIT_LOG:
596 case LSA_POLICY_INFO_AUDIT_EVENTS:
597 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
599 case LSA_POLICY_INFO_DOMAIN:
600 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
602 case LSA_POLICY_INFO_PD:
603 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
605 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
606 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
608 case LSA_POLICY_INFO_ROLE:
609 case LSA_POLICY_INFO_REPLICA:
610 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
612 case LSA_POLICY_INFO_QUOTA:
613 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
615 case LSA_POLICY_INFO_MOD:
616 case LSA_POLICY_INFO_AUDIT_FULL_SET:
617 /* according to MS-LSAD 3.1.4.4.3 */
618 return NT_STATUS_INVALID_PARAMETER;
619 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
620 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
622 case LSA_POLICY_INFO_DNS:
623 case LSA_POLICY_INFO_DNS_INT:
624 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
625 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
631 if (!(handle->access & acc_required)) {
632 /* return NT_STATUS_ACCESS_DENIED; */
635 info = talloc_zero(p->mem_ctx, union lsa_PolicyInformation);
637 return NT_STATUS_NO_MEMORY;
640 switch (r->in.level) {
641 /* according to MS-LSAD 3.1.4.4.3 */
642 case LSA_POLICY_INFO_MOD:
643 case LSA_POLICY_INFO_AUDIT_FULL_SET:
644 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
645 return NT_STATUS_INVALID_PARAMETER;
646 case LSA_POLICY_INFO_AUDIT_LOG:
647 info->audit_log.percent_full = 0;
648 info->audit_log.maximum_log_size = 0;
649 info->audit_log.retention_time = 0;
650 info->audit_log.shutdown_in_progress = 0;
651 info->audit_log.time_to_shutdown = 0;
652 info->audit_log.next_audit_record = 0;
653 status = NT_STATUS_OK;
655 case LSA_POLICY_INFO_PD:
656 info->pd.name.string = NULL;
657 status = NT_STATUS_OK;
659 case LSA_POLICY_INFO_REPLICA:
660 info->replica.source.string = NULL;
661 info->replica.account.string = NULL;
662 status = NT_STATUS_OK;
664 case LSA_POLICY_INFO_QUOTA:
665 info->quota.paged_pool = 0;
666 info->quota.non_paged_pool = 0;
667 info->quota.min_wss = 0;
668 info->quota.max_wss = 0;
669 info->quota.pagefile = 0;
670 info->quota.unknown = 0;
671 status = NT_STATUS_OK;
673 case LSA_POLICY_INFO_AUDIT_EVENTS:
676 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
678 /* check if the user has enough rights */
679 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
680 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
681 return NT_STATUS_ACCESS_DENIED;
684 /* fake info: We audit everything. ;) */
686 info->audit_events.auditing_mode = true;
687 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
688 info->audit_events.settings = talloc_zero_array(p->mem_ctx,
689 enum lsa_PolicyAuditPolicy,
690 info->audit_events.count);
691 if (!info->audit_events.settings) {
692 return NT_STATUS_NO_MEMORY;
695 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
696 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
697 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
698 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
699 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
700 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
701 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
705 case LSA_POLICY_INFO_DOMAIN:
706 /* check if the user has enough rights */
707 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
708 return NT_STATUS_ACCESS_DENIED;
710 /* Request PolicyPrimaryDomainInformation. */
711 switch (lp_server_role()) {
712 case ROLE_DOMAIN_PDC:
713 case ROLE_DOMAIN_BDC:
714 name = get_global_sam_name();
715 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
717 return NT_STATUS_NO_MEMORY;
720 case ROLE_DOMAIN_MEMBER:
721 name = lp_workgroup();
722 /* We need to return the Domain SID here. */
723 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
724 sid = dom_sid_dup(p->mem_ctx, &domain_sid);
726 return NT_STATUS_NO_MEMORY;
729 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
732 case ROLE_STANDALONE:
733 name = lp_workgroup();
737 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
739 init_dom_query_3(&info->domain, name, sid);
741 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
742 /* check if the user has enough rights */
743 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
744 return NT_STATUS_ACCESS_DENIED;
746 /* Request PolicyAccountDomainInformation. */
747 name = get_global_sam_name();
748 sid = get_global_sam_sid();
750 init_dom_query_5(&info->account_domain, name, sid);
752 case LSA_POLICY_INFO_ROLE:
753 /* check if the user has enough rights */
754 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
755 return NT_STATUS_ACCESS_DENIED;
757 switch (lp_server_role()) {
758 case ROLE_DOMAIN_BDC:
760 * only a BDC is a backup controller
761 * of the domain, it controls.
763 info->role.role = LSA_ROLE_BACKUP;
767 * any other role is a primary
768 * of the domain, it controls.
770 info->role.role = LSA_ROLE_PRIMARY;
774 case LSA_POLICY_INFO_DNS:
775 case LSA_POLICY_INFO_DNS_INT: {
776 struct pdb_domain_info *dominfo;
778 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
779 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
780 "without ADS passdb backend\n"));
781 status = NT_STATUS_INVALID_INFO_CLASS;
785 dominfo = pdb_get_domain_info(info);
786 if (dominfo == NULL) {
787 status = NT_STATUS_NO_MEMORY;
791 init_lsa_StringLarge(&info->dns.name,
793 init_lsa_StringLarge(&info->dns.dns_domain,
794 dominfo->dns_domain);
795 init_lsa_StringLarge(&info->dns.dns_forest,
796 dominfo->dns_forest);
797 info->dns.domain_guid = dominfo->guid;
798 info->dns.sid = &dominfo->sid;
802 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
804 status = NT_STATUS_INVALID_INFO_CLASS;
813 /***************************************************************************
814 _lsa_QueryInfoPolicy2
815 ***************************************************************************/
817 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
818 struct lsa_QueryInfoPolicy2 *r2)
820 struct lsa_QueryInfoPolicy r;
822 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
823 p->rng_fault_state = True;
824 return NT_STATUS_NOT_IMPLEMENTED;
828 r.in.handle = r2->in.handle;
829 r.in.level = r2->in.level;
830 r.out.info = r2->out.info;
832 return _lsa_QueryInfoPolicy(p, &r);
835 /***************************************************************************
836 _lsa_lookup_sids_internal
837 ***************************************************************************/
839 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
841 uint16_t level, /* input */
842 int num_sids, /* input */
843 struct lsa_SidPtr *sid, /* input */
844 struct lsa_RefDomainList **pp_ref, /* input/output */
845 struct lsa_TranslatedName2 **pp_names,/* input/output */
846 uint32_t *pp_mapped_count) /* input/output */
850 const struct dom_sid **sids = NULL;
851 struct lsa_RefDomainList *ref = NULL;
852 uint32 mapped_count = 0;
853 struct lsa_dom_info *dom_infos = NULL;
854 struct lsa_name_info *name_infos = NULL;
855 struct lsa_TranslatedName2 *names = NULL;
857 *pp_mapped_count = 0;
865 sids = talloc_array(p->mem_ctx, const struct dom_sid *, num_sids);
866 ref = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
868 if (sids == NULL || ref == NULL) {
869 return NT_STATUS_NO_MEMORY;
872 for (i=0; i<num_sids; i++) {
873 sids[i] = sid[i].sid;
876 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
877 &dom_infos, &name_infos);
879 if (!NT_STATUS_IS_OK(status)) {
883 names = talloc_array(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
885 return NT_STATUS_NO_MEMORY;
888 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
890 if (!dom_infos[i].valid) {
894 if (init_lsa_ref_domain_list(mem_ctx, ref,
896 &dom_infos[i].sid) != i) {
897 DEBUG(0, ("Domain %s mentioned twice??\n",
899 return NT_STATUS_INTERNAL_ERROR;
903 for (i=0; i<num_sids; i++) {
904 struct lsa_name_info *name = &name_infos[i];
906 if (name->type == SID_NAME_UNKNOWN) {
908 /* Unknown sids should return the string
909 * representation of the SID. Windows 2003 behaves
910 * rather erratic here, in many cases it returns the
911 * RID as 8 bytes hex, in others it returns the full
912 * SID. We (Jerry/VL) could not figure out which the
913 * hard cases are, so leave it with the SID. */
914 name->name = dom_sid_string(p->mem_ctx, sids[i]);
915 if (name->name == NULL) {
916 return NT_STATUS_NO_MEMORY;
922 names[i].sid_type = name->type;
923 names[i].name.string = name->name;
924 names[i].sid_index = name->dom_idx;
925 names[i].unknown = 0;
928 status = NT_STATUS_NONE_MAPPED;
929 if (mapped_count > 0) {
930 status = (mapped_count < num_sids) ?
931 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
934 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
935 num_sids, mapped_count, nt_errstr(status)));
937 *pp_mapped_count = mapped_count;
944 /***************************************************************************
946 ***************************************************************************/
948 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
949 struct lsa_LookupSids *r)
952 struct lsa_info *handle;
953 int num_sids = r->in.sids->num_sids;
954 uint32 mapped_count = 0;
955 struct lsa_RefDomainList *domains = NULL;
956 struct lsa_TranslatedName *names_out = NULL;
957 struct lsa_TranslatedName2 *names = NULL;
960 if ((r->in.level < 1) || (r->in.level > 6)) {
961 return NT_STATUS_INVALID_PARAMETER;
964 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
965 return NT_STATUS_INVALID_HANDLE;
968 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
969 return NT_STATUS_INVALID_HANDLE;
972 /* check if the user has enough rights */
973 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
974 return NT_STATUS_ACCESS_DENIED;
977 if (num_sids > MAX_LOOKUP_SIDS) {
978 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
979 MAX_LOOKUP_SIDS, num_sids));
980 return NT_STATUS_NONE_MAPPED;
983 status = _lsa_lookup_sids_internal(p,
992 /* Only return here when there is a real error.
993 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
994 the requested sids could be resolved. Older versions of XP (pre SP3)
995 rely that we return with the string representations of those SIDs in
996 that case. If we don't, XP crashes - Guenther
999 if (NT_STATUS_IS_ERR(status) &&
1000 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1004 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
1005 names_out = talloc_array(p->mem_ctx, struct lsa_TranslatedName,
1008 return NT_STATUS_NO_MEMORY;
1011 for (i=0; i<num_sids; i++) {
1012 names_out[i].sid_type = names[i].sid_type;
1013 names_out[i].name = names[i].name;
1014 names_out[i].sid_index = names[i].sid_index;
1017 *r->out.domains = domains;
1018 r->out.names->count = num_sids;
1019 r->out.names->names = names_out;
1020 *r->out.count = mapped_count;
1025 /***************************************************************************
1027 ***************************************************************************/
1029 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1030 struct lsa_LookupSids2 *r)
1033 struct lsa_info *handle;
1034 int num_sids = r->in.sids->num_sids;
1035 uint32 mapped_count = 0;
1036 struct lsa_RefDomainList *domains = NULL;
1037 struct lsa_TranslatedName2 *names = NULL;
1038 bool check_policy = true;
1041 case NDR_LSA_LOOKUPSIDS3:
1042 check_policy = false;
1044 case NDR_LSA_LOOKUPSIDS2:
1046 check_policy = true;
1049 if ((r->in.level < 1) || (r->in.level > 6)) {
1050 return NT_STATUS_INVALID_PARAMETER;
1054 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1055 return NT_STATUS_INVALID_HANDLE;
1058 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1059 return NT_STATUS_INVALID_HANDLE;
1062 /* check if the user has enough rights */
1063 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1064 return NT_STATUS_ACCESS_DENIED;
1068 if (num_sids > MAX_LOOKUP_SIDS) {
1069 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1070 MAX_LOOKUP_SIDS, num_sids));
1071 return NT_STATUS_NONE_MAPPED;
1074 status = _lsa_lookup_sids_internal(p,
1083 *r->out.domains = domains;
1084 r->out.names->count = num_sids;
1085 r->out.names->names = names;
1086 *r->out.count = mapped_count;
1091 /***************************************************************************
1093 ***************************************************************************/
1095 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1096 struct lsa_LookupSids3 *r)
1098 struct lsa_LookupSids2 q;
1100 /* No policy handle on this call. Restrict to crypto connections. */
1101 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1102 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1103 get_remote_machine_name() ));
1104 return NT_STATUS_INVALID_PARAMETER;
1108 q.in.sids = r->in.sids;
1109 q.in.level = r->in.level;
1110 q.in.lookup_options = r->in.lookup_options;
1111 q.in.client_revision = r->in.client_revision;
1112 q.in.names = r->in.names;
1113 q.in.count = r->in.count;
1115 q.out.domains = r->out.domains;
1116 q.out.names = r->out.names;
1117 q.out.count = r->out.count;
1119 return _lsa_LookupSids2(p, &q);
1122 /***************************************************************************
1123 ***************************************************************************/
1125 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1130 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1131 flags = LOOKUP_NAME_ALL;
1133 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1134 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1136 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1137 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1139 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1140 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1141 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1142 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1144 flags = LOOKUP_NAME_NONE;
1151 /***************************************************************************
1153 ***************************************************************************/
1155 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1156 struct lsa_LookupNames *r)
1158 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1159 struct lsa_info *handle;
1160 struct lsa_String *names = r->in.names;
1161 uint32 num_entries = r->in.num_names;
1162 struct lsa_RefDomainList *domains = NULL;
1163 struct lsa_TranslatedSid *rids = NULL;
1164 uint32 mapped_count = 0;
1167 if (num_entries > MAX_LOOKUP_SIDS) {
1168 num_entries = MAX_LOOKUP_SIDS;
1169 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1173 flags = lsa_lookup_level_to_flags(r->in.level);
1175 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1177 return NT_STATUS_NO_MEMORY;
1181 rids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid,
1184 return NT_STATUS_NO_MEMORY;
1190 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1191 status = NT_STATUS_INVALID_HANDLE;
1195 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1196 return NT_STATUS_INVALID_HANDLE;
1199 /* check if the user has enough rights */
1200 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1201 status = NT_STATUS_ACCESS_DENIED;
1205 /* set up the LSA Lookup RIDs response */
1206 become_root(); /* lookup_name can require root privs */
1207 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1208 names, flags, &mapped_count);
1213 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1214 if (mapped_count == 0) {
1215 status = NT_STATUS_NONE_MAPPED;
1216 } else if (mapped_count != num_entries) {
1217 status = STATUS_SOME_UNMAPPED;
1221 *r->out.count = mapped_count;
1222 *r->out.domains = domains;
1223 r->out.sids->sids = rids;
1224 r->out.sids->count = num_entries;
1229 /***************************************************************************
1231 ***************************************************************************/
1233 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1234 struct lsa_LookupNames2 *r)
1237 struct lsa_LookupNames q;
1238 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1239 struct lsa_TransSidArray *sid_array = NULL;
1242 sid_array = talloc_zero(p->mem_ctx, struct lsa_TransSidArray);
1244 return NT_STATUS_NO_MEMORY;
1247 q.in.handle = r->in.handle;
1248 q.in.num_names = r->in.num_names;
1249 q.in.names = r->in.names;
1250 q.in.level = r->in.level;
1251 q.in.sids = sid_array;
1252 q.in.count = r->in.count;
1253 /* we do not know what this is for */
1254 /* = r->in.unknown1; */
1255 /* = r->in.unknown2; */
1257 q.out.domains = r->out.domains;
1258 q.out.sids = sid_array;
1259 q.out.count = r->out.count;
1261 status = _lsa_LookupNames(p, &q);
1263 sid_array2->count = sid_array->count;
1264 sid_array2->sids = talloc_array(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1265 if (!sid_array2->sids) {
1266 return NT_STATUS_NO_MEMORY;
1269 for (i=0; i<sid_array->count; i++) {
1270 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1271 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1272 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1273 sid_array2->sids[i].unknown = 0;
1276 r->out.sids = sid_array2;
1281 /***************************************************************************
1283 ***************************************************************************/
1285 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1286 struct lsa_LookupNames3 *r)
1289 struct lsa_info *handle;
1290 struct lsa_String *names = r->in.names;
1291 uint32 num_entries = r->in.num_names;
1292 struct lsa_RefDomainList *domains = NULL;
1293 struct lsa_TranslatedSid3 *trans_sids = NULL;
1294 uint32 mapped_count = 0;
1296 bool check_policy = true;
1299 case NDR_LSA_LOOKUPNAMES4:
1300 check_policy = false;
1302 case NDR_LSA_LOOKUPNAMES3:
1304 check_policy = true;
1307 if (num_entries > MAX_LOOKUP_SIDS) {
1308 num_entries = MAX_LOOKUP_SIDS;
1309 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1312 /* Probably the lookup_level is some sort of bitmask. */
1313 if (r->in.level == 1) {
1314 flags = LOOKUP_NAME_ALL;
1317 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1319 return NT_STATUS_NO_MEMORY;
1323 trans_sids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid3,
1326 return NT_STATUS_NO_MEMORY;
1334 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1335 status = NT_STATUS_INVALID_HANDLE;
1339 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1340 return NT_STATUS_INVALID_HANDLE;
1343 /* check if the user has enough rights */
1344 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1345 status = NT_STATUS_ACCESS_DENIED;
1350 /* set up the LSA Lookup SIDs response */
1351 become_root(); /* lookup_name can require root privs */
1352 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1353 names, flags, &mapped_count);
1358 if (NT_STATUS_IS_OK(status)) {
1359 if (mapped_count == 0) {
1360 status = NT_STATUS_NONE_MAPPED;
1361 } else if (mapped_count != num_entries) {
1362 status = STATUS_SOME_UNMAPPED;
1366 *r->out.count = mapped_count;
1367 *r->out.domains = domains;
1368 r->out.sids->sids = trans_sids;
1369 r->out.sids->count = num_entries;
1374 /***************************************************************************
1376 ***************************************************************************/
1378 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1379 struct lsa_LookupNames4 *r)
1381 struct lsa_LookupNames3 q;
1383 /* No policy handle on this call. Restrict to crypto connections. */
1384 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1385 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1386 get_remote_machine_name() ));
1387 return NT_STATUS_INVALID_PARAMETER;
1391 q.in.num_names = r->in.num_names;
1392 q.in.names = r->in.names;
1393 q.in.level = r->in.level;
1394 q.in.lookup_options = r->in.lookup_options;
1395 q.in.client_revision = r->in.client_revision;
1396 q.in.sids = r->in.sids;
1397 q.in.count = r->in.count;
1399 q.out.domains = r->out.domains;
1400 q.out.sids = r->out.sids;
1401 q.out.count = r->out.count;
1403 return _lsa_LookupNames3(p, &q);
1406 /***************************************************************************
1407 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1408 ***************************************************************************/
1410 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1412 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1413 return NT_STATUS_INVALID_HANDLE;
1416 close_policy_hnd(p, r->in.handle);
1417 ZERO_STRUCTP(r->out.handle);
1418 return NT_STATUS_OK;
1421 /***************************************************************************
1422 ***************************************************************************/
1424 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1425 const struct dom_sid *sid,
1426 struct trustdom_info **info)
1429 uint32_t num_domains = 0;
1430 struct trustdom_info **domains = NULL;
1433 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1434 if (!NT_STATUS_IS_OK(status)) {
1438 for (i=0; i < num_domains; i++) {
1439 if (dom_sid_equal(&domains[i]->sid, sid)) {
1444 if (i == num_domains) {
1445 return NT_STATUS_INVALID_PARAMETER;
1450 return NT_STATUS_OK;
1453 /***************************************************************************
1454 ***************************************************************************/
1456 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1457 const char *netbios_domain_name,
1458 struct trustdom_info **info_p)
1461 struct trustdom_info *info;
1462 struct pdb_trusted_domain *td;
1464 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1465 if (!NT_STATUS_IS_OK(status)) {
1469 info = talloc(mem_ctx, struct trustdom_info);
1471 return NT_STATUS_NO_MEMORY;
1474 info->name = talloc_strdup(info, netbios_domain_name);
1475 NT_STATUS_HAVE_NO_MEMORY(info->name);
1477 sid_copy(&info->sid, &td->security_identifier);
1481 return NT_STATUS_OK;
1484 /***************************************************************************
1486 ***************************************************************************/
1488 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p,
1489 struct lsa_OpenSecret *r)
1491 struct lsa_info *handle;
1492 struct security_descriptor *psd;
1494 uint32_t acc_granted;
1496 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1497 return NT_STATUS_INVALID_HANDLE;
1500 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1501 return NT_STATUS_INVALID_HANDLE;
1504 if (!r->in.name.string) {
1505 return NT_STATUS_INVALID_PARAMETER;
1508 /* Work out max allowed. */
1509 map_max_allowed_access(p->session_info->security_token,
1510 p->session_info->unix_token,
1511 &r->in.access_mask);
1513 /* map the generic bits to the lsa policy ones */
1514 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
1516 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
1522 if (!NT_STATUS_IS_OK(status)) {
1526 status = access_check_object(psd, p->session_info->security_token,
1527 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1529 &acc_granted, "_lsa_OpenSecret");
1530 if (!NT_STATUS_IS_OK(status)) {
1534 status = create_lsa_policy_handle(p->mem_ctx, p,
1535 LSA_HANDLE_SECRET_TYPE,
1541 if (!NT_STATUS_IS_OK(status)) {
1542 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1545 return NT_STATUS_OK;
1548 /***************************************************************************
1549 _lsa_OpenTrustedDomain_base
1550 ***************************************************************************/
1552 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1553 uint32_t access_mask,
1554 struct trustdom_info *info,
1555 struct policy_handle *handle)
1557 struct security_descriptor *psd = NULL;
1559 uint32_t acc_granted;
1562 /* des_access is for the account here, not the policy
1563 * handle - so don't check against policy handle. */
1565 /* Work out max allowed. */
1566 map_max_allowed_access(p->session_info->security_token,
1567 p->session_info->unix_token,
1570 /* map the generic bits to the lsa account ones */
1571 se_map_generic(&access_mask, &lsa_trusted_domain_mapping);
1573 /* get the generic lsa account SD until we store it */
1574 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1575 &lsa_trusted_domain_mapping,
1577 if (!NT_STATUS_IS_OK(status)) {
1581 status = access_check_object(psd, p->session_info->security_token,
1582 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1583 access_mask, &acc_granted,
1584 "_lsa_OpenTrustedDomain");
1585 if (!NT_STATUS_IS_OK(status)) {
1589 status = create_lsa_policy_handle(p->mem_ctx, p,
1590 LSA_HANDLE_TRUST_TYPE,
1596 if (!NT_STATUS_IS_OK(status)) {
1597 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1600 return NT_STATUS_OK;
1603 /***************************************************************************
1604 _lsa_OpenTrustedDomain
1605 ***************************************************************************/
1607 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1608 struct lsa_OpenTrustedDomain *r)
1610 struct lsa_info *handle = NULL;
1611 struct trustdom_info *info = NULL;
1614 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1615 return NT_STATUS_INVALID_HANDLE;
1618 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1619 return NT_STATUS_INVALID_HANDLE;
1622 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1625 if (!NT_STATUS_IS_OK(status)) {
1629 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1630 r->out.trustdom_handle);
1633 /***************************************************************************
1634 _lsa_OpenTrustedDomainByName
1635 ***************************************************************************/
1637 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1638 struct lsa_OpenTrustedDomainByName *r)
1640 struct lsa_info *handle = NULL;
1641 struct trustdom_info *info = NULL;
1644 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1645 return NT_STATUS_INVALID_HANDLE;
1648 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1649 return NT_STATUS_INVALID_HANDLE;
1652 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1655 if (!NT_STATUS_IS_OK(status)) {
1659 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1660 r->out.trustdom_handle);
1663 static NTSTATUS add_trusted_domain_user(TALLOC_CTX *mem_ctx,
1664 const char *netbios_name,
1665 const char *domain_name,
1666 const struct trustDomainPasswords *auth_struct)
1669 struct samu *sam_acct;
1672 struct dom_sid user_sid;
1677 sam_acct = samu_new(mem_ctx);
1678 if (sam_acct == NULL) {
1679 return NT_STATUS_NO_MEMORY;
1682 acct_name = talloc_asprintf(mem_ctx, "%s$", netbios_name);
1683 if (acct_name == NULL) {
1684 return NT_STATUS_NO_MEMORY;
1686 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1687 return NT_STATUS_UNSUCCESSFUL;
1690 if (!pdb_set_domain(sam_acct, domain_name, PDB_SET)) {
1691 return NT_STATUS_UNSUCCESSFUL;
1694 if (!pdb_set_acct_ctrl(sam_acct, ACB_DOMTRUST, PDB_SET)) {
1695 return NT_STATUS_UNSUCCESSFUL;
1698 if (!pdb_new_rid(&rid)) {
1699 return NT_STATUS_DS_NO_MORE_RIDS;
1701 sid_compose(&user_sid, get_global_sam_sid(), rid);
1702 if (!pdb_set_user_sid(sam_acct, &user_sid, PDB_SET)) {
1703 return NT_STATUS_UNSUCCESSFUL;
1706 for (i = 0; i < auth_struct->incoming.count; i++) {
1707 switch (auth_struct->incoming.current.array[i].AuthType) {
1708 case TRUST_AUTH_TYPE_CLEAR:
1709 if (!convert_string_talloc(mem_ctx,
1712 auth_struct->incoming.current.array[i].AuthInfo.clear.password,
1713 auth_struct->incoming.current.array[i].AuthInfo.clear.size,
1716 return NT_STATUS_UNSUCCESSFUL;
1718 if (!pdb_set_plaintext_passwd(sam_acct, dummy)) {
1719 return NT_STATUS_UNSUCCESSFUL;
1727 status = pdb_add_sam_account(sam_acct);
1728 if (!NT_STATUS_IS_OK(status)) {
1732 return NT_STATUS_OK;
1735 /***************************************************************************
1736 _lsa_CreateTrustedDomainEx2
1737 ***************************************************************************/
1739 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1740 struct lsa_CreateTrustedDomainEx2 *r)
1742 struct lsa_info *policy;
1744 uint32_t acc_granted;
1745 struct security_descriptor *psd;
1747 struct pdb_trusted_domain td;
1748 struct trustDomainPasswords auth_struct;
1749 enum ndr_err_code ndr_err;
1750 DATA_BLOB auth_blob;
1753 return NT_STATUS_NOT_SUPPORTED;
1756 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1757 return NT_STATUS_INVALID_HANDLE;
1760 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1761 return NT_STATUS_ACCESS_DENIED;
1764 if (p->session_info->unix_token->uid != sec_initial_uid() &&
1765 !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1766 return NT_STATUS_ACCESS_DENIED;
1769 /* Work out max allowed. */
1770 map_max_allowed_access(p->session_info->security_token,
1771 p->session_info->unix_token,
1772 &r->in.access_mask);
1774 /* map the generic bits to the lsa policy ones */
1775 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1777 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1778 &lsa_trusted_domain_mapping,
1780 if (!NT_STATUS_IS_OK(status)) {
1784 status = access_check_object(psd, p->session_info->security_token,
1785 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1786 r->in.access_mask, &acc_granted,
1787 "_lsa_CreateTrustedDomainEx2");
1788 if (!NT_STATUS_IS_OK(status)) {
1794 td.domain_name = talloc_strdup(p->mem_ctx,
1795 r->in.info->domain_name.string);
1796 if (td.domain_name == NULL) {
1797 return NT_STATUS_NO_MEMORY;
1799 td.netbios_name = talloc_strdup(p->mem_ctx,
1800 r->in.info->netbios_name.string);
1801 if (td.netbios_name == NULL) {
1802 return NT_STATUS_NO_MEMORY;
1804 sid_copy(&td.security_identifier, r->in.info->sid);
1805 td.trust_direction = r->in.info->trust_direction;
1806 td.trust_type = r->in.info->trust_type;
1807 td.trust_attributes = r->in.info->trust_attributes;
1809 if (r->in.auth_info_internal->auth_blob.size != 0) {
1810 auth_blob.length = r->in.auth_info_internal->auth_blob.size;
1811 auth_blob.data = r->in.auth_info_internal->auth_blob.data;
1813 arcfour_crypt_blob(auth_blob.data, auth_blob.length,
1814 &p->session_info->session_key);
1816 ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
1818 (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
1819 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1820 return NT_STATUS_UNSUCCESSFUL;
1823 ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
1824 &auth_struct.incoming,
1825 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1826 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1827 return NT_STATUS_UNSUCCESSFUL;
1830 ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
1831 &auth_struct.outgoing,
1832 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1833 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1834 return NT_STATUS_UNSUCCESSFUL;
1837 td.trust_auth_incoming.data = NULL;
1838 td.trust_auth_incoming.length = 0;
1839 td.trust_auth_outgoing.data = NULL;
1840 td.trust_auth_outgoing.length = 0;
1843 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1844 if (!NT_STATUS_IS_OK(status)) {
1848 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1849 status = add_trusted_domain_user(p->mem_ctx,
1850 r->in.info->netbios_name.string,
1851 r->in.info->domain_name.string,
1853 if (!NT_STATUS_IS_OK(status)) {
1858 status = create_lsa_policy_handle(p->mem_ctx, p,
1859 LSA_HANDLE_TRUST_TYPE,
1862 r->in.info->netbios_name.string,
1864 r->out.trustdom_handle);
1865 if (!NT_STATUS_IS_OK(status)) {
1866 pdb_del_trusted_domain(r->in.info->netbios_name.string);
1867 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1870 return NT_STATUS_OK;
1873 /***************************************************************************
1874 _lsa_CreateTrustedDomainEx
1875 ***************************************************************************/
1877 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1878 struct lsa_CreateTrustedDomainEx *r)
1880 struct lsa_CreateTrustedDomainEx2 q;
1881 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1883 ZERO_STRUCT(auth_info);
1885 q.in.policy_handle = r->in.policy_handle;
1886 q.in.info = r->in.info;
1887 q.in.auth_info_internal = &auth_info;
1888 q.in.access_mask = r->in.access_mask;
1889 q.out.trustdom_handle = r->out.trustdom_handle;
1891 return _lsa_CreateTrustedDomainEx2(p, &q);
1894 /***************************************************************************
1895 _lsa_CreateTrustedDomain
1896 ***************************************************************************/
1898 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1899 struct lsa_CreateTrustedDomain *r)
1901 struct lsa_CreateTrustedDomainEx2 c;
1902 struct lsa_TrustDomainInfoInfoEx info;
1903 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1905 ZERO_STRUCT(auth_info);
1907 info.domain_name = r->in.info->name;
1908 info.netbios_name = r->in.info->name;
1909 info.sid = r->in.info->sid;
1910 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1911 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1912 info.trust_attributes = 0;
1914 c.in.policy_handle = r->in.policy_handle;
1916 c.in.auth_info_internal = &auth_info;
1917 c.in.access_mask = r->in.access_mask;
1918 c.out.trustdom_handle = r->out.trustdom_handle;
1920 return _lsa_CreateTrustedDomainEx2(p, &c);
1923 /***************************************************************************
1924 _lsa_DeleteTrustedDomain
1925 ***************************************************************************/
1927 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1928 struct lsa_DeleteTrustedDomain *r)
1931 struct lsa_info *handle;
1932 struct pdb_trusted_domain *td;
1933 struct samu *sam_acct;
1936 /* find the connection policy handle. */
1937 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1938 return NT_STATUS_INVALID_HANDLE;
1941 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1942 return NT_STATUS_INVALID_HANDLE;
1945 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1946 return NT_STATUS_ACCESS_DENIED;
1949 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1950 if (!NT_STATUS_IS_OK(status)) {
1954 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1955 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1956 sid_string_tos(r->in.dom_sid)));
1957 return NT_STATUS_UNSUCCESSFUL;
1960 if (td->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1961 sam_acct = samu_new(p->mem_ctx);
1962 if (sam_acct == NULL) {
1963 return NT_STATUS_NO_MEMORY;
1966 acct_name = talloc_asprintf(p->mem_ctx, "%s$", td->netbios_name);
1967 if (acct_name == NULL) {
1968 return NT_STATUS_NO_MEMORY;
1970 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1971 return NT_STATUS_UNSUCCESSFUL;
1973 status = pdb_delete_sam_account(sam_acct);
1974 if (!NT_STATUS_IS_OK(status)) {
1979 status = pdb_del_trusted_domain(td->netbios_name);
1980 if (!NT_STATUS_IS_OK(status)) {
1984 return NT_STATUS_OK;
1987 /***************************************************************************
1988 _lsa_CloseTrustedDomainEx
1989 ***************************************************************************/
1991 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1992 struct lsa_CloseTrustedDomainEx *r)
1994 return NT_STATUS_NOT_IMPLEMENTED;
1997 /***************************************************************************
1998 _lsa_QueryTrustedDomainInfo
1999 ***************************************************************************/
2001 static NTSTATUS pdb_trusted_domain_2_info_ex(TALLOC_CTX *mem_ctx,
2002 struct pdb_trusted_domain *td,
2003 struct lsa_TrustDomainInfoInfoEx *info_ex)
2005 if (td->domain_name == NULL ||
2006 td->netbios_name == NULL ||
2007 is_null_sid(&td->security_identifier)) {
2008 return NT_STATUS_INVALID_PARAMETER;
2011 info_ex->domain_name.string = talloc_strdup(mem_ctx, td->domain_name);
2012 info_ex->netbios_name.string = talloc_strdup(mem_ctx, td->netbios_name);
2013 info_ex->sid = dom_sid_dup(mem_ctx, &td->security_identifier);
2014 if (info_ex->domain_name.string == NULL ||
2015 info_ex->netbios_name.string == NULL ||
2016 info_ex->sid == NULL) {
2017 return NT_STATUS_NO_MEMORY;
2020 info_ex->trust_direction = td->trust_direction;
2021 info_ex->trust_type = td->trust_type;
2022 info_ex->trust_attributes = td->trust_attributes;
2024 return NT_STATUS_OK;
2027 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
2028 struct lsa_QueryTrustedDomainInfo *r)
2031 struct lsa_info *handle;
2032 union lsa_TrustedDomainInfo *info;
2033 struct pdb_trusted_domain *td;
2034 uint32_t acc_required;
2036 /* find the connection policy handle. */
2037 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
2038 return NT_STATUS_INVALID_HANDLE;
2041 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
2042 return NT_STATUS_INVALID_HANDLE;
2045 switch (r->in.level) {
2046 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2047 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2049 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2050 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
2052 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2053 acc_required = LSA_TRUSTED_QUERY_POSIX;
2055 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2056 acc_required = LSA_TRUSTED_QUERY_AUTH;
2058 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2059 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2061 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2062 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2064 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2065 acc_required = LSA_TRUSTED_QUERY_AUTH;
2067 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2068 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2069 LSA_TRUSTED_QUERY_POSIX |
2070 LSA_TRUSTED_QUERY_AUTH;
2072 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2073 acc_required = LSA_TRUSTED_QUERY_AUTH;
2075 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2076 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2077 LSA_TRUSTED_QUERY_POSIX |
2078 LSA_TRUSTED_QUERY_AUTH;
2080 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2081 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2083 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2084 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2085 LSA_TRUSTED_QUERY_POSIX |
2086 LSA_TRUSTED_QUERY_AUTH;
2088 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2089 acc_required = LSA_TRUSTED_QUERY_POSIX;
2092 return NT_STATUS_INVALID_PARAMETER;
2095 if (!(handle->access & acc_required)) {
2096 return NT_STATUS_ACCESS_DENIED;
2099 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2100 if (!NT_STATUS_IS_OK(status)) {
2104 info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
2106 return NT_STATUS_NO_MEMORY;
2109 switch (r->in.level) {
2110 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2111 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2113 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2114 return NT_STATUS_INVALID_PARAMETER;
2115 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2116 info->posix_offset.posix_offset = *td->trust_posix_offset;
2118 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2119 return NT_STATUS_INVALID_INFO_CLASS;
2120 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2121 return NT_STATUS_INVALID_PARAMETER;
2122 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2123 status = pdb_trusted_domain_2_info_ex(info, td, &info->info_ex);
2124 if (!NT_STATUS_IS_OK(status)) {
2128 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2129 return NT_STATUS_INVALID_INFO_CLASS;
2130 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2131 status = pdb_trusted_domain_2_info_ex(info, td,
2132 &info->full_info.info_ex);
2133 if (!NT_STATUS_IS_OK(status)) {
2136 info->full_info.posix_offset.posix_offset = *td->trust_posix_offset;
2137 status = auth_blob_2_auth_info(p->mem_ctx,
2138 td->trust_auth_incoming,
2139 td->trust_auth_outgoing,
2140 &info->full_info.auth_info);
2141 if (!NT_STATUS_IS_OK(status)) {
2145 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2146 return NT_STATUS_INVALID_INFO_CLASS;
2147 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2148 return NT_STATUS_INVALID_INFO_CLASS;
2149 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2150 return NT_STATUS_INVALID_PARAMETER;
2151 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2152 info->full_info2_internal.posix_offset.posix_offset = *td->trust_posix_offset;
2153 status = auth_blob_2_auth_info(p->mem_ctx,
2154 td->trust_auth_incoming,
2155 td->trust_auth_outgoing,
2156 &info->full_info2_internal.auth_info);
2157 if (!NT_STATUS_IS_OK(status)) {
2161 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2162 info->enc_types.enc_types = *td->supported_enc_type;
2165 return NT_STATUS_INVALID_PARAMETER;
2168 *r->out.info = info;
2170 return NT_STATUS_OK;
2173 /***************************************************************************
2174 _lsa_QueryTrustedDomainInfoBySid
2175 ***************************************************************************/
2177 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2178 struct lsa_QueryTrustedDomainInfoBySid *r)
2181 struct policy_handle trustdom_handle;
2182 struct lsa_OpenTrustedDomain o;
2183 struct lsa_QueryTrustedDomainInfo q;
2186 o.in.handle = r->in.handle;
2187 o.in.sid = r->in.dom_sid;
2188 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2189 o.out.trustdom_handle = &trustdom_handle;
2191 status = _lsa_OpenTrustedDomain(p, &o);
2192 if (!NT_STATUS_IS_OK(status)) {
2196 q.in.trustdom_handle = &trustdom_handle;
2197 q.in.level = r->in.level;
2198 q.out.info = r->out.info;
2200 status = _lsa_QueryTrustedDomainInfo(p, &q);
2201 if (!NT_STATUS_IS_OK(status)) {
2205 c.in.handle = &trustdom_handle;
2206 c.out.handle = &trustdom_handle;
2208 return _lsa_Close(p, &c);
2211 /***************************************************************************
2212 _lsa_QueryTrustedDomainInfoByName
2213 ***************************************************************************/
2215 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2216 struct lsa_QueryTrustedDomainInfoByName *r)
2219 struct policy_handle trustdom_handle;
2220 struct lsa_OpenTrustedDomainByName o;
2221 struct lsa_QueryTrustedDomainInfo q;
2224 o.in.handle = r->in.handle;
2225 o.in.name.string = r->in.trusted_domain->string;
2226 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2227 o.out.trustdom_handle = &trustdom_handle;
2229 status = _lsa_OpenTrustedDomainByName(p, &o);
2230 if (!NT_STATUS_IS_OK(status)) {
2231 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2232 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2237 q.in.trustdom_handle = &trustdom_handle;
2238 q.in.level = r->in.level;
2239 q.out.info = r->out.info;
2241 status = _lsa_QueryTrustedDomainInfo(p, &q);
2242 if (!NT_STATUS_IS_OK(status)) {
2246 c.in.handle = &trustdom_handle;
2247 c.out.handle = &trustdom_handle;
2249 return _lsa_Close(p, &c);
2252 /***************************************************************************
2254 ***************************************************************************/
2256 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p,
2257 struct lsa_CreateSecret *r)
2260 struct lsa_info *handle;
2261 uint32_t acc_granted;
2262 struct security_descriptor *psd;
2265 /* find the connection policy handle. */
2266 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
2267 return NT_STATUS_INVALID_HANDLE;
2270 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2271 return NT_STATUS_INVALID_HANDLE;
2274 /* check if the user has enough rights */
2276 if (!(handle->access & LSA_POLICY_CREATE_SECRET)) {
2277 return NT_STATUS_ACCESS_DENIED;
2280 /* Work out max allowed. */
2281 map_max_allowed_access(p->session_info->security_token,
2282 p->session_info->unix_token,
2283 &r->in.access_mask);
2285 /* map the generic bits to the lsa policy ones */
2286 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
2288 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2289 &lsa_secret_mapping,
2291 if (!NT_STATUS_IS_OK(status)) {
2295 status = access_check_object(psd, p->session_info->security_token,
2296 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2298 &acc_granted, "_lsa_CreateSecret");
2299 if (!NT_STATUS_IS_OK(status)) {
2303 if (!r->in.name.string) {
2304 return NT_STATUS_INVALID_PARAMETER;
2307 if (strlen(r->in.name.string) > 128) {
2308 return NT_STATUS_NAME_TOO_LONG;
2311 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
2312 NULL, NULL, NULL, NULL, NULL);
2313 if (NT_STATUS_IS_OK(status)) {
2314 return NT_STATUS_OBJECT_NAME_COLLISION;
2317 status = pdb_set_secret(r->in.name.string, NULL, NULL, psd);
2318 if (!NT_STATUS_IS_OK(status)) {
2322 status = create_lsa_policy_handle(p->mem_ctx, p,
2323 LSA_HANDLE_SECRET_TYPE,
2329 if (!NT_STATUS_IS_OK(status)) {
2330 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2333 return NT_STATUS_OK;
2336 /***************************************************************************
2338 ***************************************************************************/
2340 NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
2341 struct lsa_SetSecret *r)
2344 struct lsa_info *info = NULL;
2345 DATA_BLOB blob_new, blob_old;
2346 DATA_BLOB cleartext_blob_new = data_blob_null;
2347 DATA_BLOB cleartext_blob_old = data_blob_null;
2348 DATA_BLOB *cleartext_blob_new_p = NULL;
2349 DATA_BLOB *cleartext_blob_old_p = NULL;
2351 if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
2352 return NT_STATUS_INVALID_HANDLE;
2355 if (info->type != LSA_HANDLE_SECRET_TYPE) {
2356 return NT_STATUS_INVALID_HANDLE;
2359 if (!(info->access & LSA_SECRET_SET_VALUE)) {
2360 return NT_STATUS_ACCESS_DENIED;
2363 if (r->in.new_val) {
2364 blob_new = data_blob_const(r->in.new_val->data,
2365 r->in.new_val->length);
2367 status = sess_decrypt_blob(p->mem_ctx, &blob_new,
2368 &p->session_info->session_key,
2369 &cleartext_blob_new);
2370 if (!NT_STATUS_IS_OK(status)) {
2374 cleartext_blob_new_p = &cleartext_blob_new;
2377 if (r->in.old_val) {
2378 blob_old = data_blob_const(r->in.old_val->data,
2379 r->in.old_val->length);
2381 status = sess_decrypt_blob(p->mem_ctx, &blob_old,
2382 &p->session_info->session_key,
2383 &cleartext_blob_old);
2384 if (!NT_STATUS_IS_OK(status)) {
2388 cleartext_blob_old_p = &cleartext_blob_old;
2391 status = pdb_set_secret(info->name, cleartext_blob_new_p, cleartext_blob_old_p, NULL);
2392 if (!NT_STATUS_IS_OK(status)) {
2396 #ifdef DEBUG_PASSWORD
2397 DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
2398 dump_data(10, cleartext_blob_new.data, cleartext_blob_new.length);
2399 DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
2400 dump_data(10, cleartext_blob_old.data, cleartext_blob_old.length);
2403 return NT_STATUS_OK;
2406 /***************************************************************************
2408 ***************************************************************************/
2410 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
2411 struct lsa_QuerySecret *r)
2413 struct lsa_info *info = NULL;
2414 DATA_BLOB blob_new, blob_old;
2415 DATA_BLOB blob_new_crypt, blob_old_crypt;
2416 NTTIME nttime_new, nttime_old;
2419 if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
2420 return NT_STATUS_INVALID_HANDLE;
2423 if (info->type != LSA_HANDLE_SECRET_TYPE) {
2424 return NT_STATUS_INVALID_HANDLE;
2427 if (!(info->access & LSA_SECRET_QUERY_VALUE)) {
2428 return NT_STATUS_ACCESS_DENIED;
2431 status = pdb_get_secret(p->mem_ctx, info->name,
2432 &blob_new, &nttime_new,
2433 &blob_old, &nttime_old,
2435 if (!NT_STATUS_IS_OK(status)) {
2439 if (r->in.new_val) {
2440 if (blob_new.length) {
2441 if (!r->out.new_val->buf) {
2442 r->out.new_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2444 if (!r->out.new_val->buf) {
2445 return NT_STATUS_NO_MEMORY;
2448 blob_new_crypt = sess_encrypt_blob(p->mem_ctx, &blob_new,
2449 &p->session_info->session_key);
2450 if (!blob_new_crypt.length) {
2451 return NT_STATUS_NO_MEMORY;
2454 r->out.new_val->buf->data = blob_new_crypt.data;
2455 r->out.new_val->buf->length = blob_new_crypt.length;
2456 r->out.new_val->buf->size = blob_new_crypt.length;
2460 if (r->in.old_val) {
2461 if (blob_old.length) {
2462 if (!r->out.old_val->buf) {
2463 r->out.old_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2465 if (!r->out.old_val->buf) {
2466 return NT_STATUS_NO_MEMORY;
2469 blob_old_crypt = sess_encrypt_blob(p->mem_ctx, &blob_old,
2470 &p->session_info->session_key);
2471 if (!blob_old_crypt.length) {
2472 return NT_STATUS_NO_MEMORY;
2475 r->out.old_val->buf->data = blob_old_crypt.data;
2476 r->out.old_val->buf->length = blob_old_crypt.length;
2477 r->out.old_val->buf->size = blob_old_crypt.length;
2481 if (r->out.new_mtime) {
2482 *r->out.new_mtime = nttime_new;
2485 if (r->out.old_mtime) {
2486 *r->out.old_mtime = nttime_old;
2489 return NT_STATUS_OK;
2492 /***************************************************************************
2494 ***************************************************************************/
2496 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2497 struct lsa_DeleteObject *r)
2500 struct lsa_info *info = NULL;
2502 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2503 return NT_STATUS_INVALID_HANDLE;
2506 if (!(info->access & SEC_STD_DELETE)) {
2507 return NT_STATUS_ACCESS_DENIED;
2510 switch (info->type) {
2511 case LSA_HANDLE_ACCOUNT_TYPE:
2512 status = privilege_delete_account(&info->sid);
2513 if (!NT_STATUS_IS_OK(status)) {
2514 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2515 nt_errstr(status)));
2519 case LSA_HANDLE_TRUST_TYPE:
2520 if (!pdb_del_trusteddom_pw(info->name)) {
2521 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2523 status = NT_STATUS_OK;
2525 case LSA_HANDLE_SECRET_TYPE:
2526 status = pdb_delete_secret(info->name);
2527 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2528 return NT_STATUS_INVALID_HANDLE;
2532 return NT_STATUS_INVALID_HANDLE;
2535 close_policy_hnd(p, r->in.handle);
2536 ZERO_STRUCTP(r->out.handle);
2541 /***************************************************************************
2543 ***************************************************************************/
2545 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2546 struct lsa_EnumPrivs *r)
2548 struct lsa_info *handle;
2550 uint32 enum_context = *r->in.resume_handle;
2551 int num_privs = num_privileges_in_short_list();
2552 struct lsa_PrivEntry *entries = NULL;
2554 /* remember that the enum_context starts at 0 and not 1 */
2556 if ( enum_context >= num_privs )
2557 return NT_STATUS_NO_MORE_ENTRIES;
2559 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2560 enum_context, num_privs));
2562 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2563 return NT_STATUS_INVALID_HANDLE;
2565 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2566 return NT_STATUS_INVALID_HANDLE;
2569 /* check if the user has enough rights
2570 I don't know if it's the right one. not documented. */
2572 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2573 return NT_STATUS_ACCESS_DENIED;
2576 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2578 return NT_STATUS_NO_MEMORY;
2584 for (i = 0; i < num_privs; i++) {
2585 if( i < enum_context) {
2587 init_lsa_StringLarge(&entries[i].name, NULL);
2589 entries[i].luid.low = 0;
2590 entries[i].luid.high = 0;
2593 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2595 entries[i].luid.low = sec_privilege_from_index(i);
2596 entries[i].luid.high = 0;
2600 enum_context = num_privs;
2602 *r->out.resume_handle = enum_context;
2603 r->out.privs->count = num_privs;
2604 r->out.privs->privs = entries;
2606 return NT_STATUS_OK;
2609 /***************************************************************************
2610 _lsa_LookupPrivDisplayName
2611 ***************************************************************************/
2613 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2614 struct lsa_LookupPrivDisplayName *r)
2616 struct lsa_info *handle;
2617 const char *description;
2618 struct lsa_StringLarge *lsa_name;
2620 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2621 return NT_STATUS_INVALID_HANDLE;
2623 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2624 return NT_STATUS_INVALID_HANDLE;
2627 /* check if the user has enough rights */
2630 * I don't know if it's the right one. not documented.
2632 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2633 return NT_STATUS_ACCESS_DENIED;
2635 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2637 description = get_privilege_dispname(r->in.name->string);
2639 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2640 return NT_STATUS_NO_SUCH_PRIVILEGE;
2643 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2645 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2647 return NT_STATUS_NO_MEMORY;
2650 init_lsa_StringLarge(lsa_name, description);
2652 *r->out.returned_language_id = r->in.language_id;
2653 *r->out.disp_name = lsa_name;
2655 return NT_STATUS_OK;
2658 /***************************************************************************
2660 ***************************************************************************/
2662 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2663 struct lsa_EnumAccounts *r)
2665 struct lsa_info *handle;
2666 struct dom_sid *sid_list;
2667 int i, j, num_entries;
2669 struct lsa_SidPtr *sids = NULL;
2671 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2672 return NT_STATUS_INVALID_HANDLE;
2674 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2675 return NT_STATUS_INVALID_HANDLE;
2678 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2679 return NT_STATUS_ACCESS_DENIED;
2684 /* The only way we can currently find out all the SIDs that have been
2685 privileged is to scan all privileges */
2687 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2688 if (!NT_STATUS_IS_OK(status)) {
2692 if (*r->in.resume_handle >= num_entries) {
2693 return NT_STATUS_NO_MORE_ENTRIES;
2696 if (num_entries - *r->in.resume_handle) {
2697 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2698 num_entries - *r->in.resume_handle);
2700 talloc_free(sid_list);
2701 return NT_STATUS_NO_MEMORY;
2704 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2705 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2707 talloc_free(sid_list);
2708 return NT_STATUS_NO_MEMORY;
2713 talloc_free(sid_list);
2715 *r->out.resume_handle = num_entries;
2716 r->out.sids->num_sids = num_entries;
2717 r->out.sids->sids = sids;
2719 return NT_STATUS_OK;
2722 /***************************************************************************
2724 ***************************************************************************/
2726 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2727 struct lsa_GetUserName *r)
2729 const char *username, *domname;
2730 struct lsa_String *account_name = NULL;
2731 struct lsa_String *authority_name = NULL;
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;
2793 /* find the connection policy handle. */
2794 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2795 return NT_STATUS_INVALID_HANDLE;
2797 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2798 return NT_STATUS_INVALID_HANDLE;
2801 /* check if the user has enough rights */
2803 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2804 return NT_STATUS_ACCESS_DENIED;
2807 /* Work out max allowed. */
2808 map_max_allowed_access(p->session_info->security_token,
2809 p->session_info->unix_token,
2810 &r->in.access_mask);
2812 /* map the generic bits to the lsa policy ones */
2813 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2815 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2816 &lsa_account_mapping,
2817 r->in.sid, LSA_POLICY_ALL_ACCESS);
2818 if (!NT_STATUS_IS_OK(status)) {
2822 status = access_check_object(psd, p->session_info->security_token,
2823 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2824 &acc_granted, "_lsa_CreateAccount");
2825 if (!NT_STATUS_IS_OK(status)) {
2829 if ( is_privileged_sid( r->in.sid ) )
2830 return NT_STATUS_OBJECT_NAME_COLLISION;
2832 status = create_lsa_policy_handle(p->mem_ctx, p,
2833 LSA_HANDLE_ACCOUNT_TYPE,
2838 r->out.acct_handle);
2839 if (!NT_STATUS_IS_OK(status)) {
2840 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2843 return privilege_create_account(r->in.sid);
2846 /***************************************************************************
2848 ***************************************************************************/
2850 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2851 struct lsa_OpenAccount *r)
2853 struct lsa_info *handle;
2854 struct security_descriptor *psd = NULL;
2856 uint32_t des_access = r->in.access_mask;
2857 uint32_t acc_granted;
2860 /* find the connection policy handle. */
2861 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2862 return NT_STATUS_INVALID_HANDLE;
2864 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2865 return NT_STATUS_INVALID_HANDLE;
2868 /* des_access is for the account here, not the policy
2869 * handle - so don't check against policy handle. */
2871 /* Work out max allowed. */
2872 map_max_allowed_access(p->session_info->security_token,
2873 p->session_info->unix_token,
2876 /* map the generic bits to the lsa account ones */
2877 se_map_generic(&des_access, &lsa_account_mapping);
2879 /* get the generic lsa account SD until we store it */
2880 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2881 &lsa_account_mapping,
2882 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2883 if (!NT_STATUS_IS_OK(status)) {
2887 status = access_check_object(psd, p->session_info->security_token,
2888 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2889 &acc_granted, "_lsa_OpenAccount" );
2890 if (!NT_STATUS_IS_OK(status)) {
2894 /* TODO: Fis the parsing routine before reenabling this check! */
2896 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2897 return NT_STATUS_ACCESS_DENIED;
2900 status = create_lsa_policy_handle(p->mem_ctx, p,
2901 LSA_HANDLE_ACCOUNT_TYPE,
2906 r->out.acct_handle);
2907 if (!NT_STATUS_IS_OK(status)) {
2908 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2911 return NT_STATUS_OK;
2914 /***************************************************************************
2915 _lsa_EnumPrivsAccount
2916 For a given SID, enumerate all the privilege this account has.
2917 ***************************************************************************/
2919 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2920 struct lsa_EnumPrivsAccount *r)
2922 NTSTATUS status = NT_STATUS_OK;
2923 struct lsa_info *info=NULL;
2924 PRIVILEGE_SET *privileges;
2925 struct lsa_PrivilegeSet *priv_set = NULL;
2927 /* find the connection policy handle. */
2928 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2929 return NT_STATUS_INVALID_HANDLE;
2931 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2932 return NT_STATUS_INVALID_HANDLE;
2935 if (!(info->access & LSA_ACCOUNT_VIEW))
2936 return NT_STATUS_ACCESS_DENIED;
2938 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2939 if (!NT_STATUS_IS_OK(status)) {
2943 *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2945 return NT_STATUS_NO_MEMORY;
2948 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2949 sid_string_dbg(&info->sid),
2950 privileges->count));
2952 priv_set->count = privileges->count;
2953 priv_set->unknown = 0;
2954 priv_set->set = talloc_move(priv_set, &privileges->set);
2959 /***************************************************************************
2960 _lsa_GetSystemAccessAccount
2961 ***************************************************************************/
2963 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2964 struct lsa_GetSystemAccessAccount *r)
2967 struct lsa_info *info = NULL;
2968 struct lsa_EnumPrivsAccount e;
2969 struct lsa_PrivilegeSet *privset;
2971 /* find the connection policy handle. */
2973 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2974 return NT_STATUS_INVALID_HANDLE;
2976 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2977 return NT_STATUS_INVALID_HANDLE;
2980 if (!(info->access & LSA_ACCOUNT_VIEW))
2981 return NT_STATUS_ACCESS_DENIED;
2983 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2985 return NT_STATUS_NO_MEMORY;
2988 e.in.handle = r->in.handle;
2989 e.out.privs = &privset;
2991 status = _lsa_EnumPrivsAccount(p, &e);
2992 if (!NT_STATUS_IS_OK(status)) {
2993 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2994 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2995 nt_errstr(status)));
2999 /* Samba4 would iterate over the privset to merge the policy mode bits,
3000 * not sure samba3 can do the same here, so just return what we did in
3004 0x01 -> Log on locally
3005 0x02 -> Access this computer from network
3006 0x04 -> Log on as a batch job
3007 0x10 -> Log on as a service
3009 they can be ORed together
3012 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
3013 LSA_POLICY_MODE_NETWORK;
3015 return NT_STATUS_OK;
3018 /***************************************************************************
3019 update the systemaccount information
3020 ***************************************************************************/
3022 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
3023 struct lsa_SetSystemAccessAccount *r)
3025 struct lsa_info *info=NULL;
3029 /* find the connection policy handle. */
3030 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3031 return NT_STATUS_INVALID_HANDLE;
3033 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3034 return NT_STATUS_INVALID_HANDLE;
3037 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
3038 return NT_STATUS_ACCESS_DENIED;
3041 map = talloc_zero(p->mem_ctx, GROUP_MAP);
3043 return NT_STATUS_NO_MEMORY;
3046 if (!pdb_getgrsid(map, info->sid)) {
3048 return NT_STATUS_NO_SUCH_GROUP;
3051 status = pdb_update_group_mapping_entry(map);
3056 /***************************************************************************
3057 _lsa_AddPrivilegesToAccount
3058 For a given SID, add some privileges.
3059 ***************************************************************************/
3061 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
3062 struct lsa_AddPrivilegesToAccount *r)
3064 struct lsa_info *info = NULL;
3065 struct lsa_PrivilegeSet *set = NULL;
3067 /* find the connection policy handle. */
3068 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3069 return NT_STATUS_INVALID_HANDLE;
3071 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3072 return NT_STATUS_INVALID_HANDLE;
3075 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3076 return NT_STATUS_ACCESS_DENIED;
3081 if ( !grant_privilege_set( &info->sid, set ) ) {
3082 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
3083 sid_string_dbg(&info->sid) ));
3084 return NT_STATUS_NO_SUCH_PRIVILEGE;
3087 return NT_STATUS_OK;
3090 /***************************************************************************
3091 _lsa_RemovePrivilegesFromAccount
3092 For a given SID, remove some privileges.
3093 ***************************************************************************/
3095 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
3096 struct lsa_RemovePrivilegesFromAccount *r)
3098 struct lsa_info *info = NULL;
3099 struct lsa_PrivilegeSet *set = NULL;
3101 /* find the connection policy handle. */
3102 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3103 return NT_STATUS_INVALID_HANDLE;
3105 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3106 return NT_STATUS_INVALID_HANDLE;
3109 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3110 return NT_STATUS_ACCESS_DENIED;
3115 if ( !revoke_privilege_set( &info->sid, set) ) {
3116 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
3117 sid_string_dbg(&info->sid) ));
3118 return NT_STATUS_NO_SUCH_PRIVILEGE;
3121 return NT_STATUS_OK;
3124 /***************************************************************************
3126 ***************************************************************************/
3128 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
3129 struct lsa_LookupPrivName *r)
3131 struct lsa_info *info = NULL;
3133 struct lsa_StringLarge *lsa_name;
3135 /* find the connection policy handle. */
3136 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3137 return NT_STATUS_INVALID_HANDLE;
3140 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3141 return NT_STATUS_INVALID_HANDLE;
3144 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
3145 return NT_STATUS_ACCESS_DENIED;
3148 if (r->in.luid->high != 0) {
3149 return NT_STATUS_NO_SUCH_PRIVILEGE;
3152 name = sec_privilege_name(r->in.luid->low);
3154 return NT_STATUS_NO_SUCH_PRIVILEGE;
3157 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
3159 return NT_STATUS_NO_MEMORY;
3162 lsa_name->string = talloc_strdup(lsa_name, name);
3163 if (!lsa_name->string) {
3164 TALLOC_FREE(lsa_name);
3165 return NT_STATUS_NO_MEMORY;
3168 *r->out.name = lsa_name;
3170 return NT_STATUS_OK;
3173 /***************************************************************************
3175 ***************************************************************************/
3177 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
3178 struct lsa_QuerySecurity *r)
3180 struct lsa_info *handle=NULL;
3181 struct security_descriptor *psd = NULL;
3185 /* find the connection policy handle. */
3186 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
3187 return NT_STATUS_INVALID_HANDLE;
3189 switch (handle->type) {
3190 case LSA_HANDLE_POLICY_TYPE:
3191 case LSA_HANDLE_ACCOUNT_TYPE:
3192 case LSA_HANDLE_TRUST_TYPE:
3193 case LSA_HANDLE_SECRET_TYPE:
3195 sd_size = ndr_size_security_descriptor(psd, 0);
3196 status = NT_STATUS_OK;
3199 status = NT_STATUS_INVALID_HANDLE;
3203 if (!NT_STATUS_IS_OK(status)) {
3207 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
3208 if (!*r->out.sdbuf) {
3209 return NT_STATUS_NO_MEMORY;
3215 /***************************************************************************
3216 _lsa_AddAccountRights
3217 ***************************************************************************/
3219 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
3220 struct lsa_AddAccountRights *r)
3222 struct lsa_info *info = NULL;
3224 uint32_t acc_granted = 0;
3225 struct security_descriptor *psd = NULL;
3230 /* find the connection policy handle. */
3231 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3232 return NT_STATUS_INVALID_HANDLE;
3234 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3235 return NT_STATUS_INVALID_HANDLE;
3238 /* get the generic lsa account SD for this SID until we store it */
3239 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3240 &lsa_account_mapping,
3241 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
3242 if (!NT_STATUS_IS_OK(status)) {
3247 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3248 * on the policy handle. If it does, ask for
3249 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3250 * on the account sid. We don't check here so just use the latter. JRA.
3253 status = access_check_object(psd, p->session_info->security_token,
3254 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3255 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3256 &acc_granted, "_lsa_AddAccountRights" );
3257 if (!NT_STATUS_IS_OK(status)) {
3261 /* according to an NT4 PDC, you can add privileges to SIDs even without
3262 call_lsa_create_account() first. And you can use any arbitrary SID. */
3264 sid_copy( &sid, r->in.sid );
3266 for ( i=0; i < r->in.rights->count; i++ ) {
3268 const char *privname = r->in.rights->names[i].string;
3270 /* only try to add non-null strings */
3275 if ( !grant_privilege_by_name( &sid, privname ) ) {
3276 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3278 return NT_STATUS_NO_SUCH_PRIVILEGE;
3282 return NT_STATUS_OK;
3285 /***************************************************************************
3286 _lsa_RemoveAccountRights
3287 ***************************************************************************/
3289 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
3290 struct lsa_RemoveAccountRights *r)
3292 struct lsa_info *info = NULL;
3294 struct security_descriptor *psd = NULL;
3297 const char *privname = NULL;
3298 uint32_t acc_granted = 0;
3301 /* find the connection policy handle. */
3302 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3303 return NT_STATUS_INVALID_HANDLE;
3305 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3306 return NT_STATUS_INVALID_HANDLE;
3309 /* get the generic lsa account SD for this SID until we store it */
3310 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3311 &lsa_account_mapping,
3312 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
3313 if (!NT_STATUS_IS_OK(status)) {
3318 * From the MS DOCs. We need
3319 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3320 * and DELETE on the account sid.
3323 status = access_check_object(psd, p->session_info->security_token,
3324 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3325 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3326 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
3327 &acc_granted, "_lsa_RemoveAccountRights");
3328 if (!NT_STATUS_IS_OK(status)) {
3332 sid_copy( &sid, r->in.sid );
3334 if ( r->in.remove_all ) {
3335 if ( !revoke_all_privileges( &sid ) )
3336 return NT_STATUS_ACCESS_DENIED;
3338 return NT_STATUS_OK;
3341 for ( i=0; i < r->in.rights->count; i++ ) {
3343 privname = r->in.rights->names[i].string;
3345 /* only try to add non-null strings */
3350 if ( !revoke_privilege_by_name( &sid, privname ) ) {
3351 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3353 return NT_STATUS_NO_SUCH_PRIVILEGE;
3357 return NT_STATUS_OK;
3360 /*******************************************************************
3361 ********************************************************************/
3363 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3364 struct lsa_RightSet *r,
3365 PRIVILEGE_SET *privileges)
3368 const char *privname;
3369 const char **privname_array = NULL;
3372 for (i=0; i<privileges->count; i++) {
3373 if (privileges->set[i].luid.high) {
3376 privname = sec_privilege_name(privileges->set[i].luid.low);
3378 if (!add_string_to_array(mem_ctx, privname,
3379 &privname_array, &num_priv)) {
3380 return NT_STATUS_NO_MEMORY;
3387 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3390 return NT_STATUS_NO_MEMORY;
3393 for (i=0; i<num_priv; i++) {
3394 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3397 r->count = num_priv;
3400 return NT_STATUS_OK;
3403 /***************************************************************************
3404 _lsa_EnumAccountRights
3405 ***************************************************************************/
3407 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3408 struct lsa_EnumAccountRights *r)
3411 struct lsa_info *info = NULL;
3412 PRIVILEGE_SET *privileges;
3414 /* find the connection policy handle. */
3416 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3417 return NT_STATUS_INVALID_HANDLE;
3419 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3420 return NT_STATUS_INVALID_HANDLE;
3423 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3424 return NT_STATUS_ACCESS_DENIED;
3427 /* according to an NT4 PDC, you can add privileges to SIDs even without
3428 call_lsa_create_account() first. And you can use any arbitrary SID. */
3430 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3431 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3432 * the lsa database */
3434 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3435 if (!NT_STATUS_IS_OK(status)) {
3439 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3440 sid_string_dbg(r->in.sid), privileges->count));
3442 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3447 /***************************************************************************
3448 _lsa_LookupPrivValue
3449 ***************************************************************************/
3451 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3452 struct lsa_LookupPrivValue *r)
3454 struct lsa_info *info = NULL;
3455 const char *name = NULL;
3457 /* find the connection policy handle. */
3459 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3460 return NT_STATUS_INVALID_HANDLE;
3462 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3463 return NT_STATUS_INVALID_HANDLE;
3466 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3467 return NT_STATUS_ACCESS_DENIED;
3469 name = r->in.name->string;
3471 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3473 r->out.luid->low = sec_privilege_id(name);
3474 r->out.luid->high = 0;
3475 if (r->out.luid->low == SEC_PRIV_INVALID) {
3476 return NT_STATUS_NO_SUCH_PRIVILEGE;
3478 return NT_STATUS_OK;
3481 /***************************************************************************
3482 _lsa_EnumAccountsWithUserRight
3483 ***************************************************************************/
3485 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3486 struct lsa_EnumAccountsWithUserRight *r)
3489 struct lsa_info *info = NULL;
3490 struct dom_sid *sids = NULL;
3493 enum sec_privilege privilege;
3495 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3496 return NT_STATUS_INVALID_HANDLE;
3499 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3500 return NT_STATUS_INVALID_HANDLE;
3503 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3504 return NT_STATUS_ACCESS_DENIED;
3507 if (!r->in.name || !r->in.name->string) {
3508 return NT_STATUS_NO_SUCH_PRIVILEGE;
3511 privilege = sec_privilege_id(r->in.name->string);
3512 if (privilege == SEC_PRIV_INVALID) {
3513 return NT_STATUS_NO_SUCH_PRIVILEGE;
3516 status = privilege_enum_sids(privilege, p->mem_ctx,
3518 if (!NT_STATUS_IS_OK(status)) {
3522 r->out.sids->num_sids = num_sids;
3523 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3524 r->out.sids->num_sids);
3526 for (i=0; i < r->out.sids->num_sids; i++) {
3527 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3529 if (!r->out.sids->sids[i].sid) {
3530 TALLOC_FREE(r->out.sids->sids);
3531 r->out.sids->num_sids = 0;
3532 return NT_STATUS_NO_MEMORY;
3536 return NT_STATUS_OK;
3539 /***************************************************************************
3541 ***************************************************************************/
3543 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3544 struct lsa_Delete *r)
3546 return NT_STATUS_NOT_SUPPORTED;
3549 static NTSTATUS info_ex_2_pdb_trusted_domain(
3550 struct lsa_TrustDomainInfoInfoEx *info_ex,
3551 struct pdb_trusted_domain *td)
3553 if (info_ex->domain_name.string == NULL ||
3554 info_ex->netbios_name.string == NULL ||
3555 info_ex->sid == NULL) {
3556 return NT_STATUS_INVALID_PARAMETER;
3559 td->domain_name = talloc_strdup(td, info_ex->domain_name.string);
3560 td->netbios_name = talloc_strdup(td, info_ex->netbios_name.string);
3561 sid_copy(&td->security_identifier, info_ex->sid);
3562 if (td->domain_name == NULL ||
3563 td->netbios_name == NULL ||
3564 is_null_sid(&td->security_identifier)) {
3565 return NT_STATUS_NO_MEMORY;
3567 td->trust_direction = info_ex->trust_direction;
3568 td->trust_type = info_ex->trust_type;
3569 td->trust_attributes = info_ex->trust_attributes;
3571 return NT_STATUS_OK;
3574 static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
3575 TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
3576 struct trustDomainPasswords *auth_struct)
3578 enum ndr_err_code ndr_err;
3580 arcfour_crypt_blob(auth_blob->data, auth_blob->length,
3581 &p->session_info->session_key);
3582 ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
3584 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
3585 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3586 return NT_STATUS_INVALID_PARAMETER;
3589 return NT_STATUS_OK;
3592 static NTSTATUS get_trustauth_inout_blob(TALLOC_CTX *mem_ctx,
3593 struct trustAuthInOutBlob *iopw,
3594 DATA_BLOB *trustauth_blob)
3596 enum ndr_err_code ndr_err;
3598 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
3600 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
3601 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3602 return NT_STATUS_INVALID_PARAMETER;
3605 return NT_STATUS_OK;
3608 static NTSTATUS setInfoTrustedDomain_base(struct pipes_struct *p,
3609 TALLOC_CTX *mem_ctx,
3610 struct lsa_info *policy,
3611 enum lsa_TrustDomInfoEnum level,
3612 union lsa_TrustedDomainInfo *info)
3614 struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
3615 DATA_BLOB auth_blob;
3616 struct trustDomainPasswords auth_struct;
3619 struct pdb_trusted_domain *td;
3620 struct pdb_trusted_domain *orig_td;
3622 td = talloc_zero(mem_ctx, struct pdb_trusted_domain);
3624 return NT_STATUS_NO_MEMORY;
3628 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
3629 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3630 return NT_STATUS_ACCESS_DENIED;
3632 td->trust_posix_offset = &info->posix_offset.posix_offset;
3634 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
3635 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3636 return NT_STATUS_ACCESS_DENIED;
3638 nt_status = info_ex_2_pdb_trusted_domain(&info->info_ex, td);
3639 if (!NT_STATUS_IS_OK(nt_status)) {
3643 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
3644 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3645 return NT_STATUS_ACCESS_DENIED;
3647 nt_status = auth_info_2_auth_blob(td, &info->auth_info,
3648 &td->trust_auth_incoming,
3649 &td->trust_auth_outgoing);
3650 if (!NT_STATUS_IS_OK(nt_status)) {
3654 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
3655 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3656 return NT_STATUS_ACCESS_DENIED;
3658 td->trust_posix_offset = &info->full_info.posix_offset.posix_offset;
3659 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info.info_ex,
3661 if (!NT_STATUS_IS_OK(nt_status)) {
3664 nt_status = auth_info_2_auth_blob(td,
3665 &info->full_info.auth_info,
3666 &td->trust_auth_incoming,
3667 &td->trust_auth_outgoing);
3668 if (!NT_STATUS_IS_OK(nt_status)) {
3672 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
3673 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3674 return NT_STATUS_ACCESS_DENIED;
3676 auth_info_int = &info->auth_info_internal;
3678 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
3679 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3680 return NT_STATUS_ACCESS_DENIED;
3682 td->trust_posix_offset = &info->full_info_internal.posix_offset.posix_offset;
3683 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info_internal.info_ex,
3685 if (!NT_STATUS_IS_OK(nt_status)) {
3688 auth_info_int = &info->full_info_internal.auth_info;
3690 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
3691 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3692 return NT_STATUS_ACCESS_DENIED;
3694 td->supported_enc_type = &info->enc_types.enc_types;
3697 return NT_STATUS_INVALID_PARAMETER;
3700 /* decode auth_info_int if set */
3701 if (auth_info_int) {
3703 /* now decrypt blob */
3704 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
3705 auth_info_int->auth_blob.size);
3707 nt_status = get_trustdom_auth_blob(p, mem_ctx,
3708 &auth_blob, &auth_struct);
3709 if (!NT_STATUS_IS_OK(nt_status)) {
3713 memset(&auth_struct, 0, sizeof(auth_struct));
3716 /* TODO: verify only one object matches the dns/netbios/sid triplet and that
3717 * this is the one we already have */
3719 /* TODO: check if the trust direction is changed and we need to add or remove
3722 /* TODO: check if trust type shall be changed and return an error in this case
3724 nt_status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &policy->sid,
3726 if (!NT_STATUS_IS_OK(nt_status)) {
3731 /* TODO: should we fetch previous values from the existing entry
3732 * and append them ? */
3733 if (auth_struct.incoming.count) {
3734 nt_status = get_trustauth_inout_blob(mem_ctx,
3735 &auth_struct.incoming,
3736 &td->trust_auth_incoming);
3737 if (!NT_STATUS_IS_OK(nt_status)) {
3741 ZERO_STRUCT(td->trust_auth_incoming);
3744 if (auth_struct.outgoing.count) {
3745 nt_status = get_trustauth_inout_blob(mem_ctx,
3746 &auth_struct.outgoing,
3747 &td->trust_auth_outgoing);
3748 if (!NT_STATUS_IS_OK(nt_status)) {
3752 ZERO_STRUCT(td->trust_auth_outgoing);
3755 nt_status = pdb_set_trusted_domain(orig_td->domain_name, td);
3756 if (!NT_STATUS_IS_OK(nt_status)) {
3760 return NT_STATUS_OK;
3763 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3764 struct lsa_SetTrustedDomainInfo *r)
3767 struct policy_handle trustdom_handle;
3768 struct lsa_OpenTrustedDomain o;
3769 struct lsa_SetInformationTrustedDomain s;
3772 o.in.handle = r->in.handle;
3773 o.in.sid = r->in.dom_sid;
3774 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3775 o.out.trustdom_handle = &trustdom_handle;
3777 status = _lsa_OpenTrustedDomain(p, &o);
3778 if (!NT_STATUS_IS_OK(status)) {
3782 s.in.trustdom_handle = &trustdom_handle;
3783 s.in.level = r->in.level;
3784 s.in.info = r->in.info;
3786 status = _lsa_SetInformationTrustedDomain(p, &s);
3787 if (!NT_STATUS_IS_OK(status)) {
3791 c.in.handle = &trustdom_handle;
3792 c.out.handle = &trustdom_handle;
3794 return _lsa_Close(p, &c);
3797 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3798 struct lsa_SetTrustedDomainInfoByName *r)
3801 struct policy_handle trustdom_handle;
3802 struct lsa_OpenTrustedDomainByName o;
3803 struct lsa_SetInformationTrustedDomain s;
3806 o.in.handle = r->in.handle;
3807 o.in.name.string = r->in.trusted_domain->string;
3808 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3809 o.out.trustdom_handle = &trustdom_handle;
3811 status = _lsa_OpenTrustedDomainByName(p, &o);
3812 if (!NT_STATUS_IS_OK(status)) {
3813 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
3814 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3819 s.in.trustdom_handle = &trustdom_handle;
3820 s.in.level = r->in.level;
3821 s.in.info = r->in.info;
3823 status = _lsa_SetInformationTrustedDomain(p, &s);
3824 if (!NT_STATUS_IS_OK(status)) {
3828 c.in.handle = &trustdom_handle;
3829 c.out.handle = &trustdom_handle;
3831 return _lsa_Close(p, &c);
3834 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3835 struct lsa_SetInformationTrustedDomain *r)
3837 struct lsa_info *policy;
3839 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&policy)) {
3840 return NT_STATUS_INVALID_HANDLE;
3843 if (policy->type != LSA_HANDLE_TRUST_TYPE) {
3844 return NT_STATUS_INVALID_HANDLE;
3847 return setInfoTrustedDomain_base(p, p->mem_ctx, policy,
3848 r->in.level, r->in.info);
3853 * From here on the server routines are just dummy ones to make smbd link with
3854 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3855 * pulling the server stubs across one by one.
3858 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3860 p->rng_fault_state = True;
3861 return NT_STATUS_NOT_IMPLEMENTED;
3864 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3865 struct lsa_ChangePassword *r)
3867 p->rng_fault_state = True;
3868 return NT_STATUS_NOT_IMPLEMENTED;
3871 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3873 p->rng_fault_state = True;
3874 return NT_STATUS_NOT_IMPLEMENTED;
3877 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3879 p->rng_fault_state = True;
3880 return NT_STATUS_NOT_IMPLEMENTED;
3883 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3884 struct lsa_GetQuotasForAccount *r)
3886 p->rng_fault_state = True;
3887 return NT_STATUS_NOT_IMPLEMENTED;
3890 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3891 struct lsa_SetQuotasForAccount *r)
3893 p->rng_fault_state = True;
3894 return NT_STATUS_NOT_IMPLEMENTED;
3897 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3898 struct lsa_StorePrivateData *r)
3900 p->rng_fault_state = True;
3901 return NT_STATUS_NOT_IMPLEMENTED;
3904 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3905 struct lsa_RetrievePrivateData *r)
3907 p->rng_fault_state = True;
3908 return NT_STATUS_NOT_IMPLEMENTED;
3911 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3912 struct lsa_SetInfoPolicy2 *r)
3914 p->rng_fault_state = True;
3915 return NT_STATUS_NOT_IMPLEMENTED;
3918 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3919 struct lsa_EnumTrustedDomainsEx *r)
3921 struct lsa_info *info;
3923 struct pdb_trusted_domain **domains;
3924 struct lsa_TrustDomainInfoInfoEx *entries;
3928 /* bail out early if pdb backend is not capable of ex trusted domains,
3929 * if we dont do that, the client might not call
3930 * _lsa_EnumTrustedDomains() afterwards - gd */
3932 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3933 p->rng_fault_state = True;
3934 return NT_STATUS_NOT_IMPLEMENTED;
3937 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3938 return NT_STATUS_INVALID_HANDLE;
3940 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3941 return NT_STATUS_INVALID_HANDLE;
3944 /* check if the user has enough rights */
3945 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3946 return NT_STATUS_ACCESS_DENIED;
3949 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3952 if (!NT_STATUS_IS_OK(nt_status)) {
3956 entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3959 return NT_STATUS_NO_MEMORY;
3962 for (i=0; i<count; i++) {
3963 init_lsa_StringLarge(&entries[i].netbios_name,
3964 domains[i]->netbios_name);
3965 entries[i].sid = &domains[i]->security_identifier;
3968 if (*r->in.resume_handle >= count) {
3969 *r->out.resume_handle = -1;
3970 TALLOC_FREE(entries);
3971 return NT_STATUS_NO_MORE_ENTRIES;
3974 /* return the rest, limit by max_size. Note that we
3975 use the w2k3 element size value of 60 */
3976 r->out.domains->count = count - *r->in.resume_handle;
3977 r->out.domains->count = MIN(r->out.domains->count,
3978 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3980 r->out.domains->domains = entries + *r->in.resume_handle;
3982 if (r->out.domains->count < count - *r->in.resume_handle) {
3983 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3984 return STATUS_MORE_ENTRIES;
3987 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3988 * always be larger than the previous input resume handle, in
3989 * particular when hitting the last query it is vital to set the
3990 * resume handle correctly to avoid infinite client loops, as
3991 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3992 * status is NT_STATUS_OK - gd */
3994 *r->out.resume_handle = (uint32_t)-1;
3996 return NT_STATUS_OK;
3999 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
4000 struct lsa_QueryDomainInformationPolicy *r)
4002 p->rng_fault_state = True;
4003 return NT_STATUS_NOT_IMPLEMENTED;
4006 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
4007 struct lsa_SetDomainInformationPolicy *r)
4009 p->rng_fault_state = True;
4010 return NT_STATUS_NOT_IMPLEMENTED;
4013 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
4015 p->rng_fault_state = True;
4016 return NT_STATUS_NOT_IMPLEMENTED;
4019 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
4021 p->rng_fault_state = True;
4022 return NT_STATUS_NOT_IMPLEMENTED;
4025 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
4027 p->rng_fault_state = True;
4028 return NT_STATUS_NOT_IMPLEMENTED;
4031 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
4033 p->rng_fault_state = True;
4034 return NT_STATUS_NOT_IMPLEMENTED;
4037 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
4038 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
4040 p->rng_fault_state = True;
4041 return NT_STATUS_NOT_IMPLEMENTED;
4044 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
4045 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
4047 p->rng_fault_state = True;
4048 return NT_STATUS_NOT_IMPLEMENTED;
4051 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
4053 p->rng_fault_state = True;
4054 return NT_STATUS_NOT_IMPLEMENTED;
4057 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
4058 struct lsa_CREDRGETTARGETINFO *r)
4060 p->rng_fault_state = True;
4061 return NT_STATUS_NOT_IMPLEMENTED;
4064 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
4065 struct lsa_CREDRPROFILELOADED *r)
4067 p->rng_fault_state = True;
4068 return NT_STATUS_NOT_IMPLEMENTED;
4071 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
4072 struct lsa_CREDRGETSESSIONTYPES *r)
4074 p->rng_fault_state = True;
4075 return NT_STATUS_NOT_IMPLEMENTED;
4078 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
4079 struct lsa_LSARREGISTERAUDITEVENT *r)
4081 p->rng_fault_state = True;
4082 return NT_STATUS_NOT_IMPLEMENTED;
4085 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
4086 struct lsa_LSARGENAUDITEVENT *r)
4088 p->rng_fault_state = True;
4089 return NT_STATUS_NOT_IMPLEMENTED;
4092 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
4093 struct lsa_LSARUNREGISTERAUDITEVENT *r)
4095 p->rng_fault_state = True;
4096 return NT_STATUS_NOT_IMPLEMENTED;
4099 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
4100 struct lsa_lsaRQueryForestTrustInformation *r)
4102 p->rng_fault_state = True;
4103 return NT_STATUS_NOT_IMPLEMENTED;
4106 #define DNS_CMP_MATCH 0
4107 #define DNS_CMP_FIRST_IS_CHILD 1
4108 #define DNS_CMP_SECOND_IS_CHILD 2
4109 #define DNS_CMP_NO_MATCH 3
4111 /* this function assumes names are well formed DNS names.
4112 * it doesn't validate them */
4113 static int dns_cmp(const char *s1, size_t l1,
4114 const char *s2, size_t l2)
4116 const char *p1, *p2;
4121 if (strcasecmp_m(s1, s2) == 0) {
4122 return DNS_CMP_MATCH;
4124 return DNS_CMP_NO_MATCH;
4132 cret = DNS_CMP_FIRST_IS_CHILD;
4138 cret = DNS_CMP_SECOND_IS_CHILD;
4141 if (p1[t1 - t2 - 1] != '.') {
4142 return DNS_CMP_NO_MATCH;
4145 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
4149 return DNS_CMP_NO_MATCH;
4152 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
4153 struct lsa_ForestTrustInformation *lfti,
4154 struct ForestTrustInfo *fti)
4156 struct lsa_ForestTrustRecord *lrec;
4157 struct ForestTrustInfoRecord *rec;
4158 struct lsa_StringLarge *tln;
4159 struct lsa_ForestTrustDomainInfo *info;
4163 fti->count = lfti->count;
4164 fti->records = talloc_array(mem_ctx,
4165 struct ForestTrustInfoRecordArmor,
4167 if (!fti->records) {
4168 return NT_STATUS_NO_MEMORY;
4170 for (i = 0; i < fti->count; i++) {
4171 lrec = lfti->entries[i];
4172 rec = &fti->records[i].record;
4174 rec->flags = lrec->flags;
4175 rec->timestamp = lrec->time;
4176 rec->type = lrec->type;
4178 switch (lrec->type) {
4179 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
4180 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4181 tln = &lrec->forest_trust_data.top_level_name;
4182 rec->data.name.string =
4183 talloc_strdup(mem_ctx, tln->string);
4184 if (!rec->data.name.string) {
4185 return NT_STATUS_NO_MEMORY;
4187 rec->data.name.size = strlen(rec->data.name.string);
4189 case LSA_FOREST_TRUST_DOMAIN_INFO:
4190 info = &lrec->forest_trust_data.domain_info;
4191 rec->data.info.sid = *info->domain_sid;
4192 rec->data.info.dns_name.string =
4193 talloc_strdup(mem_ctx,
4194 info->dns_domain_name.string);
4195 if (!rec->data.info.dns_name.string) {
4196 return NT_STATUS_NO_MEMORY;
4198 rec->data.info.dns_name.size =
4199 strlen(rec->data.info.dns_name.string);
4200 rec->data.info.netbios_name.string =
4201 talloc_strdup(mem_ctx,
4202 info->netbios_domain_name.string);
4203 if (!rec->data.info.netbios_name.string) {
4204 return NT_STATUS_NO_MEMORY;
4206 rec->data.info.netbios_name.size =
4207 strlen(rec->data.info.netbios_name.string);
4210 return NT_STATUS_INVALID_DOMAIN_STATE;
4214 return NT_STATUS_OK;
4217 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4218 uint32_t index, uint32_t collision_type,
4219 uint32_t conflict_type, const char *tdo_name);
4221 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
4222 const char *tdo_name,
4223 struct ForestTrustInfo *tdo_fti,
4224 struct ForestTrustInfo *new_fti,
4225 struct lsa_ForestTrustCollisionInfo *c_info)
4227 struct ForestTrustInfoRecord *nrec;
4228 struct ForestTrustInfoRecord *trec;
4229 const char *dns_name;
4230 const char *nb_name = NULL;
4231 struct dom_sid *sid = NULL;
4232 const char *tname = NULL;
4237 uint32_t new_fti_idx;
4239 /* use always TDO type, until we understand when Xref can be used */
4240 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
4245 bool ex_rule = false;
4248 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
4250 nrec = &new_fti->records[new_fti_idx].record;
4252 tln_conflict = false;
4253 sid_conflict = false;
4254 nb_conflict = false;
4257 switch (nrec->type) {
4258 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4259 /* exclusions do not conflict by definition */
4262 case FOREST_TRUST_TOP_LEVEL_NAME:
4263 dns_name = nrec->data.name.string;
4264 dns_len = nrec->data.name.size;
4267 case LSA_FOREST_TRUST_DOMAIN_INFO:
4268 dns_name = nrec->data.info.dns_name.string;
4269 dns_len = nrec->data.info.dns_name.size;
4270 nb_name = nrec->data.info.netbios_name.string;
4271 nb_len = nrec->data.info.netbios_name.size;
4272 sid = &nrec->data.info.sid;
4276 if (!dns_name) continue;
4278 /* check if this is already taken and not excluded */
4279 for (i = 0; i < tdo_fti->count; i++) {
4280 trec = &tdo_fti->records[i].record;
4282 switch (trec->type) {
4283 case FOREST_TRUST_TOP_LEVEL_NAME:
4285 tname = trec->data.name.string;
4286 tlen = trec->data.name.size;
4288 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
4290 tname = trec->data.name.string;
4291 tlen = trec->data.name.size;
4293 case FOREST_TRUST_DOMAIN_INFO:
4295 tname = trec->data.info.dns_name.string;
4296 tlen = trec->data.info.dns_name.size;
4299 return NT_STATUS_INVALID_PARAMETER;
4301 ret = dns_cmp(dns_name, dns_len, tname, tlen);
4304 /* if it matches exclusion,
4305 * it doesn't conflict */
4311 case DNS_CMP_FIRST_IS_CHILD:
4312 case DNS_CMP_SECOND_IS_CHILD:
4313 tln_conflict = true;
4319 /* explicit exclusion, no dns name conflict here */
4321 tln_conflict = false;
4324 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
4328 /* also test for domain info */
4329 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
4330 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
4331 sid_conflict = true;
4333 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
4334 strcasecmp_m(trec->data.info.netbios_name.string,
4341 nt_status = add_collision(c_info, new_fti_idx,
4343 LSA_TLN_DISABLED_CONFLICT,
4347 nt_status = add_collision(c_info, new_fti_idx,
4349 LSA_SID_DISABLED_CONFLICT,
4353 nt_status = add_collision(c_info, new_fti_idx,
4355 LSA_NB_DISABLED_CONFLICT,
4360 return NT_STATUS_OK;
4363 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4364 uint32_t idx, uint32_t collision_type,
4365 uint32_t conflict_type, const char *tdo_name)
4367 struct lsa_ForestTrustCollisionRecord **es;
4368 uint32_t i = c_info->count;
4370 es = talloc_realloc(c_info, c_info->entries,
4371 struct lsa_ForestTrustCollisionRecord *, i + 1);
4373 return NT_STATUS_NO_MEMORY;
4375 c_info->entries = es;
4376 c_info->count = i + 1;
4378 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4380 return NT_STATUS_NO_MEMORY;
4384 es[i]->type = collision_type;
4385 es[i]->flags.flags = conflict_type;
4386 es[i]->name.string = talloc_strdup(es[i], tdo_name);
4387 if (!es[i]->name.string) {
4388 return NT_STATUS_NO_MEMORY;
4390 es[i]->name.size = strlen(es[i]->name.string);
4392 return NT_STATUS_OK;
4395 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
4396 struct pdb_trusted_domain *td,
4397 struct ForestTrustInfo *info)
4399 enum ndr_err_code ndr_err;
4401 if (td->trust_forest_trust_info.length == 0 ||
4402 td->trust_forest_trust_info.data == NULL) {
4403 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4405 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
4407 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
4408 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4409 return NT_STATUS_INVALID_DOMAIN_STATE;
4412 return NT_STATUS_OK;
4415 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
4416 struct ForestTrustInfo *fti)
4418 struct ForestTrustDataDomainInfo *info;
4419 struct ForestTrustInfoRecord *rec;
4423 fti->records = talloc_array(fti,
4424 struct ForestTrustInfoRecordArmor, 2);
4425 if (!fti->records) {
4426 return NT_STATUS_NO_MEMORY;
4430 rec = &fti->records[0].record;
4434 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
4436 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
4437 if (!rec->data.name.string) {
4438 return NT_STATUS_NO_MEMORY;
4440 rec->data.name.size = strlen(rec->data.name.string);
4443 rec = &fti->records[1].record;
4447 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
4449 info = &rec->data.info;
4451 info->sid = dom_info->sid;
4452 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
4453 if (!info->dns_name.string) {
4454 return NT_STATUS_NO_MEMORY;
4456 info->dns_name.size = strlen(info->dns_name.string);
4457 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
4458 if (!info->netbios_name.string) {
4459 return NT_STATUS_NO_MEMORY;
4461 info->netbios_name.size = strlen(info->netbios_name.string);
4463 return NT_STATUS_OK;
4466 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
4467 struct lsa_lsaRSetForestTrustInformation *r)
4472 struct lsa_info *handle;
4473 uint32_t num_domains;
4474 struct pdb_trusted_domain **domains;
4475 struct ForestTrustInfo *nfti;
4476 struct ForestTrustInfo *fti;
4477 struct lsa_ForestTrustCollisionInfo *c_info;
4478 struct pdb_domain_info *dom_info;
4479 enum ndr_err_code ndr_err;
4482 return NT_STATUS_NOT_SUPPORTED;
4485 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
4486 return NT_STATUS_INVALID_HANDLE;
4489 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
4490 return NT_STATUS_INVALID_HANDLE;
4493 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
4494 return NT_STATUS_ACCESS_DENIED;
4497 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
4498 if (!NT_STATUS_IS_OK(status)) {
4501 if (num_domains == 0) {
4502 return NT_STATUS_NO_SUCH_DOMAIN;
4505 for (i = 0; i < num_domains; i++) {
4506 if (domains[i]->domain_name == NULL) {
4507 return NT_STATUS_INVALID_DOMAIN_STATE;
4509 if (strcasecmp_m(domains[i]->domain_name,
4510 r->in.trusted_domain_name->string) == 0) {
4514 if (i >= num_domains) {
4515 return NT_STATUS_NO_SUCH_DOMAIN;
4518 if (!(domains[i]->trust_attributes &
4519 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4520 return NT_STATUS_INVALID_PARAMETER;
4523 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4524 return NT_STATUS_INVALID_PARAMETER;
4527 /* The following section until COPY_END is a copy from
4528 * source4/rpmc_server/lsa/scesrc_lsa.c */
4529 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
4531 return NT_STATUS_NO_MEMORY;
4534 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4535 if (!NT_STATUS_IS_OK(status)) {
4539 c_info = talloc_zero(r->out.collision_info,
4540 struct lsa_ForestTrustCollisionInfo);
4542 return NT_STATUS_NO_MEMORY;
4545 /* first check own info, then other domains */
4546 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4548 return NT_STATUS_NO_MEMORY;
4551 dom_info = pdb_get_domain_info(p->mem_ctx);
4553 status = own_ft_info(dom_info, fti);
4554 if (!NT_STATUS_IS_OK(status)) {
4558 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
4559 if (!NT_STATUS_IS_OK(status)) {
4563 for (j = 0; j < num_domains; j++) {
4564 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4566 return NT_STATUS_NO_MEMORY;
4569 status = get_ft_info(p->mem_ctx, domains[j], fti);
4570 if (!NT_STATUS_IS_OK(status)) {
4571 if (NT_STATUS_EQUAL(status,
4572 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4578 if (domains[j]->domain_name == NULL) {
4579 return NT_STATUS_INVALID_DOMAIN_STATE;
4582 status = check_ft_info(c_info, domains[j]->domain_name,
4584 if (!NT_STATUS_IS_OK(status)) {
4589 *r->out.collision_info = c_info;
4591 if (r->in.check_only != 0) {
4592 return NT_STATUS_OK;
4597 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
4599 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4600 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4601 return NT_STATUS_INVALID_PARAMETER;
4604 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
4605 if (!NT_STATUS_IS_OK(status)) {
4609 return NT_STATUS_OK;
4612 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
4613 struct lsa_CREDRRENAME *r)
4615 p->rng_fault_state = True;
4616 return NT_STATUS_NOT_IMPLEMENTED;
4619 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
4620 struct lsa_LSAROPENPOLICYSCE *r)
4622 p->rng_fault_state = True;
4623 return NT_STATUS_NOT_IMPLEMENTED;
4626 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4627 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4629 p->rng_fault_state = True;
4630 return NT_STATUS_NOT_IMPLEMENTED;
4633 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4634 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4636 p->rng_fault_state = True;
4637 return NT_STATUS_NOT_IMPLEMENTED;
4640 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4641 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4643 p->rng_fault_state = True;
4644 return NT_STATUS_NOT_IMPLEMENTED;