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"
47 #include "lib/privileges.h"
50 #define DBGC_CLASS DBGC_RPC_SRV
52 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
54 enum lsa_handle_type {
55 LSA_HANDLE_POLICY_TYPE = 1,
56 LSA_HANDLE_ACCOUNT_TYPE = 2,
57 LSA_HANDLE_TRUST_TYPE = 3};
63 enum lsa_handle_type type;
64 struct security_descriptor *sd;
67 const struct generic_mapping lsa_account_mapping = {
71 LSA_ACCOUNT_ALL_ACCESS
74 const struct generic_mapping lsa_policy_mapping = {
81 const struct generic_mapping lsa_secret_mapping = {
88 const struct generic_mapping lsa_trusted_domain_mapping = {
89 LSA_TRUSTED_DOMAIN_READ,
90 LSA_TRUSTED_DOMAIN_WRITE,
91 LSA_TRUSTED_DOMAIN_EXECUTE,
92 LSA_TRUSTED_DOMAIN_ALL_ACCESS
95 /***************************************************************************
96 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
97 ***************************************************************************/
99 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
100 struct lsa_RefDomainList *ref,
101 const char *dom_name,
102 struct dom_sid *dom_sid)
106 if (dom_name != NULL) {
107 for (num = 0; num < ref->count; num++) {
108 if (dom_sid_equal(dom_sid, ref->domains[num].sid)) {
116 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
117 /* index not found, already at maximum domain limit */
121 ref->count = num + 1;
122 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
124 ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains,
125 struct lsa_DomainInfo, ref->count);
130 ZERO_STRUCT(ref->domains[num]);
132 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
133 ref->domains[num].sid = dom_sid_dup(mem_ctx, dom_sid);
134 if (!ref->domains[num].sid) {
142 /***************************************************************************
143 initialize a lsa_DomainInfo structure.
144 ***************************************************************************/
146 static void init_dom_query_3(struct lsa_DomainInfo *r,
150 init_lsa_StringLarge(&r->name, name);
154 /***************************************************************************
155 initialize a lsa_DomainInfo structure.
156 ***************************************************************************/
158 static void init_dom_query_5(struct lsa_DomainInfo *r,
162 init_lsa_StringLarge(&r->name, name);
166 /***************************************************************************
167 lookup_lsa_rids. Must be called as root for lookup_name to work.
168 ***************************************************************************/
170 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
171 struct lsa_RefDomainList *ref,
172 struct lsa_TranslatedSid *prid,
173 uint32_t num_entries,
174 struct lsa_String *name,
176 uint32_t *pmapped_count)
178 uint32 mapped_count, i;
180 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
185 for (i = 0; i < num_entries; i++) {
189 const char *full_name;
191 enum lsa_SidType type;
193 /* Split name into domain and user component */
195 /* follow w2k8 behavior and return the builtin domain when no
196 * input has been passed in */
198 if (name[i].string) {
199 full_name = name[i].string;
201 full_name = "BUILTIN";
204 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
206 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
208 type = SID_NAME_UNKNOWN;
213 case SID_NAME_DOM_GRP:
214 case SID_NAME_DOMAIN:
216 case SID_NAME_WKN_GRP:
217 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
218 /* Leave these unchanged */
221 /* Don't hand out anything but the list above */
222 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
223 type = SID_NAME_UNKNOWN;
230 if (type != SID_NAME_UNKNOWN) {
231 if (type == SID_NAME_DOMAIN) {
234 sid_split_rid(&sid, &rid);
236 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
240 prid[i].sid_type = type;
242 prid[i].sid_index = dom_idx;
245 *pmapped_count = mapped_count;
249 /***************************************************************************
250 lookup_lsa_sids. Must be called as root for lookup_name to work.
251 ***************************************************************************/
253 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
254 struct lsa_RefDomainList *ref,
255 struct lsa_TranslatedSid3 *trans_sids,
256 uint32_t num_entries,
257 struct lsa_String *name,
259 uint32 *pmapped_count)
261 uint32 mapped_count, i;
263 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
268 for (i = 0; i < num_entries; i++) {
272 const char *full_name;
274 enum lsa_SidType type;
278 /* Split name into domain and user component */
280 full_name = name[i].string;
281 if (full_name == NULL) {
282 return NT_STATUS_NO_MEMORY;
285 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
287 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
289 type = SID_NAME_UNKNOWN;
294 case SID_NAME_DOM_GRP:
295 case SID_NAME_DOMAIN:
297 case SID_NAME_WKN_GRP:
298 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
299 /* Leave these unchanged */
302 /* Don't hand out anything but the list above */
303 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
304 type = SID_NAME_UNKNOWN;
311 if (type != SID_NAME_UNKNOWN) {
312 struct dom_sid domain_sid;
313 sid_copy(&domain_sid, &sid);
314 sid_split_rid(&domain_sid, &rid);
315 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
319 /* Initialize the lsa_TranslatedSid3 return. */
320 trans_sids[i].sid_type = type;
321 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
322 trans_sids[i].sid_index = dom_idx;
325 *pmapped_count = mapped_count;
329 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
330 const struct generic_mapping *map,
331 struct dom_sid *sid, uint32_t sid_access)
333 struct dom_sid adm_sid;
334 struct security_ace ace[5];
337 struct security_acl *psa = NULL;
339 /* READ|EXECUTE access for Everyone */
341 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
342 map->generic_execute | map->generic_read, 0);
344 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
346 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
347 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
348 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
349 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
351 /* Add Full Access for Domain Admins */
352 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
353 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
354 map->generic_all, 0);
356 /* If we have a sid, give it some special access */
359 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
363 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
364 return NT_STATUS_NO_MEMORY;
366 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
367 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
368 psa, sd_size)) == NULL)
369 return NT_STATUS_NO_MEMORY;
374 /***************************************************************************
375 ***************************************************************************/
377 static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
378 struct pipes_struct *p,
379 enum lsa_handle_type type,
380 uint32_t acc_granted,
383 const struct security_descriptor *sd,
384 struct policy_handle *handle)
386 struct lsa_info *info;
388 ZERO_STRUCTP(handle);
390 info = talloc_zero(mem_ctx, struct lsa_info);
392 return NT_STATUS_NO_MEMORY;
396 info->access = acc_granted;
399 sid_copy(&info->sid, sid);
402 info->name = talloc_strdup(info, name);
405 info->sd = dup_sec_desc(info, sd);
408 return NT_STATUS_NO_MEMORY;
412 if (!create_policy_hnd(p, handle, info)) {
414 ZERO_STRUCTP(handle);
415 return NT_STATUS_NO_MEMORY;
421 /***************************************************************************
423 ***************************************************************************/
425 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
426 struct lsa_OpenPolicy2 *r)
428 struct security_descriptor *psd = NULL;
430 uint32 des_access = r->in.access_mask;
434 /* Work out max allowed. */
435 map_max_allowed_access(p->session_info->security_token,
436 &p->session_info->utok,
439 /* map the generic bits to the lsa policy ones */
440 se_map_generic(&des_access, &lsa_policy_mapping);
442 /* get the generic lsa policy SD until we store it */
443 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
445 if (!NT_STATUS_IS_OK(status)) {
449 status = access_check_object(psd, p->session_info->security_token,
450 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
451 &acc_granted, "_lsa_OpenPolicy2" );
452 if (!NT_STATUS_IS_OK(status)) {
456 status = create_lsa_policy_handle(p->mem_ctx, p,
457 LSA_HANDLE_POLICY_TYPE,
459 get_global_sam_sid(),
463 if (!NT_STATUS_IS_OK(status)) {
464 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
470 /***************************************************************************
472 ***************************************************************************/
474 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
475 struct lsa_OpenPolicy *r)
477 struct lsa_OpenPolicy2 o;
479 o.in.system_name = NULL; /* should be ignored */
480 o.in.attr = r->in.attr;
481 o.in.access_mask = r->in.access_mask;
483 o.out.handle = r->out.handle;
485 return _lsa_OpenPolicy2(p, &o);
488 /***************************************************************************
489 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
491 ***************************************************************************/
493 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
494 struct lsa_EnumTrustDom *r)
496 struct lsa_info *info;
498 struct trustdom_info **domains;
499 struct lsa_DomainInfo *entries;
503 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
504 return NT_STATUS_INVALID_HANDLE;
506 if (info->type != LSA_HANDLE_POLICY_TYPE) {
507 return NT_STATUS_INVALID_HANDLE;
510 /* check if the user has enough rights */
511 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
512 return NT_STATUS_ACCESS_DENIED;
515 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
518 if (!NT_STATUS_IS_OK(nt_status)) {
522 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo, count);
524 return NT_STATUS_NO_MEMORY;
527 for (i=0; i<count; i++) {
528 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
529 entries[i].sid = &domains[i]->sid;
532 if (*r->in.resume_handle >= count) {
533 *r->out.resume_handle = -1;
534 TALLOC_FREE(entries);
535 return NT_STATUS_NO_MORE_ENTRIES;
538 /* return the rest, limit by max_size. Note that we
539 use the w2k3 element size value of 60 */
540 r->out.domains->count = count - *r->in.resume_handle;
541 r->out.domains->count = MIN(r->out.domains->count,
542 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
544 r->out.domains->domains = entries + *r->in.resume_handle;
546 if (r->out.domains->count < count - *r->in.resume_handle) {
547 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
548 return STATUS_MORE_ENTRIES;
551 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
552 * always be larger than the previous input resume handle, in
553 * particular when hitting the last query it is vital to set the
554 * resume handle correctly to avoid infinite client loops, as
555 * seen e.g. with Windows XP SP3 when resume handle is 0 and
556 * status is NT_STATUS_OK - gd */
558 *r->out.resume_handle = (uint32_t)-1;
563 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
564 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
565 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
567 /***************************************************************************
569 ***************************************************************************/
571 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
572 struct lsa_QueryInfoPolicy *r)
574 NTSTATUS status = NT_STATUS_OK;
575 struct lsa_info *handle;
576 struct dom_sid domain_sid;
578 struct dom_sid *sid = NULL;
579 union lsa_PolicyInformation *info = NULL;
580 uint32_t acc_required = 0;
582 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
583 return NT_STATUS_INVALID_HANDLE;
585 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
586 return NT_STATUS_INVALID_HANDLE;
589 switch (r->in.level) {
590 case LSA_POLICY_INFO_AUDIT_LOG:
591 case LSA_POLICY_INFO_AUDIT_EVENTS:
592 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
594 case LSA_POLICY_INFO_DOMAIN:
595 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
597 case LSA_POLICY_INFO_PD:
598 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
600 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
601 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
603 case LSA_POLICY_INFO_ROLE:
604 case LSA_POLICY_INFO_REPLICA:
605 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
607 case LSA_POLICY_INFO_QUOTA:
608 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
610 case LSA_POLICY_INFO_MOD:
611 case LSA_POLICY_INFO_AUDIT_FULL_SET:
612 /* according to MS-LSAD 3.1.4.4.3 */
613 return NT_STATUS_INVALID_PARAMETER;
614 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
615 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
617 case LSA_POLICY_INFO_DNS:
618 case LSA_POLICY_INFO_DNS_INT:
619 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
620 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
626 if (!(handle->access & acc_required)) {
627 /* return NT_STATUS_ACCESS_DENIED; */
630 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
632 return NT_STATUS_NO_MEMORY;
635 switch (r->in.level) {
636 /* according to MS-LSAD 3.1.4.4.3 */
637 case LSA_POLICY_INFO_MOD:
638 case LSA_POLICY_INFO_AUDIT_FULL_SET:
639 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
640 return NT_STATUS_INVALID_PARAMETER;
641 case LSA_POLICY_INFO_AUDIT_LOG:
642 info->audit_log.percent_full = 0;
643 info->audit_log.maximum_log_size = 0;
644 info->audit_log.retention_time = 0;
645 info->audit_log.shutdown_in_progress = 0;
646 info->audit_log.time_to_shutdown = 0;
647 info->audit_log.next_audit_record = 0;
648 status = NT_STATUS_OK;
650 case LSA_POLICY_INFO_PD:
651 info->pd.name.string = NULL;
652 status = NT_STATUS_OK;
654 case LSA_POLICY_INFO_REPLICA:
655 info->replica.source.string = NULL;
656 info->replica.account.string = NULL;
657 status = NT_STATUS_OK;
659 case LSA_POLICY_INFO_QUOTA:
660 info->quota.paged_pool = 0;
661 info->quota.non_paged_pool = 0;
662 info->quota.min_wss = 0;
663 info->quota.max_wss = 0;
664 info->quota.pagefile = 0;
665 info->quota.unknown = 0;
666 status = NT_STATUS_OK;
668 case LSA_POLICY_INFO_AUDIT_EVENTS:
671 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
673 /* check if the user has enough rights */
674 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
675 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
676 return NT_STATUS_ACCESS_DENIED;
679 /* fake info: We audit everything. ;) */
681 info->audit_events.auditing_mode = true;
682 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
683 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
684 enum lsa_PolicyAuditPolicy,
685 info->audit_events.count);
686 if (!info->audit_events.settings) {
687 return NT_STATUS_NO_MEMORY;
690 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
691 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
692 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
693 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
694 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
695 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
696 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
700 case LSA_POLICY_INFO_DOMAIN:
701 /* check if the user has enough rights */
702 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
703 return NT_STATUS_ACCESS_DENIED;
705 /* Request PolicyPrimaryDomainInformation. */
706 switch (lp_server_role()) {
707 case ROLE_DOMAIN_PDC:
708 case ROLE_DOMAIN_BDC:
709 name = get_global_sam_name();
710 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
712 return NT_STATUS_NO_MEMORY;
715 case ROLE_DOMAIN_MEMBER:
716 name = lp_workgroup();
717 /* We need to return the Domain SID here. */
718 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
719 sid = dom_sid_dup(p->mem_ctx, &domain_sid);
721 return NT_STATUS_NO_MEMORY;
724 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
727 case ROLE_STANDALONE:
728 name = lp_workgroup();
732 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
734 init_dom_query_3(&info->domain, name, sid);
736 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
737 /* check if the user has enough rights */
738 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
739 return NT_STATUS_ACCESS_DENIED;
741 /* Request PolicyAccountDomainInformation. */
742 name = get_global_sam_name();
743 sid = get_global_sam_sid();
745 init_dom_query_5(&info->account_domain, name, sid);
747 case LSA_POLICY_INFO_ROLE:
748 /* check if the user has enough rights */
749 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
750 return NT_STATUS_ACCESS_DENIED;
752 switch (lp_server_role()) {
753 case ROLE_DOMAIN_BDC:
755 * only a BDC is a backup controller
756 * of the domain, it controls.
758 info->role.role = LSA_ROLE_BACKUP;
762 * any other role is a primary
763 * of the domain, it controls.
765 info->role.role = LSA_ROLE_PRIMARY;
769 case LSA_POLICY_INFO_DNS:
770 case LSA_POLICY_INFO_DNS_INT: {
771 struct pdb_domain_info *dominfo;
773 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
774 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
775 "without ADS passdb backend\n"));
776 status = NT_STATUS_INVALID_INFO_CLASS;
780 dominfo = pdb_get_domain_info(info);
781 if (dominfo == NULL) {
782 status = NT_STATUS_NO_MEMORY;
786 init_lsa_StringLarge(&info->dns.name,
788 init_lsa_StringLarge(&info->dns.dns_domain,
789 dominfo->dns_domain);
790 init_lsa_StringLarge(&info->dns.dns_forest,
791 dominfo->dns_forest);
792 info->dns.domain_guid = dominfo->guid;
793 info->dns.sid = &dominfo->sid;
797 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
799 status = NT_STATUS_INVALID_INFO_CLASS;
808 /***************************************************************************
809 _lsa_QueryInfoPolicy2
810 ***************************************************************************/
812 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
813 struct lsa_QueryInfoPolicy2 *r2)
815 struct lsa_QueryInfoPolicy r;
817 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
818 p->rng_fault_state = True;
819 return NT_STATUS_NOT_IMPLEMENTED;
823 r.in.handle = r2->in.handle;
824 r.in.level = r2->in.level;
825 r.out.info = r2->out.info;
827 return _lsa_QueryInfoPolicy(p, &r);
830 /***************************************************************************
831 _lsa_lookup_sids_internal
832 ***************************************************************************/
834 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
836 uint16_t level, /* input */
837 int num_sids, /* input */
838 struct lsa_SidPtr *sid, /* input */
839 struct lsa_RefDomainList **pp_ref, /* input/output */
840 struct lsa_TranslatedName2 **pp_names,/* input/output */
841 uint32_t *pp_mapped_count) /* input/output */
845 const struct dom_sid **sids = NULL;
846 struct lsa_RefDomainList *ref = NULL;
847 uint32 mapped_count = 0;
848 struct lsa_dom_info *dom_infos = NULL;
849 struct lsa_name_info *name_infos = NULL;
850 struct lsa_TranslatedName2 *names = NULL;
852 *pp_mapped_count = 0;
860 sids = TALLOC_ARRAY(p->mem_ctx, const struct dom_sid *, num_sids);
861 ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
863 if (sids == NULL || ref == NULL) {
864 return NT_STATUS_NO_MEMORY;
867 for (i=0; i<num_sids; i++) {
868 sids[i] = sid[i].sid;
871 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
872 &dom_infos, &name_infos);
874 if (!NT_STATUS_IS_OK(status)) {
878 names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
880 return NT_STATUS_NO_MEMORY;
883 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
885 if (!dom_infos[i].valid) {
889 if (init_lsa_ref_domain_list(mem_ctx, ref,
891 &dom_infos[i].sid) != i) {
892 DEBUG(0, ("Domain %s mentioned twice??\n",
894 return NT_STATUS_INTERNAL_ERROR;
898 for (i=0; i<num_sids; i++) {
899 struct lsa_name_info *name = &name_infos[i];
901 if (name->type == SID_NAME_UNKNOWN) {
903 /* Unknown sids should return the string
904 * representation of the SID. Windows 2003 behaves
905 * rather erratic here, in many cases it returns the
906 * RID as 8 bytes hex, in others it returns the full
907 * SID. We (Jerry/VL) could not figure out which the
908 * hard cases are, so leave it with the SID. */
909 name->name = dom_sid_string(p->mem_ctx, sids[i]);
910 if (name->name == NULL) {
911 return NT_STATUS_NO_MEMORY;
917 names[i].sid_type = name->type;
918 names[i].name.string = name->name;
919 names[i].sid_index = name->dom_idx;
920 names[i].unknown = 0;
923 status = NT_STATUS_NONE_MAPPED;
924 if (mapped_count > 0) {
925 status = (mapped_count < num_sids) ?
926 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
929 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
930 num_sids, mapped_count, nt_errstr(status)));
932 *pp_mapped_count = mapped_count;
939 /***************************************************************************
941 ***************************************************************************/
943 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
944 struct lsa_LookupSids *r)
947 struct lsa_info *handle;
948 int num_sids = r->in.sids->num_sids;
949 uint32 mapped_count = 0;
950 struct lsa_RefDomainList *domains = NULL;
951 struct lsa_TranslatedName *names_out = NULL;
952 struct lsa_TranslatedName2 *names = NULL;
955 if ((r->in.level < 1) || (r->in.level > 6)) {
956 return NT_STATUS_INVALID_PARAMETER;
959 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
960 return NT_STATUS_INVALID_HANDLE;
963 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
964 return NT_STATUS_INVALID_HANDLE;
967 /* check if the user has enough rights */
968 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
969 return NT_STATUS_ACCESS_DENIED;
972 if (num_sids > MAX_LOOKUP_SIDS) {
973 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
974 MAX_LOOKUP_SIDS, num_sids));
975 return NT_STATUS_NONE_MAPPED;
978 status = _lsa_lookup_sids_internal(p,
987 /* Only return here when there is a real error.
988 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
989 the requested sids could be resolved. Older versions of XP (pre SP3)
990 rely that we return with the string representations of those SIDs in
991 that case. If we don't, XP crashes - Guenther
994 if (NT_STATUS_IS_ERR(status) &&
995 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
999 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
1000 names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
1003 return NT_STATUS_NO_MEMORY;
1006 for (i=0; i<num_sids; i++) {
1007 names_out[i].sid_type = names[i].sid_type;
1008 names_out[i].name = names[i].name;
1009 names_out[i].sid_index = names[i].sid_index;
1012 *r->out.domains = domains;
1013 r->out.names->count = num_sids;
1014 r->out.names->names = names_out;
1015 *r->out.count = mapped_count;
1020 /***************************************************************************
1022 ***************************************************************************/
1024 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1025 struct lsa_LookupSids2 *r)
1028 struct lsa_info *handle;
1029 int num_sids = r->in.sids->num_sids;
1030 uint32 mapped_count = 0;
1031 struct lsa_RefDomainList *domains = NULL;
1032 struct lsa_TranslatedName2 *names = NULL;
1033 bool check_policy = true;
1036 case NDR_LSA_LOOKUPSIDS3:
1037 check_policy = false;
1039 case NDR_LSA_LOOKUPSIDS2:
1041 check_policy = true;
1044 if ((r->in.level < 1) || (r->in.level > 6)) {
1045 return NT_STATUS_INVALID_PARAMETER;
1049 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1050 return NT_STATUS_INVALID_HANDLE;
1053 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1054 return NT_STATUS_INVALID_HANDLE;
1057 /* check if the user has enough rights */
1058 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1059 return NT_STATUS_ACCESS_DENIED;
1063 if (num_sids > MAX_LOOKUP_SIDS) {
1064 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1065 MAX_LOOKUP_SIDS, num_sids));
1066 return NT_STATUS_NONE_MAPPED;
1069 status = _lsa_lookup_sids_internal(p,
1078 *r->out.domains = domains;
1079 r->out.names->count = num_sids;
1080 r->out.names->names = names;
1081 *r->out.count = mapped_count;
1086 /***************************************************************************
1088 ***************************************************************************/
1090 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1091 struct lsa_LookupSids3 *r)
1093 struct lsa_LookupSids2 q;
1095 /* No policy handle on this call. Restrict to crypto connections. */
1096 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1097 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1098 get_remote_machine_name() ));
1099 return NT_STATUS_INVALID_PARAMETER;
1103 q.in.sids = r->in.sids;
1104 q.in.level = r->in.level;
1105 q.in.lookup_options = r->in.lookup_options;
1106 q.in.client_revision = r->in.client_revision;
1107 q.in.names = r->in.names;
1108 q.in.count = r->in.count;
1110 q.out.domains = r->out.domains;
1111 q.out.names = r->out.names;
1112 q.out.count = r->out.count;
1114 return _lsa_LookupSids2(p, &q);
1117 /***************************************************************************
1118 ***************************************************************************/
1120 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1125 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1126 flags = LOOKUP_NAME_ALL;
1128 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1129 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1131 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1132 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1134 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1135 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1136 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1137 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1139 flags = LOOKUP_NAME_NONE;
1146 /***************************************************************************
1148 ***************************************************************************/
1150 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1151 struct lsa_LookupNames *r)
1153 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1154 struct lsa_info *handle;
1155 struct lsa_String *names = r->in.names;
1156 uint32 num_entries = r->in.num_names;
1157 struct lsa_RefDomainList *domains = NULL;
1158 struct lsa_TranslatedSid *rids = NULL;
1159 uint32 mapped_count = 0;
1162 if (num_entries > MAX_LOOKUP_SIDS) {
1163 num_entries = MAX_LOOKUP_SIDS;
1164 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1168 flags = lsa_lookup_level_to_flags(r->in.level);
1170 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1172 return NT_STATUS_NO_MEMORY;
1176 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1179 return NT_STATUS_NO_MEMORY;
1185 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1186 status = NT_STATUS_INVALID_HANDLE;
1190 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1191 return NT_STATUS_INVALID_HANDLE;
1194 /* check if the user has enough rights */
1195 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1196 status = NT_STATUS_ACCESS_DENIED;
1200 /* set up the LSA Lookup RIDs response */
1201 become_root(); /* lookup_name can require root privs */
1202 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1203 names, flags, &mapped_count);
1208 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1209 if (mapped_count == 0) {
1210 status = NT_STATUS_NONE_MAPPED;
1211 } else if (mapped_count != num_entries) {
1212 status = STATUS_SOME_UNMAPPED;
1216 *r->out.count = mapped_count;
1217 *r->out.domains = domains;
1218 r->out.sids->sids = rids;
1219 r->out.sids->count = num_entries;
1224 /***************************************************************************
1226 ***************************************************************************/
1228 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1229 struct lsa_LookupNames2 *r)
1232 struct lsa_LookupNames q;
1233 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1234 struct lsa_TransSidArray *sid_array = NULL;
1237 sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1239 return NT_STATUS_NO_MEMORY;
1242 q.in.handle = r->in.handle;
1243 q.in.num_names = r->in.num_names;
1244 q.in.names = r->in.names;
1245 q.in.level = r->in.level;
1246 q.in.sids = sid_array;
1247 q.in.count = r->in.count;
1248 /* we do not know what this is for */
1249 /* = r->in.unknown1; */
1250 /* = r->in.unknown2; */
1252 q.out.domains = r->out.domains;
1253 q.out.sids = sid_array;
1254 q.out.count = r->out.count;
1256 status = _lsa_LookupNames(p, &q);
1258 sid_array2->count = sid_array->count;
1259 sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1260 if (!sid_array2->sids) {
1261 return NT_STATUS_NO_MEMORY;
1264 for (i=0; i<sid_array->count; i++) {
1265 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1266 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1267 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1268 sid_array2->sids[i].unknown = 0;
1271 r->out.sids = sid_array2;
1276 /***************************************************************************
1278 ***************************************************************************/
1280 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1281 struct lsa_LookupNames3 *r)
1284 struct lsa_info *handle;
1285 struct lsa_String *names = r->in.names;
1286 uint32 num_entries = r->in.num_names;
1287 struct lsa_RefDomainList *domains = NULL;
1288 struct lsa_TranslatedSid3 *trans_sids = NULL;
1289 uint32 mapped_count = 0;
1291 bool check_policy = true;
1294 case NDR_LSA_LOOKUPNAMES4:
1295 check_policy = false;
1297 case NDR_LSA_LOOKUPNAMES3:
1299 check_policy = true;
1302 if (num_entries > MAX_LOOKUP_SIDS) {
1303 num_entries = MAX_LOOKUP_SIDS;
1304 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1307 /* Probably the lookup_level is some sort of bitmask. */
1308 if (r->in.level == 1) {
1309 flags = LOOKUP_NAME_ALL;
1312 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1314 return NT_STATUS_NO_MEMORY;
1318 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1321 return NT_STATUS_NO_MEMORY;
1329 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1330 status = NT_STATUS_INVALID_HANDLE;
1334 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1335 return NT_STATUS_INVALID_HANDLE;
1338 /* check if the user has enough rights */
1339 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1340 status = NT_STATUS_ACCESS_DENIED;
1345 /* set up the LSA Lookup SIDs response */
1346 become_root(); /* lookup_name can require root privs */
1347 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1348 names, flags, &mapped_count);
1353 if (NT_STATUS_IS_OK(status)) {
1354 if (mapped_count == 0) {
1355 status = NT_STATUS_NONE_MAPPED;
1356 } else if (mapped_count != num_entries) {
1357 status = STATUS_SOME_UNMAPPED;
1361 *r->out.count = mapped_count;
1362 *r->out.domains = domains;
1363 r->out.sids->sids = trans_sids;
1364 r->out.sids->count = num_entries;
1369 /***************************************************************************
1371 ***************************************************************************/
1373 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1374 struct lsa_LookupNames4 *r)
1376 struct lsa_LookupNames3 q;
1378 /* No policy handle on this call. Restrict to crypto connections. */
1379 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1380 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1381 get_remote_machine_name() ));
1382 return NT_STATUS_INVALID_PARAMETER;
1386 q.in.num_names = r->in.num_names;
1387 q.in.names = r->in.names;
1388 q.in.level = r->in.level;
1389 q.in.lookup_options = r->in.lookup_options;
1390 q.in.client_revision = r->in.client_revision;
1391 q.in.sids = r->in.sids;
1392 q.in.count = r->in.count;
1394 q.out.domains = r->out.domains;
1395 q.out.sids = r->out.sids;
1396 q.out.count = r->out.count;
1398 return _lsa_LookupNames3(p, &q);
1401 /***************************************************************************
1402 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1403 ***************************************************************************/
1405 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1407 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1408 return NT_STATUS_INVALID_HANDLE;
1411 close_policy_hnd(p, r->in.handle);
1412 ZERO_STRUCTP(r->out.handle);
1413 return NT_STATUS_OK;
1416 /***************************************************************************
1417 ***************************************************************************/
1419 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1420 const struct dom_sid *sid,
1421 struct trustdom_info **info)
1424 uint32_t num_domains = 0;
1425 struct trustdom_info **domains = NULL;
1428 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1429 if (!NT_STATUS_IS_OK(status)) {
1433 for (i=0; i < num_domains; i++) {
1434 if (dom_sid_equal(&domains[i]->sid, sid)) {
1439 if (i == num_domains) {
1440 return NT_STATUS_INVALID_PARAMETER;
1445 return NT_STATUS_OK;
1448 /***************************************************************************
1449 ***************************************************************************/
1451 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1452 const char *netbios_domain_name,
1453 struct trustdom_info **info_p)
1456 struct trustdom_info *info;
1457 struct pdb_trusted_domain *td;
1459 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1460 if (!NT_STATUS_IS_OK(status)) {
1464 info = talloc(mem_ctx, struct trustdom_info);
1466 return NT_STATUS_NO_MEMORY;
1469 info->name = talloc_strdup(info, netbios_domain_name);
1470 NT_STATUS_HAVE_NO_MEMORY(info->name);
1472 sid_copy(&info->sid, &td->security_identifier);
1476 return NT_STATUS_OK;
1479 /***************************************************************************
1480 ***************************************************************************/
1482 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p, struct lsa_OpenSecret *r)
1484 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1487 /***************************************************************************
1488 _lsa_OpenTrustedDomain_base
1489 ***************************************************************************/
1491 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1492 uint32_t access_mask,
1493 struct trustdom_info *info,
1494 struct policy_handle *handle)
1496 struct security_descriptor *psd = NULL;
1498 uint32_t acc_granted;
1501 /* des_access is for the account here, not the policy
1502 * handle - so don't check against policy handle. */
1504 /* Work out max allowed. */
1505 map_max_allowed_access(p->session_info->security_token,
1506 &p->session_info->utok,
1509 /* map the generic bits to the lsa account ones */
1510 se_map_generic(&access_mask, &lsa_account_mapping);
1512 /* get the generic lsa account SD until we store it */
1513 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1514 &lsa_trusted_domain_mapping,
1516 if (!NT_STATUS_IS_OK(status)) {
1520 status = access_check_object(psd, p->session_info->security_token,
1521 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1522 access_mask, &acc_granted,
1523 "_lsa_OpenTrustedDomain");
1524 if (!NT_STATUS_IS_OK(status)) {
1528 status = create_lsa_policy_handle(p->mem_ctx, p,
1529 LSA_HANDLE_TRUST_TYPE,
1535 if (!NT_STATUS_IS_OK(status)) {
1536 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1539 return NT_STATUS_OK;
1542 /***************************************************************************
1543 _lsa_OpenTrustedDomain
1544 ***************************************************************************/
1546 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1547 struct lsa_OpenTrustedDomain *r)
1549 struct lsa_info *handle = NULL;
1550 struct trustdom_info *info = NULL;
1553 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1554 return NT_STATUS_INVALID_HANDLE;
1557 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1558 return NT_STATUS_INVALID_HANDLE;
1561 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1564 if (!NT_STATUS_IS_OK(status)) {
1568 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1569 r->out.trustdom_handle);
1572 /***************************************************************************
1573 _lsa_OpenTrustedDomainByName
1574 ***************************************************************************/
1576 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1577 struct lsa_OpenTrustedDomainByName *r)
1579 struct lsa_info *handle = NULL;
1580 struct trustdom_info *info = NULL;
1583 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1584 return NT_STATUS_INVALID_HANDLE;
1587 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1588 return NT_STATUS_INVALID_HANDLE;
1591 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1594 if (!NT_STATUS_IS_OK(status)) {
1598 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1599 r->out.trustdom_handle);
1602 static NTSTATUS add_trusted_domain_user(TALLOC_CTX *mem_ctx,
1603 const char *netbios_name,
1604 const char *domain_name,
1605 const struct trustDomainPasswords *auth_struct)
1608 struct samu *sam_acct;
1611 struct dom_sid user_sid;
1616 sam_acct = samu_new(mem_ctx);
1617 if (sam_acct == NULL) {
1618 return NT_STATUS_NO_MEMORY;
1621 acct_name = talloc_asprintf(mem_ctx, "%s$", netbios_name);
1622 if (acct_name == NULL) {
1623 return NT_STATUS_NO_MEMORY;
1625 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1626 return NT_STATUS_UNSUCCESSFUL;
1629 if (!pdb_set_domain(sam_acct, domain_name, PDB_SET)) {
1630 return NT_STATUS_UNSUCCESSFUL;
1633 if (!pdb_set_acct_ctrl(sam_acct, ACB_DOMTRUST, PDB_SET)) {
1634 return NT_STATUS_UNSUCCESSFUL;
1637 if (!pdb_new_rid(&rid)) {
1638 return NT_STATUS_DS_NO_MORE_RIDS;
1640 sid_compose(&user_sid, get_global_sam_sid(), rid);
1641 if (!pdb_set_user_sid(sam_acct, &user_sid, PDB_SET)) {
1642 return NT_STATUS_UNSUCCESSFUL;
1645 for (i = 0; i < auth_struct->incoming.count; i++) {
1646 switch (auth_struct->incoming.current.array[i].AuthType) {
1647 case TRUST_AUTH_TYPE_CLEAR:
1648 if (!convert_string_talloc(mem_ctx,
1651 auth_struct->incoming.current.array[i].AuthInfo.clear.password,
1652 auth_struct->incoming.current.array[i].AuthInfo.clear.size,
1655 return NT_STATUS_UNSUCCESSFUL;
1657 if (!pdb_set_plaintext_passwd(sam_acct, dummy)) {
1658 return NT_STATUS_UNSUCCESSFUL;
1666 status = pdb_add_sam_account(sam_acct);
1667 if (!NT_STATUS_IS_OK(status)) {
1671 return NT_STATUS_OK;
1674 /***************************************************************************
1675 _lsa_CreateTrustedDomainEx2
1676 ***************************************************************************/
1678 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1679 struct lsa_CreateTrustedDomainEx2 *r)
1681 struct lsa_info *policy;
1683 uint32_t acc_granted;
1684 struct security_descriptor *psd;
1686 struct pdb_trusted_domain td;
1687 struct trustDomainPasswords auth_struct;
1688 enum ndr_err_code ndr_err;
1689 DATA_BLOB auth_blob;
1692 return NT_STATUS_NOT_SUPPORTED;
1695 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1696 return NT_STATUS_INVALID_HANDLE;
1699 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1700 return NT_STATUS_ACCESS_DENIED;
1703 if (p->session_info->utok.uid != sec_initial_uid() &&
1704 !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1705 return NT_STATUS_ACCESS_DENIED;
1708 /* Work out max allowed. */
1709 map_max_allowed_access(p->session_info->security_token,
1710 &p->session_info->utok,
1711 &r->in.access_mask);
1713 /* map the generic bits to the lsa policy ones */
1714 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1716 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1717 &lsa_trusted_domain_mapping,
1719 if (!NT_STATUS_IS_OK(status)) {
1723 status = access_check_object(psd, p->session_info->security_token,
1724 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1725 r->in.access_mask, &acc_granted,
1726 "_lsa_CreateTrustedDomainEx2");
1727 if (!NT_STATUS_IS_OK(status)) {
1733 td.domain_name = talloc_strdup(p->mem_ctx,
1734 r->in.info->domain_name.string);
1735 if (td.domain_name == NULL) {
1736 return NT_STATUS_NO_MEMORY;
1738 td.netbios_name = talloc_strdup(p->mem_ctx,
1739 r->in.info->netbios_name.string);
1740 if (td.netbios_name == NULL) {
1741 return NT_STATUS_NO_MEMORY;
1743 sid_copy(&td.security_identifier, r->in.info->sid);
1744 td.trust_direction = r->in.info->trust_direction;
1745 td.trust_type = r->in.info->trust_type;
1746 td.trust_attributes = r->in.info->trust_attributes;
1748 if (r->in.auth_info->auth_blob.size != 0) {
1749 auth_blob.length = r->in.auth_info->auth_blob.size;
1750 auth_blob.data = r->in.auth_info->auth_blob.data;
1752 arcfour_crypt_blob(auth_blob.data, auth_blob.length,
1753 &p->session_info->user_session_key);
1755 ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
1757 (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
1758 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1759 return NT_STATUS_UNSUCCESSFUL;
1762 ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
1763 &auth_struct.incoming,
1764 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1765 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1766 return NT_STATUS_UNSUCCESSFUL;
1769 ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
1770 &auth_struct.outgoing,
1771 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1772 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1773 return NT_STATUS_UNSUCCESSFUL;
1776 td.trust_auth_incoming.data = NULL;
1777 td.trust_auth_incoming.length = 0;
1778 td.trust_auth_outgoing.data = NULL;
1779 td.trust_auth_outgoing.length = 0;
1782 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1783 if (!NT_STATUS_IS_OK(status)) {
1787 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1788 status = add_trusted_domain_user(p->mem_ctx,
1789 r->in.info->netbios_name.string,
1790 r->in.info->domain_name.string,
1792 if (!NT_STATUS_IS_OK(status)) {
1797 status = create_lsa_policy_handle(p->mem_ctx, p,
1798 LSA_HANDLE_TRUST_TYPE,
1801 r->in.info->netbios_name.string,
1803 r->out.trustdom_handle);
1804 if (!NT_STATUS_IS_OK(status)) {
1805 pdb_del_trusteddom_pw(r->in.info->netbios_name.string);
1806 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1809 return NT_STATUS_OK;
1812 /***************************************************************************
1813 _lsa_CreateTrustedDomainEx
1814 ***************************************************************************/
1816 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1817 struct lsa_CreateTrustedDomainEx *r)
1819 struct lsa_CreateTrustedDomainEx2 q;
1821 q.in.policy_handle = r->in.policy_handle;
1822 q.in.info = r->in.info;
1823 q.in.auth_info = r->in.auth_info;
1824 q.in.access_mask = r->in.access_mask;
1825 q.out.trustdom_handle = r->out.trustdom_handle;
1827 return _lsa_CreateTrustedDomainEx2(p, &q);
1830 /***************************************************************************
1831 _lsa_CreateTrustedDomain
1832 ***************************************************************************/
1834 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1835 struct lsa_CreateTrustedDomain *r)
1837 struct lsa_CreateTrustedDomainEx2 c;
1838 struct lsa_TrustDomainInfoInfoEx info;
1839 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1841 ZERO_STRUCT(auth_info);
1843 info.domain_name = r->in.info->name;
1844 info.netbios_name = r->in.info->name;
1845 info.sid = r->in.info->sid;
1846 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1847 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1848 info.trust_attributes = 0;
1850 c.in.policy_handle = r->in.policy_handle;
1852 c.in.auth_info = &auth_info;
1853 c.in.access_mask = r->in.access_mask;
1854 c.out.trustdom_handle = r->out.trustdom_handle;
1856 return _lsa_CreateTrustedDomainEx2(p, &c);
1859 /***************************************************************************
1860 _lsa_DeleteTrustedDomain
1861 ***************************************************************************/
1863 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1864 struct lsa_DeleteTrustedDomain *r)
1867 struct lsa_info *handle;
1868 struct pdb_trusted_domain *td;
1869 struct samu *sam_acct;
1872 /* find the connection policy handle. */
1873 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1874 return NT_STATUS_INVALID_HANDLE;
1877 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1878 return NT_STATUS_INVALID_HANDLE;
1881 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1882 return NT_STATUS_ACCESS_DENIED;
1885 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1886 if (!NT_STATUS_IS_OK(status)) {
1890 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1891 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1892 sid_string_tos(r->in.dom_sid)));
1893 return NT_STATUS_UNSUCCESSFUL;
1896 if (td->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1897 sam_acct = samu_new(p->mem_ctx);
1898 if (sam_acct == NULL) {
1899 return NT_STATUS_NO_MEMORY;
1902 acct_name = talloc_asprintf(p->mem_ctx, "%s$", td->netbios_name);
1903 if (acct_name == NULL) {
1904 return NT_STATUS_NO_MEMORY;
1906 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1907 return NT_STATUS_UNSUCCESSFUL;
1909 status = pdb_delete_sam_account(sam_acct);
1910 if (!NT_STATUS_IS_OK(status)) {
1915 status = pdb_del_trusted_domain(td->netbios_name);
1916 if (!NT_STATUS_IS_OK(status)) {
1920 return NT_STATUS_OK;
1923 /***************************************************************************
1924 _lsa_CloseTrustedDomainEx
1925 ***************************************************************************/
1927 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1928 struct lsa_CloseTrustedDomainEx *r)
1930 return NT_STATUS_NOT_IMPLEMENTED;
1933 /***************************************************************************
1934 _lsa_QueryTrustedDomainInfo
1935 ***************************************************************************/
1937 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
1938 struct lsa_QueryTrustedDomainInfo *r)
1941 struct lsa_info *handle;
1942 union lsa_TrustedDomainInfo *info;
1943 struct pdb_trusted_domain *td;
1944 uint32_t acc_required;
1946 /* find the connection policy handle. */
1947 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
1948 return NT_STATUS_INVALID_HANDLE;
1951 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
1952 return NT_STATUS_INVALID_HANDLE;
1955 switch (r->in.level) {
1956 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1957 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1959 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1960 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
1962 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1963 acc_required = LSA_TRUSTED_QUERY_POSIX;
1965 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
1966 acc_required = LSA_TRUSTED_QUERY_AUTH;
1968 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1969 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1971 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1972 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1974 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1975 acc_required = LSA_TRUSTED_QUERY_AUTH;
1977 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1978 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1979 LSA_TRUSTED_QUERY_POSIX |
1980 LSA_TRUSTED_QUERY_AUTH;
1982 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1983 acc_required = LSA_TRUSTED_QUERY_AUTH;
1985 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1986 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1987 LSA_TRUSTED_QUERY_POSIX |
1988 LSA_TRUSTED_QUERY_AUTH;
1990 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1991 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1993 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1994 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1995 LSA_TRUSTED_QUERY_POSIX |
1996 LSA_TRUSTED_QUERY_AUTH;
1998 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1999 acc_required = LSA_TRUSTED_QUERY_POSIX;
2002 return NT_STATUS_INVALID_PARAMETER;
2005 if (!(handle->access & acc_required)) {
2006 return NT_STATUS_ACCESS_DENIED;
2009 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2010 if (!NT_STATUS_IS_OK(status)) {
2014 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_TrustedDomainInfo);
2016 return NT_STATUS_NO_MEMORY;
2019 switch (r->in.level) {
2020 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2021 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2023 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2024 return NT_STATUS_INVALID_PARAMETER;
2025 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2027 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2028 return NT_STATUS_INVALID_INFO_CLASS;
2029 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2030 return NT_STATUS_INVALID_PARAMETER;
2031 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2032 init_lsa_StringLarge(&info->info_ex.domain_name, td->domain_name);
2033 init_lsa_StringLarge(&info->info_ex.netbios_name, td->netbios_name);
2034 info->info_ex.sid = dom_sid_dup(info, &td->security_identifier);
2035 if (!info->info_ex.sid) {
2036 return NT_STATUS_NO_MEMORY;
2038 info->info_ex.trust_direction = td->trust_direction;
2039 info->info_ex.trust_type = td->trust_type;
2040 info->info_ex.trust_attributes = td->trust_attributes;
2042 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2043 return NT_STATUS_INVALID_INFO_CLASS;
2044 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2046 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2047 return NT_STATUS_INVALID_INFO_CLASS;
2048 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2049 return NT_STATUS_INVALID_INFO_CLASS;
2050 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2051 return NT_STATUS_INVALID_PARAMETER;
2052 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2054 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2057 return NT_STATUS_INVALID_PARAMETER;
2060 *r->out.info = info;
2062 return NT_STATUS_OK;
2065 /***************************************************************************
2066 _lsa_QueryTrustedDomainInfoBySid
2067 ***************************************************************************/
2069 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2070 struct lsa_QueryTrustedDomainInfoBySid *r)
2073 struct policy_handle trustdom_handle;
2074 struct lsa_OpenTrustedDomain o;
2075 struct lsa_QueryTrustedDomainInfo q;
2078 o.in.handle = r->in.handle;
2079 o.in.sid = r->in.dom_sid;
2080 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2081 o.out.trustdom_handle = &trustdom_handle;
2083 status = _lsa_OpenTrustedDomain(p, &o);
2084 if (!NT_STATUS_IS_OK(status)) {
2088 q.in.trustdom_handle = &trustdom_handle;
2089 q.in.level = r->in.level;
2090 q.out.info = r->out.info;
2092 status = _lsa_QueryTrustedDomainInfo(p, &q);
2093 if (!NT_STATUS_IS_OK(status)) {
2097 c.in.handle = &trustdom_handle;
2098 c.out.handle = &trustdom_handle;
2100 return _lsa_Close(p, &c);
2103 /***************************************************************************
2104 _lsa_QueryTrustedDomainInfoByName
2105 ***************************************************************************/
2107 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2108 struct lsa_QueryTrustedDomainInfoByName *r)
2111 struct policy_handle trustdom_handle;
2112 struct lsa_OpenTrustedDomainByName o;
2113 struct lsa_QueryTrustedDomainInfo q;
2116 o.in.handle = r->in.handle;
2117 o.in.name.string = r->in.trusted_domain->string;
2118 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2119 o.out.trustdom_handle = &trustdom_handle;
2121 status = _lsa_OpenTrustedDomainByName(p, &o);
2122 if (!NT_STATUS_IS_OK(status)) {
2123 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2124 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2129 q.in.trustdom_handle = &trustdom_handle;
2130 q.in.level = r->in.level;
2131 q.out.info = r->out.info;
2133 status = _lsa_QueryTrustedDomainInfo(p, &q);
2134 if (!NT_STATUS_IS_OK(status)) {
2138 c.in.handle = &trustdom_handle;
2139 c.out.handle = &trustdom_handle;
2141 return _lsa_Close(p, &c);
2144 /***************************************************************************
2145 ***************************************************************************/
2147 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p, struct lsa_CreateSecret *r)
2149 return NT_STATUS_ACCESS_DENIED;
2152 /***************************************************************************
2153 ***************************************************************************/
2155 NTSTATUS _lsa_SetSecret(struct pipes_struct *p, struct lsa_SetSecret *r)
2157 return NT_STATUS_ACCESS_DENIED;
2160 /***************************************************************************
2162 ***************************************************************************/
2164 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2165 struct lsa_DeleteObject *r)
2168 struct lsa_info *info = NULL;
2170 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2171 return NT_STATUS_INVALID_HANDLE;
2174 if (!(info->access & SEC_STD_DELETE)) {
2175 return NT_STATUS_ACCESS_DENIED;
2178 switch (info->type) {
2179 case LSA_HANDLE_ACCOUNT_TYPE:
2180 status = privilege_delete_account(&info->sid);
2181 if (!NT_STATUS_IS_OK(status)) {
2182 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2183 nt_errstr(status)));
2188 return NT_STATUS_INVALID_HANDLE;
2191 close_policy_hnd(p, r->in.handle);
2192 ZERO_STRUCTP(r->out.handle);
2197 /***************************************************************************
2199 ***************************************************************************/
2201 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2202 struct lsa_EnumPrivs *r)
2204 struct lsa_info *handle;
2206 uint32 enum_context = *r->in.resume_handle;
2207 int num_privs = num_privileges_in_short_list();
2208 struct lsa_PrivEntry *entries = NULL;
2210 /* remember that the enum_context starts at 0 and not 1 */
2212 if ( enum_context >= num_privs )
2213 return NT_STATUS_NO_MORE_ENTRIES;
2215 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2216 enum_context, num_privs));
2218 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2219 return NT_STATUS_INVALID_HANDLE;
2221 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2222 return NT_STATUS_INVALID_HANDLE;
2225 /* check if the user has enough rights
2226 I don't know if it's the right one. not documented. */
2228 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2229 return NT_STATUS_ACCESS_DENIED;
2232 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2234 return NT_STATUS_NO_MEMORY;
2240 for (i = 0; i < num_privs; i++) {
2241 if( i < enum_context) {
2243 init_lsa_StringLarge(&entries[i].name, NULL);
2245 entries[i].luid.low = 0;
2246 entries[i].luid.high = 0;
2249 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2251 entries[i].luid.low = sec_privilege_from_index(i);
2252 entries[i].luid.high = 0;
2256 enum_context = num_privs;
2258 *r->out.resume_handle = enum_context;
2259 r->out.privs->count = num_privs;
2260 r->out.privs->privs = entries;
2262 return NT_STATUS_OK;
2265 /***************************************************************************
2266 _lsa_LookupPrivDisplayName
2267 ***************************************************************************/
2269 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2270 struct lsa_LookupPrivDisplayName *r)
2272 struct lsa_info *handle;
2273 const char *description;
2274 struct lsa_StringLarge *lsa_name;
2276 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2277 return NT_STATUS_INVALID_HANDLE;
2279 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2280 return NT_STATUS_INVALID_HANDLE;
2283 /* check if the user has enough rights */
2286 * I don't know if it's the right one. not documented.
2288 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2289 return NT_STATUS_ACCESS_DENIED;
2291 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2293 description = get_privilege_dispname(r->in.name->string);
2295 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2296 return NT_STATUS_NO_SUCH_PRIVILEGE;
2299 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2301 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2303 return NT_STATUS_NO_MEMORY;
2306 init_lsa_StringLarge(lsa_name, description);
2308 *r->out.returned_language_id = r->in.language_id;
2309 *r->out.disp_name = lsa_name;
2311 return NT_STATUS_OK;
2314 /***************************************************************************
2316 ***************************************************************************/
2318 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2319 struct lsa_EnumAccounts *r)
2321 struct lsa_info *handle;
2322 struct dom_sid *sid_list;
2323 int i, j, num_entries;
2325 struct lsa_SidPtr *sids = NULL;
2327 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2328 return NT_STATUS_INVALID_HANDLE;
2330 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2331 return NT_STATUS_INVALID_HANDLE;
2334 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2335 return NT_STATUS_ACCESS_DENIED;
2340 /* The only way we can currently find out all the SIDs that have been
2341 privileged is to scan all privileges */
2343 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2344 if (!NT_STATUS_IS_OK(status)) {
2348 if (*r->in.resume_handle >= num_entries) {
2349 return NT_STATUS_NO_MORE_ENTRIES;
2352 if (num_entries - *r->in.resume_handle) {
2353 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
2354 num_entries - *r->in.resume_handle);
2356 talloc_free(sid_list);
2357 return NT_STATUS_NO_MEMORY;
2360 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2361 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2363 talloc_free(sid_list);
2364 return NT_STATUS_NO_MEMORY;
2369 talloc_free(sid_list);
2371 *r->out.resume_handle = num_entries;
2372 r->out.sids->num_sids = num_entries;
2373 r->out.sids->sids = sids;
2375 return NT_STATUS_OK;
2378 /***************************************************************************
2380 ***************************************************************************/
2382 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2383 struct lsa_GetUserName *r)
2385 const char *username, *domname;
2386 struct lsa_String *account_name = NULL;
2387 struct lsa_String *authority_name = NULL;
2389 if (r->in.account_name &&
2390 *r->in.account_name) {
2391 return NT_STATUS_INVALID_PARAMETER;
2394 if (r->in.authority_name &&
2395 *r->in.authority_name) {
2396 return NT_STATUS_INVALID_PARAMETER;
2399 if (p->session_info->guest) {
2401 * I'm 99% sure this is not the right place to do this,
2402 * global_sid_Anonymous should probably be put into the token
2403 * instead of the guest id -- vl
2405 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2406 &domname, &username, NULL)) {
2407 return NT_STATUS_NO_MEMORY;
2410 username = p->session_info->sanitized_username;
2411 domname = p->session_info->info3->base.domain.string;
2414 account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2415 if (!account_name) {
2416 return NT_STATUS_NO_MEMORY;
2418 init_lsa_String(account_name, username);
2420 if (r->out.authority_name) {
2421 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2422 if (!authority_name) {
2423 return NT_STATUS_NO_MEMORY;
2425 init_lsa_String(authority_name, domname);
2428 *r->out.account_name = account_name;
2429 if (r->out.authority_name) {
2430 *r->out.authority_name = authority_name;
2433 return NT_STATUS_OK;
2436 /***************************************************************************
2438 ***************************************************************************/
2440 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2441 struct lsa_CreateAccount *r)
2444 struct lsa_info *handle;
2445 uint32_t acc_granted;
2446 struct security_descriptor *psd;
2449 /* find the connection policy handle. */
2450 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2451 return NT_STATUS_INVALID_HANDLE;
2453 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2454 return NT_STATUS_INVALID_HANDLE;
2457 /* check if the user has enough rights */
2459 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2460 return NT_STATUS_ACCESS_DENIED;
2463 /* Work out max allowed. */
2464 map_max_allowed_access(p->session_info->security_token,
2465 &p->session_info->utok,
2466 &r->in.access_mask);
2468 /* map the generic bits to the lsa policy ones */
2469 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2471 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2472 &lsa_account_mapping,
2473 r->in.sid, LSA_POLICY_ALL_ACCESS);
2474 if (!NT_STATUS_IS_OK(status)) {
2478 status = access_check_object(psd, p->session_info->security_token,
2479 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2480 &acc_granted, "_lsa_CreateAccount");
2481 if (!NT_STATUS_IS_OK(status)) {
2485 if ( is_privileged_sid( r->in.sid ) )
2486 return NT_STATUS_OBJECT_NAME_COLLISION;
2488 status = create_lsa_policy_handle(p->mem_ctx, p,
2489 LSA_HANDLE_ACCOUNT_TYPE,
2494 r->out.acct_handle);
2495 if (!NT_STATUS_IS_OK(status)) {
2496 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2499 return privilege_create_account(r->in.sid);
2502 /***************************************************************************
2504 ***************************************************************************/
2506 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2507 struct lsa_OpenAccount *r)
2509 struct lsa_info *handle;
2510 struct security_descriptor *psd = NULL;
2512 uint32_t des_access = r->in.access_mask;
2513 uint32_t acc_granted;
2516 /* find the connection policy handle. */
2517 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2518 return NT_STATUS_INVALID_HANDLE;
2520 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2521 return NT_STATUS_INVALID_HANDLE;
2524 /* des_access is for the account here, not the policy
2525 * handle - so don't check against policy handle. */
2527 /* Work out max allowed. */
2528 map_max_allowed_access(p->session_info->security_token,
2529 &p->session_info->utok,
2532 /* map the generic bits to the lsa account ones */
2533 se_map_generic(&des_access, &lsa_account_mapping);
2535 /* get the generic lsa account SD until we store it */
2536 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2537 &lsa_account_mapping,
2538 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2539 if (!NT_STATUS_IS_OK(status)) {
2543 status = access_check_object(psd, p->session_info->security_token,
2544 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2545 &acc_granted, "_lsa_OpenAccount" );
2546 if (!NT_STATUS_IS_OK(status)) {
2550 /* TODO: Fis the parsing routine before reenabling this check! */
2552 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2553 return NT_STATUS_ACCESS_DENIED;
2556 status = create_lsa_policy_handle(p->mem_ctx, p,
2557 LSA_HANDLE_ACCOUNT_TYPE,
2562 r->out.acct_handle);
2563 if (!NT_STATUS_IS_OK(status)) {
2564 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2567 return NT_STATUS_OK;
2570 /***************************************************************************
2571 _lsa_EnumPrivsAccount
2572 For a given SID, enumerate all the privilege this account has.
2573 ***************************************************************************/
2575 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2576 struct lsa_EnumPrivsAccount *r)
2578 NTSTATUS status = NT_STATUS_OK;
2579 struct lsa_info *info=NULL;
2580 PRIVILEGE_SET *privileges;
2581 struct lsa_PrivilegeSet *priv_set = NULL;
2583 /* find the connection policy handle. */
2584 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2585 return NT_STATUS_INVALID_HANDLE;
2587 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2588 return NT_STATUS_INVALID_HANDLE;
2591 if (!(info->access & LSA_ACCOUNT_VIEW))
2592 return NT_STATUS_ACCESS_DENIED;
2594 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2595 if (!NT_STATUS_IS_OK(status)) {
2599 *r->out.privs = priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
2601 return NT_STATUS_NO_MEMORY;
2604 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2605 sid_string_dbg(&info->sid),
2606 privileges->count));
2608 priv_set->count = privileges->count;
2609 priv_set->unknown = 0;
2610 priv_set->set = talloc_move(priv_set, &privileges->set);
2615 /***************************************************************************
2616 _lsa_GetSystemAccessAccount
2617 ***************************************************************************/
2619 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2620 struct lsa_GetSystemAccessAccount *r)
2623 struct lsa_info *info = NULL;
2624 struct lsa_EnumPrivsAccount e;
2625 struct lsa_PrivilegeSet *privset;
2627 /* find the connection policy handle. */
2629 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2630 return NT_STATUS_INVALID_HANDLE;
2632 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2633 return NT_STATUS_INVALID_HANDLE;
2636 if (!(info->access & LSA_ACCOUNT_VIEW))
2637 return NT_STATUS_ACCESS_DENIED;
2639 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2641 return NT_STATUS_NO_MEMORY;
2644 e.in.handle = r->in.handle;
2645 e.out.privs = &privset;
2647 status = _lsa_EnumPrivsAccount(p, &e);
2648 if (!NT_STATUS_IS_OK(status)) {
2649 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2650 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2651 nt_errstr(status)));
2655 /* Samba4 would iterate over the privset to merge the policy mode bits,
2656 * not sure samba3 can do the same here, so just return what we did in
2660 0x01 -> Log on locally
2661 0x02 -> Access this computer from network
2662 0x04 -> Log on as a batch job
2663 0x10 -> Log on as a service
2665 they can be ORed together
2668 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2669 LSA_POLICY_MODE_NETWORK;
2671 return NT_STATUS_OK;
2674 /***************************************************************************
2675 update the systemaccount information
2676 ***************************************************************************/
2678 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2679 struct lsa_SetSystemAccessAccount *r)
2681 struct lsa_info *info=NULL;
2684 /* find the connection policy handle. */
2685 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2686 return NT_STATUS_INVALID_HANDLE;
2688 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2689 return NT_STATUS_INVALID_HANDLE;
2692 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2693 return NT_STATUS_ACCESS_DENIED;
2696 if (!pdb_getgrsid(&map, info->sid))
2697 return NT_STATUS_NO_SUCH_GROUP;
2699 return pdb_update_group_mapping_entry(&map);
2702 /***************************************************************************
2703 _lsa_AddPrivilegesToAccount
2704 For a given SID, add some privileges.
2705 ***************************************************************************/
2707 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
2708 struct lsa_AddPrivilegesToAccount *r)
2710 struct lsa_info *info = NULL;
2711 struct lsa_PrivilegeSet *set = NULL;
2713 /* find the connection policy handle. */
2714 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2715 return NT_STATUS_INVALID_HANDLE;
2717 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2718 return NT_STATUS_INVALID_HANDLE;
2721 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2722 return NT_STATUS_ACCESS_DENIED;
2727 if ( !grant_privilege_set( &info->sid, set ) ) {
2728 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2729 sid_string_dbg(&info->sid) ));
2730 return NT_STATUS_NO_SUCH_PRIVILEGE;
2733 return NT_STATUS_OK;
2736 /***************************************************************************
2737 _lsa_RemovePrivilegesFromAccount
2738 For a given SID, remove some privileges.
2739 ***************************************************************************/
2741 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2742 struct lsa_RemovePrivilegesFromAccount *r)
2744 struct lsa_info *info = NULL;
2745 struct lsa_PrivilegeSet *set = NULL;
2747 /* find the connection policy handle. */
2748 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2749 return NT_STATUS_INVALID_HANDLE;
2751 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2752 return NT_STATUS_INVALID_HANDLE;
2755 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2756 return NT_STATUS_ACCESS_DENIED;
2761 if ( !revoke_privilege_set( &info->sid, set) ) {
2762 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2763 sid_string_dbg(&info->sid) ));
2764 return NT_STATUS_NO_SUCH_PRIVILEGE;
2767 return NT_STATUS_OK;
2770 /***************************************************************************
2772 ***************************************************************************/
2774 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2775 struct lsa_LookupPrivName *r)
2777 struct lsa_info *info = NULL;
2779 struct lsa_StringLarge *lsa_name;
2781 /* find the connection policy handle. */
2782 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2783 return NT_STATUS_INVALID_HANDLE;
2786 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2787 return NT_STATUS_INVALID_HANDLE;
2790 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2791 return NT_STATUS_ACCESS_DENIED;
2794 if (r->in.luid->high != 0) {
2795 return NT_STATUS_NO_SUCH_PRIVILEGE;
2798 name = sec_privilege_name(r->in.luid->low);
2800 return NT_STATUS_NO_SUCH_PRIVILEGE;
2803 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2805 return NT_STATUS_NO_MEMORY;
2808 lsa_name->string = talloc_strdup(lsa_name, name);
2809 if (!lsa_name->string) {
2810 TALLOC_FREE(lsa_name);
2811 return NT_STATUS_NO_MEMORY;
2814 *r->out.name = lsa_name;
2816 return NT_STATUS_OK;
2819 /***************************************************************************
2821 ***************************************************************************/
2823 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
2824 struct lsa_QuerySecurity *r)
2826 struct lsa_info *handle=NULL;
2827 struct security_descriptor *psd = NULL;
2831 /* find the connection policy handle. */
2832 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2833 return NT_STATUS_INVALID_HANDLE;
2835 switch (handle->type) {
2836 case LSA_HANDLE_POLICY_TYPE:
2837 case LSA_HANDLE_ACCOUNT_TYPE:
2838 case LSA_HANDLE_TRUST_TYPE:
2840 sd_size = ndr_size_security_descriptor(psd, 0);
2841 status = NT_STATUS_OK;
2844 status = NT_STATUS_INVALID_HANDLE;
2848 if (!NT_STATUS_IS_OK(status)) {
2852 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2853 if (!*r->out.sdbuf) {
2854 return NT_STATUS_NO_MEMORY;
2860 /***************************************************************************
2861 _lsa_AddAccountRights
2862 ***************************************************************************/
2864 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
2865 struct lsa_AddAccountRights *r)
2867 struct lsa_info *info = NULL;
2869 uint32_t acc_granted = 0;
2870 struct security_descriptor *psd = NULL;
2875 /* find the connection policy handle. */
2876 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2877 return NT_STATUS_INVALID_HANDLE;
2879 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2880 return NT_STATUS_INVALID_HANDLE;
2883 /* get the generic lsa account SD for this SID until we store it */
2884 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2885 &lsa_account_mapping,
2886 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2887 if (!NT_STATUS_IS_OK(status)) {
2892 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2893 * on the policy handle. If it does, ask for
2894 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2895 * on the account sid. We don't check here so just use the latter. JRA.
2898 status = access_check_object(psd, p->session_info->security_token,
2899 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2900 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2901 &acc_granted, "_lsa_AddAccountRights" );
2902 if (!NT_STATUS_IS_OK(status)) {
2906 /* according to an NT4 PDC, you can add privileges to SIDs even without
2907 call_lsa_create_account() first. And you can use any arbitrary SID. */
2909 sid_copy( &sid, r->in.sid );
2911 for ( i=0; i < r->in.rights->count; i++ ) {
2913 const char *privname = r->in.rights->names[i].string;
2915 /* only try to add non-null strings */
2920 if ( !grant_privilege_by_name( &sid, privname ) ) {
2921 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2923 return NT_STATUS_NO_SUCH_PRIVILEGE;
2927 return NT_STATUS_OK;
2930 /***************************************************************************
2931 _lsa_RemoveAccountRights
2932 ***************************************************************************/
2934 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
2935 struct lsa_RemoveAccountRights *r)
2937 struct lsa_info *info = NULL;
2939 struct security_descriptor *psd = NULL;
2942 const char *privname = NULL;
2943 uint32_t acc_granted = 0;
2946 /* find the connection policy handle. */
2947 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2948 return NT_STATUS_INVALID_HANDLE;
2950 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2951 return NT_STATUS_INVALID_HANDLE;
2954 /* get the generic lsa account SD for this SID until we store it */
2955 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2956 &lsa_account_mapping,
2957 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2958 if (!NT_STATUS_IS_OK(status)) {
2963 * From the MS DOCs. We need
2964 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2965 * and DELETE on the account sid.
2968 status = access_check_object(psd, p->session_info->security_token,
2969 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2970 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2971 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
2972 &acc_granted, "_lsa_RemoveAccountRights");
2973 if (!NT_STATUS_IS_OK(status)) {
2977 sid_copy( &sid, r->in.sid );
2979 if ( r->in.remove_all ) {
2980 if ( !revoke_all_privileges( &sid ) )
2981 return NT_STATUS_ACCESS_DENIED;
2983 return NT_STATUS_OK;
2986 for ( i=0; i < r->in.rights->count; i++ ) {
2988 privname = r->in.rights->names[i].string;
2990 /* only try to add non-null strings */
2995 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2996 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2998 return NT_STATUS_NO_SUCH_PRIVILEGE;
3002 return NT_STATUS_OK;
3005 /*******************************************************************
3006 ********************************************************************/
3008 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3009 struct lsa_RightSet *r,
3010 PRIVILEGE_SET *privileges)
3013 const char *privname;
3014 const char **privname_array = NULL;
3017 for (i=0; i<privileges->count; i++) {
3018 if (privileges->set[i].luid.high) {
3021 privname = sec_privilege_name(privileges->set[i].luid.low);
3023 if (!add_string_to_array(mem_ctx, privname,
3024 &privname_array, &num_priv)) {
3025 return NT_STATUS_NO_MEMORY;
3032 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
3035 return NT_STATUS_NO_MEMORY;
3038 for (i=0; i<num_priv; i++) {
3039 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3042 r->count = num_priv;
3045 return NT_STATUS_OK;
3048 /***************************************************************************
3049 _lsa_EnumAccountRights
3050 ***************************************************************************/
3052 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3053 struct lsa_EnumAccountRights *r)
3056 struct lsa_info *info = NULL;
3057 PRIVILEGE_SET *privileges;
3059 /* find the connection policy handle. */
3061 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3062 return NT_STATUS_INVALID_HANDLE;
3064 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3065 return NT_STATUS_INVALID_HANDLE;
3068 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3069 return NT_STATUS_ACCESS_DENIED;
3072 /* according to an NT4 PDC, you can add privileges to SIDs even without
3073 call_lsa_create_account() first. And you can use any arbitrary SID. */
3075 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3076 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3077 * the lsa database */
3079 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3080 if (!NT_STATUS_IS_OK(status)) {
3084 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3085 sid_string_dbg(r->in.sid), privileges->count));
3087 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3092 /***************************************************************************
3093 _lsa_LookupPrivValue
3094 ***************************************************************************/
3096 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3097 struct lsa_LookupPrivValue *r)
3099 struct lsa_info *info = NULL;
3100 const char *name = NULL;
3102 /* find the connection policy handle. */
3104 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3105 return NT_STATUS_INVALID_HANDLE;
3107 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3108 return NT_STATUS_INVALID_HANDLE;
3111 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3112 return NT_STATUS_ACCESS_DENIED;
3114 name = r->in.name->string;
3116 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3118 r->out.luid->low = sec_privilege_id(name);
3119 r->out.luid->high = 0;
3120 if (r->out.luid->low == SEC_PRIV_INVALID) {
3121 return NT_STATUS_NO_SUCH_PRIVILEGE;
3123 return NT_STATUS_OK;
3126 /***************************************************************************
3127 _lsa_EnumAccountsWithUserRight
3128 ***************************************************************************/
3130 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3131 struct lsa_EnumAccountsWithUserRight *r)
3134 struct lsa_info *info = NULL;
3135 struct dom_sid *sids = NULL;
3138 enum sec_privilege privilege;
3140 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3141 return NT_STATUS_INVALID_HANDLE;
3144 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3145 return NT_STATUS_INVALID_HANDLE;
3148 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3149 return NT_STATUS_ACCESS_DENIED;
3152 if (!r->in.name || !r->in.name->string) {
3153 return NT_STATUS_NO_SUCH_PRIVILEGE;
3156 privilege = sec_privilege_id(r->in.name->string);
3157 if (privilege == SEC_PRIV_INVALID) {
3158 return NT_STATUS_NO_SUCH_PRIVILEGE;
3161 status = privilege_enum_sids(privilege, p->mem_ctx,
3163 if (!NT_STATUS_IS_OK(status)) {
3167 r->out.sids->num_sids = num_sids;
3168 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3169 r->out.sids->num_sids);
3171 for (i=0; i < r->out.sids->num_sids; i++) {
3172 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3174 if (!r->out.sids->sids[i].sid) {
3175 TALLOC_FREE(r->out.sids->sids);
3176 r->out.sids->num_sids = 0;
3177 return NT_STATUS_NO_MEMORY;
3181 return NT_STATUS_OK;
3184 /***************************************************************************
3186 ***************************************************************************/
3188 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3189 struct lsa_Delete *r)
3191 return NT_STATUS_NOT_SUPPORTED;
3195 * From here on the server routines are just dummy ones to make smbd link with
3196 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3197 * pulling the server stubs across one by one.
3200 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3202 p->rng_fault_state = True;
3203 return NT_STATUS_NOT_IMPLEMENTED;
3206 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3207 struct lsa_ChangePassword *r)
3209 p->rng_fault_state = True;
3210 return NT_STATUS_NOT_IMPLEMENTED;
3213 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3215 p->rng_fault_state = True;
3216 return NT_STATUS_NOT_IMPLEMENTED;
3219 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3221 p->rng_fault_state = True;
3222 return NT_STATUS_NOT_IMPLEMENTED;
3225 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3226 struct lsa_GetQuotasForAccount *r)
3228 p->rng_fault_state = True;
3229 return NT_STATUS_NOT_IMPLEMENTED;
3232 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3233 struct lsa_SetQuotasForAccount *r)
3235 p->rng_fault_state = True;
3236 return NT_STATUS_NOT_IMPLEMENTED;
3239 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3240 struct lsa_SetInformationTrustedDomain *r)
3242 p->rng_fault_state = True;
3243 return NT_STATUS_NOT_IMPLEMENTED;
3246 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
3248 p->rng_fault_state = True;
3249 return NT_STATUS_NOT_IMPLEMENTED;
3252 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3253 struct lsa_SetTrustedDomainInfo *r)
3255 p->rng_fault_state = True;
3256 return NT_STATUS_NOT_IMPLEMENTED;
3259 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3260 struct lsa_StorePrivateData *r)
3262 p->rng_fault_state = True;
3263 return NT_STATUS_NOT_IMPLEMENTED;
3266 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3267 struct lsa_RetrievePrivateData *r)
3269 p->rng_fault_state = True;
3270 return NT_STATUS_NOT_IMPLEMENTED;
3273 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3274 struct lsa_SetInfoPolicy2 *r)
3276 p->rng_fault_state = True;
3277 return NT_STATUS_NOT_IMPLEMENTED;
3280 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3281 struct lsa_SetTrustedDomainInfoByName *r)
3283 p->rng_fault_state = True;
3284 return NT_STATUS_NOT_IMPLEMENTED;
3287 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3288 struct lsa_EnumTrustedDomainsEx *r)
3290 struct lsa_info *info;
3292 struct pdb_trusted_domain **domains;
3293 struct lsa_TrustDomainInfoInfoEx *entries;
3297 /* bail out early if pdb backend is not capable of ex trusted domains,
3298 * if we dont do that, the client might not call
3299 * _lsa_EnumTrustedDomains() afterwards - gd */
3301 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3302 p->rng_fault_state = True;
3303 return NT_STATUS_NOT_IMPLEMENTED;
3306 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3307 return NT_STATUS_INVALID_HANDLE;
3309 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3310 return NT_STATUS_INVALID_HANDLE;
3313 /* check if the user has enough rights */
3314 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3315 return NT_STATUS_ACCESS_DENIED;
3318 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3321 if (!NT_STATUS_IS_OK(nt_status)) {
3325 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3328 return NT_STATUS_NO_MEMORY;
3331 for (i=0; i<count; i++) {
3332 init_lsa_StringLarge(&entries[i].netbios_name,
3333 domains[i]->netbios_name);
3334 entries[i].sid = &domains[i]->security_identifier;
3337 if (*r->in.resume_handle >= count) {
3338 *r->out.resume_handle = -1;
3339 TALLOC_FREE(entries);
3340 return NT_STATUS_NO_MORE_ENTRIES;
3343 /* return the rest, limit by max_size. Note that we
3344 use the w2k3 element size value of 60 */
3345 r->out.domains->count = count - *r->in.resume_handle;
3346 r->out.domains->count = MIN(r->out.domains->count,
3347 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3349 r->out.domains->domains = entries + *r->in.resume_handle;
3351 if (r->out.domains->count < count - *r->in.resume_handle) {
3352 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3353 return STATUS_MORE_ENTRIES;
3356 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3357 * always be larger than the previous input resume handle, in
3358 * particular when hitting the last query it is vital to set the
3359 * resume handle correctly to avoid infinite client loops, as
3360 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3361 * status is NT_STATUS_OK - gd */
3363 *r->out.resume_handle = (uint32_t)-1;
3365 return NT_STATUS_OK;
3368 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3369 struct lsa_QueryDomainInformationPolicy *r)
3371 p->rng_fault_state = True;
3372 return NT_STATUS_NOT_IMPLEMENTED;
3375 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3376 struct lsa_SetDomainInformationPolicy *r)
3378 p->rng_fault_state = True;
3379 return NT_STATUS_NOT_IMPLEMENTED;
3382 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3384 p->rng_fault_state = True;
3385 return NT_STATUS_NOT_IMPLEMENTED;
3388 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3390 p->rng_fault_state = True;
3391 return NT_STATUS_NOT_IMPLEMENTED;
3394 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3396 p->rng_fault_state = True;
3397 return NT_STATUS_NOT_IMPLEMENTED;
3400 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3402 p->rng_fault_state = True;
3403 return NT_STATUS_NOT_IMPLEMENTED;
3406 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3407 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3409 p->rng_fault_state = True;
3410 return NT_STATUS_NOT_IMPLEMENTED;
3413 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3414 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3416 p->rng_fault_state = True;
3417 return NT_STATUS_NOT_IMPLEMENTED;
3420 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3422 p->rng_fault_state = True;
3423 return NT_STATUS_NOT_IMPLEMENTED;
3426 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3427 struct lsa_CREDRGETTARGETINFO *r)
3429 p->rng_fault_state = True;
3430 return NT_STATUS_NOT_IMPLEMENTED;
3433 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3434 struct lsa_CREDRPROFILELOADED *r)
3436 p->rng_fault_state = True;
3437 return NT_STATUS_NOT_IMPLEMENTED;
3440 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3441 struct lsa_CREDRGETSESSIONTYPES *r)
3443 p->rng_fault_state = True;
3444 return NT_STATUS_NOT_IMPLEMENTED;
3447 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3448 struct lsa_LSARREGISTERAUDITEVENT *r)
3450 p->rng_fault_state = True;
3451 return NT_STATUS_NOT_IMPLEMENTED;
3454 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3455 struct lsa_LSARGENAUDITEVENT *r)
3457 p->rng_fault_state = True;
3458 return NT_STATUS_NOT_IMPLEMENTED;
3461 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3462 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3464 p->rng_fault_state = True;
3465 return NT_STATUS_NOT_IMPLEMENTED;
3468 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3469 struct lsa_lsaRQueryForestTrustInformation *r)
3471 p->rng_fault_state = True;
3472 return NT_STATUS_NOT_IMPLEMENTED;
3475 #define DNS_CMP_MATCH 0
3476 #define DNS_CMP_FIRST_IS_CHILD 1
3477 #define DNS_CMP_SECOND_IS_CHILD 2
3478 #define DNS_CMP_NO_MATCH 3
3480 /* this function assumes names are well formed DNS names.
3481 * it doesn't validate them */
3482 static int dns_cmp(const char *s1, size_t l1,
3483 const char *s2, size_t l2)
3485 const char *p1, *p2;
3490 if (StrCaseCmp(s1, s2) == 0) {
3491 return DNS_CMP_MATCH;
3493 return DNS_CMP_NO_MATCH;
3501 cret = DNS_CMP_FIRST_IS_CHILD;
3507 cret = DNS_CMP_SECOND_IS_CHILD;
3510 if (p1[t1 - t2 - 1] != '.') {
3511 return DNS_CMP_NO_MATCH;
3514 if (StrCaseCmp(&p1[t1 - t2], p2) == 0) {
3518 return DNS_CMP_NO_MATCH;
3521 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3522 struct lsa_ForestTrustInformation *lfti,
3523 struct ForestTrustInfo *fti)
3525 struct lsa_ForestTrustRecord *lrec;
3526 struct ForestTrustInfoRecord *rec;
3527 struct lsa_StringLarge *tln;
3528 struct lsa_ForestTrustDomainInfo *info;
3532 fti->count = lfti->count;
3533 fti->records = talloc_array(mem_ctx,
3534 struct ForestTrustInfoRecordArmor,
3536 if (!fti->records) {
3537 return NT_STATUS_NO_MEMORY;
3539 for (i = 0; i < fti->count; i++) {
3540 lrec = lfti->entries[i];
3541 rec = &fti->records[i].record;
3543 rec->flags = lrec->flags;
3544 rec->timestamp = lrec->time;
3545 rec->type = lrec->type;
3547 switch (lrec->type) {
3548 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3549 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3550 tln = &lrec->forest_trust_data.top_level_name;
3551 rec->data.name.string =
3552 talloc_strdup(mem_ctx, tln->string);
3553 if (!rec->data.name.string) {
3554 return NT_STATUS_NO_MEMORY;
3556 rec->data.name.size = strlen(rec->data.name.string);
3558 case LSA_FOREST_TRUST_DOMAIN_INFO:
3559 info = &lrec->forest_trust_data.domain_info;
3560 rec->data.info.sid = *info->domain_sid;
3561 rec->data.info.dns_name.string =
3562 talloc_strdup(mem_ctx,
3563 info->dns_domain_name.string);
3564 if (!rec->data.info.dns_name.string) {
3565 return NT_STATUS_NO_MEMORY;
3567 rec->data.info.dns_name.size =
3568 strlen(rec->data.info.dns_name.string);
3569 rec->data.info.netbios_name.string =
3570 talloc_strdup(mem_ctx,
3571 info->netbios_domain_name.string);
3572 if (!rec->data.info.netbios_name.string) {
3573 return NT_STATUS_NO_MEMORY;
3575 rec->data.info.netbios_name.size =
3576 strlen(rec->data.info.netbios_name.string);
3579 return NT_STATUS_INVALID_DOMAIN_STATE;
3583 return NT_STATUS_OK;
3586 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3587 uint32_t index, uint32_t collision_type,
3588 uint32_t conflict_type, const char *tdo_name);
3590 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
3591 const char *tdo_name,
3592 struct ForestTrustInfo *tdo_fti,
3593 struct ForestTrustInfo *new_fti,
3594 struct lsa_ForestTrustCollisionInfo *c_info)
3596 struct ForestTrustInfoRecord *nrec;
3597 struct ForestTrustInfoRecord *trec;
3598 const char *dns_name;
3599 const char *nb_name = NULL;
3600 struct dom_sid *sid = NULL;
3601 const char *tname = NULL;
3606 uint32_t new_fti_idx;
3608 /* use always TDO type, until we understand when Xref can be used */
3609 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
3614 bool ex_rule = false;
3617 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
3619 nrec = &new_fti->records[new_fti_idx].record;
3621 tln_conflict = false;
3622 sid_conflict = false;
3623 nb_conflict = false;
3626 switch (nrec->type) {
3627 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3628 /* exclusions do not conflict by definition */
3631 case FOREST_TRUST_TOP_LEVEL_NAME:
3632 dns_name = nrec->data.name.string;
3633 dns_len = nrec->data.name.size;
3636 case LSA_FOREST_TRUST_DOMAIN_INFO:
3637 dns_name = nrec->data.info.dns_name.string;
3638 dns_len = nrec->data.info.dns_name.size;
3639 nb_name = nrec->data.info.netbios_name.string;
3640 nb_len = nrec->data.info.netbios_name.size;
3641 sid = &nrec->data.info.sid;
3645 if (!dns_name) continue;
3647 /* check if this is already taken and not excluded */
3648 for (i = 0; i < tdo_fti->count; i++) {
3649 trec = &tdo_fti->records[i].record;
3651 switch (trec->type) {
3652 case FOREST_TRUST_TOP_LEVEL_NAME:
3654 tname = trec->data.name.string;
3655 tlen = trec->data.name.size;
3657 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
3659 tname = trec->data.name.string;
3660 tlen = trec->data.name.size;
3662 case FOREST_TRUST_DOMAIN_INFO:
3664 tname = trec->data.info.dns_name.string;
3665 tlen = trec->data.info.dns_name.size;
3667 return NT_STATUS_INVALID_PARAMETER;
3669 ret = dns_cmp(dns_name, dns_len, tname, tlen);
3672 /* if it matches exclusion,
3673 * it doesn't conflict */
3679 case DNS_CMP_FIRST_IS_CHILD:
3680 case DNS_CMP_SECOND_IS_CHILD:
3681 tln_conflict = true;
3687 /* explicit exclusion, no dns name conflict here */
3689 tln_conflict = false;
3692 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
3696 /* also test for domain info */
3697 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
3698 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
3699 sid_conflict = true;
3701 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
3702 StrCaseCmp(trec->data.info.netbios_name.string,
3709 nt_status = add_collision(c_info, new_fti_idx,
3711 LSA_TLN_DISABLED_CONFLICT,
3715 nt_status = add_collision(c_info, new_fti_idx,
3717 LSA_SID_DISABLED_CONFLICT,
3721 nt_status = add_collision(c_info, new_fti_idx,
3723 LSA_NB_DISABLED_CONFLICT,
3728 return NT_STATUS_OK;
3731 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3732 uint32_t idx, uint32_t collision_type,
3733 uint32_t conflict_type, const char *tdo_name)
3735 struct lsa_ForestTrustCollisionRecord **es;
3736 uint32_t i = c_info->count;
3738 es = talloc_realloc(c_info, c_info->entries,
3739 struct lsa_ForestTrustCollisionRecord *, i + 1);
3741 return NT_STATUS_NO_MEMORY;
3743 c_info->entries = es;
3744 c_info->count = i + 1;
3746 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
3748 return NT_STATUS_NO_MEMORY;
3752 es[i]->type = collision_type;
3753 es[i]->flags.flags = conflict_type;
3754 es[i]->name.string = talloc_strdup(es[i], tdo_name);
3755 if (!es[i]->name.string) {
3756 return NT_STATUS_NO_MEMORY;
3758 es[i]->name.size = strlen(es[i]->name.string);
3760 return NT_STATUS_OK;
3763 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3764 struct pdb_trusted_domain *td,
3765 struct ForestTrustInfo *info)
3767 enum ndr_err_code ndr_err;
3769 if (td->trust_forest_trust_info.length == 0 ||
3770 td->trust_forest_trust_info.data == NULL) {
3771 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3773 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
3775 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3776 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3777 return NT_STATUS_INVALID_DOMAIN_STATE;
3780 return NT_STATUS_OK;
3783 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
3784 struct ForestTrustInfo *fti)
3786 struct ForestTrustDataDomainInfo *info;
3787 struct ForestTrustInfoRecord *rec;
3791 fti->records = talloc_array(fti,
3792 struct ForestTrustInfoRecordArmor, 2);
3793 if (!fti->records) {
3794 return NT_STATUS_NO_MEMORY;
3798 rec = &fti->records[0].record;
3802 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3804 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
3805 if (!rec->data.name.string) {
3806 return NT_STATUS_NO_MEMORY;
3808 rec->data.name.size = strlen(rec->data.name.string);
3811 rec = &fti->records[1].record;
3815 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3817 info = &rec->data.info;
3819 info->sid = dom_info->sid;
3820 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
3821 if (!info->dns_name.string) {
3822 return NT_STATUS_NO_MEMORY;
3824 info->dns_name.size = strlen(info->dns_name.string);
3825 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
3826 if (!info->netbios_name.string) {
3827 return NT_STATUS_NO_MEMORY;
3829 info->netbios_name.size = strlen(info->netbios_name.string);
3831 return NT_STATUS_OK;
3834 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
3835 struct lsa_lsaRSetForestTrustInformation *r)
3840 struct lsa_info *handle;
3841 uint32_t num_domains;
3842 struct pdb_trusted_domain **domains;
3843 struct ForestTrustInfo *nfti;
3844 struct ForestTrustInfo *fti;
3845 struct lsa_ForestTrustCollisionInfo *c_info;
3846 struct pdb_domain_info *dom_info;
3847 enum ndr_err_code ndr_err;
3850 return NT_STATUS_NOT_SUPPORTED;
3853 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
3854 return NT_STATUS_INVALID_HANDLE;
3857 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
3858 return NT_STATUS_INVALID_HANDLE;
3861 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
3862 return NT_STATUS_ACCESS_DENIED;
3865 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
3866 if (!NT_STATUS_IS_OK(status)) {
3869 if (num_domains == 0) {
3870 return NT_STATUS_NO_SUCH_DOMAIN;
3873 for (i = 0; i < num_domains; i++) {
3874 if (domains[i]->domain_name == NULL) {
3875 return NT_STATUS_INVALID_DOMAIN_STATE;
3877 if (StrCaseCmp(domains[i]->domain_name,
3878 r->in.trusted_domain_name->string) == 0) {
3882 if (i >= num_domains) {
3883 return NT_STATUS_NO_SUCH_DOMAIN;
3886 if (!(domains[i]->trust_attributes &
3887 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
3888 return NT_STATUS_INVALID_PARAMETER;
3891 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
3892 return NT_STATUS_INVALID_PARAMETER;
3895 /* The following section until COPY_END is a copy from
3896 * source4/rpmc_server/lsa/scesrc_lsa.c */
3897 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
3899 return NT_STATUS_NO_MEMORY;
3902 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
3903 if (!NT_STATUS_IS_OK(status)) {
3907 c_info = talloc_zero(r->out.collision_info,
3908 struct lsa_ForestTrustCollisionInfo);
3910 return NT_STATUS_NO_MEMORY;
3913 /* first check own info, then other domains */
3914 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3916 return NT_STATUS_NO_MEMORY;
3919 dom_info = pdb_get_domain_info(p->mem_ctx);
3921 status = own_ft_info(dom_info, fti);
3922 if (!NT_STATUS_IS_OK(status)) {
3926 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
3927 if (!NT_STATUS_IS_OK(status)) {
3931 for (j = 0; j < num_domains; j++) {
3932 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3934 return NT_STATUS_NO_MEMORY;
3937 status = get_ft_info(p->mem_ctx, domains[j], fti);
3938 if (!NT_STATUS_IS_OK(status)) {
3939 if (NT_STATUS_EQUAL(status,
3940 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3946 if (domains[j]->domain_name == NULL) {
3947 return NT_STATUS_INVALID_DOMAIN_STATE;
3950 status = check_ft_info(c_info, domains[j]->domain_name,
3952 if (!NT_STATUS_IS_OK(status)) {
3957 *r->out.collision_info = c_info;
3959 if (r->in.check_only != 0) {
3960 return NT_STATUS_OK;
3965 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
3967 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
3968 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3969 return NT_STATUS_INVALID_PARAMETER;
3972 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
3973 if (!NT_STATUS_IS_OK(status)) {
3977 return NT_STATUS_OK;
3980 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
3981 struct lsa_CREDRRENAME *r)
3983 p->rng_fault_state = True;
3984 return NT_STATUS_NOT_IMPLEMENTED;
3987 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
3988 struct lsa_LSAROPENPOLICYSCE *r)
3990 p->rng_fault_state = True;
3991 return NT_STATUS_NOT_IMPLEMENTED;
3994 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
3995 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3997 p->rng_fault_state = True;
3998 return NT_STATUS_NOT_IMPLEMENTED;
4001 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4002 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4004 p->rng_fault_state = True;
4005 return NT_STATUS_NOT_IMPLEMENTED;
4008 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4009 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4011 p->rng_fault_state = True;
4012 return NT_STATUS_NOT_IMPLEMENTED;