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. */
33 #include "../librpc/gen_ndr/srv_lsa.h"
35 #include "../librpc/gen_ndr/netlogon.h"
36 #include "rpc_client/init_lsa.h"
37 #include "../libcli/security/security.h"
38 #include "../libcli/security/dom_sid.h"
39 #include "../librpc/gen_ndr/drsblobs.h"
40 #include "../librpc/gen_ndr/ndr_drsblobs.h"
41 #include "../lib/crypto/arcfour.h"
42 #include "../libcli/security/dom_sid.h"
43 #include "../librpc/gen_ndr/ndr_security.h"
48 #define DBGC_CLASS DBGC_RPC_SRV
50 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
52 enum lsa_handle_type {
53 LSA_HANDLE_POLICY_TYPE = 1,
54 LSA_HANDLE_ACCOUNT_TYPE = 2,
55 LSA_HANDLE_TRUST_TYPE = 3};
61 enum lsa_handle_type type;
62 struct security_descriptor *sd;
65 const struct generic_mapping lsa_account_mapping = {
69 LSA_ACCOUNT_ALL_ACCESS
72 const struct generic_mapping lsa_policy_mapping = {
79 const struct generic_mapping lsa_secret_mapping = {
86 const struct generic_mapping lsa_trusted_domain_mapping = {
87 LSA_TRUSTED_DOMAIN_READ,
88 LSA_TRUSTED_DOMAIN_WRITE,
89 LSA_TRUSTED_DOMAIN_EXECUTE,
90 LSA_TRUSTED_DOMAIN_ALL_ACCESS
93 /***************************************************************************
94 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
95 ***************************************************************************/
97 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
98 struct lsa_RefDomainList *ref,
100 struct dom_sid *dom_sid)
104 if (dom_name != NULL) {
105 for (num = 0; num < ref->count; num++) {
106 if (dom_sid_equal(dom_sid, ref->domains[num].sid)) {
114 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
115 /* index not found, already at maximum domain limit */
119 ref->count = num + 1;
120 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
122 ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains,
123 struct lsa_DomainInfo, ref->count);
128 ZERO_STRUCT(ref->domains[num]);
130 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
131 ref->domains[num].sid = dom_sid_dup(mem_ctx, dom_sid);
132 if (!ref->domains[num].sid) {
140 /***************************************************************************
141 initialize a lsa_DomainInfo structure.
142 ***************************************************************************/
144 static void init_dom_query_3(struct lsa_DomainInfo *r,
148 init_lsa_StringLarge(&r->name, name);
152 /***************************************************************************
153 initialize a lsa_DomainInfo structure.
154 ***************************************************************************/
156 static void init_dom_query_5(struct lsa_DomainInfo *r,
160 init_lsa_StringLarge(&r->name, name);
164 /***************************************************************************
165 lookup_lsa_rids. Must be called as root for lookup_name to work.
166 ***************************************************************************/
168 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
169 struct lsa_RefDomainList *ref,
170 struct lsa_TranslatedSid *prid,
171 uint32_t num_entries,
172 struct lsa_String *name,
174 uint32_t *pmapped_count)
176 uint32 mapped_count, i;
178 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
183 for (i = 0; i < num_entries; i++) {
187 const char *full_name;
189 enum lsa_SidType type;
191 /* Split name into domain and user component */
193 /* follow w2k8 behavior and return the builtin domain when no
194 * input has been passed in */
196 if (name[i].string) {
197 full_name = name[i].string;
199 full_name = "BUILTIN";
202 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
204 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
206 type = SID_NAME_UNKNOWN;
211 case SID_NAME_DOM_GRP:
212 case SID_NAME_DOMAIN:
214 case SID_NAME_WKN_GRP:
215 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
216 /* Leave these unchanged */
219 /* Don't hand out anything but the list above */
220 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
221 type = SID_NAME_UNKNOWN;
228 if (type != SID_NAME_UNKNOWN) {
229 if (type == SID_NAME_DOMAIN) {
232 sid_split_rid(&sid, &rid);
234 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
238 prid[i].sid_type = type;
240 prid[i].sid_index = dom_idx;
243 *pmapped_count = mapped_count;
247 /***************************************************************************
248 lookup_lsa_sids. Must be called as root for lookup_name to work.
249 ***************************************************************************/
251 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
252 struct lsa_RefDomainList *ref,
253 struct lsa_TranslatedSid3 *trans_sids,
254 uint32_t num_entries,
255 struct lsa_String *name,
257 uint32 *pmapped_count)
259 uint32 mapped_count, i;
261 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
266 for (i = 0; i < num_entries; i++) {
270 const char *full_name;
272 enum lsa_SidType type;
276 /* Split name into domain and user component */
278 full_name = name[i].string;
279 if (full_name == NULL) {
280 return NT_STATUS_NO_MEMORY;
283 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
285 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
287 type = SID_NAME_UNKNOWN;
292 case SID_NAME_DOM_GRP:
293 case SID_NAME_DOMAIN:
295 case SID_NAME_WKN_GRP:
296 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
297 /* Leave these unchanged */
300 /* Don't hand out anything but the list above */
301 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
302 type = SID_NAME_UNKNOWN;
309 if (type != SID_NAME_UNKNOWN) {
310 struct dom_sid domain_sid;
311 sid_copy(&domain_sid, &sid);
312 sid_split_rid(&domain_sid, &rid);
313 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
317 /* Initialize the lsa_TranslatedSid3 return. */
318 trans_sids[i].sid_type = type;
319 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
320 trans_sids[i].sid_index = dom_idx;
323 *pmapped_count = mapped_count;
327 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
328 const struct generic_mapping *map,
329 struct dom_sid *sid, uint32_t sid_access)
331 struct dom_sid adm_sid;
332 struct security_ace ace[5];
335 struct security_acl *psa = NULL;
337 /* READ|EXECUTE access for Everyone */
339 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
340 map->generic_execute | map->generic_read, 0);
342 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
344 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
345 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
346 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
347 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
349 /* Add Full Access for Domain Admins */
350 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
351 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
352 map->generic_all, 0);
354 /* If we have a sid, give it some special access */
357 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
361 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
362 return NT_STATUS_NO_MEMORY;
364 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
365 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
366 psa, sd_size)) == NULL)
367 return NT_STATUS_NO_MEMORY;
372 /***************************************************************************
373 ***************************************************************************/
375 static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
376 struct pipes_struct *p,
377 enum lsa_handle_type type,
378 uint32_t acc_granted,
381 const struct security_descriptor *sd,
382 struct policy_handle *handle)
384 struct lsa_info *info;
386 ZERO_STRUCTP(handle);
388 info = talloc_zero(mem_ctx, struct lsa_info);
390 return NT_STATUS_NO_MEMORY;
394 info->access = acc_granted;
397 sid_copy(&info->sid, sid);
400 info->name = talloc_strdup(info, name);
403 info->sd = dup_sec_desc(info, sd);
406 return NT_STATUS_NO_MEMORY;
410 if (!create_policy_hnd(p, handle, info)) {
412 ZERO_STRUCTP(handle);
413 return NT_STATUS_NO_MEMORY;
419 /***************************************************************************
421 ***************************************************************************/
423 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
424 struct lsa_OpenPolicy2 *r)
426 struct security_descriptor *psd = NULL;
428 uint32 des_access = r->in.access_mask;
432 /* Work out max allowed. */
433 map_max_allowed_access(p->session_info->security_token,
434 &p->session_info->utok,
437 /* map the generic bits to the lsa policy ones */
438 se_map_generic(&des_access, &lsa_policy_mapping);
440 /* get the generic lsa policy SD until we store it */
441 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
443 if (!NT_STATUS_IS_OK(status)) {
447 status = access_check_object(psd, p->session_info->security_token,
448 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
449 &acc_granted, "_lsa_OpenPolicy2" );
450 if (!NT_STATUS_IS_OK(status)) {
454 status = create_lsa_policy_handle(p->mem_ctx, p,
455 LSA_HANDLE_POLICY_TYPE,
457 get_global_sam_sid(),
461 if (!NT_STATUS_IS_OK(status)) {
462 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
468 /***************************************************************************
470 ***************************************************************************/
472 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
473 struct lsa_OpenPolicy *r)
475 struct lsa_OpenPolicy2 o;
477 o.in.system_name = NULL; /* should be ignored */
478 o.in.attr = r->in.attr;
479 o.in.access_mask = r->in.access_mask;
481 o.out.handle = r->out.handle;
483 return _lsa_OpenPolicy2(p, &o);
486 /***************************************************************************
487 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
489 ***************************************************************************/
491 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
492 struct lsa_EnumTrustDom *r)
494 struct lsa_info *info;
496 struct trustdom_info **domains;
497 struct lsa_DomainInfo *entries;
501 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
502 return NT_STATUS_INVALID_HANDLE;
504 if (info->type != LSA_HANDLE_POLICY_TYPE) {
505 return NT_STATUS_INVALID_HANDLE;
508 /* check if the user has enough rights */
509 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
510 return NT_STATUS_ACCESS_DENIED;
513 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
516 if (!NT_STATUS_IS_OK(nt_status)) {
520 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo, count);
522 return NT_STATUS_NO_MEMORY;
525 for (i=0; i<count; i++) {
526 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
527 entries[i].sid = &domains[i]->sid;
530 if (*r->in.resume_handle >= count) {
531 *r->out.resume_handle = -1;
532 TALLOC_FREE(entries);
533 return NT_STATUS_NO_MORE_ENTRIES;
536 /* return the rest, limit by max_size. Note that we
537 use the w2k3 element size value of 60 */
538 r->out.domains->count = count - *r->in.resume_handle;
539 r->out.domains->count = MIN(r->out.domains->count,
540 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
542 r->out.domains->domains = entries + *r->in.resume_handle;
544 if (r->out.domains->count < count - *r->in.resume_handle) {
545 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
546 return STATUS_MORE_ENTRIES;
549 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
550 * always be larger than the previous input resume handle, in
551 * particular when hitting the last query it is vital to set the
552 * resume handle correctly to avoid infinite client loops, as
553 * seen e.g. with Windows XP SP3 when resume handle is 0 and
554 * status is NT_STATUS_OK - gd */
556 *r->out.resume_handle = (uint32_t)-1;
561 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
562 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
563 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
565 /***************************************************************************
567 ***************************************************************************/
569 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
570 struct lsa_QueryInfoPolicy *r)
572 NTSTATUS status = NT_STATUS_OK;
573 struct lsa_info *handle;
574 struct dom_sid domain_sid;
576 struct dom_sid *sid = NULL;
577 union lsa_PolicyInformation *info = NULL;
578 uint32_t acc_required = 0;
580 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
581 return NT_STATUS_INVALID_HANDLE;
583 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
584 return NT_STATUS_INVALID_HANDLE;
587 switch (r->in.level) {
588 case LSA_POLICY_INFO_AUDIT_LOG:
589 case LSA_POLICY_INFO_AUDIT_EVENTS:
590 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
592 case LSA_POLICY_INFO_DOMAIN:
593 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
595 case LSA_POLICY_INFO_PD:
596 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
598 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
599 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
601 case LSA_POLICY_INFO_ROLE:
602 case LSA_POLICY_INFO_REPLICA:
603 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
605 case LSA_POLICY_INFO_QUOTA:
606 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
608 case LSA_POLICY_INFO_MOD:
609 case LSA_POLICY_INFO_AUDIT_FULL_SET:
610 /* according to MS-LSAD 3.1.4.4.3 */
611 return NT_STATUS_INVALID_PARAMETER;
612 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
613 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
615 case LSA_POLICY_INFO_DNS:
616 case LSA_POLICY_INFO_DNS_INT:
617 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
618 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
624 if (!(handle->access & acc_required)) {
625 /* return NT_STATUS_ACCESS_DENIED; */
628 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
630 return NT_STATUS_NO_MEMORY;
633 switch (r->in.level) {
634 /* according to MS-LSAD 3.1.4.4.3 */
635 case LSA_POLICY_INFO_MOD:
636 case LSA_POLICY_INFO_AUDIT_FULL_SET:
637 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
638 return NT_STATUS_INVALID_PARAMETER;
639 case LSA_POLICY_INFO_AUDIT_LOG:
640 info->audit_log.percent_full = 0;
641 info->audit_log.maximum_log_size = 0;
642 info->audit_log.retention_time = 0;
643 info->audit_log.shutdown_in_progress = 0;
644 info->audit_log.time_to_shutdown = 0;
645 info->audit_log.next_audit_record = 0;
646 status = NT_STATUS_OK;
648 case LSA_POLICY_INFO_PD:
649 info->pd.name.string = NULL;
650 status = NT_STATUS_OK;
652 case LSA_POLICY_INFO_REPLICA:
653 info->replica.source.string = NULL;
654 info->replica.account.string = NULL;
655 status = NT_STATUS_OK;
657 case LSA_POLICY_INFO_QUOTA:
658 info->quota.paged_pool = 0;
659 info->quota.non_paged_pool = 0;
660 info->quota.min_wss = 0;
661 info->quota.max_wss = 0;
662 info->quota.pagefile = 0;
663 info->quota.unknown = 0;
664 status = NT_STATUS_OK;
666 case LSA_POLICY_INFO_AUDIT_EVENTS:
669 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
671 /* check if the user has enough rights */
672 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
673 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
674 return NT_STATUS_ACCESS_DENIED;
677 /* fake info: We audit everything. ;) */
679 info->audit_events.auditing_mode = true;
680 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
681 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
682 enum lsa_PolicyAuditPolicy,
683 info->audit_events.count);
684 if (!info->audit_events.settings) {
685 return NT_STATUS_NO_MEMORY;
688 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
689 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
690 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
691 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
692 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
693 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
694 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
698 case LSA_POLICY_INFO_DOMAIN:
699 /* check if the user has enough rights */
700 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
701 return NT_STATUS_ACCESS_DENIED;
703 /* Request PolicyPrimaryDomainInformation. */
704 switch (lp_server_role()) {
705 case ROLE_DOMAIN_PDC:
706 case ROLE_DOMAIN_BDC:
707 name = get_global_sam_name();
708 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
710 return NT_STATUS_NO_MEMORY;
713 case ROLE_DOMAIN_MEMBER:
714 name = lp_workgroup();
715 /* We need to return the Domain SID here. */
716 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
717 sid = dom_sid_dup(p->mem_ctx, &domain_sid);
719 return NT_STATUS_NO_MEMORY;
722 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
725 case ROLE_STANDALONE:
726 name = lp_workgroup();
730 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
732 init_dom_query_3(&info->domain, name, sid);
734 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
735 /* check if the user has enough rights */
736 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
737 return NT_STATUS_ACCESS_DENIED;
739 /* Request PolicyAccountDomainInformation. */
740 name = get_global_sam_name();
741 sid = get_global_sam_sid();
743 init_dom_query_5(&info->account_domain, name, sid);
745 case LSA_POLICY_INFO_ROLE:
746 /* check if the user has enough rights */
747 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
748 return NT_STATUS_ACCESS_DENIED;
750 switch (lp_server_role()) {
751 case ROLE_DOMAIN_BDC:
753 * only a BDC is a backup controller
754 * of the domain, it controls.
756 info->role.role = LSA_ROLE_BACKUP;
760 * any other role is a primary
761 * of the domain, it controls.
763 info->role.role = LSA_ROLE_PRIMARY;
767 case LSA_POLICY_INFO_DNS:
768 case LSA_POLICY_INFO_DNS_INT: {
769 struct pdb_domain_info *dominfo;
771 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
772 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
773 "without ADS passdb backend\n"));
774 status = NT_STATUS_INVALID_INFO_CLASS;
778 dominfo = pdb_get_domain_info(info);
779 if (dominfo == NULL) {
780 status = NT_STATUS_NO_MEMORY;
784 init_lsa_StringLarge(&info->dns.name,
786 init_lsa_StringLarge(&info->dns.dns_domain,
787 dominfo->dns_domain);
788 init_lsa_StringLarge(&info->dns.dns_forest,
789 dominfo->dns_forest);
790 info->dns.domain_guid = dominfo->guid;
791 info->dns.sid = &dominfo->sid;
795 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
797 status = NT_STATUS_INVALID_INFO_CLASS;
806 /***************************************************************************
807 _lsa_QueryInfoPolicy2
808 ***************************************************************************/
810 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
811 struct lsa_QueryInfoPolicy2 *r2)
813 struct lsa_QueryInfoPolicy r;
815 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
816 p->rng_fault_state = True;
817 return NT_STATUS_NOT_IMPLEMENTED;
821 r.in.handle = r2->in.handle;
822 r.in.level = r2->in.level;
823 r.out.info = r2->out.info;
825 return _lsa_QueryInfoPolicy(p, &r);
828 /***************************************************************************
829 _lsa_lookup_sids_internal
830 ***************************************************************************/
832 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
834 uint16_t level, /* input */
835 int num_sids, /* input */
836 struct lsa_SidPtr *sid, /* input */
837 struct lsa_RefDomainList **pp_ref, /* input/output */
838 struct lsa_TranslatedName2 **pp_names,/* input/output */
839 uint32_t *pp_mapped_count) /* input/output */
843 const struct dom_sid **sids = NULL;
844 struct lsa_RefDomainList *ref = NULL;
845 uint32 mapped_count = 0;
846 struct lsa_dom_info *dom_infos = NULL;
847 struct lsa_name_info *name_infos = NULL;
848 struct lsa_TranslatedName2 *names = NULL;
850 *pp_mapped_count = 0;
858 sids = TALLOC_ARRAY(p->mem_ctx, const struct dom_sid *, num_sids);
859 ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
861 if (sids == NULL || ref == NULL) {
862 return NT_STATUS_NO_MEMORY;
865 for (i=0; i<num_sids; i++) {
866 sids[i] = sid[i].sid;
869 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
870 &dom_infos, &name_infos);
872 if (!NT_STATUS_IS_OK(status)) {
876 names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
878 return NT_STATUS_NO_MEMORY;
881 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
883 if (!dom_infos[i].valid) {
887 if (init_lsa_ref_domain_list(mem_ctx, ref,
889 &dom_infos[i].sid) != i) {
890 DEBUG(0, ("Domain %s mentioned twice??\n",
892 return NT_STATUS_INTERNAL_ERROR;
896 for (i=0; i<num_sids; i++) {
897 struct lsa_name_info *name = &name_infos[i];
899 if (name->type == SID_NAME_UNKNOWN) {
901 /* Unknown sids should return the string
902 * representation of the SID. Windows 2003 behaves
903 * rather erratic here, in many cases it returns the
904 * RID as 8 bytes hex, in others it returns the full
905 * SID. We (Jerry/VL) could not figure out which the
906 * hard cases are, so leave it with the SID. */
907 name->name = dom_sid_string(p->mem_ctx, sids[i]);
908 if (name->name == NULL) {
909 return NT_STATUS_NO_MEMORY;
915 names[i].sid_type = name->type;
916 names[i].name.string = name->name;
917 names[i].sid_index = name->dom_idx;
918 names[i].unknown = 0;
921 status = NT_STATUS_NONE_MAPPED;
922 if (mapped_count > 0) {
923 status = (mapped_count < num_sids) ?
924 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
927 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
928 num_sids, mapped_count, nt_errstr(status)));
930 *pp_mapped_count = mapped_count;
937 /***************************************************************************
939 ***************************************************************************/
941 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
942 struct lsa_LookupSids *r)
945 struct lsa_info *handle;
946 int num_sids = r->in.sids->num_sids;
947 uint32 mapped_count = 0;
948 struct lsa_RefDomainList *domains = NULL;
949 struct lsa_TranslatedName *names_out = NULL;
950 struct lsa_TranslatedName2 *names = NULL;
953 if ((r->in.level < 1) || (r->in.level > 6)) {
954 return NT_STATUS_INVALID_PARAMETER;
957 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
958 return NT_STATUS_INVALID_HANDLE;
961 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
962 return NT_STATUS_INVALID_HANDLE;
965 /* check if the user has enough rights */
966 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
967 return NT_STATUS_ACCESS_DENIED;
970 if (num_sids > MAX_LOOKUP_SIDS) {
971 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
972 MAX_LOOKUP_SIDS, num_sids));
973 return NT_STATUS_NONE_MAPPED;
976 status = _lsa_lookup_sids_internal(p,
985 /* Only return here when there is a real error.
986 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
987 the requested sids could be resolved. Older versions of XP (pre SP3)
988 rely that we return with the string representations of those SIDs in
989 that case. If we don't, XP crashes - Guenther
992 if (NT_STATUS_IS_ERR(status) &&
993 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
997 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
998 names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
1001 return NT_STATUS_NO_MEMORY;
1004 for (i=0; i<num_sids; i++) {
1005 names_out[i].sid_type = names[i].sid_type;
1006 names_out[i].name = names[i].name;
1007 names_out[i].sid_index = names[i].sid_index;
1010 *r->out.domains = domains;
1011 r->out.names->count = num_sids;
1012 r->out.names->names = names_out;
1013 *r->out.count = mapped_count;
1018 /***************************************************************************
1020 ***************************************************************************/
1022 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1023 struct lsa_LookupSids2 *r)
1026 struct lsa_info *handle;
1027 int num_sids = r->in.sids->num_sids;
1028 uint32 mapped_count = 0;
1029 struct lsa_RefDomainList *domains = NULL;
1030 struct lsa_TranslatedName2 *names = NULL;
1031 bool check_policy = true;
1034 case NDR_LSA_LOOKUPSIDS3:
1035 check_policy = false;
1037 case NDR_LSA_LOOKUPSIDS2:
1039 check_policy = true;
1042 if ((r->in.level < 1) || (r->in.level > 6)) {
1043 return NT_STATUS_INVALID_PARAMETER;
1047 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1048 return NT_STATUS_INVALID_HANDLE;
1051 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1052 return NT_STATUS_INVALID_HANDLE;
1055 /* check if the user has enough rights */
1056 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1057 return NT_STATUS_ACCESS_DENIED;
1061 if (num_sids > MAX_LOOKUP_SIDS) {
1062 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1063 MAX_LOOKUP_SIDS, num_sids));
1064 return NT_STATUS_NONE_MAPPED;
1067 status = _lsa_lookup_sids_internal(p,
1076 *r->out.domains = domains;
1077 r->out.names->count = num_sids;
1078 r->out.names->names = names;
1079 *r->out.count = mapped_count;
1084 /***************************************************************************
1086 ***************************************************************************/
1088 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1089 struct lsa_LookupSids3 *r)
1091 struct lsa_LookupSids2 q;
1093 /* No policy handle on this call. Restrict to crypto connections. */
1094 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1095 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1096 get_remote_machine_name() ));
1097 return NT_STATUS_INVALID_PARAMETER;
1101 q.in.sids = r->in.sids;
1102 q.in.level = r->in.level;
1103 q.in.lookup_options = r->in.lookup_options;
1104 q.in.client_revision = r->in.client_revision;
1105 q.in.names = r->in.names;
1106 q.in.count = r->in.count;
1108 q.out.domains = r->out.domains;
1109 q.out.names = r->out.names;
1110 q.out.count = r->out.count;
1112 return _lsa_LookupSids2(p, &q);
1115 /***************************************************************************
1116 ***************************************************************************/
1118 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1123 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1124 flags = LOOKUP_NAME_ALL;
1126 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1127 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1129 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1130 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1132 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1133 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1134 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1135 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1137 flags = LOOKUP_NAME_NONE;
1144 /***************************************************************************
1146 ***************************************************************************/
1148 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1149 struct lsa_LookupNames *r)
1151 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1152 struct lsa_info *handle;
1153 struct lsa_String *names = r->in.names;
1154 uint32 num_entries = r->in.num_names;
1155 struct lsa_RefDomainList *domains = NULL;
1156 struct lsa_TranslatedSid *rids = NULL;
1157 uint32 mapped_count = 0;
1160 if (num_entries > MAX_LOOKUP_SIDS) {
1161 num_entries = MAX_LOOKUP_SIDS;
1162 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1166 flags = lsa_lookup_level_to_flags(r->in.level);
1168 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1170 return NT_STATUS_NO_MEMORY;
1174 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1177 return NT_STATUS_NO_MEMORY;
1183 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1184 status = NT_STATUS_INVALID_HANDLE;
1188 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1189 return NT_STATUS_INVALID_HANDLE;
1192 /* check if the user has enough rights */
1193 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1194 status = NT_STATUS_ACCESS_DENIED;
1198 /* set up the LSA Lookup RIDs response */
1199 become_root(); /* lookup_name can require root privs */
1200 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1201 names, flags, &mapped_count);
1206 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1207 if (mapped_count == 0) {
1208 status = NT_STATUS_NONE_MAPPED;
1209 } else if (mapped_count != num_entries) {
1210 status = STATUS_SOME_UNMAPPED;
1214 *r->out.count = mapped_count;
1215 *r->out.domains = domains;
1216 r->out.sids->sids = rids;
1217 r->out.sids->count = num_entries;
1222 /***************************************************************************
1224 ***************************************************************************/
1226 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1227 struct lsa_LookupNames2 *r)
1230 struct lsa_LookupNames q;
1231 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1232 struct lsa_TransSidArray *sid_array = NULL;
1235 sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1237 return NT_STATUS_NO_MEMORY;
1240 q.in.handle = r->in.handle;
1241 q.in.num_names = r->in.num_names;
1242 q.in.names = r->in.names;
1243 q.in.level = r->in.level;
1244 q.in.sids = sid_array;
1245 q.in.count = r->in.count;
1246 /* we do not know what this is for */
1247 /* = r->in.unknown1; */
1248 /* = r->in.unknown2; */
1250 q.out.domains = r->out.domains;
1251 q.out.sids = sid_array;
1252 q.out.count = r->out.count;
1254 status = _lsa_LookupNames(p, &q);
1256 sid_array2->count = sid_array->count;
1257 sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1258 if (!sid_array2->sids) {
1259 return NT_STATUS_NO_MEMORY;
1262 for (i=0; i<sid_array->count; i++) {
1263 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1264 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1265 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1266 sid_array2->sids[i].unknown = 0;
1269 r->out.sids = sid_array2;
1274 /***************************************************************************
1276 ***************************************************************************/
1278 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1279 struct lsa_LookupNames3 *r)
1282 struct lsa_info *handle;
1283 struct lsa_String *names = r->in.names;
1284 uint32 num_entries = r->in.num_names;
1285 struct lsa_RefDomainList *domains = NULL;
1286 struct lsa_TranslatedSid3 *trans_sids = NULL;
1287 uint32 mapped_count = 0;
1289 bool check_policy = true;
1292 case NDR_LSA_LOOKUPNAMES4:
1293 check_policy = false;
1295 case NDR_LSA_LOOKUPNAMES3:
1297 check_policy = true;
1300 if (num_entries > MAX_LOOKUP_SIDS) {
1301 num_entries = MAX_LOOKUP_SIDS;
1302 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1305 /* Probably the lookup_level is some sort of bitmask. */
1306 if (r->in.level == 1) {
1307 flags = LOOKUP_NAME_ALL;
1310 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1312 return NT_STATUS_NO_MEMORY;
1316 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1319 return NT_STATUS_NO_MEMORY;
1327 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1328 status = NT_STATUS_INVALID_HANDLE;
1332 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1333 return NT_STATUS_INVALID_HANDLE;
1336 /* check if the user has enough rights */
1337 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1338 status = NT_STATUS_ACCESS_DENIED;
1343 /* set up the LSA Lookup SIDs response */
1344 become_root(); /* lookup_name can require root privs */
1345 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1346 names, flags, &mapped_count);
1351 if (NT_STATUS_IS_OK(status)) {
1352 if (mapped_count == 0) {
1353 status = NT_STATUS_NONE_MAPPED;
1354 } else if (mapped_count != num_entries) {
1355 status = STATUS_SOME_UNMAPPED;
1359 *r->out.count = mapped_count;
1360 *r->out.domains = domains;
1361 r->out.sids->sids = trans_sids;
1362 r->out.sids->count = num_entries;
1367 /***************************************************************************
1369 ***************************************************************************/
1371 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1372 struct lsa_LookupNames4 *r)
1374 struct lsa_LookupNames3 q;
1376 /* No policy handle on this call. Restrict to crypto connections. */
1377 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1378 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1379 get_remote_machine_name() ));
1380 return NT_STATUS_INVALID_PARAMETER;
1384 q.in.num_names = r->in.num_names;
1385 q.in.names = r->in.names;
1386 q.in.level = r->in.level;
1387 q.in.lookup_options = r->in.lookup_options;
1388 q.in.client_revision = r->in.client_revision;
1389 q.in.sids = r->in.sids;
1390 q.in.count = r->in.count;
1392 q.out.domains = r->out.domains;
1393 q.out.sids = r->out.sids;
1394 q.out.count = r->out.count;
1396 return _lsa_LookupNames3(p, &q);
1399 /***************************************************************************
1400 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1401 ***************************************************************************/
1403 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1405 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1406 return NT_STATUS_INVALID_HANDLE;
1409 close_policy_hnd(p, r->in.handle);
1410 ZERO_STRUCTP(r->out.handle);
1411 return NT_STATUS_OK;
1414 /***************************************************************************
1415 ***************************************************************************/
1417 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1418 const struct dom_sid *sid,
1419 struct trustdom_info **info)
1422 uint32_t num_domains = 0;
1423 struct trustdom_info **domains = NULL;
1426 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1427 if (!NT_STATUS_IS_OK(status)) {
1431 for (i=0; i < num_domains; i++) {
1432 if (dom_sid_equal(&domains[i]->sid, sid)) {
1437 if (i == num_domains) {
1438 return NT_STATUS_INVALID_PARAMETER;
1443 return NT_STATUS_OK;
1446 /***************************************************************************
1447 ***************************************************************************/
1449 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1450 const char *netbios_domain_name,
1451 struct trustdom_info **info_p)
1454 struct trustdom_info *info;
1455 struct pdb_trusted_domain *td;
1457 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1458 if (!NT_STATUS_IS_OK(status)) {
1462 info = talloc(mem_ctx, struct trustdom_info);
1464 return NT_STATUS_NO_MEMORY;
1467 info->name = talloc_strdup(info, netbios_domain_name);
1468 NT_STATUS_HAVE_NO_MEMORY(info->name);
1470 sid_copy(&info->sid, &td->security_identifier);
1474 return NT_STATUS_OK;
1477 /***************************************************************************
1478 ***************************************************************************/
1480 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p, struct lsa_OpenSecret *r)
1482 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1485 /***************************************************************************
1486 _lsa_OpenTrustedDomain_base
1487 ***************************************************************************/
1489 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1490 uint32_t access_mask,
1491 struct trustdom_info *info,
1492 struct policy_handle *handle)
1494 struct security_descriptor *psd = NULL;
1496 uint32_t acc_granted;
1499 /* des_access is for the account here, not the policy
1500 * handle - so don't check against policy handle. */
1502 /* Work out max allowed. */
1503 map_max_allowed_access(p->session_info->security_token,
1504 &p->session_info->utok,
1507 /* map the generic bits to the lsa account ones */
1508 se_map_generic(&access_mask, &lsa_account_mapping);
1510 /* get the generic lsa account SD until we store it */
1511 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1512 &lsa_trusted_domain_mapping,
1514 if (!NT_STATUS_IS_OK(status)) {
1518 status = access_check_object(psd, p->session_info->security_token,
1519 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1520 access_mask, &acc_granted,
1521 "_lsa_OpenTrustedDomain");
1522 if (!NT_STATUS_IS_OK(status)) {
1526 status = create_lsa_policy_handle(p->mem_ctx, p,
1527 LSA_HANDLE_TRUST_TYPE,
1533 if (!NT_STATUS_IS_OK(status)) {
1534 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1537 return NT_STATUS_OK;
1540 /***************************************************************************
1541 _lsa_OpenTrustedDomain
1542 ***************************************************************************/
1544 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1545 struct lsa_OpenTrustedDomain *r)
1547 struct lsa_info *handle = NULL;
1548 struct trustdom_info *info = NULL;
1551 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1552 return NT_STATUS_INVALID_HANDLE;
1555 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1556 return NT_STATUS_INVALID_HANDLE;
1559 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1562 if (!NT_STATUS_IS_OK(status)) {
1566 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1567 r->out.trustdom_handle);
1570 /***************************************************************************
1571 _lsa_OpenTrustedDomainByName
1572 ***************************************************************************/
1574 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1575 struct lsa_OpenTrustedDomainByName *r)
1577 struct lsa_info *handle = NULL;
1578 struct trustdom_info *info = NULL;
1581 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1582 return NT_STATUS_INVALID_HANDLE;
1585 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1586 return NT_STATUS_INVALID_HANDLE;
1589 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1592 if (!NT_STATUS_IS_OK(status)) {
1596 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1597 r->out.trustdom_handle);
1600 static NTSTATUS add_trusted_domain_user(TALLOC_CTX *mem_ctx,
1601 const char *netbios_name,
1602 const char *domain_name,
1603 const struct trustDomainPasswords *auth_struct)
1606 struct samu *sam_acct;
1609 struct dom_sid user_sid;
1614 sam_acct = samu_new(mem_ctx);
1615 if (sam_acct == NULL) {
1616 return NT_STATUS_NO_MEMORY;
1619 acct_name = talloc_asprintf(mem_ctx, "%s$", netbios_name);
1620 if (acct_name == NULL) {
1621 return NT_STATUS_NO_MEMORY;
1623 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1624 return NT_STATUS_UNSUCCESSFUL;
1627 if (!pdb_set_domain(sam_acct, domain_name, PDB_SET)) {
1628 return NT_STATUS_UNSUCCESSFUL;
1631 if (!pdb_set_acct_ctrl(sam_acct, ACB_DOMTRUST, PDB_SET)) {
1632 return NT_STATUS_UNSUCCESSFUL;
1635 if (!pdb_new_rid(&rid)) {
1636 return NT_STATUS_DS_NO_MORE_RIDS;
1638 sid_compose(&user_sid, get_global_sam_sid(), rid);
1639 if (!pdb_set_user_sid(sam_acct, &user_sid, PDB_SET)) {
1640 return NT_STATUS_UNSUCCESSFUL;
1643 for (i = 0; i < auth_struct->incoming.count; i++) {
1644 switch (auth_struct->incoming.current.array[i].AuthType) {
1645 case TRUST_AUTH_TYPE_CLEAR:
1646 if (!convert_string_talloc(mem_ctx,
1649 auth_struct->incoming.current.array[i].AuthInfo.clear.password,
1650 auth_struct->incoming.current.array[i].AuthInfo.clear.size,
1653 return NT_STATUS_UNSUCCESSFUL;
1655 if (!pdb_set_plaintext_passwd(sam_acct, dummy)) {
1656 return NT_STATUS_UNSUCCESSFUL;
1664 status = pdb_add_sam_account(sam_acct);
1665 if (!NT_STATUS_IS_OK(status)) {
1669 return NT_STATUS_OK;
1672 /***************************************************************************
1673 _lsa_CreateTrustedDomainEx2
1674 ***************************************************************************/
1676 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1677 struct lsa_CreateTrustedDomainEx2 *r)
1679 struct lsa_info *policy;
1681 uint32_t acc_granted;
1682 struct security_descriptor *psd;
1684 struct pdb_trusted_domain td;
1685 struct trustDomainPasswords auth_struct;
1686 enum ndr_err_code ndr_err;
1687 DATA_BLOB auth_blob;
1690 return NT_STATUS_NOT_SUPPORTED;
1693 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1694 return NT_STATUS_INVALID_HANDLE;
1697 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1698 return NT_STATUS_ACCESS_DENIED;
1701 if (p->session_info->utok.uid != sec_initial_uid() &&
1702 !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1703 return NT_STATUS_ACCESS_DENIED;
1706 /* Work out max allowed. */
1707 map_max_allowed_access(p->session_info->security_token,
1708 &p->session_info->utok,
1709 &r->in.access_mask);
1711 /* map the generic bits to the lsa policy ones */
1712 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1714 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1715 &lsa_trusted_domain_mapping,
1717 if (!NT_STATUS_IS_OK(status)) {
1721 status = access_check_object(psd, p->session_info->security_token,
1722 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1723 r->in.access_mask, &acc_granted,
1724 "_lsa_CreateTrustedDomainEx2");
1725 if (!NT_STATUS_IS_OK(status)) {
1731 td.domain_name = talloc_strdup(p->mem_ctx,
1732 r->in.info->domain_name.string);
1733 if (td.domain_name == NULL) {
1734 return NT_STATUS_NO_MEMORY;
1736 td.netbios_name = talloc_strdup(p->mem_ctx,
1737 r->in.info->netbios_name.string);
1738 if (td.netbios_name == NULL) {
1739 return NT_STATUS_NO_MEMORY;
1741 sid_copy(&td.security_identifier, r->in.info->sid);
1742 td.trust_direction = r->in.info->trust_direction;
1743 td.trust_type = r->in.info->trust_type;
1744 td.trust_attributes = r->in.info->trust_attributes;
1746 if (r->in.auth_info->auth_blob.size != 0) {
1747 auth_blob.length = r->in.auth_info->auth_blob.size;
1748 auth_blob.data = r->in.auth_info->auth_blob.data;
1750 arcfour_crypt_blob(auth_blob.data, auth_blob.length,
1751 &p->session_info->user_session_key);
1753 ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
1755 (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
1756 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1757 return NT_STATUS_UNSUCCESSFUL;
1760 ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
1761 &auth_struct.incoming,
1762 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1763 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1764 return NT_STATUS_UNSUCCESSFUL;
1767 ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
1768 &auth_struct.outgoing,
1769 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1770 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1771 return NT_STATUS_UNSUCCESSFUL;
1774 td.trust_auth_incoming.data = NULL;
1775 td.trust_auth_incoming.length = 0;
1776 td.trust_auth_outgoing.data = NULL;
1777 td.trust_auth_outgoing.length = 0;
1780 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1781 if (!NT_STATUS_IS_OK(status)) {
1785 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1786 status = add_trusted_domain_user(p->mem_ctx,
1787 r->in.info->netbios_name.string,
1788 r->in.info->domain_name.string,
1790 if (!NT_STATUS_IS_OK(status)) {
1795 status = create_lsa_policy_handle(p->mem_ctx, p,
1796 LSA_HANDLE_TRUST_TYPE,
1799 r->in.info->netbios_name.string,
1801 r->out.trustdom_handle);
1802 if (!NT_STATUS_IS_OK(status)) {
1803 pdb_del_trusteddom_pw(r->in.info->netbios_name.string);
1804 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1807 return NT_STATUS_OK;
1810 /***************************************************************************
1811 _lsa_CreateTrustedDomainEx
1812 ***************************************************************************/
1814 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1815 struct lsa_CreateTrustedDomainEx *r)
1817 struct lsa_CreateTrustedDomainEx2 q;
1819 q.in.policy_handle = r->in.policy_handle;
1820 q.in.info = r->in.info;
1821 q.in.auth_info = r->in.auth_info;
1822 q.in.access_mask = r->in.access_mask;
1823 q.out.trustdom_handle = r->out.trustdom_handle;
1825 return _lsa_CreateTrustedDomainEx2(p, &q);
1828 /***************************************************************************
1829 _lsa_CreateTrustedDomain
1830 ***************************************************************************/
1832 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1833 struct lsa_CreateTrustedDomain *r)
1835 struct lsa_CreateTrustedDomainEx2 c;
1836 struct lsa_TrustDomainInfoInfoEx info;
1837 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1839 ZERO_STRUCT(auth_info);
1841 info.domain_name = r->in.info->name;
1842 info.netbios_name = r->in.info->name;
1843 info.sid = r->in.info->sid;
1844 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1845 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1846 info.trust_attributes = 0;
1848 c.in.policy_handle = r->in.policy_handle;
1850 c.in.auth_info = &auth_info;
1851 c.in.access_mask = r->in.access_mask;
1852 c.out.trustdom_handle = r->out.trustdom_handle;
1854 return _lsa_CreateTrustedDomainEx2(p, &c);
1857 /***************************************************************************
1858 _lsa_DeleteTrustedDomain
1859 ***************************************************************************/
1861 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1862 struct lsa_DeleteTrustedDomain *r)
1865 struct lsa_info *handle;
1866 struct pdb_trusted_domain *td;
1867 struct samu *sam_acct;
1870 /* find the connection policy handle. */
1871 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1872 return NT_STATUS_INVALID_HANDLE;
1875 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1876 return NT_STATUS_INVALID_HANDLE;
1879 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1880 return NT_STATUS_ACCESS_DENIED;
1883 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1884 if (!NT_STATUS_IS_OK(status)) {
1888 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1889 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1890 sid_string_tos(r->in.dom_sid)));
1891 return NT_STATUS_UNSUCCESSFUL;
1894 if (td->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1895 sam_acct = samu_new(p->mem_ctx);
1896 if (sam_acct == NULL) {
1897 return NT_STATUS_NO_MEMORY;
1900 acct_name = talloc_asprintf(p->mem_ctx, "%s$", td->netbios_name);
1901 if (acct_name == NULL) {
1902 return NT_STATUS_NO_MEMORY;
1904 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1905 return NT_STATUS_UNSUCCESSFUL;
1907 status = pdb_delete_sam_account(sam_acct);
1908 if (!NT_STATUS_IS_OK(status)) {
1913 status = pdb_del_trusted_domain(td->netbios_name);
1914 if (!NT_STATUS_IS_OK(status)) {
1918 return NT_STATUS_OK;
1921 /***************************************************************************
1922 _lsa_CloseTrustedDomainEx
1923 ***************************************************************************/
1925 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1926 struct lsa_CloseTrustedDomainEx *r)
1928 return NT_STATUS_NOT_IMPLEMENTED;
1931 /***************************************************************************
1932 _lsa_QueryTrustedDomainInfo
1933 ***************************************************************************/
1935 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
1936 struct lsa_QueryTrustedDomainInfo *r)
1939 struct lsa_info *handle;
1940 union lsa_TrustedDomainInfo *info;
1941 struct pdb_trusted_domain *td;
1942 uint32_t acc_required;
1944 /* find the connection policy handle. */
1945 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
1946 return NT_STATUS_INVALID_HANDLE;
1949 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
1950 return NT_STATUS_INVALID_HANDLE;
1953 switch (r->in.level) {
1954 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1955 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1957 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1958 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
1960 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1961 acc_required = LSA_TRUSTED_QUERY_POSIX;
1963 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
1964 acc_required = LSA_TRUSTED_QUERY_AUTH;
1966 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1967 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1969 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1970 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1972 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1973 acc_required = LSA_TRUSTED_QUERY_AUTH;
1975 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1976 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1977 LSA_TRUSTED_QUERY_POSIX |
1978 LSA_TRUSTED_QUERY_AUTH;
1980 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1981 acc_required = LSA_TRUSTED_QUERY_AUTH;
1983 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1984 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1985 LSA_TRUSTED_QUERY_POSIX |
1986 LSA_TRUSTED_QUERY_AUTH;
1988 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1989 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1991 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1992 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1993 LSA_TRUSTED_QUERY_POSIX |
1994 LSA_TRUSTED_QUERY_AUTH;
1996 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1997 acc_required = LSA_TRUSTED_QUERY_POSIX;
2000 return NT_STATUS_INVALID_PARAMETER;
2003 if (!(handle->access & acc_required)) {
2004 return NT_STATUS_ACCESS_DENIED;
2007 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2008 if (!NT_STATUS_IS_OK(status)) {
2012 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_TrustedDomainInfo);
2014 return NT_STATUS_NO_MEMORY;
2017 switch (r->in.level) {
2018 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2019 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2021 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2022 return NT_STATUS_INVALID_PARAMETER;
2023 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2025 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2026 return NT_STATUS_INVALID_INFO_CLASS;
2027 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2028 return NT_STATUS_INVALID_PARAMETER;
2029 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2030 init_lsa_StringLarge(&info->info_ex.domain_name, td->domain_name);
2031 init_lsa_StringLarge(&info->info_ex.netbios_name, td->netbios_name);
2032 info->info_ex.sid = dom_sid_dup(info, &td->security_identifier);
2033 if (!info->info_ex.sid) {
2034 return NT_STATUS_NO_MEMORY;
2036 info->info_ex.trust_direction = td->trust_direction;
2037 info->info_ex.trust_type = td->trust_type;
2038 info->info_ex.trust_attributes = td->trust_attributes;
2040 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2041 return NT_STATUS_INVALID_INFO_CLASS;
2042 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2044 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2045 return NT_STATUS_INVALID_INFO_CLASS;
2046 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2047 return NT_STATUS_INVALID_INFO_CLASS;
2048 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2049 return NT_STATUS_INVALID_PARAMETER;
2050 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2052 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2055 return NT_STATUS_INVALID_PARAMETER;
2058 *r->out.info = info;
2060 return NT_STATUS_OK;
2063 /***************************************************************************
2064 _lsa_QueryTrustedDomainInfoBySid
2065 ***************************************************************************/
2067 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2068 struct lsa_QueryTrustedDomainInfoBySid *r)
2071 struct policy_handle trustdom_handle;
2072 struct lsa_OpenTrustedDomain o;
2073 struct lsa_QueryTrustedDomainInfo q;
2076 o.in.handle = r->in.handle;
2077 o.in.sid = r->in.dom_sid;
2078 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2079 o.out.trustdom_handle = &trustdom_handle;
2081 status = _lsa_OpenTrustedDomain(p, &o);
2082 if (!NT_STATUS_IS_OK(status)) {
2086 q.in.trustdom_handle = &trustdom_handle;
2087 q.in.level = r->in.level;
2088 q.out.info = r->out.info;
2090 status = _lsa_QueryTrustedDomainInfo(p, &q);
2091 if (!NT_STATUS_IS_OK(status)) {
2095 c.in.handle = &trustdom_handle;
2096 c.out.handle = &trustdom_handle;
2098 return _lsa_Close(p, &c);
2101 /***************************************************************************
2102 _lsa_QueryTrustedDomainInfoByName
2103 ***************************************************************************/
2105 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2106 struct lsa_QueryTrustedDomainInfoByName *r)
2109 struct policy_handle trustdom_handle;
2110 struct lsa_OpenTrustedDomainByName o;
2111 struct lsa_QueryTrustedDomainInfo q;
2114 o.in.handle = r->in.handle;
2115 o.in.name.string = r->in.trusted_domain->string;
2116 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2117 o.out.trustdom_handle = &trustdom_handle;
2119 status = _lsa_OpenTrustedDomainByName(p, &o);
2120 if (!NT_STATUS_IS_OK(status)) {
2121 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2122 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2127 q.in.trustdom_handle = &trustdom_handle;
2128 q.in.level = r->in.level;
2129 q.out.info = r->out.info;
2131 status = _lsa_QueryTrustedDomainInfo(p, &q);
2132 if (!NT_STATUS_IS_OK(status)) {
2136 c.in.handle = &trustdom_handle;
2137 c.out.handle = &trustdom_handle;
2139 return _lsa_Close(p, &c);
2142 /***************************************************************************
2143 ***************************************************************************/
2145 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p, struct lsa_CreateSecret *r)
2147 return NT_STATUS_ACCESS_DENIED;
2150 /***************************************************************************
2151 ***************************************************************************/
2153 NTSTATUS _lsa_SetSecret(struct pipes_struct *p, struct lsa_SetSecret *r)
2155 return NT_STATUS_ACCESS_DENIED;
2158 /***************************************************************************
2160 ***************************************************************************/
2162 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2163 struct lsa_DeleteObject *r)
2166 struct lsa_info *info = NULL;
2168 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2169 return NT_STATUS_INVALID_HANDLE;
2172 if (!(info->access & SEC_STD_DELETE)) {
2173 return NT_STATUS_ACCESS_DENIED;
2176 switch (info->type) {
2177 case LSA_HANDLE_ACCOUNT_TYPE:
2178 status = privilege_delete_account(&info->sid);
2179 if (!NT_STATUS_IS_OK(status)) {
2180 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2181 nt_errstr(status)));
2186 return NT_STATUS_INVALID_HANDLE;
2189 close_policy_hnd(p, r->in.handle);
2190 ZERO_STRUCTP(r->out.handle);
2195 /***************************************************************************
2197 ***************************************************************************/
2199 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2200 struct lsa_EnumPrivs *r)
2202 struct lsa_info *handle;
2204 uint32 enum_context = *r->in.resume_handle;
2205 int num_privs = num_privileges_in_short_list();
2206 struct lsa_PrivEntry *entries = NULL;
2208 /* remember that the enum_context starts at 0 and not 1 */
2210 if ( enum_context >= num_privs )
2211 return NT_STATUS_NO_MORE_ENTRIES;
2213 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2214 enum_context, num_privs));
2216 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2217 return NT_STATUS_INVALID_HANDLE;
2219 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2220 return NT_STATUS_INVALID_HANDLE;
2223 /* check if the user has enough rights
2224 I don't know if it's the right one. not documented. */
2226 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2227 return NT_STATUS_ACCESS_DENIED;
2230 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2232 return NT_STATUS_NO_MEMORY;
2238 for (i = 0; i < num_privs; i++) {
2239 if( i < enum_context) {
2241 init_lsa_StringLarge(&entries[i].name, NULL);
2243 entries[i].luid.low = 0;
2244 entries[i].luid.high = 0;
2247 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2249 entries[i].luid.low = sec_privilege_from_index(i);
2250 entries[i].luid.high = 0;
2254 enum_context = num_privs;
2256 *r->out.resume_handle = enum_context;
2257 r->out.privs->count = num_privs;
2258 r->out.privs->privs = entries;
2260 return NT_STATUS_OK;
2263 /***************************************************************************
2264 _lsa_LookupPrivDisplayName
2265 ***************************************************************************/
2267 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2268 struct lsa_LookupPrivDisplayName *r)
2270 struct lsa_info *handle;
2271 const char *description;
2272 struct lsa_StringLarge *lsa_name;
2274 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2275 return NT_STATUS_INVALID_HANDLE;
2277 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2278 return NT_STATUS_INVALID_HANDLE;
2281 /* check if the user has enough rights */
2284 * I don't know if it's the right one. not documented.
2286 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2287 return NT_STATUS_ACCESS_DENIED;
2289 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2291 description = get_privilege_dispname(r->in.name->string);
2293 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2294 return NT_STATUS_NO_SUCH_PRIVILEGE;
2297 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2299 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2301 return NT_STATUS_NO_MEMORY;
2304 init_lsa_StringLarge(lsa_name, description);
2306 *r->out.returned_language_id = r->in.language_id;
2307 *r->out.disp_name = lsa_name;
2309 return NT_STATUS_OK;
2312 /***************************************************************************
2314 ***************************************************************************/
2316 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2317 struct lsa_EnumAccounts *r)
2319 struct lsa_info *handle;
2320 struct dom_sid *sid_list;
2321 int i, j, num_entries;
2323 struct lsa_SidPtr *sids = NULL;
2325 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2326 return NT_STATUS_INVALID_HANDLE;
2328 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2329 return NT_STATUS_INVALID_HANDLE;
2332 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2333 return NT_STATUS_ACCESS_DENIED;
2338 /* The only way we can currently find out all the SIDs that have been
2339 privileged is to scan all privileges */
2341 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2342 if (!NT_STATUS_IS_OK(status)) {
2346 if (*r->in.resume_handle >= num_entries) {
2347 return NT_STATUS_NO_MORE_ENTRIES;
2350 if (num_entries - *r->in.resume_handle) {
2351 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
2352 num_entries - *r->in.resume_handle);
2354 talloc_free(sid_list);
2355 return NT_STATUS_NO_MEMORY;
2358 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2359 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2361 talloc_free(sid_list);
2362 return NT_STATUS_NO_MEMORY;
2367 talloc_free(sid_list);
2369 *r->out.resume_handle = num_entries;
2370 r->out.sids->num_sids = num_entries;
2371 r->out.sids->sids = sids;
2373 return NT_STATUS_OK;
2376 /***************************************************************************
2378 ***************************************************************************/
2380 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2381 struct lsa_GetUserName *r)
2383 const char *username, *domname;
2384 struct lsa_String *account_name = NULL;
2385 struct lsa_String *authority_name = NULL;
2387 if (r->in.account_name &&
2388 *r->in.account_name) {
2389 return NT_STATUS_INVALID_PARAMETER;
2392 if (r->in.authority_name &&
2393 *r->in.authority_name) {
2394 return NT_STATUS_INVALID_PARAMETER;
2397 if (p->session_info->guest) {
2399 * I'm 99% sure this is not the right place to do this,
2400 * global_sid_Anonymous should probably be put into the token
2401 * instead of the guest id -- vl
2403 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2404 &domname, &username, NULL)) {
2405 return NT_STATUS_NO_MEMORY;
2408 username = p->session_info->sanitized_username;
2409 domname = p->session_info->info3->base.domain.string;
2412 account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2413 if (!account_name) {
2414 return NT_STATUS_NO_MEMORY;
2416 init_lsa_String(account_name, username);
2418 if (r->out.authority_name) {
2419 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2420 if (!authority_name) {
2421 return NT_STATUS_NO_MEMORY;
2423 init_lsa_String(authority_name, domname);
2426 *r->out.account_name = account_name;
2427 if (r->out.authority_name) {
2428 *r->out.authority_name = authority_name;
2431 return NT_STATUS_OK;
2434 /***************************************************************************
2436 ***************************************************************************/
2438 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2439 struct lsa_CreateAccount *r)
2442 struct lsa_info *handle;
2443 uint32_t acc_granted;
2444 struct security_descriptor *psd;
2447 /* find the connection policy handle. */
2448 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2449 return NT_STATUS_INVALID_HANDLE;
2451 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2452 return NT_STATUS_INVALID_HANDLE;
2455 /* check if the user has enough rights */
2457 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2458 return NT_STATUS_ACCESS_DENIED;
2461 /* Work out max allowed. */
2462 map_max_allowed_access(p->session_info->security_token,
2463 &p->session_info->utok,
2464 &r->in.access_mask);
2466 /* map the generic bits to the lsa policy ones */
2467 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2469 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2470 &lsa_account_mapping,
2471 r->in.sid, LSA_POLICY_ALL_ACCESS);
2472 if (!NT_STATUS_IS_OK(status)) {
2476 status = access_check_object(psd, p->session_info->security_token,
2477 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2478 &acc_granted, "_lsa_CreateAccount");
2479 if (!NT_STATUS_IS_OK(status)) {
2483 if ( is_privileged_sid( r->in.sid ) )
2484 return NT_STATUS_OBJECT_NAME_COLLISION;
2486 status = create_lsa_policy_handle(p->mem_ctx, p,
2487 LSA_HANDLE_ACCOUNT_TYPE,
2492 r->out.acct_handle);
2493 if (!NT_STATUS_IS_OK(status)) {
2494 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2497 return privilege_create_account(r->in.sid);
2500 /***************************************************************************
2502 ***************************************************************************/
2504 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2505 struct lsa_OpenAccount *r)
2507 struct lsa_info *handle;
2508 struct security_descriptor *psd = NULL;
2510 uint32_t des_access = r->in.access_mask;
2511 uint32_t acc_granted;
2514 /* find the connection policy handle. */
2515 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2516 return NT_STATUS_INVALID_HANDLE;
2518 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2519 return NT_STATUS_INVALID_HANDLE;
2522 /* des_access is for the account here, not the policy
2523 * handle - so don't check against policy handle. */
2525 /* Work out max allowed. */
2526 map_max_allowed_access(p->session_info->security_token,
2527 &p->session_info->utok,
2530 /* map the generic bits to the lsa account ones */
2531 se_map_generic(&des_access, &lsa_account_mapping);
2533 /* get the generic lsa account SD until we store it */
2534 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2535 &lsa_account_mapping,
2536 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2537 if (!NT_STATUS_IS_OK(status)) {
2541 status = access_check_object(psd, p->session_info->security_token,
2542 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2543 &acc_granted, "_lsa_OpenAccount" );
2544 if (!NT_STATUS_IS_OK(status)) {
2548 /* TODO: Fis the parsing routine before reenabling this check! */
2550 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2551 return NT_STATUS_ACCESS_DENIED;
2554 status = create_lsa_policy_handle(p->mem_ctx, p,
2555 LSA_HANDLE_ACCOUNT_TYPE,
2560 r->out.acct_handle);
2561 if (!NT_STATUS_IS_OK(status)) {
2562 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2565 return NT_STATUS_OK;
2568 /***************************************************************************
2569 _lsa_EnumPrivsAccount
2570 For a given SID, enumerate all the privilege this account has.
2571 ***************************************************************************/
2573 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2574 struct lsa_EnumPrivsAccount *r)
2576 NTSTATUS status = NT_STATUS_OK;
2577 struct lsa_info *info=NULL;
2578 PRIVILEGE_SET *privileges;
2579 struct lsa_PrivilegeSet *priv_set = NULL;
2581 /* find the connection policy handle. */
2582 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2583 return NT_STATUS_INVALID_HANDLE;
2585 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2586 return NT_STATUS_INVALID_HANDLE;
2589 if (!(info->access & LSA_ACCOUNT_VIEW))
2590 return NT_STATUS_ACCESS_DENIED;
2592 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2593 if (!NT_STATUS_IS_OK(status)) {
2597 *r->out.privs = priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
2599 return NT_STATUS_NO_MEMORY;
2602 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2603 sid_string_dbg(&info->sid),
2604 privileges->count));
2606 priv_set->count = privileges->count;
2607 priv_set->unknown = 0;
2608 priv_set->set = talloc_move(priv_set, &privileges->set);
2613 /***************************************************************************
2614 _lsa_GetSystemAccessAccount
2615 ***************************************************************************/
2617 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2618 struct lsa_GetSystemAccessAccount *r)
2621 struct lsa_info *info = NULL;
2622 struct lsa_EnumPrivsAccount e;
2623 struct lsa_PrivilegeSet *privset;
2625 /* find the connection policy handle. */
2627 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2628 return NT_STATUS_INVALID_HANDLE;
2630 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2631 return NT_STATUS_INVALID_HANDLE;
2634 if (!(info->access & LSA_ACCOUNT_VIEW))
2635 return NT_STATUS_ACCESS_DENIED;
2637 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2639 return NT_STATUS_NO_MEMORY;
2642 e.in.handle = r->in.handle;
2643 e.out.privs = &privset;
2645 status = _lsa_EnumPrivsAccount(p, &e);
2646 if (!NT_STATUS_IS_OK(status)) {
2647 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2648 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2649 nt_errstr(status)));
2653 /* Samba4 would iterate over the privset to merge the policy mode bits,
2654 * not sure samba3 can do the same here, so just return what we did in
2658 0x01 -> Log on locally
2659 0x02 -> Access this computer from network
2660 0x04 -> Log on as a batch job
2661 0x10 -> Log on as a service
2663 they can be ORed together
2666 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2667 LSA_POLICY_MODE_NETWORK;
2669 return NT_STATUS_OK;
2672 /***************************************************************************
2673 update the systemaccount information
2674 ***************************************************************************/
2676 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2677 struct lsa_SetSystemAccessAccount *r)
2679 struct lsa_info *info=NULL;
2682 /* find the connection policy handle. */
2683 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2684 return NT_STATUS_INVALID_HANDLE;
2686 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2687 return NT_STATUS_INVALID_HANDLE;
2690 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2691 return NT_STATUS_ACCESS_DENIED;
2694 if (!pdb_getgrsid(&map, info->sid))
2695 return NT_STATUS_NO_SUCH_GROUP;
2697 return pdb_update_group_mapping_entry(&map);
2700 /***************************************************************************
2701 _lsa_AddPrivilegesToAccount
2702 For a given SID, add some privileges.
2703 ***************************************************************************/
2705 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
2706 struct lsa_AddPrivilegesToAccount *r)
2708 struct lsa_info *info = NULL;
2709 struct lsa_PrivilegeSet *set = NULL;
2711 /* find the connection policy handle. */
2712 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2713 return NT_STATUS_INVALID_HANDLE;
2715 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2716 return NT_STATUS_INVALID_HANDLE;
2719 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2720 return NT_STATUS_ACCESS_DENIED;
2725 if ( !grant_privilege_set( &info->sid, set ) ) {
2726 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2727 sid_string_dbg(&info->sid) ));
2728 return NT_STATUS_NO_SUCH_PRIVILEGE;
2731 return NT_STATUS_OK;
2734 /***************************************************************************
2735 _lsa_RemovePrivilegesFromAccount
2736 For a given SID, remove some privileges.
2737 ***************************************************************************/
2739 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2740 struct lsa_RemovePrivilegesFromAccount *r)
2742 struct lsa_info *info = NULL;
2743 struct lsa_PrivilegeSet *set = NULL;
2745 /* find the connection policy handle. */
2746 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2747 return NT_STATUS_INVALID_HANDLE;
2749 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2750 return NT_STATUS_INVALID_HANDLE;
2753 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2754 return NT_STATUS_ACCESS_DENIED;
2759 if ( !revoke_privilege_set( &info->sid, set) ) {
2760 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2761 sid_string_dbg(&info->sid) ));
2762 return NT_STATUS_NO_SUCH_PRIVILEGE;
2765 return NT_STATUS_OK;
2768 /***************************************************************************
2770 ***************************************************************************/
2772 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2773 struct lsa_LookupPrivName *r)
2775 struct lsa_info *info = NULL;
2777 struct lsa_StringLarge *lsa_name;
2779 /* find the connection policy handle. */
2780 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2781 return NT_STATUS_INVALID_HANDLE;
2784 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2785 return NT_STATUS_INVALID_HANDLE;
2788 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2789 return NT_STATUS_ACCESS_DENIED;
2792 if (r->in.luid->high != 0) {
2793 return NT_STATUS_NO_SUCH_PRIVILEGE;
2796 name = sec_privilege_name(r->in.luid->low);
2798 return NT_STATUS_NO_SUCH_PRIVILEGE;
2801 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2803 return NT_STATUS_NO_MEMORY;
2806 lsa_name->string = talloc_strdup(lsa_name, name);
2807 if (!lsa_name->string) {
2808 TALLOC_FREE(lsa_name);
2809 return NT_STATUS_NO_MEMORY;
2812 *r->out.name = lsa_name;
2814 return NT_STATUS_OK;
2817 /***************************************************************************
2819 ***************************************************************************/
2821 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
2822 struct lsa_QuerySecurity *r)
2824 struct lsa_info *handle=NULL;
2825 struct security_descriptor *psd = NULL;
2829 /* find the connection policy handle. */
2830 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2831 return NT_STATUS_INVALID_HANDLE;
2833 switch (handle->type) {
2834 case LSA_HANDLE_POLICY_TYPE:
2835 case LSA_HANDLE_ACCOUNT_TYPE:
2836 case LSA_HANDLE_TRUST_TYPE:
2838 sd_size = ndr_size_security_descriptor(psd, 0);
2839 status = NT_STATUS_OK;
2842 status = NT_STATUS_INVALID_HANDLE;
2846 if (!NT_STATUS_IS_OK(status)) {
2850 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2851 if (!*r->out.sdbuf) {
2852 return NT_STATUS_NO_MEMORY;
2858 /***************************************************************************
2859 _lsa_AddAccountRights
2860 ***************************************************************************/
2862 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
2863 struct lsa_AddAccountRights *r)
2865 struct lsa_info *info = NULL;
2867 uint32_t acc_granted = 0;
2868 struct security_descriptor *psd = NULL;
2873 /* find the connection policy handle. */
2874 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2875 return NT_STATUS_INVALID_HANDLE;
2877 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2878 return NT_STATUS_INVALID_HANDLE;
2881 /* get the generic lsa account SD for this SID until we store it */
2882 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2883 &lsa_account_mapping,
2884 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2885 if (!NT_STATUS_IS_OK(status)) {
2890 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2891 * on the policy handle. If it does, ask for
2892 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2893 * on the account sid. We don't check here so just use the latter. JRA.
2896 status = access_check_object(psd, p->session_info->security_token,
2897 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2898 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2899 &acc_granted, "_lsa_AddAccountRights" );
2900 if (!NT_STATUS_IS_OK(status)) {
2904 /* according to an NT4 PDC, you can add privileges to SIDs even without
2905 call_lsa_create_account() first. And you can use any arbitrary SID. */
2907 sid_copy( &sid, r->in.sid );
2909 for ( i=0; i < r->in.rights->count; i++ ) {
2911 const char *privname = r->in.rights->names[i].string;
2913 /* only try to add non-null strings */
2918 if ( !grant_privilege_by_name( &sid, privname ) ) {
2919 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2921 return NT_STATUS_NO_SUCH_PRIVILEGE;
2925 return NT_STATUS_OK;
2928 /***************************************************************************
2929 _lsa_RemoveAccountRights
2930 ***************************************************************************/
2932 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
2933 struct lsa_RemoveAccountRights *r)
2935 struct lsa_info *info = NULL;
2937 struct security_descriptor *psd = NULL;
2940 const char *privname = NULL;
2941 uint32_t acc_granted = 0;
2944 /* find the connection policy handle. */
2945 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2946 return NT_STATUS_INVALID_HANDLE;
2948 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2949 return NT_STATUS_INVALID_HANDLE;
2952 /* get the generic lsa account SD for this SID until we store it */
2953 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2954 &lsa_account_mapping,
2955 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2956 if (!NT_STATUS_IS_OK(status)) {
2961 * From the MS DOCs. We need
2962 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2963 * and DELETE on the account sid.
2966 status = access_check_object(psd, p->session_info->security_token,
2967 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2968 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2969 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
2970 &acc_granted, "_lsa_RemoveAccountRights");
2971 if (!NT_STATUS_IS_OK(status)) {
2975 sid_copy( &sid, r->in.sid );
2977 if ( r->in.remove_all ) {
2978 if ( !revoke_all_privileges( &sid ) )
2979 return NT_STATUS_ACCESS_DENIED;
2981 return NT_STATUS_OK;
2984 for ( i=0; i < r->in.rights->count; i++ ) {
2986 privname = r->in.rights->names[i].string;
2988 /* only try to add non-null strings */
2993 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2994 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2996 return NT_STATUS_NO_SUCH_PRIVILEGE;
3000 return NT_STATUS_OK;
3003 /*******************************************************************
3004 ********************************************************************/
3006 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3007 struct lsa_RightSet *r,
3008 PRIVILEGE_SET *privileges)
3011 const char *privname;
3012 const char **privname_array = NULL;
3015 for (i=0; i<privileges->count; i++) {
3016 if (privileges->set[i].luid.high) {
3019 privname = sec_privilege_name(privileges->set[i].luid.low);
3021 if (!add_string_to_array(mem_ctx, privname,
3022 &privname_array, &num_priv)) {
3023 return NT_STATUS_NO_MEMORY;
3030 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
3033 return NT_STATUS_NO_MEMORY;
3036 for (i=0; i<num_priv; i++) {
3037 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3040 r->count = num_priv;
3043 return NT_STATUS_OK;
3046 /***************************************************************************
3047 _lsa_EnumAccountRights
3048 ***************************************************************************/
3050 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3051 struct lsa_EnumAccountRights *r)
3054 struct lsa_info *info = NULL;
3055 PRIVILEGE_SET *privileges;
3057 /* find the connection policy handle. */
3059 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3060 return NT_STATUS_INVALID_HANDLE;
3062 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3063 return NT_STATUS_INVALID_HANDLE;
3066 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3067 return NT_STATUS_ACCESS_DENIED;
3070 /* according to an NT4 PDC, you can add privileges to SIDs even without
3071 call_lsa_create_account() first. And you can use any arbitrary SID. */
3073 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3074 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3075 * the lsa database */
3077 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3078 if (!NT_STATUS_IS_OK(status)) {
3082 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3083 sid_string_dbg(r->in.sid), privileges->count));
3085 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3090 /***************************************************************************
3091 _lsa_LookupPrivValue
3092 ***************************************************************************/
3094 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3095 struct lsa_LookupPrivValue *r)
3097 struct lsa_info *info = NULL;
3098 const char *name = NULL;
3100 /* 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_POLICY_TYPE) {
3106 return NT_STATUS_INVALID_HANDLE;
3109 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3110 return NT_STATUS_ACCESS_DENIED;
3112 name = r->in.name->string;
3114 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3116 r->out.luid->low = sec_privilege_id(name);
3117 r->out.luid->high = 0;
3118 if (r->out.luid->low == SEC_PRIV_INVALID) {
3119 return NT_STATUS_NO_SUCH_PRIVILEGE;
3121 return NT_STATUS_OK;
3124 /***************************************************************************
3125 _lsa_EnumAccountsWithUserRight
3126 ***************************************************************************/
3128 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3129 struct lsa_EnumAccountsWithUserRight *r)
3132 struct lsa_info *info = NULL;
3133 struct dom_sid *sids = NULL;
3136 enum sec_privilege privilege;
3138 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3139 return NT_STATUS_INVALID_HANDLE;
3142 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3143 return NT_STATUS_INVALID_HANDLE;
3146 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3147 return NT_STATUS_ACCESS_DENIED;
3150 if (!r->in.name || !r->in.name->string) {
3151 return NT_STATUS_NO_SUCH_PRIVILEGE;
3154 privilege = sec_privilege_id(r->in.name->string);
3155 if (privilege == SEC_PRIV_INVALID) {
3156 return NT_STATUS_NO_SUCH_PRIVILEGE;
3159 status = privilege_enum_sids(privilege, p->mem_ctx,
3161 if (!NT_STATUS_IS_OK(status)) {
3165 r->out.sids->num_sids = num_sids;
3166 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3167 r->out.sids->num_sids);
3169 for (i=0; i < r->out.sids->num_sids; i++) {
3170 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3172 if (!r->out.sids->sids[i].sid) {
3173 TALLOC_FREE(r->out.sids->sids);
3174 r->out.sids->num_sids = 0;
3175 return NT_STATUS_NO_MEMORY;
3179 return NT_STATUS_OK;
3182 /***************************************************************************
3184 ***************************************************************************/
3186 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3187 struct lsa_Delete *r)
3189 return NT_STATUS_NOT_SUPPORTED;
3193 * From here on the server routines are just dummy ones to make smbd link with
3194 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3195 * pulling the server stubs across one by one.
3198 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3200 p->rng_fault_state = True;
3201 return NT_STATUS_NOT_IMPLEMENTED;
3204 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3205 struct lsa_ChangePassword *r)
3207 p->rng_fault_state = True;
3208 return NT_STATUS_NOT_IMPLEMENTED;
3211 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3213 p->rng_fault_state = True;
3214 return NT_STATUS_NOT_IMPLEMENTED;
3217 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3219 p->rng_fault_state = True;
3220 return NT_STATUS_NOT_IMPLEMENTED;
3223 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3224 struct lsa_GetQuotasForAccount *r)
3226 p->rng_fault_state = True;
3227 return NT_STATUS_NOT_IMPLEMENTED;
3230 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3231 struct lsa_SetQuotasForAccount *r)
3233 p->rng_fault_state = True;
3234 return NT_STATUS_NOT_IMPLEMENTED;
3237 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3238 struct lsa_SetInformationTrustedDomain *r)
3240 p->rng_fault_state = True;
3241 return NT_STATUS_NOT_IMPLEMENTED;
3244 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
3246 p->rng_fault_state = True;
3247 return NT_STATUS_NOT_IMPLEMENTED;
3250 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3251 struct lsa_SetTrustedDomainInfo *r)
3253 p->rng_fault_state = True;
3254 return NT_STATUS_NOT_IMPLEMENTED;
3257 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3258 struct lsa_StorePrivateData *r)
3260 p->rng_fault_state = True;
3261 return NT_STATUS_NOT_IMPLEMENTED;
3264 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3265 struct lsa_RetrievePrivateData *r)
3267 p->rng_fault_state = True;
3268 return NT_STATUS_NOT_IMPLEMENTED;
3271 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3272 struct lsa_SetInfoPolicy2 *r)
3274 p->rng_fault_state = True;
3275 return NT_STATUS_NOT_IMPLEMENTED;
3278 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3279 struct lsa_SetTrustedDomainInfoByName *r)
3281 p->rng_fault_state = True;
3282 return NT_STATUS_NOT_IMPLEMENTED;
3285 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3286 struct lsa_EnumTrustedDomainsEx *r)
3288 struct lsa_info *info;
3290 struct pdb_trusted_domain **domains;
3291 struct lsa_TrustDomainInfoInfoEx *entries;
3295 /* bail out early if pdb backend is not capable of ex trusted domains,
3296 * if we dont do that, the client might not call
3297 * _lsa_EnumTrustedDomains() afterwards - gd */
3299 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3300 p->rng_fault_state = True;
3301 return NT_STATUS_NOT_IMPLEMENTED;
3304 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3305 return NT_STATUS_INVALID_HANDLE;
3307 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3308 return NT_STATUS_INVALID_HANDLE;
3311 /* check if the user has enough rights */
3312 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3313 return NT_STATUS_ACCESS_DENIED;
3316 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3319 if (!NT_STATUS_IS_OK(nt_status)) {
3323 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3326 return NT_STATUS_NO_MEMORY;
3329 for (i=0; i<count; i++) {
3330 init_lsa_StringLarge(&entries[i].netbios_name,
3331 domains[i]->netbios_name);
3332 entries[i].sid = &domains[i]->security_identifier;
3335 if (*r->in.resume_handle >= count) {
3336 *r->out.resume_handle = -1;
3337 TALLOC_FREE(entries);
3338 return NT_STATUS_NO_MORE_ENTRIES;
3341 /* return the rest, limit by max_size. Note that we
3342 use the w2k3 element size value of 60 */
3343 r->out.domains->count = count - *r->in.resume_handle;
3344 r->out.domains->count = MIN(r->out.domains->count,
3345 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3347 r->out.domains->domains = entries + *r->in.resume_handle;
3349 if (r->out.domains->count < count - *r->in.resume_handle) {
3350 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3351 return STATUS_MORE_ENTRIES;
3354 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3355 * always be larger than the previous input resume handle, in
3356 * particular when hitting the last query it is vital to set the
3357 * resume handle correctly to avoid infinite client loops, as
3358 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3359 * status is NT_STATUS_OK - gd */
3361 *r->out.resume_handle = (uint32_t)-1;
3363 return NT_STATUS_OK;
3366 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3367 struct lsa_QueryDomainInformationPolicy *r)
3369 p->rng_fault_state = True;
3370 return NT_STATUS_NOT_IMPLEMENTED;
3373 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3374 struct lsa_SetDomainInformationPolicy *r)
3376 p->rng_fault_state = True;
3377 return NT_STATUS_NOT_IMPLEMENTED;
3380 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3382 p->rng_fault_state = True;
3383 return NT_STATUS_NOT_IMPLEMENTED;
3386 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3388 p->rng_fault_state = True;
3389 return NT_STATUS_NOT_IMPLEMENTED;
3392 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3394 p->rng_fault_state = True;
3395 return NT_STATUS_NOT_IMPLEMENTED;
3398 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3400 p->rng_fault_state = True;
3401 return NT_STATUS_NOT_IMPLEMENTED;
3404 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3405 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3407 p->rng_fault_state = True;
3408 return NT_STATUS_NOT_IMPLEMENTED;
3411 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3412 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3414 p->rng_fault_state = True;
3415 return NT_STATUS_NOT_IMPLEMENTED;
3418 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3420 p->rng_fault_state = True;
3421 return NT_STATUS_NOT_IMPLEMENTED;
3424 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3425 struct lsa_CREDRGETTARGETINFO *r)
3427 p->rng_fault_state = True;
3428 return NT_STATUS_NOT_IMPLEMENTED;
3431 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3432 struct lsa_CREDRPROFILELOADED *r)
3434 p->rng_fault_state = True;
3435 return NT_STATUS_NOT_IMPLEMENTED;
3438 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3439 struct lsa_CREDRGETSESSIONTYPES *r)
3441 p->rng_fault_state = True;
3442 return NT_STATUS_NOT_IMPLEMENTED;
3445 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3446 struct lsa_LSARREGISTERAUDITEVENT *r)
3448 p->rng_fault_state = True;
3449 return NT_STATUS_NOT_IMPLEMENTED;
3452 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3453 struct lsa_LSARGENAUDITEVENT *r)
3455 p->rng_fault_state = True;
3456 return NT_STATUS_NOT_IMPLEMENTED;
3459 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3460 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3462 p->rng_fault_state = True;
3463 return NT_STATUS_NOT_IMPLEMENTED;
3466 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3467 struct lsa_lsaRQueryForestTrustInformation *r)
3469 p->rng_fault_state = True;
3470 return NT_STATUS_NOT_IMPLEMENTED;
3473 #define DNS_CMP_MATCH 0
3474 #define DNS_CMP_FIRST_IS_CHILD 1
3475 #define DNS_CMP_SECOND_IS_CHILD 2
3476 #define DNS_CMP_NO_MATCH 3
3478 /* this function assumes names are well formed DNS names.
3479 * it doesn't validate them */
3480 static int dns_cmp(const char *s1, size_t l1,
3481 const char *s2, size_t l2)
3483 const char *p1, *p2;
3488 if (StrCaseCmp(s1, s2) == 0) {
3489 return DNS_CMP_MATCH;
3491 return DNS_CMP_NO_MATCH;
3499 cret = DNS_CMP_FIRST_IS_CHILD;
3505 cret = DNS_CMP_SECOND_IS_CHILD;
3508 if (p1[t1 - t2 - 1] != '.') {
3509 return DNS_CMP_NO_MATCH;
3512 if (StrCaseCmp(&p1[t1 - t2], p2) == 0) {
3516 return DNS_CMP_NO_MATCH;
3519 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3520 struct lsa_ForestTrustInformation *lfti,
3521 struct ForestTrustInfo *fti)
3523 struct lsa_ForestTrustRecord *lrec;
3524 struct ForestTrustInfoRecord *rec;
3525 struct lsa_StringLarge *tln;
3526 struct lsa_ForestTrustDomainInfo *info;
3530 fti->count = lfti->count;
3531 fti->records = talloc_array(mem_ctx,
3532 struct ForestTrustInfoRecordArmor,
3534 if (!fti->records) {
3535 return NT_STATUS_NO_MEMORY;
3537 for (i = 0; i < fti->count; i++) {
3538 lrec = lfti->entries[i];
3539 rec = &fti->records[i].record;
3541 rec->flags = lrec->flags;
3542 rec->timestamp = lrec->time;
3543 rec->type = lrec->type;
3545 switch (lrec->type) {
3546 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3547 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3548 tln = &lrec->forest_trust_data.top_level_name;
3549 rec->data.name.string =
3550 talloc_strdup(mem_ctx, tln->string);
3551 if (!rec->data.name.string) {
3552 return NT_STATUS_NO_MEMORY;
3554 rec->data.name.size = strlen(rec->data.name.string);
3556 case LSA_FOREST_TRUST_DOMAIN_INFO:
3557 info = &lrec->forest_trust_data.domain_info;
3558 rec->data.info.sid = *info->domain_sid;
3559 rec->data.info.dns_name.string =
3560 talloc_strdup(mem_ctx,
3561 info->dns_domain_name.string);
3562 if (!rec->data.info.dns_name.string) {
3563 return NT_STATUS_NO_MEMORY;
3565 rec->data.info.dns_name.size =
3566 strlen(rec->data.info.dns_name.string);
3567 rec->data.info.netbios_name.string =
3568 talloc_strdup(mem_ctx,
3569 info->netbios_domain_name.string);
3570 if (!rec->data.info.netbios_name.string) {
3571 return NT_STATUS_NO_MEMORY;
3573 rec->data.info.netbios_name.size =
3574 strlen(rec->data.info.netbios_name.string);
3577 return NT_STATUS_INVALID_DOMAIN_STATE;
3581 return NT_STATUS_OK;
3584 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3585 uint32_t index, uint32_t collision_type,
3586 uint32_t conflict_type, const char *tdo_name);
3588 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
3589 const char *tdo_name,
3590 struct ForestTrustInfo *tdo_fti,
3591 struct ForestTrustInfo *new_fti,
3592 struct lsa_ForestTrustCollisionInfo *c_info)
3594 struct ForestTrustInfoRecord *nrec;
3595 struct ForestTrustInfoRecord *trec;
3596 const char *dns_name;
3597 const char *nb_name = NULL;
3598 struct dom_sid *sid = NULL;
3599 const char *tname = NULL;
3604 uint32_t new_fti_idx;
3606 /* use always TDO type, until we understand when Xref can be used */
3607 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
3612 bool ex_rule = false;
3615 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
3617 nrec = &new_fti->records[new_fti_idx].record;
3619 tln_conflict = false;
3620 sid_conflict = false;
3621 nb_conflict = false;
3624 switch (nrec->type) {
3625 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3626 /* exclusions do not conflict by definition */
3629 case FOREST_TRUST_TOP_LEVEL_NAME:
3630 dns_name = nrec->data.name.string;
3631 dns_len = nrec->data.name.size;
3634 case LSA_FOREST_TRUST_DOMAIN_INFO:
3635 dns_name = nrec->data.info.dns_name.string;
3636 dns_len = nrec->data.info.dns_name.size;
3637 nb_name = nrec->data.info.netbios_name.string;
3638 nb_len = nrec->data.info.netbios_name.size;
3639 sid = &nrec->data.info.sid;
3643 if (!dns_name) continue;
3645 /* check if this is already taken and not excluded */
3646 for (i = 0; i < tdo_fti->count; i++) {
3647 trec = &tdo_fti->records[i].record;
3649 switch (trec->type) {
3650 case FOREST_TRUST_TOP_LEVEL_NAME:
3652 tname = trec->data.name.string;
3653 tlen = trec->data.name.size;
3655 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
3657 tname = trec->data.name.string;
3658 tlen = trec->data.name.size;
3660 case FOREST_TRUST_DOMAIN_INFO:
3662 tname = trec->data.info.dns_name.string;
3663 tlen = trec->data.info.dns_name.size;
3665 return NT_STATUS_INVALID_PARAMETER;
3667 ret = dns_cmp(dns_name, dns_len, tname, tlen);
3670 /* if it matches exclusion,
3671 * it doesn't conflict */
3677 case DNS_CMP_FIRST_IS_CHILD:
3678 case DNS_CMP_SECOND_IS_CHILD:
3679 tln_conflict = true;
3685 /* explicit exclusion, no dns name conflict here */
3687 tln_conflict = false;
3690 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
3694 /* also test for domain info */
3695 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
3696 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
3697 sid_conflict = true;
3699 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
3700 StrCaseCmp(trec->data.info.netbios_name.string,
3707 nt_status = add_collision(c_info, new_fti_idx,
3709 LSA_TLN_DISABLED_CONFLICT,
3713 nt_status = add_collision(c_info, new_fti_idx,
3715 LSA_SID_DISABLED_CONFLICT,
3719 nt_status = add_collision(c_info, new_fti_idx,
3721 LSA_NB_DISABLED_CONFLICT,
3726 return NT_STATUS_OK;
3729 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3730 uint32_t idx, uint32_t collision_type,
3731 uint32_t conflict_type, const char *tdo_name)
3733 struct lsa_ForestTrustCollisionRecord **es;
3734 uint32_t i = c_info->count;
3736 es = talloc_realloc(c_info, c_info->entries,
3737 struct lsa_ForestTrustCollisionRecord *, i + 1);
3739 return NT_STATUS_NO_MEMORY;
3741 c_info->entries = es;
3742 c_info->count = i + 1;
3744 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
3746 return NT_STATUS_NO_MEMORY;
3750 es[i]->type = collision_type;
3751 es[i]->flags.flags = conflict_type;
3752 es[i]->name.string = talloc_strdup(es[i], tdo_name);
3753 if (!es[i]->name.string) {
3754 return NT_STATUS_NO_MEMORY;
3756 es[i]->name.size = strlen(es[i]->name.string);
3758 return NT_STATUS_OK;
3761 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3762 struct pdb_trusted_domain *td,
3763 struct ForestTrustInfo *info)
3765 enum ndr_err_code ndr_err;
3767 if (td->trust_forest_trust_info.length == 0 ||
3768 td->trust_forest_trust_info.data == NULL) {
3769 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3771 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
3773 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3774 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3775 return NT_STATUS_INVALID_DOMAIN_STATE;
3778 return NT_STATUS_OK;
3781 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
3782 struct ForestTrustInfo *fti)
3784 struct ForestTrustDataDomainInfo *info;
3785 struct ForestTrustInfoRecord *rec;
3789 fti->records = talloc_array(fti,
3790 struct ForestTrustInfoRecordArmor, 2);
3791 if (!fti->records) {
3792 return NT_STATUS_NO_MEMORY;
3796 rec = &fti->records[0].record;
3800 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3802 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
3803 if (!rec->data.name.string) {
3804 return NT_STATUS_NO_MEMORY;
3806 rec->data.name.size = strlen(rec->data.name.string);
3809 rec = &fti->records[1].record;
3813 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3815 info = &rec->data.info;
3817 info->sid = dom_info->sid;
3818 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
3819 if (!info->dns_name.string) {
3820 return NT_STATUS_NO_MEMORY;
3822 info->dns_name.size = strlen(info->dns_name.string);
3823 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
3824 if (!info->netbios_name.string) {
3825 return NT_STATUS_NO_MEMORY;
3827 info->netbios_name.size = strlen(info->netbios_name.string);
3829 return NT_STATUS_OK;
3832 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
3833 struct lsa_lsaRSetForestTrustInformation *r)
3838 struct lsa_info *handle;
3839 uint32_t num_domains;
3840 struct pdb_trusted_domain **domains;
3841 struct ForestTrustInfo *nfti;
3842 struct ForestTrustInfo *fti;
3843 struct lsa_ForestTrustCollisionInfo *c_info;
3844 struct pdb_domain_info *dom_info;
3845 enum ndr_err_code ndr_err;
3848 return NT_STATUS_NOT_SUPPORTED;
3851 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
3852 return NT_STATUS_INVALID_HANDLE;
3855 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
3856 return NT_STATUS_INVALID_HANDLE;
3859 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
3860 return NT_STATUS_ACCESS_DENIED;
3863 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
3864 if (!NT_STATUS_IS_OK(status)) {
3867 if (num_domains == 0) {
3868 return NT_STATUS_NO_SUCH_DOMAIN;
3871 for (i = 0; i < num_domains; i++) {
3872 if (domains[i]->domain_name == NULL) {
3873 return NT_STATUS_INVALID_DOMAIN_STATE;
3875 if (StrCaseCmp(domains[i]->domain_name,
3876 r->in.trusted_domain_name->string) == 0) {
3880 if (i >= num_domains) {
3881 return NT_STATUS_NO_SUCH_DOMAIN;
3884 if (!(domains[i]->trust_attributes &
3885 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
3886 return NT_STATUS_INVALID_PARAMETER;
3889 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
3890 return NT_STATUS_INVALID_PARAMETER;
3893 /* The following section until COPY_END is a copy from
3894 * source4/rpmc_server/lsa/scesrc_lsa.c */
3895 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
3897 return NT_STATUS_NO_MEMORY;
3900 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
3901 if (!NT_STATUS_IS_OK(status)) {
3905 c_info = talloc_zero(r->out.collision_info,
3906 struct lsa_ForestTrustCollisionInfo);
3908 return NT_STATUS_NO_MEMORY;
3911 /* first check own info, then other domains */
3912 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3914 return NT_STATUS_NO_MEMORY;
3917 dom_info = pdb_get_domain_info(p->mem_ctx);
3919 status = own_ft_info(dom_info, fti);
3920 if (!NT_STATUS_IS_OK(status)) {
3924 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
3925 if (!NT_STATUS_IS_OK(status)) {
3929 for (j = 0; j < num_domains; j++) {
3930 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3932 return NT_STATUS_NO_MEMORY;
3935 status = get_ft_info(p->mem_ctx, domains[j], fti);
3936 if (!NT_STATUS_IS_OK(status)) {
3937 if (NT_STATUS_EQUAL(status,
3938 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3944 if (domains[j]->domain_name == NULL) {
3945 return NT_STATUS_INVALID_DOMAIN_STATE;
3948 status = check_ft_info(c_info, domains[j]->domain_name,
3950 if (!NT_STATUS_IS_OK(status)) {
3955 *r->out.collision_info = c_info;
3957 if (r->in.check_only != 0) {
3958 return NT_STATUS_OK;
3963 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
3965 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
3966 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3967 return NT_STATUS_INVALID_PARAMETER;
3970 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
3971 if (!NT_STATUS_IS_OK(status)) {
3975 return NT_STATUS_OK;
3978 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
3979 struct lsa_CREDRRENAME *r)
3981 p->rng_fault_state = True;
3982 return NT_STATUS_NOT_IMPLEMENTED;
3985 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
3986 struct lsa_LSAROPENPOLICYSCE *r)
3988 p->rng_fault_state = True;
3989 return NT_STATUS_NOT_IMPLEMENTED;
3992 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
3993 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3995 p->rng_fault_state = True;
3996 return NT_STATUS_NOT_IMPLEMENTED;
3999 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4000 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4002 p->rng_fault_state = True;
4003 return NT_STATUS_NOT_IMPLEMENTED;
4006 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4007 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4009 p->rng_fault_state = True;
4010 return NT_STATUS_NOT_IMPLEMENTED;