2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Jeremy Allison 2001, 2006.
8 * Copyright (C) Rafal Szczesniak 2002,
9 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
10 * Copyright (C) Simo Sorce 2003.
11 * Copyright (C) Gerald (Jerry) Carter 2005.
12 * Copyright (C) Volker Lendecke 2005.
13 * Copyright (C) Guenther Deschner 2008.
14 * Copyright (C) Andrew Bartlett 2010.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
30 /* This is the implementation of the lsa server code. */
34 #include "../librpc/gen_ndr/srv_lsa.h"
36 #include "../librpc/gen_ndr/netlogon.h"
37 #include "rpc_client/init_lsa.h"
38 #include "../libcli/security/security.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../librpc/gen_ndr/drsblobs.h"
41 #include "../librpc/gen_ndr/ndr_drsblobs.h"
42 #include "../lib/crypto/arcfour.h"
43 #include "../libcli/security/dom_sid.h"
44 #include "../librpc/gen_ndr/ndr_security.h"
47 #include "lib/privileges.h"
48 #include "rpc_server/srv_access_check.h"
51 #define DBGC_CLASS DBGC_RPC_SRV
53 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
55 enum lsa_handle_type {
56 LSA_HANDLE_POLICY_TYPE = 1,
57 LSA_HANDLE_ACCOUNT_TYPE = 2,
58 LSA_HANDLE_TRUST_TYPE = 3};
64 enum lsa_handle_type type;
65 struct security_descriptor *sd;
68 const struct generic_mapping lsa_account_mapping = {
72 LSA_ACCOUNT_ALL_ACCESS
75 const struct generic_mapping lsa_policy_mapping = {
82 const struct generic_mapping lsa_secret_mapping = {
89 const struct generic_mapping lsa_trusted_domain_mapping = {
90 LSA_TRUSTED_DOMAIN_READ,
91 LSA_TRUSTED_DOMAIN_WRITE,
92 LSA_TRUSTED_DOMAIN_EXECUTE,
93 LSA_TRUSTED_DOMAIN_ALL_ACCESS
96 /***************************************************************************
97 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
98 ***************************************************************************/
100 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
101 struct lsa_RefDomainList *ref,
102 const char *dom_name,
103 struct dom_sid *dom_sid)
107 if (dom_name != NULL) {
108 for (num = 0; num < ref->count; num++) {
109 if (dom_sid_equal(dom_sid, ref->domains[num].sid)) {
117 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
118 /* index not found, already at maximum domain limit */
122 ref->count = num + 1;
123 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
125 ref->domains = talloc_realloc(mem_ctx, ref->domains,
126 struct lsa_DomainInfo, ref->count);
131 ZERO_STRUCT(ref->domains[num]);
133 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
134 ref->domains[num].sid = dom_sid_dup(mem_ctx, dom_sid);
135 if (!ref->domains[num].sid) {
143 /***************************************************************************
144 initialize a lsa_DomainInfo structure.
145 ***************************************************************************/
147 static void init_dom_query_3(struct lsa_DomainInfo *r,
151 init_lsa_StringLarge(&r->name, name);
155 /***************************************************************************
156 initialize a lsa_DomainInfo structure.
157 ***************************************************************************/
159 static void init_dom_query_5(struct lsa_DomainInfo *r,
163 init_lsa_StringLarge(&r->name, name);
167 /***************************************************************************
168 lookup_lsa_rids. Must be called as root for lookup_name to work.
169 ***************************************************************************/
171 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
172 struct lsa_RefDomainList *ref,
173 struct lsa_TranslatedSid *prid,
174 uint32_t num_entries,
175 struct lsa_String *name,
177 uint32_t *pmapped_count)
179 uint32 mapped_count, i;
181 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
186 for (i = 0; i < num_entries; i++) {
190 const char *full_name;
192 enum lsa_SidType type;
194 /* Split name into domain and user component */
196 /* follow w2k8 behavior and return the builtin domain when no
197 * input has been passed in */
199 if (name[i].string) {
200 full_name = name[i].string;
202 full_name = "BUILTIN";
205 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
207 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
209 type = SID_NAME_UNKNOWN;
214 case SID_NAME_DOM_GRP:
215 case SID_NAME_DOMAIN:
217 case SID_NAME_WKN_GRP:
218 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
219 /* Leave these unchanged */
222 /* Don't hand out anything but the list above */
223 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
224 type = SID_NAME_UNKNOWN;
231 if (type != SID_NAME_UNKNOWN) {
232 if (type == SID_NAME_DOMAIN) {
235 sid_split_rid(&sid, &rid);
237 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
241 prid[i].sid_type = type;
243 prid[i].sid_index = dom_idx;
246 *pmapped_count = mapped_count;
250 /***************************************************************************
251 lookup_lsa_sids. Must be called as root for lookup_name to work.
252 ***************************************************************************/
254 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
255 struct lsa_RefDomainList *ref,
256 struct lsa_TranslatedSid3 *trans_sids,
257 uint32_t num_entries,
258 struct lsa_String *name,
260 uint32 *pmapped_count)
262 uint32 mapped_count, i;
264 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
269 for (i = 0; i < num_entries; i++) {
273 const char *full_name;
275 enum lsa_SidType type;
279 /* Split name into domain and user component */
281 full_name = name[i].string;
282 if (full_name == NULL) {
283 return NT_STATUS_NO_MEMORY;
286 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
288 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
290 type = SID_NAME_UNKNOWN;
295 case SID_NAME_DOM_GRP:
296 case SID_NAME_DOMAIN:
298 case SID_NAME_WKN_GRP:
299 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
300 /* Leave these unchanged */
303 /* Don't hand out anything but the list above */
304 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
305 type = SID_NAME_UNKNOWN;
312 if (type != SID_NAME_UNKNOWN) {
313 struct dom_sid domain_sid;
314 sid_copy(&domain_sid, &sid);
315 sid_split_rid(&domain_sid, &rid);
316 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
320 /* Initialize the lsa_TranslatedSid3 return. */
321 trans_sids[i].sid_type = type;
322 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
323 trans_sids[i].sid_index = dom_idx;
326 *pmapped_count = mapped_count;
330 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
331 const struct generic_mapping *map,
332 struct dom_sid *sid, uint32_t sid_access)
334 struct dom_sid adm_sid;
335 struct security_ace ace[5];
338 struct security_acl *psa = NULL;
340 /* READ|EXECUTE access for Everyone */
342 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
343 map->generic_execute | map->generic_read, 0);
345 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
347 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
348 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
349 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
350 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
352 /* Add Full Access for Domain Admins */
353 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
354 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
355 map->generic_all, 0);
357 /* If we have a sid, give it some special access */
360 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
364 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
365 return NT_STATUS_NO_MEMORY;
367 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
368 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
369 psa, sd_size)) == NULL)
370 return NT_STATUS_NO_MEMORY;
375 /***************************************************************************
376 ***************************************************************************/
378 static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
379 struct pipes_struct *p,
380 enum lsa_handle_type type,
381 uint32_t acc_granted,
384 const struct security_descriptor *sd,
385 struct policy_handle *handle)
387 struct lsa_info *info;
389 ZERO_STRUCTP(handle);
391 info = talloc_zero(mem_ctx, struct lsa_info);
393 return NT_STATUS_NO_MEMORY;
397 info->access = acc_granted;
400 sid_copy(&info->sid, sid);
403 info->name = talloc_strdup(info, name);
406 info->sd = dup_sec_desc(info, sd);
409 return NT_STATUS_NO_MEMORY;
413 if (!create_policy_hnd(p, handle, info)) {
415 ZERO_STRUCTP(handle);
416 return NT_STATUS_NO_MEMORY;
422 /***************************************************************************
424 ***************************************************************************/
426 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
427 struct lsa_OpenPolicy2 *r)
429 struct security_descriptor *psd = NULL;
431 uint32 des_access = r->in.access_mask;
435 /* Work out max allowed. */
436 map_max_allowed_access(p->session_info->security_token,
437 p->session_info->unix_token,
440 /* map the generic bits to the lsa policy ones */
441 se_map_generic(&des_access, &lsa_policy_mapping);
443 /* get the generic lsa policy SD until we store it */
444 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
446 if (!NT_STATUS_IS_OK(status)) {
450 status = access_check_object(psd, p->session_info->security_token,
451 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
452 &acc_granted, "_lsa_OpenPolicy2" );
453 if (!NT_STATUS_IS_OK(status)) {
457 status = create_lsa_policy_handle(p->mem_ctx, p,
458 LSA_HANDLE_POLICY_TYPE,
460 get_global_sam_sid(),
464 if (!NT_STATUS_IS_OK(status)) {
465 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
471 /***************************************************************************
473 ***************************************************************************/
475 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
476 struct lsa_OpenPolicy *r)
478 struct lsa_OpenPolicy2 o;
480 o.in.system_name = NULL; /* should be ignored */
481 o.in.attr = r->in.attr;
482 o.in.access_mask = r->in.access_mask;
484 o.out.handle = r->out.handle;
486 return _lsa_OpenPolicy2(p, &o);
489 /***************************************************************************
490 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
492 ***************************************************************************/
494 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
495 struct lsa_EnumTrustDom *r)
497 struct lsa_info *info;
499 struct trustdom_info **domains;
500 struct lsa_DomainInfo *entries;
504 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
505 return NT_STATUS_INVALID_HANDLE;
507 if (info->type != LSA_HANDLE_POLICY_TYPE) {
508 return NT_STATUS_INVALID_HANDLE;
511 /* check if the user has enough rights */
512 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
513 return NT_STATUS_ACCESS_DENIED;
516 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
519 if (!NT_STATUS_IS_OK(nt_status)) {
523 entries = talloc_zero_array(p->mem_ctx, struct lsa_DomainInfo, count);
525 return NT_STATUS_NO_MEMORY;
528 for (i=0; i<count; i++) {
529 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
530 entries[i].sid = &domains[i]->sid;
533 if (*r->in.resume_handle >= count) {
534 *r->out.resume_handle = -1;
535 TALLOC_FREE(entries);
536 return NT_STATUS_NO_MORE_ENTRIES;
539 /* return the rest, limit by max_size. Note that we
540 use the w2k3 element size value of 60 */
541 r->out.domains->count = count - *r->in.resume_handle;
542 r->out.domains->count = MIN(r->out.domains->count,
543 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
545 r->out.domains->domains = entries + *r->in.resume_handle;
547 if (r->out.domains->count < count - *r->in.resume_handle) {
548 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
549 return STATUS_MORE_ENTRIES;
552 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
553 * always be larger than the previous input resume handle, in
554 * particular when hitting the last query it is vital to set the
555 * resume handle correctly to avoid infinite client loops, as
556 * seen e.g. with Windows XP SP3 when resume handle is 0 and
557 * status is NT_STATUS_OK - gd */
559 *r->out.resume_handle = (uint32_t)-1;
564 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
565 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
566 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
568 /***************************************************************************
570 ***************************************************************************/
572 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
573 struct lsa_QueryInfoPolicy *r)
575 NTSTATUS status = NT_STATUS_OK;
576 struct lsa_info *handle;
577 struct dom_sid domain_sid;
579 struct dom_sid *sid = NULL;
580 union lsa_PolicyInformation *info = NULL;
581 uint32_t acc_required = 0;
583 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
584 return NT_STATUS_INVALID_HANDLE;
586 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
587 return NT_STATUS_INVALID_HANDLE;
590 switch (r->in.level) {
591 case LSA_POLICY_INFO_AUDIT_LOG:
592 case LSA_POLICY_INFO_AUDIT_EVENTS:
593 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
595 case LSA_POLICY_INFO_DOMAIN:
596 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
598 case LSA_POLICY_INFO_PD:
599 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
601 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
602 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
604 case LSA_POLICY_INFO_ROLE:
605 case LSA_POLICY_INFO_REPLICA:
606 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
608 case LSA_POLICY_INFO_QUOTA:
609 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
611 case LSA_POLICY_INFO_MOD:
612 case LSA_POLICY_INFO_AUDIT_FULL_SET:
613 /* according to MS-LSAD 3.1.4.4.3 */
614 return NT_STATUS_INVALID_PARAMETER;
615 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
616 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
618 case LSA_POLICY_INFO_DNS:
619 case LSA_POLICY_INFO_DNS_INT:
620 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
621 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
627 if (!(handle->access & acc_required)) {
628 /* return NT_STATUS_ACCESS_DENIED; */
631 info = talloc_zero(p->mem_ctx, union lsa_PolicyInformation);
633 return NT_STATUS_NO_MEMORY;
636 switch (r->in.level) {
637 /* according to MS-LSAD 3.1.4.4.3 */
638 case LSA_POLICY_INFO_MOD:
639 case LSA_POLICY_INFO_AUDIT_FULL_SET:
640 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
641 return NT_STATUS_INVALID_PARAMETER;
642 case LSA_POLICY_INFO_AUDIT_LOG:
643 info->audit_log.percent_full = 0;
644 info->audit_log.maximum_log_size = 0;
645 info->audit_log.retention_time = 0;
646 info->audit_log.shutdown_in_progress = 0;
647 info->audit_log.time_to_shutdown = 0;
648 info->audit_log.next_audit_record = 0;
649 status = NT_STATUS_OK;
651 case LSA_POLICY_INFO_PD:
652 info->pd.name.string = NULL;
653 status = NT_STATUS_OK;
655 case LSA_POLICY_INFO_REPLICA:
656 info->replica.source.string = NULL;
657 info->replica.account.string = NULL;
658 status = NT_STATUS_OK;
660 case LSA_POLICY_INFO_QUOTA:
661 info->quota.paged_pool = 0;
662 info->quota.non_paged_pool = 0;
663 info->quota.min_wss = 0;
664 info->quota.max_wss = 0;
665 info->quota.pagefile = 0;
666 info->quota.unknown = 0;
667 status = NT_STATUS_OK;
669 case LSA_POLICY_INFO_AUDIT_EVENTS:
672 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
674 /* check if the user has enough rights */
675 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
676 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
677 return NT_STATUS_ACCESS_DENIED;
680 /* fake info: We audit everything. ;) */
682 info->audit_events.auditing_mode = true;
683 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
684 info->audit_events.settings = talloc_zero_array(p->mem_ctx,
685 enum lsa_PolicyAuditPolicy,
686 info->audit_events.count);
687 if (!info->audit_events.settings) {
688 return NT_STATUS_NO_MEMORY;
691 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
692 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
693 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
694 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
695 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
696 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
697 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
701 case LSA_POLICY_INFO_DOMAIN:
702 /* check if the user has enough rights */
703 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
704 return NT_STATUS_ACCESS_DENIED;
706 /* Request PolicyPrimaryDomainInformation. */
707 switch (lp_server_role()) {
708 case ROLE_DOMAIN_PDC:
709 case ROLE_DOMAIN_BDC:
710 name = get_global_sam_name();
711 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
713 return NT_STATUS_NO_MEMORY;
716 case ROLE_DOMAIN_MEMBER:
717 name = lp_workgroup();
718 /* We need to return the Domain SID here. */
719 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
720 sid = dom_sid_dup(p->mem_ctx, &domain_sid);
722 return NT_STATUS_NO_MEMORY;
725 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
728 case ROLE_STANDALONE:
729 name = lp_workgroup();
733 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
735 init_dom_query_3(&info->domain, name, sid);
737 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
738 /* check if the user has enough rights */
739 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
740 return NT_STATUS_ACCESS_DENIED;
742 /* Request PolicyAccountDomainInformation. */
743 name = get_global_sam_name();
744 sid = get_global_sam_sid();
746 init_dom_query_5(&info->account_domain, name, sid);
748 case LSA_POLICY_INFO_ROLE:
749 /* check if the user has enough rights */
750 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
751 return NT_STATUS_ACCESS_DENIED;
753 switch (lp_server_role()) {
754 case ROLE_DOMAIN_BDC:
756 * only a BDC is a backup controller
757 * of the domain, it controls.
759 info->role.role = LSA_ROLE_BACKUP;
763 * any other role is a primary
764 * of the domain, it controls.
766 info->role.role = LSA_ROLE_PRIMARY;
770 case LSA_POLICY_INFO_DNS:
771 case LSA_POLICY_INFO_DNS_INT: {
772 struct pdb_domain_info *dominfo;
774 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
775 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
776 "without ADS passdb backend\n"));
777 status = NT_STATUS_INVALID_INFO_CLASS;
781 dominfo = pdb_get_domain_info(info);
782 if (dominfo == NULL) {
783 status = NT_STATUS_NO_MEMORY;
787 init_lsa_StringLarge(&info->dns.name,
789 init_lsa_StringLarge(&info->dns.dns_domain,
790 dominfo->dns_domain);
791 init_lsa_StringLarge(&info->dns.dns_forest,
792 dominfo->dns_forest);
793 info->dns.domain_guid = dominfo->guid;
794 info->dns.sid = &dominfo->sid;
798 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
800 status = NT_STATUS_INVALID_INFO_CLASS;
809 /***************************************************************************
810 _lsa_QueryInfoPolicy2
811 ***************************************************************************/
813 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
814 struct lsa_QueryInfoPolicy2 *r2)
816 struct lsa_QueryInfoPolicy r;
818 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
819 p->rng_fault_state = True;
820 return NT_STATUS_NOT_IMPLEMENTED;
824 r.in.handle = r2->in.handle;
825 r.in.level = r2->in.level;
826 r.out.info = r2->out.info;
828 return _lsa_QueryInfoPolicy(p, &r);
831 /***************************************************************************
832 _lsa_lookup_sids_internal
833 ***************************************************************************/
835 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
837 uint16_t level, /* input */
838 int num_sids, /* input */
839 struct lsa_SidPtr *sid, /* input */
840 struct lsa_RefDomainList **pp_ref, /* input/output */
841 struct lsa_TranslatedName2 **pp_names,/* input/output */
842 uint32_t *pp_mapped_count) /* input/output */
846 const struct dom_sid **sids = NULL;
847 struct lsa_RefDomainList *ref = NULL;
848 uint32 mapped_count = 0;
849 struct lsa_dom_info *dom_infos = NULL;
850 struct lsa_name_info *name_infos = NULL;
851 struct lsa_TranslatedName2 *names = NULL;
853 *pp_mapped_count = 0;
861 sids = talloc_array(p->mem_ctx, const struct dom_sid *, num_sids);
862 ref = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
864 if (sids == NULL || ref == NULL) {
865 return NT_STATUS_NO_MEMORY;
868 for (i=0; i<num_sids; i++) {
869 sids[i] = sid[i].sid;
872 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
873 &dom_infos, &name_infos);
875 if (!NT_STATUS_IS_OK(status)) {
879 names = talloc_array(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
881 return NT_STATUS_NO_MEMORY;
884 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
886 if (!dom_infos[i].valid) {
890 if (init_lsa_ref_domain_list(mem_ctx, ref,
892 &dom_infos[i].sid) != i) {
893 DEBUG(0, ("Domain %s mentioned twice??\n",
895 return NT_STATUS_INTERNAL_ERROR;
899 for (i=0; i<num_sids; i++) {
900 struct lsa_name_info *name = &name_infos[i];
902 if (name->type == SID_NAME_UNKNOWN) {
904 /* Unknown sids should return the string
905 * representation of the SID. Windows 2003 behaves
906 * rather erratic here, in many cases it returns the
907 * RID as 8 bytes hex, in others it returns the full
908 * SID. We (Jerry/VL) could not figure out which the
909 * hard cases are, so leave it with the SID. */
910 name->name = dom_sid_string(p->mem_ctx, sids[i]);
911 if (name->name == NULL) {
912 return NT_STATUS_NO_MEMORY;
918 names[i].sid_type = name->type;
919 names[i].name.string = name->name;
920 names[i].sid_index = name->dom_idx;
921 names[i].unknown = 0;
924 status = NT_STATUS_NONE_MAPPED;
925 if (mapped_count > 0) {
926 status = (mapped_count < num_sids) ?
927 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
930 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
931 num_sids, mapped_count, nt_errstr(status)));
933 *pp_mapped_count = mapped_count;
940 /***************************************************************************
942 ***************************************************************************/
944 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
945 struct lsa_LookupSids *r)
948 struct lsa_info *handle;
949 int num_sids = r->in.sids->num_sids;
950 uint32 mapped_count = 0;
951 struct lsa_RefDomainList *domains = NULL;
952 struct lsa_TranslatedName *names_out = NULL;
953 struct lsa_TranslatedName2 *names = NULL;
956 if ((r->in.level < 1) || (r->in.level > 6)) {
957 return NT_STATUS_INVALID_PARAMETER;
960 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
961 return NT_STATUS_INVALID_HANDLE;
964 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
965 return NT_STATUS_INVALID_HANDLE;
968 /* check if the user has enough rights */
969 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
970 return NT_STATUS_ACCESS_DENIED;
973 if (num_sids > MAX_LOOKUP_SIDS) {
974 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
975 MAX_LOOKUP_SIDS, num_sids));
976 return NT_STATUS_NONE_MAPPED;
979 status = _lsa_lookup_sids_internal(p,
988 /* Only return here when there is a real error.
989 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
990 the requested sids could be resolved. Older versions of XP (pre SP3)
991 rely that we return with the string representations of those SIDs in
992 that case. If we don't, XP crashes - Guenther
995 if (NT_STATUS_IS_ERR(status) &&
996 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1000 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
1001 names_out = talloc_array(p->mem_ctx, struct lsa_TranslatedName,
1004 return NT_STATUS_NO_MEMORY;
1007 for (i=0; i<num_sids; i++) {
1008 names_out[i].sid_type = names[i].sid_type;
1009 names_out[i].name = names[i].name;
1010 names_out[i].sid_index = names[i].sid_index;
1013 *r->out.domains = domains;
1014 r->out.names->count = num_sids;
1015 r->out.names->names = names_out;
1016 *r->out.count = mapped_count;
1021 /***************************************************************************
1023 ***************************************************************************/
1025 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1026 struct lsa_LookupSids2 *r)
1029 struct lsa_info *handle;
1030 int num_sids = r->in.sids->num_sids;
1031 uint32 mapped_count = 0;
1032 struct lsa_RefDomainList *domains = NULL;
1033 struct lsa_TranslatedName2 *names = NULL;
1034 bool check_policy = true;
1037 case NDR_LSA_LOOKUPSIDS3:
1038 check_policy = false;
1040 case NDR_LSA_LOOKUPSIDS2:
1042 check_policy = true;
1045 if ((r->in.level < 1) || (r->in.level > 6)) {
1046 return NT_STATUS_INVALID_PARAMETER;
1050 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1051 return NT_STATUS_INVALID_HANDLE;
1054 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1055 return NT_STATUS_INVALID_HANDLE;
1058 /* check if the user has enough rights */
1059 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1060 return NT_STATUS_ACCESS_DENIED;
1064 if (num_sids > MAX_LOOKUP_SIDS) {
1065 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1066 MAX_LOOKUP_SIDS, num_sids));
1067 return NT_STATUS_NONE_MAPPED;
1070 status = _lsa_lookup_sids_internal(p,
1079 *r->out.domains = domains;
1080 r->out.names->count = num_sids;
1081 r->out.names->names = names;
1082 *r->out.count = mapped_count;
1087 /***************************************************************************
1089 ***************************************************************************/
1091 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1092 struct lsa_LookupSids3 *r)
1094 struct lsa_LookupSids2 q;
1096 /* No policy handle on this call. Restrict to crypto connections. */
1097 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1098 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1099 get_remote_machine_name() ));
1100 return NT_STATUS_INVALID_PARAMETER;
1104 q.in.sids = r->in.sids;
1105 q.in.level = r->in.level;
1106 q.in.lookup_options = r->in.lookup_options;
1107 q.in.client_revision = r->in.client_revision;
1108 q.in.names = r->in.names;
1109 q.in.count = r->in.count;
1111 q.out.domains = r->out.domains;
1112 q.out.names = r->out.names;
1113 q.out.count = r->out.count;
1115 return _lsa_LookupSids2(p, &q);
1118 /***************************************************************************
1119 ***************************************************************************/
1121 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1126 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1127 flags = LOOKUP_NAME_ALL;
1129 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1130 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1132 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1133 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1135 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1136 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1137 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1138 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1140 flags = LOOKUP_NAME_NONE;
1147 /***************************************************************************
1149 ***************************************************************************/
1151 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1152 struct lsa_LookupNames *r)
1154 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1155 struct lsa_info *handle;
1156 struct lsa_String *names = r->in.names;
1157 uint32 num_entries = r->in.num_names;
1158 struct lsa_RefDomainList *domains = NULL;
1159 struct lsa_TranslatedSid *rids = NULL;
1160 uint32 mapped_count = 0;
1163 if (num_entries > MAX_LOOKUP_SIDS) {
1164 num_entries = MAX_LOOKUP_SIDS;
1165 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1169 flags = lsa_lookup_level_to_flags(r->in.level);
1171 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1173 return NT_STATUS_NO_MEMORY;
1177 rids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid,
1180 return NT_STATUS_NO_MEMORY;
1186 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1187 status = NT_STATUS_INVALID_HANDLE;
1191 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1192 return NT_STATUS_INVALID_HANDLE;
1195 /* check if the user has enough rights */
1196 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1197 status = NT_STATUS_ACCESS_DENIED;
1201 /* set up the LSA Lookup RIDs response */
1202 become_root(); /* lookup_name can require root privs */
1203 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1204 names, flags, &mapped_count);
1209 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1210 if (mapped_count == 0) {
1211 status = NT_STATUS_NONE_MAPPED;
1212 } else if (mapped_count != num_entries) {
1213 status = STATUS_SOME_UNMAPPED;
1217 *r->out.count = mapped_count;
1218 *r->out.domains = domains;
1219 r->out.sids->sids = rids;
1220 r->out.sids->count = num_entries;
1225 /***************************************************************************
1227 ***************************************************************************/
1229 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1230 struct lsa_LookupNames2 *r)
1233 struct lsa_LookupNames q;
1234 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1235 struct lsa_TransSidArray *sid_array = NULL;
1238 sid_array = talloc_zero(p->mem_ctx, struct lsa_TransSidArray);
1240 return NT_STATUS_NO_MEMORY;
1243 q.in.handle = r->in.handle;
1244 q.in.num_names = r->in.num_names;
1245 q.in.names = r->in.names;
1246 q.in.level = r->in.level;
1247 q.in.sids = sid_array;
1248 q.in.count = r->in.count;
1249 /* we do not know what this is for */
1250 /* = r->in.unknown1; */
1251 /* = r->in.unknown2; */
1253 q.out.domains = r->out.domains;
1254 q.out.sids = sid_array;
1255 q.out.count = r->out.count;
1257 status = _lsa_LookupNames(p, &q);
1259 sid_array2->count = sid_array->count;
1260 sid_array2->sids = talloc_array(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1261 if (!sid_array2->sids) {
1262 return NT_STATUS_NO_MEMORY;
1265 for (i=0; i<sid_array->count; i++) {
1266 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1267 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1268 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1269 sid_array2->sids[i].unknown = 0;
1272 r->out.sids = sid_array2;
1277 /***************************************************************************
1279 ***************************************************************************/
1281 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1282 struct lsa_LookupNames3 *r)
1285 struct lsa_info *handle;
1286 struct lsa_String *names = r->in.names;
1287 uint32 num_entries = r->in.num_names;
1288 struct lsa_RefDomainList *domains = NULL;
1289 struct lsa_TranslatedSid3 *trans_sids = NULL;
1290 uint32 mapped_count = 0;
1292 bool check_policy = true;
1295 case NDR_LSA_LOOKUPNAMES4:
1296 check_policy = false;
1298 case NDR_LSA_LOOKUPNAMES3:
1300 check_policy = true;
1303 if (num_entries > MAX_LOOKUP_SIDS) {
1304 num_entries = MAX_LOOKUP_SIDS;
1305 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1308 /* Probably the lookup_level is some sort of bitmask. */
1309 if (r->in.level == 1) {
1310 flags = LOOKUP_NAME_ALL;
1313 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1315 return NT_STATUS_NO_MEMORY;
1319 trans_sids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid3,
1322 return NT_STATUS_NO_MEMORY;
1330 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1331 status = NT_STATUS_INVALID_HANDLE;
1335 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1336 return NT_STATUS_INVALID_HANDLE;
1339 /* check if the user has enough rights */
1340 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1341 status = NT_STATUS_ACCESS_DENIED;
1346 /* set up the LSA Lookup SIDs response */
1347 become_root(); /* lookup_name can require root privs */
1348 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1349 names, flags, &mapped_count);
1354 if (NT_STATUS_IS_OK(status)) {
1355 if (mapped_count == 0) {
1356 status = NT_STATUS_NONE_MAPPED;
1357 } else if (mapped_count != num_entries) {
1358 status = STATUS_SOME_UNMAPPED;
1362 *r->out.count = mapped_count;
1363 *r->out.domains = domains;
1364 r->out.sids->sids = trans_sids;
1365 r->out.sids->count = num_entries;
1370 /***************************************************************************
1372 ***************************************************************************/
1374 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1375 struct lsa_LookupNames4 *r)
1377 struct lsa_LookupNames3 q;
1379 /* No policy handle on this call. Restrict to crypto connections. */
1380 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1381 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1382 get_remote_machine_name() ));
1383 return NT_STATUS_INVALID_PARAMETER;
1387 q.in.num_names = r->in.num_names;
1388 q.in.names = r->in.names;
1389 q.in.level = r->in.level;
1390 q.in.lookup_options = r->in.lookup_options;
1391 q.in.client_revision = r->in.client_revision;
1392 q.in.sids = r->in.sids;
1393 q.in.count = r->in.count;
1395 q.out.domains = r->out.domains;
1396 q.out.sids = r->out.sids;
1397 q.out.count = r->out.count;
1399 return _lsa_LookupNames3(p, &q);
1402 /***************************************************************************
1403 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1404 ***************************************************************************/
1406 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1408 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1409 return NT_STATUS_INVALID_HANDLE;
1412 close_policy_hnd(p, r->in.handle);
1413 ZERO_STRUCTP(r->out.handle);
1414 return NT_STATUS_OK;
1417 /***************************************************************************
1418 ***************************************************************************/
1420 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1421 const struct dom_sid *sid,
1422 struct trustdom_info **info)
1425 uint32_t num_domains = 0;
1426 struct trustdom_info **domains = NULL;
1429 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1430 if (!NT_STATUS_IS_OK(status)) {
1434 for (i=0; i < num_domains; i++) {
1435 if (dom_sid_equal(&domains[i]->sid, sid)) {
1440 if (i == num_domains) {
1441 return NT_STATUS_INVALID_PARAMETER;
1446 return NT_STATUS_OK;
1449 /***************************************************************************
1450 ***************************************************************************/
1452 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1453 const char *netbios_domain_name,
1454 struct trustdom_info **info_p)
1457 struct trustdom_info *info;
1458 struct pdb_trusted_domain *td;
1460 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1461 if (!NT_STATUS_IS_OK(status)) {
1465 info = talloc(mem_ctx, struct trustdom_info);
1467 return NT_STATUS_NO_MEMORY;
1470 info->name = talloc_strdup(info, netbios_domain_name);
1471 NT_STATUS_HAVE_NO_MEMORY(info->name);
1473 sid_copy(&info->sid, &td->security_identifier);
1477 return NT_STATUS_OK;
1480 /***************************************************************************
1481 ***************************************************************************/
1483 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p, struct lsa_OpenSecret *r)
1485 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1488 /***************************************************************************
1489 _lsa_OpenTrustedDomain_base
1490 ***************************************************************************/
1492 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1493 uint32_t access_mask,
1494 struct trustdom_info *info,
1495 struct policy_handle *handle)
1497 struct security_descriptor *psd = NULL;
1499 uint32_t acc_granted;
1502 /* des_access is for the account here, not the policy
1503 * handle - so don't check against policy handle. */
1505 /* Work out max allowed. */
1506 map_max_allowed_access(p->session_info->security_token,
1507 p->session_info->unix_token,
1510 /* map the generic bits to the lsa account ones */
1511 se_map_generic(&access_mask, &lsa_account_mapping);
1513 /* get the generic lsa account SD until we store it */
1514 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1515 &lsa_trusted_domain_mapping,
1517 if (!NT_STATUS_IS_OK(status)) {
1521 status = access_check_object(psd, p->session_info->security_token,
1522 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1523 access_mask, &acc_granted,
1524 "_lsa_OpenTrustedDomain");
1525 if (!NT_STATUS_IS_OK(status)) {
1529 status = create_lsa_policy_handle(p->mem_ctx, p,
1530 LSA_HANDLE_TRUST_TYPE,
1536 if (!NT_STATUS_IS_OK(status)) {
1537 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1540 return NT_STATUS_OK;
1543 /***************************************************************************
1544 _lsa_OpenTrustedDomain
1545 ***************************************************************************/
1547 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1548 struct lsa_OpenTrustedDomain *r)
1550 struct lsa_info *handle = NULL;
1551 struct trustdom_info *info = NULL;
1554 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1555 return NT_STATUS_INVALID_HANDLE;
1558 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1559 return NT_STATUS_INVALID_HANDLE;
1562 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1565 if (!NT_STATUS_IS_OK(status)) {
1569 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1570 r->out.trustdom_handle);
1573 /***************************************************************************
1574 _lsa_OpenTrustedDomainByName
1575 ***************************************************************************/
1577 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1578 struct lsa_OpenTrustedDomainByName *r)
1580 struct lsa_info *handle = NULL;
1581 struct trustdom_info *info = NULL;
1584 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1585 return NT_STATUS_INVALID_HANDLE;
1588 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1589 return NT_STATUS_INVALID_HANDLE;
1592 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1595 if (!NT_STATUS_IS_OK(status)) {
1599 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1600 r->out.trustdom_handle);
1603 static NTSTATUS add_trusted_domain_user(TALLOC_CTX *mem_ctx,
1604 const char *netbios_name,
1605 const char *domain_name,
1606 const struct trustDomainPasswords *auth_struct)
1609 struct samu *sam_acct;
1612 struct dom_sid user_sid;
1617 sam_acct = samu_new(mem_ctx);
1618 if (sam_acct == NULL) {
1619 return NT_STATUS_NO_MEMORY;
1622 acct_name = talloc_asprintf(mem_ctx, "%s$", netbios_name);
1623 if (acct_name == NULL) {
1624 return NT_STATUS_NO_MEMORY;
1626 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1627 return NT_STATUS_UNSUCCESSFUL;
1630 if (!pdb_set_domain(sam_acct, domain_name, PDB_SET)) {
1631 return NT_STATUS_UNSUCCESSFUL;
1634 if (!pdb_set_acct_ctrl(sam_acct, ACB_DOMTRUST, PDB_SET)) {
1635 return NT_STATUS_UNSUCCESSFUL;
1638 if (!pdb_new_rid(&rid)) {
1639 return NT_STATUS_DS_NO_MORE_RIDS;
1641 sid_compose(&user_sid, get_global_sam_sid(), rid);
1642 if (!pdb_set_user_sid(sam_acct, &user_sid, PDB_SET)) {
1643 return NT_STATUS_UNSUCCESSFUL;
1646 for (i = 0; i < auth_struct->incoming.count; i++) {
1647 switch (auth_struct->incoming.current.array[i].AuthType) {
1648 case TRUST_AUTH_TYPE_CLEAR:
1649 if (!convert_string_talloc(mem_ctx,
1652 auth_struct->incoming.current.array[i].AuthInfo.clear.password,
1653 auth_struct->incoming.current.array[i].AuthInfo.clear.size,
1656 return NT_STATUS_UNSUCCESSFUL;
1658 if (!pdb_set_plaintext_passwd(sam_acct, dummy)) {
1659 return NT_STATUS_UNSUCCESSFUL;
1667 status = pdb_add_sam_account(sam_acct);
1668 if (!NT_STATUS_IS_OK(status)) {
1672 return NT_STATUS_OK;
1675 /***************************************************************************
1676 _lsa_CreateTrustedDomainEx2
1677 ***************************************************************************/
1679 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1680 struct lsa_CreateTrustedDomainEx2 *r)
1682 struct lsa_info *policy;
1684 uint32_t acc_granted;
1685 struct security_descriptor *psd;
1687 struct pdb_trusted_domain td;
1688 struct trustDomainPasswords auth_struct;
1689 enum ndr_err_code ndr_err;
1690 DATA_BLOB auth_blob;
1693 return NT_STATUS_NOT_SUPPORTED;
1696 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1697 return NT_STATUS_INVALID_HANDLE;
1700 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1701 return NT_STATUS_ACCESS_DENIED;
1704 if (p->session_info->unix_token->uid != sec_initial_uid() &&
1705 !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1706 return NT_STATUS_ACCESS_DENIED;
1709 /* Work out max allowed. */
1710 map_max_allowed_access(p->session_info->security_token,
1711 p->session_info->unix_token,
1712 &r->in.access_mask);
1714 /* map the generic bits to the lsa policy ones */
1715 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1717 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1718 &lsa_trusted_domain_mapping,
1720 if (!NT_STATUS_IS_OK(status)) {
1724 status = access_check_object(psd, p->session_info->security_token,
1725 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1726 r->in.access_mask, &acc_granted,
1727 "_lsa_CreateTrustedDomainEx2");
1728 if (!NT_STATUS_IS_OK(status)) {
1734 td.domain_name = talloc_strdup(p->mem_ctx,
1735 r->in.info->domain_name.string);
1736 if (td.domain_name == NULL) {
1737 return NT_STATUS_NO_MEMORY;
1739 td.netbios_name = talloc_strdup(p->mem_ctx,
1740 r->in.info->netbios_name.string);
1741 if (td.netbios_name == NULL) {
1742 return NT_STATUS_NO_MEMORY;
1744 sid_copy(&td.security_identifier, r->in.info->sid);
1745 td.trust_direction = r->in.info->trust_direction;
1746 td.trust_type = r->in.info->trust_type;
1747 td.trust_attributes = r->in.info->trust_attributes;
1749 if (r->in.auth_info_internal->auth_blob.size != 0) {
1750 auth_blob.length = r->in.auth_info_internal->auth_blob.size;
1751 auth_blob.data = r->in.auth_info_internal->auth_blob.data;
1753 arcfour_crypt_blob(auth_blob.data, auth_blob.length,
1754 &p->session_info->session_key);
1756 ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
1758 (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
1759 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1760 return NT_STATUS_UNSUCCESSFUL;
1763 ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
1764 &auth_struct.incoming,
1765 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1766 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1767 return NT_STATUS_UNSUCCESSFUL;
1770 ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
1771 &auth_struct.outgoing,
1772 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1773 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1774 return NT_STATUS_UNSUCCESSFUL;
1777 td.trust_auth_incoming.data = NULL;
1778 td.trust_auth_incoming.length = 0;
1779 td.trust_auth_outgoing.data = NULL;
1780 td.trust_auth_outgoing.length = 0;
1783 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1784 if (!NT_STATUS_IS_OK(status)) {
1788 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1789 status = add_trusted_domain_user(p->mem_ctx,
1790 r->in.info->netbios_name.string,
1791 r->in.info->domain_name.string,
1793 if (!NT_STATUS_IS_OK(status)) {
1798 status = create_lsa_policy_handle(p->mem_ctx, p,
1799 LSA_HANDLE_TRUST_TYPE,
1802 r->in.info->netbios_name.string,
1804 r->out.trustdom_handle);
1805 if (!NT_STATUS_IS_OK(status)) {
1806 pdb_del_trusteddom_pw(r->in.info->netbios_name.string);
1807 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1810 return NT_STATUS_OK;
1813 /***************************************************************************
1814 _lsa_CreateTrustedDomainEx
1815 ***************************************************************************/
1817 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1818 struct lsa_CreateTrustedDomainEx *r)
1820 struct lsa_CreateTrustedDomainEx2 q;
1821 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1823 ZERO_STRUCT(auth_info);
1825 q.in.policy_handle = r->in.policy_handle;
1826 q.in.info = r->in.info;
1827 q.in.auth_info_internal = &auth_info;
1828 q.in.access_mask = r->in.access_mask;
1829 q.out.trustdom_handle = r->out.trustdom_handle;
1831 return _lsa_CreateTrustedDomainEx2(p, &q);
1834 /***************************************************************************
1835 _lsa_CreateTrustedDomain
1836 ***************************************************************************/
1838 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1839 struct lsa_CreateTrustedDomain *r)
1841 struct lsa_CreateTrustedDomainEx2 c;
1842 struct lsa_TrustDomainInfoInfoEx info;
1843 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1845 ZERO_STRUCT(auth_info);
1847 info.domain_name = r->in.info->name;
1848 info.netbios_name = r->in.info->name;
1849 info.sid = r->in.info->sid;
1850 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1851 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1852 info.trust_attributes = 0;
1854 c.in.policy_handle = r->in.policy_handle;
1856 c.in.auth_info_internal = &auth_info;
1857 c.in.access_mask = r->in.access_mask;
1858 c.out.trustdom_handle = r->out.trustdom_handle;
1860 return _lsa_CreateTrustedDomainEx2(p, &c);
1863 /***************************************************************************
1864 _lsa_DeleteTrustedDomain
1865 ***************************************************************************/
1867 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1868 struct lsa_DeleteTrustedDomain *r)
1871 struct lsa_info *handle;
1872 struct pdb_trusted_domain *td;
1873 struct samu *sam_acct;
1876 /* find the connection policy handle. */
1877 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1878 return NT_STATUS_INVALID_HANDLE;
1881 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1882 return NT_STATUS_INVALID_HANDLE;
1885 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1886 return NT_STATUS_ACCESS_DENIED;
1889 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1890 if (!NT_STATUS_IS_OK(status)) {
1894 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1895 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1896 sid_string_tos(r->in.dom_sid)));
1897 return NT_STATUS_UNSUCCESSFUL;
1900 if (td->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1901 sam_acct = samu_new(p->mem_ctx);
1902 if (sam_acct == NULL) {
1903 return NT_STATUS_NO_MEMORY;
1906 acct_name = talloc_asprintf(p->mem_ctx, "%s$", td->netbios_name);
1907 if (acct_name == NULL) {
1908 return NT_STATUS_NO_MEMORY;
1910 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1911 return NT_STATUS_UNSUCCESSFUL;
1913 status = pdb_delete_sam_account(sam_acct);
1914 if (!NT_STATUS_IS_OK(status)) {
1919 status = pdb_del_trusted_domain(td->netbios_name);
1920 if (!NT_STATUS_IS_OK(status)) {
1924 return NT_STATUS_OK;
1927 /***************************************************************************
1928 _lsa_CloseTrustedDomainEx
1929 ***************************************************************************/
1931 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1932 struct lsa_CloseTrustedDomainEx *r)
1934 return NT_STATUS_NOT_IMPLEMENTED;
1937 /***************************************************************************
1938 _lsa_QueryTrustedDomainInfo
1939 ***************************************************************************/
1941 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
1942 struct lsa_QueryTrustedDomainInfo *r)
1945 struct lsa_info *handle;
1946 union lsa_TrustedDomainInfo *info;
1947 struct pdb_trusted_domain *td;
1948 uint32_t acc_required;
1950 /* find the connection policy handle. */
1951 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
1952 return NT_STATUS_INVALID_HANDLE;
1955 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
1956 return NT_STATUS_INVALID_HANDLE;
1959 switch (r->in.level) {
1960 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1961 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1963 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1964 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
1966 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1967 acc_required = LSA_TRUSTED_QUERY_POSIX;
1969 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
1970 acc_required = LSA_TRUSTED_QUERY_AUTH;
1972 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1973 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1975 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1976 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1978 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1979 acc_required = LSA_TRUSTED_QUERY_AUTH;
1981 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1982 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1983 LSA_TRUSTED_QUERY_POSIX |
1984 LSA_TRUSTED_QUERY_AUTH;
1986 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1987 acc_required = LSA_TRUSTED_QUERY_AUTH;
1989 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1990 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1991 LSA_TRUSTED_QUERY_POSIX |
1992 LSA_TRUSTED_QUERY_AUTH;
1994 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1995 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1997 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1998 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1999 LSA_TRUSTED_QUERY_POSIX |
2000 LSA_TRUSTED_QUERY_AUTH;
2002 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2003 acc_required = LSA_TRUSTED_QUERY_POSIX;
2006 return NT_STATUS_INVALID_PARAMETER;
2009 if (!(handle->access & acc_required)) {
2010 return NT_STATUS_ACCESS_DENIED;
2013 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2014 if (!NT_STATUS_IS_OK(status)) {
2018 info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
2020 return NT_STATUS_NO_MEMORY;
2023 switch (r->in.level) {
2024 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2025 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2027 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2028 return NT_STATUS_INVALID_PARAMETER;
2029 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2031 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2032 return NT_STATUS_INVALID_INFO_CLASS;
2033 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2034 return NT_STATUS_INVALID_PARAMETER;
2035 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2036 init_lsa_StringLarge(&info->info_ex.domain_name, td->domain_name);
2037 init_lsa_StringLarge(&info->info_ex.netbios_name, td->netbios_name);
2038 info->info_ex.sid = dom_sid_dup(info, &td->security_identifier);
2039 if (!info->info_ex.sid) {
2040 return NT_STATUS_NO_MEMORY;
2042 info->info_ex.trust_direction = td->trust_direction;
2043 info->info_ex.trust_type = td->trust_type;
2044 info->info_ex.trust_attributes = td->trust_attributes;
2046 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2047 return NT_STATUS_INVALID_INFO_CLASS;
2048 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2050 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2051 return NT_STATUS_INVALID_INFO_CLASS;
2052 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2053 return NT_STATUS_INVALID_INFO_CLASS;
2054 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2055 return NT_STATUS_INVALID_PARAMETER;
2056 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2058 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2061 return NT_STATUS_INVALID_PARAMETER;
2064 *r->out.info = info;
2066 return NT_STATUS_OK;
2069 /***************************************************************************
2070 _lsa_QueryTrustedDomainInfoBySid
2071 ***************************************************************************/
2073 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2074 struct lsa_QueryTrustedDomainInfoBySid *r)
2077 struct policy_handle trustdom_handle;
2078 struct lsa_OpenTrustedDomain o;
2079 struct lsa_QueryTrustedDomainInfo q;
2082 o.in.handle = r->in.handle;
2083 o.in.sid = r->in.dom_sid;
2084 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2085 o.out.trustdom_handle = &trustdom_handle;
2087 status = _lsa_OpenTrustedDomain(p, &o);
2088 if (!NT_STATUS_IS_OK(status)) {
2092 q.in.trustdom_handle = &trustdom_handle;
2093 q.in.level = r->in.level;
2094 q.out.info = r->out.info;
2096 status = _lsa_QueryTrustedDomainInfo(p, &q);
2097 if (!NT_STATUS_IS_OK(status)) {
2101 c.in.handle = &trustdom_handle;
2102 c.out.handle = &trustdom_handle;
2104 return _lsa_Close(p, &c);
2107 /***************************************************************************
2108 _lsa_QueryTrustedDomainInfoByName
2109 ***************************************************************************/
2111 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2112 struct lsa_QueryTrustedDomainInfoByName *r)
2115 struct policy_handle trustdom_handle;
2116 struct lsa_OpenTrustedDomainByName o;
2117 struct lsa_QueryTrustedDomainInfo q;
2120 o.in.handle = r->in.handle;
2121 o.in.name.string = r->in.trusted_domain->string;
2122 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2123 o.out.trustdom_handle = &trustdom_handle;
2125 status = _lsa_OpenTrustedDomainByName(p, &o);
2126 if (!NT_STATUS_IS_OK(status)) {
2127 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2128 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2133 q.in.trustdom_handle = &trustdom_handle;
2134 q.in.level = r->in.level;
2135 q.out.info = r->out.info;
2137 status = _lsa_QueryTrustedDomainInfo(p, &q);
2138 if (!NT_STATUS_IS_OK(status)) {
2142 c.in.handle = &trustdom_handle;
2143 c.out.handle = &trustdom_handle;
2145 return _lsa_Close(p, &c);
2148 /***************************************************************************
2149 ***************************************************************************/
2151 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p, struct lsa_CreateSecret *r)
2153 return NT_STATUS_ACCESS_DENIED;
2156 /***************************************************************************
2157 ***************************************************************************/
2159 NTSTATUS _lsa_SetSecret(struct pipes_struct *p, struct lsa_SetSecret *r)
2161 return NT_STATUS_ACCESS_DENIED;
2164 /***************************************************************************
2166 ***************************************************************************/
2168 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2169 struct lsa_DeleteObject *r)
2172 struct lsa_info *info = NULL;
2174 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2175 return NT_STATUS_INVALID_HANDLE;
2178 if (!(info->access & SEC_STD_DELETE)) {
2179 return NT_STATUS_ACCESS_DENIED;
2182 switch (info->type) {
2183 case LSA_HANDLE_ACCOUNT_TYPE:
2184 status = privilege_delete_account(&info->sid);
2185 if (!NT_STATUS_IS_OK(status)) {
2186 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2187 nt_errstr(status)));
2191 case LSA_HANDLE_TRUST_TYPE:
2192 if (!pdb_del_trusteddom_pw(info->name)) {
2193 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2195 status = NT_STATUS_OK;
2198 return NT_STATUS_INVALID_HANDLE;
2201 close_policy_hnd(p, r->in.handle);
2202 ZERO_STRUCTP(r->out.handle);
2207 /***************************************************************************
2209 ***************************************************************************/
2211 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2212 struct lsa_EnumPrivs *r)
2214 struct lsa_info *handle;
2216 uint32 enum_context = *r->in.resume_handle;
2217 int num_privs = num_privileges_in_short_list();
2218 struct lsa_PrivEntry *entries = NULL;
2220 /* remember that the enum_context starts at 0 and not 1 */
2222 if ( enum_context >= num_privs )
2223 return NT_STATUS_NO_MORE_ENTRIES;
2225 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2226 enum_context, num_privs));
2228 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2229 return NT_STATUS_INVALID_HANDLE;
2231 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2232 return NT_STATUS_INVALID_HANDLE;
2235 /* check if the user has enough rights
2236 I don't know if it's the right one. not documented. */
2238 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2239 return NT_STATUS_ACCESS_DENIED;
2242 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2244 return NT_STATUS_NO_MEMORY;
2250 for (i = 0; i < num_privs; i++) {
2251 if( i < enum_context) {
2253 init_lsa_StringLarge(&entries[i].name, NULL);
2255 entries[i].luid.low = 0;
2256 entries[i].luid.high = 0;
2259 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2261 entries[i].luid.low = sec_privilege_from_index(i);
2262 entries[i].luid.high = 0;
2266 enum_context = num_privs;
2268 *r->out.resume_handle = enum_context;
2269 r->out.privs->count = num_privs;
2270 r->out.privs->privs = entries;
2272 return NT_STATUS_OK;
2275 /***************************************************************************
2276 _lsa_LookupPrivDisplayName
2277 ***************************************************************************/
2279 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2280 struct lsa_LookupPrivDisplayName *r)
2282 struct lsa_info *handle;
2283 const char *description;
2284 struct lsa_StringLarge *lsa_name;
2286 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2287 return NT_STATUS_INVALID_HANDLE;
2289 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2290 return NT_STATUS_INVALID_HANDLE;
2293 /* check if the user has enough rights */
2296 * I don't know if it's the right one. not documented.
2298 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2299 return NT_STATUS_ACCESS_DENIED;
2301 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2303 description = get_privilege_dispname(r->in.name->string);
2305 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2306 return NT_STATUS_NO_SUCH_PRIVILEGE;
2309 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2311 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2313 return NT_STATUS_NO_MEMORY;
2316 init_lsa_StringLarge(lsa_name, description);
2318 *r->out.returned_language_id = r->in.language_id;
2319 *r->out.disp_name = lsa_name;
2321 return NT_STATUS_OK;
2324 /***************************************************************************
2326 ***************************************************************************/
2328 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2329 struct lsa_EnumAccounts *r)
2331 struct lsa_info *handle;
2332 struct dom_sid *sid_list;
2333 int i, j, num_entries;
2335 struct lsa_SidPtr *sids = NULL;
2337 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2338 return NT_STATUS_INVALID_HANDLE;
2340 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2341 return NT_STATUS_INVALID_HANDLE;
2344 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2345 return NT_STATUS_ACCESS_DENIED;
2350 /* The only way we can currently find out all the SIDs that have been
2351 privileged is to scan all privileges */
2353 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2354 if (!NT_STATUS_IS_OK(status)) {
2358 if (*r->in.resume_handle >= num_entries) {
2359 return NT_STATUS_NO_MORE_ENTRIES;
2362 if (num_entries - *r->in.resume_handle) {
2363 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2364 num_entries - *r->in.resume_handle);
2366 talloc_free(sid_list);
2367 return NT_STATUS_NO_MEMORY;
2370 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2371 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2373 talloc_free(sid_list);
2374 return NT_STATUS_NO_MEMORY;
2379 talloc_free(sid_list);
2381 *r->out.resume_handle = num_entries;
2382 r->out.sids->num_sids = num_entries;
2383 r->out.sids->sids = sids;
2385 return NT_STATUS_OK;
2388 /***************************************************************************
2390 ***************************************************************************/
2392 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2393 struct lsa_GetUserName *r)
2395 const char *username, *domname;
2396 struct lsa_String *account_name = NULL;
2397 struct lsa_String *authority_name = NULL;
2399 if (r->in.account_name &&
2400 *r->in.account_name) {
2401 return NT_STATUS_INVALID_PARAMETER;
2404 if (r->in.authority_name &&
2405 *r->in.authority_name) {
2406 return NT_STATUS_INVALID_PARAMETER;
2409 if (security_session_user_level(p->session_info, NULL) < SECURITY_USER) {
2411 * I'm 99% sure this is not the right place to do this,
2412 * global_sid_Anonymous should probably be put into the token
2413 * instead of the guest id -- vl
2415 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2416 &domname, &username, NULL)) {
2417 return NT_STATUS_NO_MEMORY;
2420 username = p->session_info->unix_info->sanitized_username;
2421 domname = p->session_info->info->domain_name;
2424 account_name = talloc(p->mem_ctx, struct lsa_String);
2425 if (!account_name) {
2426 return NT_STATUS_NO_MEMORY;
2428 init_lsa_String(account_name, username);
2430 if (r->out.authority_name) {
2431 authority_name = talloc(p->mem_ctx, struct lsa_String);
2432 if (!authority_name) {
2433 return NT_STATUS_NO_MEMORY;
2435 init_lsa_String(authority_name, domname);
2438 *r->out.account_name = account_name;
2439 if (r->out.authority_name) {
2440 *r->out.authority_name = authority_name;
2443 return NT_STATUS_OK;
2446 /***************************************************************************
2448 ***************************************************************************/
2450 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2451 struct lsa_CreateAccount *r)
2454 struct lsa_info *handle;
2455 uint32_t acc_granted;
2456 struct security_descriptor *psd;
2459 /* find the connection policy handle. */
2460 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2461 return NT_STATUS_INVALID_HANDLE;
2463 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2464 return NT_STATUS_INVALID_HANDLE;
2467 /* check if the user has enough rights */
2469 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2470 return NT_STATUS_ACCESS_DENIED;
2473 /* Work out max allowed. */
2474 map_max_allowed_access(p->session_info->security_token,
2475 p->session_info->unix_token,
2476 &r->in.access_mask);
2478 /* map the generic bits to the lsa policy ones */
2479 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2481 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2482 &lsa_account_mapping,
2483 r->in.sid, LSA_POLICY_ALL_ACCESS);
2484 if (!NT_STATUS_IS_OK(status)) {
2488 status = access_check_object(psd, p->session_info->security_token,
2489 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2490 &acc_granted, "_lsa_CreateAccount");
2491 if (!NT_STATUS_IS_OK(status)) {
2495 if ( is_privileged_sid( r->in.sid ) )
2496 return NT_STATUS_OBJECT_NAME_COLLISION;
2498 status = create_lsa_policy_handle(p->mem_ctx, p,
2499 LSA_HANDLE_ACCOUNT_TYPE,
2504 r->out.acct_handle);
2505 if (!NT_STATUS_IS_OK(status)) {
2506 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2509 return privilege_create_account(r->in.sid);
2512 /***************************************************************************
2514 ***************************************************************************/
2516 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2517 struct lsa_OpenAccount *r)
2519 struct lsa_info *handle;
2520 struct security_descriptor *psd = NULL;
2522 uint32_t des_access = r->in.access_mask;
2523 uint32_t acc_granted;
2526 /* find the connection policy handle. */
2527 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2528 return NT_STATUS_INVALID_HANDLE;
2530 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2531 return NT_STATUS_INVALID_HANDLE;
2534 /* des_access is for the account here, not the policy
2535 * handle - so don't check against policy handle. */
2537 /* Work out max allowed. */
2538 map_max_allowed_access(p->session_info->security_token,
2539 p->session_info->unix_token,
2542 /* map the generic bits to the lsa account ones */
2543 se_map_generic(&des_access, &lsa_account_mapping);
2545 /* get the generic lsa account SD until we store it */
2546 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2547 &lsa_account_mapping,
2548 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2549 if (!NT_STATUS_IS_OK(status)) {
2553 status = access_check_object(psd, p->session_info->security_token,
2554 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2555 &acc_granted, "_lsa_OpenAccount" );
2556 if (!NT_STATUS_IS_OK(status)) {
2560 /* TODO: Fis the parsing routine before reenabling this check! */
2562 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2563 return NT_STATUS_ACCESS_DENIED;
2566 status = create_lsa_policy_handle(p->mem_ctx, p,
2567 LSA_HANDLE_ACCOUNT_TYPE,
2572 r->out.acct_handle);
2573 if (!NT_STATUS_IS_OK(status)) {
2574 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2577 return NT_STATUS_OK;
2580 /***************************************************************************
2581 _lsa_EnumPrivsAccount
2582 For a given SID, enumerate all the privilege this account has.
2583 ***************************************************************************/
2585 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2586 struct lsa_EnumPrivsAccount *r)
2588 NTSTATUS status = NT_STATUS_OK;
2589 struct lsa_info *info=NULL;
2590 PRIVILEGE_SET *privileges;
2591 struct lsa_PrivilegeSet *priv_set = NULL;
2593 /* find the connection policy handle. */
2594 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2595 return NT_STATUS_INVALID_HANDLE;
2597 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2598 return NT_STATUS_INVALID_HANDLE;
2601 if (!(info->access & LSA_ACCOUNT_VIEW))
2602 return NT_STATUS_ACCESS_DENIED;
2604 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2605 if (!NT_STATUS_IS_OK(status)) {
2609 *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2611 return NT_STATUS_NO_MEMORY;
2614 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2615 sid_string_dbg(&info->sid),
2616 privileges->count));
2618 priv_set->count = privileges->count;
2619 priv_set->unknown = 0;
2620 priv_set->set = talloc_move(priv_set, &privileges->set);
2625 /***************************************************************************
2626 _lsa_GetSystemAccessAccount
2627 ***************************************************************************/
2629 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2630 struct lsa_GetSystemAccessAccount *r)
2633 struct lsa_info *info = NULL;
2634 struct lsa_EnumPrivsAccount e;
2635 struct lsa_PrivilegeSet *privset;
2637 /* find the connection policy handle. */
2639 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2640 return NT_STATUS_INVALID_HANDLE;
2642 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2643 return NT_STATUS_INVALID_HANDLE;
2646 if (!(info->access & LSA_ACCOUNT_VIEW))
2647 return NT_STATUS_ACCESS_DENIED;
2649 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2651 return NT_STATUS_NO_MEMORY;
2654 e.in.handle = r->in.handle;
2655 e.out.privs = &privset;
2657 status = _lsa_EnumPrivsAccount(p, &e);
2658 if (!NT_STATUS_IS_OK(status)) {
2659 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2660 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2661 nt_errstr(status)));
2665 /* Samba4 would iterate over the privset to merge the policy mode bits,
2666 * not sure samba3 can do the same here, so just return what we did in
2670 0x01 -> Log on locally
2671 0x02 -> Access this computer from network
2672 0x04 -> Log on as a batch job
2673 0x10 -> Log on as a service
2675 they can be ORed together
2678 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2679 LSA_POLICY_MODE_NETWORK;
2681 return NT_STATUS_OK;
2684 /***************************************************************************
2685 update the systemaccount information
2686 ***************************************************************************/
2688 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2689 struct lsa_SetSystemAccessAccount *r)
2691 struct lsa_info *info=NULL;
2694 /* find the connection policy handle. */
2695 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2696 return NT_STATUS_INVALID_HANDLE;
2698 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2699 return NT_STATUS_INVALID_HANDLE;
2702 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2703 return NT_STATUS_ACCESS_DENIED;
2706 if (!pdb_getgrsid(&map, info->sid))
2707 return NT_STATUS_NO_SUCH_GROUP;
2709 return pdb_update_group_mapping_entry(&map);
2712 /***************************************************************************
2713 _lsa_AddPrivilegesToAccount
2714 For a given SID, add some privileges.
2715 ***************************************************************************/
2717 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
2718 struct lsa_AddPrivilegesToAccount *r)
2720 struct lsa_info *info = NULL;
2721 struct lsa_PrivilegeSet *set = NULL;
2723 /* find the connection policy handle. */
2724 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2725 return NT_STATUS_INVALID_HANDLE;
2727 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2728 return NT_STATUS_INVALID_HANDLE;
2731 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2732 return NT_STATUS_ACCESS_DENIED;
2737 if ( !grant_privilege_set( &info->sid, set ) ) {
2738 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2739 sid_string_dbg(&info->sid) ));
2740 return NT_STATUS_NO_SUCH_PRIVILEGE;
2743 return NT_STATUS_OK;
2746 /***************************************************************************
2747 _lsa_RemovePrivilegesFromAccount
2748 For a given SID, remove some privileges.
2749 ***************************************************************************/
2751 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2752 struct lsa_RemovePrivilegesFromAccount *r)
2754 struct lsa_info *info = NULL;
2755 struct lsa_PrivilegeSet *set = NULL;
2757 /* find the connection policy handle. */
2758 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2759 return NT_STATUS_INVALID_HANDLE;
2761 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2762 return NT_STATUS_INVALID_HANDLE;
2765 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2766 return NT_STATUS_ACCESS_DENIED;
2771 if ( !revoke_privilege_set( &info->sid, set) ) {
2772 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2773 sid_string_dbg(&info->sid) ));
2774 return NT_STATUS_NO_SUCH_PRIVILEGE;
2777 return NT_STATUS_OK;
2780 /***************************************************************************
2782 ***************************************************************************/
2784 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2785 struct lsa_LookupPrivName *r)
2787 struct lsa_info *info = NULL;
2789 struct lsa_StringLarge *lsa_name;
2791 /* find the connection policy handle. */
2792 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2793 return NT_STATUS_INVALID_HANDLE;
2796 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2797 return NT_STATUS_INVALID_HANDLE;
2800 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2801 return NT_STATUS_ACCESS_DENIED;
2804 if (r->in.luid->high != 0) {
2805 return NT_STATUS_NO_SUCH_PRIVILEGE;
2808 name = sec_privilege_name(r->in.luid->low);
2810 return NT_STATUS_NO_SUCH_PRIVILEGE;
2813 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2815 return NT_STATUS_NO_MEMORY;
2818 lsa_name->string = talloc_strdup(lsa_name, name);
2819 if (!lsa_name->string) {
2820 TALLOC_FREE(lsa_name);
2821 return NT_STATUS_NO_MEMORY;
2824 *r->out.name = lsa_name;
2826 return NT_STATUS_OK;
2829 /***************************************************************************
2831 ***************************************************************************/
2833 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
2834 struct lsa_QuerySecurity *r)
2836 struct lsa_info *handle=NULL;
2837 struct security_descriptor *psd = NULL;
2841 /* find the connection policy handle. */
2842 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2843 return NT_STATUS_INVALID_HANDLE;
2845 switch (handle->type) {
2846 case LSA_HANDLE_POLICY_TYPE:
2847 case LSA_HANDLE_ACCOUNT_TYPE:
2848 case LSA_HANDLE_TRUST_TYPE:
2850 sd_size = ndr_size_security_descriptor(psd, 0);
2851 status = NT_STATUS_OK;
2854 status = NT_STATUS_INVALID_HANDLE;
2858 if (!NT_STATUS_IS_OK(status)) {
2862 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2863 if (!*r->out.sdbuf) {
2864 return NT_STATUS_NO_MEMORY;
2870 /***************************************************************************
2871 _lsa_AddAccountRights
2872 ***************************************************************************/
2874 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
2875 struct lsa_AddAccountRights *r)
2877 struct lsa_info *info = NULL;
2879 uint32_t acc_granted = 0;
2880 struct security_descriptor *psd = NULL;
2885 /* find the connection policy handle. */
2886 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2887 return NT_STATUS_INVALID_HANDLE;
2889 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2890 return NT_STATUS_INVALID_HANDLE;
2893 /* get the generic lsa account SD for this SID until we store it */
2894 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2895 &lsa_account_mapping,
2896 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2897 if (!NT_STATUS_IS_OK(status)) {
2902 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2903 * on the policy handle. If it does, ask for
2904 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2905 * on the account sid. We don't check here so just use the latter. JRA.
2908 status = access_check_object(psd, p->session_info->security_token,
2909 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2910 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2911 &acc_granted, "_lsa_AddAccountRights" );
2912 if (!NT_STATUS_IS_OK(status)) {
2916 /* according to an NT4 PDC, you can add privileges to SIDs even without
2917 call_lsa_create_account() first. And you can use any arbitrary SID. */
2919 sid_copy( &sid, r->in.sid );
2921 for ( i=0; i < r->in.rights->count; i++ ) {
2923 const char *privname = r->in.rights->names[i].string;
2925 /* only try to add non-null strings */
2930 if ( !grant_privilege_by_name( &sid, privname ) ) {
2931 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2933 return NT_STATUS_NO_SUCH_PRIVILEGE;
2937 return NT_STATUS_OK;
2940 /***************************************************************************
2941 _lsa_RemoveAccountRights
2942 ***************************************************************************/
2944 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
2945 struct lsa_RemoveAccountRights *r)
2947 struct lsa_info *info = NULL;
2949 struct security_descriptor *psd = NULL;
2952 const char *privname = NULL;
2953 uint32_t acc_granted = 0;
2956 /* find the connection policy handle. */
2957 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2958 return NT_STATUS_INVALID_HANDLE;
2960 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2961 return NT_STATUS_INVALID_HANDLE;
2964 /* get the generic lsa account SD for this SID until we store it */
2965 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2966 &lsa_account_mapping,
2967 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2968 if (!NT_STATUS_IS_OK(status)) {
2973 * From the MS DOCs. We need
2974 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2975 * and DELETE on the account sid.
2978 status = access_check_object(psd, p->session_info->security_token,
2979 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2980 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2981 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
2982 &acc_granted, "_lsa_RemoveAccountRights");
2983 if (!NT_STATUS_IS_OK(status)) {
2987 sid_copy( &sid, r->in.sid );
2989 if ( r->in.remove_all ) {
2990 if ( !revoke_all_privileges( &sid ) )
2991 return NT_STATUS_ACCESS_DENIED;
2993 return NT_STATUS_OK;
2996 for ( i=0; i < r->in.rights->count; i++ ) {
2998 privname = r->in.rights->names[i].string;
3000 /* only try to add non-null strings */
3005 if ( !revoke_privilege_by_name( &sid, privname ) ) {
3006 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3008 return NT_STATUS_NO_SUCH_PRIVILEGE;
3012 return NT_STATUS_OK;
3015 /*******************************************************************
3016 ********************************************************************/
3018 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3019 struct lsa_RightSet *r,
3020 PRIVILEGE_SET *privileges)
3023 const char *privname;
3024 const char **privname_array = NULL;
3027 for (i=0; i<privileges->count; i++) {
3028 if (privileges->set[i].luid.high) {
3031 privname = sec_privilege_name(privileges->set[i].luid.low);
3033 if (!add_string_to_array(mem_ctx, privname,
3034 &privname_array, &num_priv)) {
3035 return NT_STATUS_NO_MEMORY;
3042 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3045 return NT_STATUS_NO_MEMORY;
3048 for (i=0; i<num_priv; i++) {
3049 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3052 r->count = num_priv;
3055 return NT_STATUS_OK;
3058 /***************************************************************************
3059 _lsa_EnumAccountRights
3060 ***************************************************************************/
3062 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3063 struct lsa_EnumAccountRights *r)
3066 struct lsa_info *info = NULL;
3067 PRIVILEGE_SET *privileges;
3069 /* find the connection policy handle. */
3071 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3072 return NT_STATUS_INVALID_HANDLE;
3074 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3075 return NT_STATUS_INVALID_HANDLE;
3078 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3079 return NT_STATUS_ACCESS_DENIED;
3082 /* according to an NT4 PDC, you can add privileges to SIDs even without
3083 call_lsa_create_account() first. And you can use any arbitrary SID. */
3085 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3086 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3087 * the lsa database */
3089 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3090 if (!NT_STATUS_IS_OK(status)) {
3094 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3095 sid_string_dbg(r->in.sid), privileges->count));
3097 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3102 /***************************************************************************
3103 _lsa_LookupPrivValue
3104 ***************************************************************************/
3106 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3107 struct lsa_LookupPrivValue *r)
3109 struct lsa_info *info = NULL;
3110 const char *name = NULL;
3112 /* find the connection policy handle. */
3114 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3115 return NT_STATUS_INVALID_HANDLE;
3117 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3118 return NT_STATUS_INVALID_HANDLE;
3121 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3122 return NT_STATUS_ACCESS_DENIED;
3124 name = r->in.name->string;
3126 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3128 r->out.luid->low = sec_privilege_id(name);
3129 r->out.luid->high = 0;
3130 if (r->out.luid->low == SEC_PRIV_INVALID) {
3131 return NT_STATUS_NO_SUCH_PRIVILEGE;
3133 return NT_STATUS_OK;
3136 /***************************************************************************
3137 _lsa_EnumAccountsWithUserRight
3138 ***************************************************************************/
3140 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3141 struct lsa_EnumAccountsWithUserRight *r)
3144 struct lsa_info *info = NULL;
3145 struct dom_sid *sids = NULL;
3148 enum sec_privilege privilege;
3150 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3151 return NT_STATUS_INVALID_HANDLE;
3154 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3155 return NT_STATUS_INVALID_HANDLE;
3158 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3159 return NT_STATUS_ACCESS_DENIED;
3162 if (!r->in.name || !r->in.name->string) {
3163 return NT_STATUS_NO_SUCH_PRIVILEGE;
3166 privilege = sec_privilege_id(r->in.name->string);
3167 if (privilege == SEC_PRIV_INVALID) {
3168 return NT_STATUS_NO_SUCH_PRIVILEGE;
3171 status = privilege_enum_sids(privilege, p->mem_ctx,
3173 if (!NT_STATUS_IS_OK(status)) {
3177 r->out.sids->num_sids = num_sids;
3178 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3179 r->out.sids->num_sids);
3181 for (i=0; i < r->out.sids->num_sids; i++) {
3182 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3184 if (!r->out.sids->sids[i].sid) {
3185 TALLOC_FREE(r->out.sids->sids);
3186 r->out.sids->num_sids = 0;
3187 return NT_STATUS_NO_MEMORY;
3191 return NT_STATUS_OK;
3194 /***************************************************************************
3196 ***************************************************************************/
3198 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3199 struct lsa_Delete *r)
3201 return NT_STATUS_NOT_SUPPORTED;
3205 * From here on the server routines are just dummy ones to make smbd link with
3206 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3207 * pulling the server stubs across one by one.
3210 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3212 p->rng_fault_state = True;
3213 return NT_STATUS_NOT_IMPLEMENTED;
3216 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3217 struct lsa_ChangePassword *r)
3219 p->rng_fault_state = True;
3220 return NT_STATUS_NOT_IMPLEMENTED;
3223 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3225 p->rng_fault_state = True;
3226 return NT_STATUS_NOT_IMPLEMENTED;
3229 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3231 p->rng_fault_state = True;
3232 return NT_STATUS_NOT_IMPLEMENTED;
3235 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3236 struct lsa_GetQuotasForAccount *r)
3238 p->rng_fault_state = True;
3239 return NT_STATUS_NOT_IMPLEMENTED;
3242 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3243 struct lsa_SetQuotasForAccount *r)
3245 p->rng_fault_state = True;
3246 return NT_STATUS_NOT_IMPLEMENTED;
3249 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3250 struct lsa_SetInformationTrustedDomain *r)
3252 p->rng_fault_state = True;
3253 return NT_STATUS_NOT_IMPLEMENTED;
3256 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
3258 p->rng_fault_state = True;
3259 return NT_STATUS_NOT_IMPLEMENTED;
3262 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3263 struct lsa_SetTrustedDomainInfo *r)
3265 p->rng_fault_state = True;
3266 return NT_STATUS_NOT_IMPLEMENTED;
3269 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3270 struct lsa_StorePrivateData *r)
3272 p->rng_fault_state = True;
3273 return NT_STATUS_NOT_IMPLEMENTED;
3276 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3277 struct lsa_RetrievePrivateData *r)
3279 p->rng_fault_state = True;
3280 return NT_STATUS_NOT_IMPLEMENTED;
3283 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3284 struct lsa_SetInfoPolicy2 *r)
3286 p->rng_fault_state = True;
3287 return NT_STATUS_NOT_IMPLEMENTED;
3290 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3291 struct lsa_SetTrustedDomainInfoByName *r)
3293 p->rng_fault_state = True;
3294 return NT_STATUS_NOT_IMPLEMENTED;
3297 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3298 struct lsa_EnumTrustedDomainsEx *r)
3300 struct lsa_info *info;
3302 struct pdb_trusted_domain **domains;
3303 struct lsa_TrustDomainInfoInfoEx *entries;
3307 /* bail out early if pdb backend is not capable of ex trusted domains,
3308 * if we dont do that, the client might not call
3309 * _lsa_EnumTrustedDomains() afterwards - gd */
3311 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3312 p->rng_fault_state = True;
3313 return NT_STATUS_NOT_IMPLEMENTED;
3316 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3317 return NT_STATUS_INVALID_HANDLE;
3319 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3320 return NT_STATUS_INVALID_HANDLE;
3323 /* check if the user has enough rights */
3324 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3325 return NT_STATUS_ACCESS_DENIED;
3328 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3331 if (!NT_STATUS_IS_OK(nt_status)) {
3335 entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3338 return NT_STATUS_NO_MEMORY;
3341 for (i=0; i<count; i++) {
3342 init_lsa_StringLarge(&entries[i].netbios_name,
3343 domains[i]->netbios_name);
3344 entries[i].sid = &domains[i]->security_identifier;
3347 if (*r->in.resume_handle >= count) {
3348 *r->out.resume_handle = -1;
3349 TALLOC_FREE(entries);
3350 return NT_STATUS_NO_MORE_ENTRIES;
3353 /* return the rest, limit by max_size. Note that we
3354 use the w2k3 element size value of 60 */
3355 r->out.domains->count = count - *r->in.resume_handle;
3356 r->out.domains->count = MIN(r->out.domains->count,
3357 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3359 r->out.domains->domains = entries + *r->in.resume_handle;
3361 if (r->out.domains->count < count - *r->in.resume_handle) {
3362 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3363 return STATUS_MORE_ENTRIES;
3366 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3367 * always be larger than the previous input resume handle, in
3368 * particular when hitting the last query it is vital to set the
3369 * resume handle correctly to avoid infinite client loops, as
3370 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3371 * status is NT_STATUS_OK - gd */
3373 *r->out.resume_handle = (uint32_t)-1;
3375 return NT_STATUS_OK;
3378 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3379 struct lsa_QueryDomainInformationPolicy *r)
3381 p->rng_fault_state = True;
3382 return NT_STATUS_NOT_IMPLEMENTED;
3385 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3386 struct lsa_SetDomainInformationPolicy *r)
3388 p->rng_fault_state = True;
3389 return NT_STATUS_NOT_IMPLEMENTED;
3392 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3394 p->rng_fault_state = True;
3395 return NT_STATUS_NOT_IMPLEMENTED;
3398 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3400 p->rng_fault_state = True;
3401 return NT_STATUS_NOT_IMPLEMENTED;
3404 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3406 p->rng_fault_state = True;
3407 return NT_STATUS_NOT_IMPLEMENTED;
3410 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3412 p->rng_fault_state = True;
3413 return NT_STATUS_NOT_IMPLEMENTED;
3416 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3417 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3419 p->rng_fault_state = True;
3420 return NT_STATUS_NOT_IMPLEMENTED;
3423 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3424 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3426 p->rng_fault_state = True;
3427 return NT_STATUS_NOT_IMPLEMENTED;
3430 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3432 p->rng_fault_state = True;
3433 return NT_STATUS_NOT_IMPLEMENTED;
3436 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3437 struct lsa_CREDRGETTARGETINFO *r)
3439 p->rng_fault_state = True;
3440 return NT_STATUS_NOT_IMPLEMENTED;
3443 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3444 struct lsa_CREDRPROFILELOADED *r)
3446 p->rng_fault_state = True;
3447 return NT_STATUS_NOT_IMPLEMENTED;
3450 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3451 struct lsa_CREDRGETSESSIONTYPES *r)
3453 p->rng_fault_state = True;
3454 return NT_STATUS_NOT_IMPLEMENTED;
3457 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3458 struct lsa_LSARREGISTERAUDITEVENT *r)
3460 p->rng_fault_state = True;
3461 return NT_STATUS_NOT_IMPLEMENTED;
3464 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3465 struct lsa_LSARGENAUDITEVENT *r)
3467 p->rng_fault_state = True;
3468 return NT_STATUS_NOT_IMPLEMENTED;
3471 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3472 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3474 p->rng_fault_state = True;
3475 return NT_STATUS_NOT_IMPLEMENTED;
3478 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3479 struct lsa_lsaRQueryForestTrustInformation *r)
3481 p->rng_fault_state = True;
3482 return NT_STATUS_NOT_IMPLEMENTED;
3485 #define DNS_CMP_MATCH 0
3486 #define DNS_CMP_FIRST_IS_CHILD 1
3487 #define DNS_CMP_SECOND_IS_CHILD 2
3488 #define DNS_CMP_NO_MATCH 3
3490 /* this function assumes names are well formed DNS names.
3491 * it doesn't validate them */
3492 static int dns_cmp(const char *s1, size_t l1,
3493 const char *s2, size_t l2)
3495 const char *p1, *p2;
3500 if (strcasecmp_m(s1, s2) == 0) {
3501 return DNS_CMP_MATCH;
3503 return DNS_CMP_NO_MATCH;
3511 cret = DNS_CMP_FIRST_IS_CHILD;
3517 cret = DNS_CMP_SECOND_IS_CHILD;
3520 if (p1[t1 - t2 - 1] != '.') {
3521 return DNS_CMP_NO_MATCH;
3524 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
3528 return DNS_CMP_NO_MATCH;
3531 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3532 struct lsa_ForestTrustInformation *lfti,
3533 struct ForestTrustInfo *fti)
3535 struct lsa_ForestTrustRecord *lrec;
3536 struct ForestTrustInfoRecord *rec;
3537 struct lsa_StringLarge *tln;
3538 struct lsa_ForestTrustDomainInfo *info;
3542 fti->count = lfti->count;
3543 fti->records = talloc_array(mem_ctx,
3544 struct ForestTrustInfoRecordArmor,
3546 if (!fti->records) {
3547 return NT_STATUS_NO_MEMORY;
3549 for (i = 0; i < fti->count; i++) {
3550 lrec = lfti->entries[i];
3551 rec = &fti->records[i].record;
3553 rec->flags = lrec->flags;
3554 rec->timestamp = lrec->time;
3555 rec->type = lrec->type;
3557 switch (lrec->type) {
3558 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3559 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3560 tln = &lrec->forest_trust_data.top_level_name;
3561 rec->data.name.string =
3562 talloc_strdup(mem_ctx, tln->string);
3563 if (!rec->data.name.string) {
3564 return NT_STATUS_NO_MEMORY;
3566 rec->data.name.size = strlen(rec->data.name.string);
3568 case LSA_FOREST_TRUST_DOMAIN_INFO:
3569 info = &lrec->forest_trust_data.domain_info;
3570 rec->data.info.sid = *info->domain_sid;
3571 rec->data.info.dns_name.string =
3572 talloc_strdup(mem_ctx,
3573 info->dns_domain_name.string);
3574 if (!rec->data.info.dns_name.string) {
3575 return NT_STATUS_NO_MEMORY;
3577 rec->data.info.dns_name.size =
3578 strlen(rec->data.info.dns_name.string);
3579 rec->data.info.netbios_name.string =
3580 talloc_strdup(mem_ctx,
3581 info->netbios_domain_name.string);
3582 if (!rec->data.info.netbios_name.string) {
3583 return NT_STATUS_NO_MEMORY;
3585 rec->data.info.netbios_name.size =
3586 strlen(rec->data.info.netbios_name.string);
3589 return NT_STATUS_INVALID_DOMAIN_STATE;
3593 return NT_STATUS_OK;
3596 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3597 uint32_t index, uint32_t collision_type,
3598 uint32_t conflict_type, const char *tdo_name);
3600 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
3601 const char *tdo_name,
3602 struct ForestTrustInfo *tdo_fti,
3603 struct ForestTrustInfo *new_fti,
3604 struct lsa_ForestTrustCollisionInfo *c_info)
3606 struct ForestTrustInfoRecord *nrec;
3607 struct ForestTrustInfoRecord *trec;
3608 const char *dns_name;
3609 const char *nb_name = NULL;
3610 struct dom_sid *sid = NULL;
3611 const char *tname = NULL;
3616 uint32_t new_fti_idx;
3618 /* use always TDO type, until we understand when Xref can be used */
3619 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
3624 bool ex_rule = false;
3627 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
3629 nrec = &new_fti->records[new_fti_idx].record;
3631 tln_conflict = false;
3632 sid_conflict = false;
3633 nb_conflict = false;
3636 switch (nrec->type) {
3637 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3638 /* exclusions do not conflict by definition */
3641 case FOREST_TRUST_TOP_LEVEL_NAME:
3642 dns_name = nrec->data.name.string;
3643 dns_len = nrec->data.name.size;
3646 case LSA_FOREST_TRUST_DOMAIN_INFO:
3647 dns_name = nrec->data.info.dns_name.string;
3648 dns_len = nrec->data.info.dns_name.size;
3649 nb_name = nrec->data.info.netbios_name.string;
3650 nb_len = nrec->data.info.netbios_name.size;
3651 sid = &nrec->data.info.sid;
3655 if (!dns_name) continue;
3657 /* check if this is already taken and not excluded */
3658 for (i = 0; i < tdo_fti->count; i++) {
3659 trec = &tdo_fti->records[i].record;
3661 switch (trec->type) {
3662 case FOREST_TRUST_TOP_LEVEL_NAME:
3664 tname = trec->data.name.string;
3665 tlen = trec->data.name.size;
3667 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
3669 tname = trec->data.name.string;
3670 tlen = trec->data.name.size;
3672 case FOREST_TRUST_DOMAIN_INFO:
3674 tname = trec->data.info.dns_name.string;
3675 tlen = trec->data.info.dns_name.size;
3678 return NT_STATUS_INVALID_PARAMETER;
3680 ret = dns_cmp(dns_name, dns_len, tname, tlen);
3683 /* if it matches exclusion,
3684 * it doesn't conflict */
3690 case DNS_CMP_FIRST_IS_CHILD:
3691 case DNS_CMP_SECOND_IS_CHILD:
3692 tln_conflict = true;
3698 /* explicit exclusion, no dns name conflict here */
3700 tln_conflict = false;
3703 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
3707 /* also test for domain info */
3708 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
3709 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
3710 sid_conflict = true;
3712 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
3713 strcasecmp_m(trec->data.info.netbios_name.string,
3720 nt_status = add_collision(c_info, new_fti_idx,
3722 LSA_TLN_DISABLED_CONFLICT,
3726 nt_status = add_collision(c_info, new_fti_idx,
3728 LSA_SID_DISABLED_CONFLICT,
3732 nt_status = add_collision(c_info, new_fti_idx,
3734 LSA_NB_DISABLED_CONFLICT,
3739 return NT_STATUS_OK;
3742 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3743 uint32_t idx, uint32_t collision_type,
3744 uint32_t conflict_type, const char *tdo_name)
3746 struct lsa_ForestTrustCollisionRecord **es;
3747 uint32_t i = c_info->count;
3749 es = talloc_realloc(c_info, c_info->entries,
3750 struct lsa_ForestTrustCollisionRecord *, i + 1);
3752 return NT_STATUS_NO_MEMORY;
3754 c_info->entries = es;
3755 c_info->count = i + 1;
3757 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
3759 return NT_STATUS_NO_MEMORY;
3763 es[i]->type = collision_type;
3764 es[i]->flags.flags = conflict_type;
3765 es[i]->name.string = talloc_strdup(es[i], tdo_name);
3766 if (!es[i]->name.string) {
3767 return NT_STATUS_NO_MEMORY;
3769 es[i]->name.size = strlen(es[i]->name.string);
3771 return NT_STATUS_OK;
3774 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3775 struct pdb_trusted_domain *td,
3776 struct ForestTrustInfo *info)
3778 enum ndr_err_code ndr_err;
3780 if (td->trust_forest_trust_info.length == 0 ||
3781 td->trust_forest_trust_info.data == NULL) {
3782 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3784 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
3786 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3787 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3788 return NT_STATUS_INVALID_DOMAIN_STATE;
3791 return NT_STATUS_OK;
3794 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
3795 struct ForestTrustInfo *fti)
3797 struct ForestTrustDataDomainInfo *info;
3798 struct ForestTrustInfoRecord *rec;
3802 fti->records = talloc_array(fti,
3803 struct ForestTrustInfoRecordArmor, 2);
3804 if (!fti->records) {
3805 return NT_STATUS_NO_MEMORY;
3809 rec = &fti->records[0].record;
3813 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3815 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
3816 if (!rec->data.name.string) {
3817 return NT_STATUS_NO_MEMORY;
3819 rec->data.name.size = strlen(rec->data.name.string);
3822 rec = &fti->records[1].record;
3826 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3828 info = &rec->data.info;
3830 info->sid = dom_info->sid;
3831 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
3832 if (!info->dns_name.string) {
3833 return NT_STATUS_NO_MEMORY;
3835 info->dns_name.size = strlen(info->dns_name.string);
3836 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
3837 if (!info->netbios_name.string) {
3838 return NT_STATUS_NO_MEMORY;
3840 info->netbios_name.size = strlen(info->netbios_name.string);
3842 return NT_STATUS_OK;
3845 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
3846 struct lsa_lsaRSetForestTrustInformation *r)
3851 struct lsa_info *handle;
3852 uint32_t num_domains;
3853 struct pdb_trusted_domain **domains;
3854 struct ForestTrustInfo *nfti;
3855 struct ForestTrustInfo *fti;
3856 struct lsa_ForestTrustCollisionInfo *c_info;
3857 struct pdb_domain_info *dom_info;
3858 enum ndr_err_code ndr_err;
3861 return NT_STATUS_NOT_SUPPORTED;
3864 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
3865 return NT_STATUS_INVALID_HANDLE;
3868 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
3869 return NT_STATUS_INVALID_HANDLE;
3872 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
3873 return NT_STATUS_ACCESS_DENIED;
3876 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
3877 if (!NT_STATUS_IS_OK(status)) {
3880 if (num_domains == 0) {
3881 return NT_STATUS_NO_SUCH_DOMAIN;
3884 for (i = 0; i < num_domains; i++) {
3885 if (domains[i]->domain_name == NULL) {
3886 return NT_STATUS_INVALID_DOMAIN_STATE;
3888 if (strcasecmp_m(domains[i]->domain_name,
3889 r->in.trusted_domain_name->string) == 0) {
3893 if (i >= num_domains) {
3894 return NT_STATUS_NO_SUCH_DOMAIN;
3897 if (!(domains[i]->trust_attributes &
3898 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
3899 return NT_STATUS_INVALID_PARAMETER;
3902 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
3903 return NT_STATUS_INVALID_PARAMETER;
3906 /* The following section until COPY_END is a copy from
3907 * source4/rpmc_server/lsa/scesrc_lsa.c */
3908 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
3910 return NT_STATUS_NO_MEMORY;
3913 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
3914 if (!NT_STATUS_IS_OK(status)) {
3918 c_info = talloc_zero(r->out.collision_info,
3919 struct lsa_ForestTrustCollisionInfo);
3921 return NT_STATUS_NO_MEMORY;
3924 /* first check own info, then other domains */
3925 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3927 return NT_STATUS_NO_MEMORY;
3930 dom_info = pdb_get_domain_info(p->mem_ctx);
3932 status = own_ft_info(dom_info, fti);
3933 if (!NT_STATUS_IS_OK(status)) {
3937 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
3938 if (!NT_STATUS_IS_OK(status)) {
3942 for (j = 0; j < num_domains; j++) {
3943 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3945 return NT_STATUS_NO_MEMORY;
3948 status = get_ft_info(p->mem_ctx, domains[j], fti);
3949 if (!NT_STATUS_IS_OK(status)) {
3950 if (NT_STATUS_EQUAL(status,
3951 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3957 if (domains[j]->domain_name == NULL) {
3958 return NT_STATUS_INVALID_DOMAIN_STATE;
3961 status = check_ft_info(c_info, domains[j]->domain_name,
3963 if (!NT_STATUS_IS_OK(status)) {
3968 *r->out.collision_info = c_info;
3970 if (r->in.check_only != 0) {
3971 return NT_STATUS_OK;
3976 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
3978 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
3979 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3980 return NT_STATUS_INVALID_PARAMETER;
3983 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
3984 if (!NT_STATUS_IS_OK(status)) {
3988 return NT_STATUS_OK;
3991 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
3992 struct lsa_CREDRRENAME *r)
3994 p->rng_fault_state = True;
3995 return NT_STATUS_NOT_IMPLEMENTED;
3998 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
3999 struct lsa_LSAROPENPOLICYSCE *r)
4001 p->rng_fault_state = True;
4002 return NT_STATUS_NOT_IMPLEMENTED;
4005 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4006 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4008 p->rng_fault_state = True;
4009 return NT_STATUS_NOT_IMPLEMENTED;
4012 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4013 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4015 p->rng_fault_state = True;
4016 return NT_STATUS_NOT_IMPLEMENTED;
4019 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4020 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4022 p->rng_fault_state = True;
4023 return NT_STATUS_NOT_IMPLEMENTED;