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)));
2192 return NT_STATUS_INVALID_HANDLE;
2195 close_policy_hnd(p, r->in.handle);
2196 ZERO_STRUCTP(r->out.handle);
2201 /***************************************************************************
2203 ***************************************************************************/
2205 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2206 struct lsa_EnumPrivs *r)
2208 struct lsa_info *handle;
2210 uint32 enum_context = *r->in.resume_handle;
2211 int num_privs = num_privileges_in_short_list();
2212 struct lsa_PrivEntry *entries = NULL;
2214 /* remember that the enum_context starts at 0 and not 1 */
2216 if ( enum_context >= num_privs )
2217 return NT_STATUS_NO_MORE_ENTRIES;
2219 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2220 enum_context, num_privs));
2222 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2223 return NT_STATUS_INVALID_HANDLE;
2225 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2226 return NT_STATUS_INVALID_HANDLE;
2229 /* check if the user has enough rights
2230 I don't know if it's the right one. not documented. */
2232 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2233 return NT_STATUS_ACCESS_DENIED;
2236 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2238 return NT_STATUS_NO_MEMORY;
2244 for (i = 0; i < num_privs; i++) {
2245 if( i < enum_context) {
2247 init_lsa_StringLarge(&entries[i].name, NULL);
2249 entries[i].luid.low = 0;
2250 entries[i].luid.high = 0;
2253 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2255 entries[i].luid.low = sec_privilege_from_index(i);
2256 entries[i].luid.high = 0;
2260 enum_context = num_privs;
2262 *r->out.resume_handle = enum_context;
2263 r->out.privs->count = num_privs;
2264 r->out.privs->privs = entries;
2266 return NT_STATUS_OK;
2269 /***************************************************************************
2270 _lsa_LookupPrivDisplayName
2271 ***************************************************************************/
2273 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2274 struct lsa_LookupPrivDisplayName *r)
2276 struct lsa_info *handle;
2277 const char *description;
2278 struct lsa_StringLarge *lsa_name;
2280 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2281 return NT_STATUS_INVALID_HANDLE;
2283 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2284 return NT_STATUS_INVALID_HANDLE;
2287 /* check if the user has enough rights */
2290 * I don't know if it's the right one. not documented.
2292 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2293 return NT_STATUS_ACCESS_DENIED;
2295 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2297 description = get_privilege_dispname(r->in.name->string);
2299 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2300 return NT_STATUS_NO_SUCH_PRIVILEGE;
2303 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2305 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2307 return NT_STATUS_NO_MEMORY;
2310 init_lsa_StringLarge(lsa_name, description);
2312 *r->out.returned_language_id = r->in.language_id;
2313 *r->out.disp_name = lsa_name;
2315 return NT_STATUS_OK;
2318 /***************************************************************************
2320 ***************************************************************************/
2322 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2323 struct lsa_EnumAccounts *r)
2325 struct lsa_info *handle;
2326 struct dom_sid *sid_list;
2327 int i, j, num_entries;
2329 struct lsa_SidPtr *sids = NULL;
2331 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2332 return NT_STATUS_INVALID_HANDLE;
2334 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2335 return NT_STATUS_INVALID_HANDLE;
2338 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2339 return NT_STATUS_ACCESS_DENIED;
2344 /* The only way we can currently find out all the SIDs that have been
2345 privileged is to scan all privileges */
2347 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2348 if (!NT_STATUS_IS_OK(status)) {
2352 if (*r->in.resume_handle >= num_entries) {
2353 return NT_STATUS_NO_MORE_ENTRIES;
2356 if (num_entries - *r->in.resume_handle) {
2357 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2358 num_entries - *r->in.resume_handle);
2360 talloc_free(sid_list);
2361 return NT_STATUS_NO_MEMORY;
2364 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2365 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2367 talloc_free(sid_list);
2368 return NT_STATUS_NO_MEMORY;
2373 talloc_free(sid_list);
2375 *r->out.resume_handle = num_entries;
2376 r->out.sids->num_sids = num_entries;
2377 r->out.sids->sids = sids;
2379 return NT_STATUS_OK;
2382 /***************************************************************************
2384 ***************************************************************************/
2386 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2387 struct lsa_GetUserName *r)
2389 const char *username, *domname;
2390 struct lsa_String *account_name = NULL;
2391 struct lsa_String *authority_name = NULL;
2393 if (r->in.account_name &&
2394 *r->in.account_name) {
2395 return NT_STATUS_INVALID_PARAMETER;
2398 if (r->in.authority_name &&
2399 *r->in.authority_name) {
2400 return NT_STATUS_INVALID_PARAMETER;
2403 if (p->session_info->guest) {
2405 * I'm 99% sure this is not the right place to do this,
2406 * global_sid_Anonymous should probably be put into the token
2407 * instead of the guest id -- vl
2409 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2410 &domname, &username, NULL)) {
2411 return NT_STATUS_NO_MEMORY;
2414 username = p->session_info->sanitized_username;
2415 domname = p->session_info->info3->base.domain.string;
2418 account_name = talloc(p->mem_ctx, struct lsa_String);
2419 if (!account_name) {
2420 return NT_STATUS_NO_MEMORY;
2422 init_lsa_String(account_name, username);
2424 if (r->out.authority_name) {
2425 authority_name = talloc(p->mem_ctx, struct lsa_String);
2426 if (!authority_name) {
2427 return NT_STATUS_NO_MEMORY;
2429 init_lsa_String(authority_name, domname);
2432 *r->out.account_name = account_name;
2433 if (r->out.authority_name) {
2434 *r->out.authority_name = authority_name;
2437 return NT_STATUS_OK;
2440 /***************************************************************************
2442 ***************************************************************************/
2444 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2445 struct lsa_CreateAccount *r)
2448 struct lsa_info *handle;
2449 uint32_t acc_granted;
2450 struct security_descriptor *psd;
2453 /* find the connection policy handle. */
2454 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2455 return NT_STATUS_INVALID_HANDLE;
2457 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2458 return NT_STATUS_INVALID_HANDLE;
2461 /* check if the user has enough rights */
2463 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2464 return NT_STATUS_ACCESS_DENIED;
2467 /* Work out max allowed. */
2468 map_max_allowed_access(p->session_info->security_token,
2469 p->session_info->unix_token,
2470 &r->in.access_mask);
2472 /* map the generic bits to the lsa policy ones */
2473 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2475 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2476 &lsa_account_mapping,
2477 r->in.sid, LSA_POLICY_ALL_ACCESS);
2478 if (!NT_STATUS_IS_OK(status)) {
2482 status = access_check_object(psd, p->session_info->security_token,
2483 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2484 &acc_granted, "_lsa_CreateAccount");
2485 if (!NT_STATUS_IS_OK(status)) {
2489 if ( is_privileged_sid( r->in.sid ) )
2490 return NT_STATUS_OBJECT_NAME_COLLISION;
2492 status = create_lsa_policy_handle(p->mem_ctx, p,
2493 LSA_HANDLE_ACCOUNT_TYPE,
2498 r->out.acct_handle);
2499 if (!NT_STATUS_IS_OK(status)) {
2500 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2503 return privilege_create_account(r->in.sid);
2506 /***************************************************************************
2508 ***************************************************************************/
2510 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2511 struct lsa_OpenAccount *r)
2513 struct lsa_info *handle;
2514 struct security_descriptor *psd = NULL;
2516 uint32_t des_access = r->in.access_mask;
2517 uint32_t acc_granted;
2520 /* find the connection policy handle. */
2521 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2522 return NT_STATUS_INVALID_HANDLE;
2524 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2525 return NT_STATUS_INVALID_HANDLE;
2528 /* des_access is for the account here, not the policy
2529 * handle - so don't check against policy handle. */
2531 /* Work out max allowed. */
2532 map_max_allowed_access(p->session_info->security_token,
2533 p->session_info->unix_token,
2536 /* map the generic bits to the lsa account ones */
2537 se_map_generic(&des_access, &lsa_account_mapping);
2539 /* get the generic lsa account SD until we store it */
2540 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2541 &lsa_account_mapping,
2542 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2543 if (!NT_STATUS_IS_OK(status)) {
2547 status = access_check_object(psd, p->session_info->security_token,
2548 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2549 &acc_granted, "_lsa_OpenAccount" );
2550 if (!NT_STATUS_IS_OK(status)) {
2554 /* TODO: Fis the parsing routine before reenabling this check! */
2556 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2557 return NT_STATUS_ACCESS_DENIED;
2560 status = create_lsa_policy_handle(p->mem_ctx, p,
2561 LSA_HANDLE_ACCOUNT_TYPE,
2566 r->out.acct_handle);
2567 if (!NT_STATUS_IS_OK(status)) {
2568 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2571 return NT_STATUS_OK;
2574 /***************************************************************************
2575 _lsa_EnumPrivsAccount
2576 For a given SID, enumerate all the privilege this account has.
2577 ***************************************************************************/
2579 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2580 struct lsa_EnumPrivsAccount *r)
2582 NTSTATUS status = NT_STATUS_OK;
2583 struct lsa_info *info=NULL;
2584 PRIVILEGE_SET *privileges;
2585 struct lsa_PrivilegeSet *priv_set = NULL;
2587 /* find the connection policy handle. */
2588 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2589 return NT_STATUS_INVALID_HANDLE;
2591 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2592 return NT_STATUS_INVALID_HANDLE;
2595 if (!(info->access & LSA_ACCOUNT_VIEW))
2596 return NT_STATUS_ACCESS_DENIED;
2598 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2599 if (!NT_STATUS_IS_OK(status)) {
2603 *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2605 return NT_STATUS_NO_MEMORY;
2608 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2609 sid_string_dbg(&info->sid),
2610 privileges->count));
2612 priv_set->count = privileges->count;
2613 priv_set->unknown = 0;
2614 priv_set->set = talloc_move(priv_set, &privileges->set);
2619 /***************************************************************************
2620 _lsa_GetSystemAccessAccount
2621 ***************************************************************************/
2623 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2624 struct lsa_GetSystemAccessAccount *r)
2627 struct lsa_info *info = NULL;
2628 struct lsa_EnumPrivsAccount e;
2629 struct lsa_PrivilegeSet *privset;
2631 /* find the connection policy handle. */
2633 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2634 return NT_STATUS_INVALID_HANDLE;
2636 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2637 return NT_STATUS_INVALID_HANDLE;
2640 if (!(info->access & LSA_ACCOUNT_VIEW))
2641 return NT_STATUS_ACCESS_DENIED;
2643 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2645 return NT_STATUS_NO_MEMORY;
2648 e.in.handle = r->in.handle;
2649 e.out.privs = &privset;
2651 status = _lsa_EnumPrivsAccount(p, &e);
2652 if (!NT_STATUS_IS_OK(status)) {
2653 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2654 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2655 nt_errstr(status)));
2659 /* Samba4 would iterate over the privset to merge the policy mode bits,
2660 * not sure samba3 can do the same here, so just return what we did in
2664 0x01 -> Log on locally
2665 0x02 -> Access this computer from network
2666 0x04 -> Log on as a batch job
2667 0x10 -> Log on as a service
2669 they can be ORed together
2672 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2673 LSA_POLICY_MODE_NETWORK;
2675 return NT_STATUS_OK;
2678 /***************************************************************************
2679 update the systemaccount information
2680 ***************************************************************************/
2682 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2683 struct lsa_SetSystemAccessAccount *r)
2685 struct lsa_info *info=NULL;
2688 /* find the connection policy handle. */
2689 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2690 return NT_STATUS_INVALID_HANDLE;
2692 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2693 return NT_STATUS_INVALID_HANDLE;
2696 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2697 return NT_STATUS_ACCESS_DENIED;
2700 if (!pdb_getgrsid(&map, info->sid))
2701 return NT_STATUS_NO_SUCH_GROUP;
2703 return pdb_update_group_mapping_entry(&map);
2706 /***************************************************************************
2707 _lsa_AddPrivilegesToAccount
2708 For a given SID, add some privileges.
2709 ***************************************************************************/
2711 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
2712 struct lsa_AddPrivilegesToAccount *r)
2714 struct lsa_info *info = NULL;
2715 struct lsa_PrivilegeSet *set = NULL;
2717 /* find the connection policy handle. */
2718 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2719 return NT_STATUS_INVALID_HANDLE;
2721 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2722 return NT_STATUS_INVALID_HANDLE;
2725 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2726 return NT_STATUS_ACCESS_DENIED;
2731 if ( !grant_privilege_set( &info->sid, set ) ) {
2732 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2733 sid_string_dbg(&info->sid) ));
2734 return NT_STATUS_NO_SUCH_PRIVILEGE;
2737 return NT_STATUS_OK;
2740 /***************************************************************************
2741 _lsa_RemovePrivilegesFromAccount
2742 For a given SID, remove some privileges.
2743 ***************************************************************************/
2745 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2746 struct lsa_RemovePrivilegesFromAccount *r)
2748 struct lsa_info *info = NULL;
2749 struct lsa_PrivilegeSet *set = NULL;
2751 /* find the connection policy handle. */
2752 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2753 return NT_STATUS_INVALID_HANDLE;
2755 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2756 return NT_STATUS_INVALID_HANDLE;
2759 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2760 return NT_STATUS_ACCESS_DENIED;
2765 if ( !revoke_privilege_set( &info->sid, set) ) {
2766 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2767 sid_string_dbg(&info->sid) ));
2768 return NT_STATUS_NO_SUCH_PRIVILEGE;
2771 return NT_STATUS_OK;
2774 /***************************************************************************
2776 ***************************************************************************/
2778 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2779 struct lsa_LookupPrivName *r)
2781 struct lsa_info *info = NULL;
2783 struct lsa_StringLarge *lsa_name;
2785 /* find the connection policy handle. */
2786 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2787 return NT_STATUS_INVALID_HANDLE;
2790 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2791 return NT_STATUS_INVALID_HANDLE;
2794 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2795 return NT_STATUS_ACCESS_DENIED;
2798 if (r->in.luid->high != 0) {
2799 return NT_STATUS_NO_SUCH_PRIVILEGE;
2802 name = sec_privilege_name(r->in.luid->low);
2804 return NT_STATUS_NO_SUCH_PRIVILEGE;
2807 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2809 return NT_STATUS_NO_MEMORY;
2812 lsa_name->string = talloc_strdup(lsa_name, name);
2813 if (!lsa_name->string) {
2814 TALLOC_FREE(lsa_name);
2815 return NT_STATUS_NO_MEMORY;
2818 *r->out.name = lsa_name;
2820 return NT_STATUS_OK;
2823 /***************************************************************************
2825 ***************************************************************************/
2827 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
2828 struct lsa_QuerySecurity *r)
2830 struct lsa_info *handle=NULL;
2831 struct security_descriptor *psd = NULL;
2835 /* find the connection policy handle. */
2836 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2837 return NT_STATUS_INVALID_HANDLE;
2839 switch (handle->type) {
2840 case LSA_HANDLE_POLICY_TYPE:
2841 case LSA_HANDLE_ACCOUNT_TYPE:
2842 case LSA_HANDLE_TRUST_TYPE:
2844 sd_size = ndr_size_security_descriptor(psd, 0);
2845 status = NT_STATUS_OK;
2848 status = NT_STATUS_INVALID_HANDLE;
2852 if (!NT_STATUS_IS_OK(status)) {
2856 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2857 if (!*r->out.sdbuf) {
2858 return NT_STATUS_NO_MEMORY;
2864 /***************************************************************************
2865 _lsa_AddAccountRights
2866 ***************************************************************************/
2868 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
2869 struct lsa_AddAccountRights *r)
2871 struct lsa_info *info = NULL;
2873 uint32_t acc_granted = 0;
2874 struct security_descriptor *psd = NULL;
2879 /* find the connection policy handle. */
2880 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2881 return NT_STATUS_INVALID_HANDLE;
2883 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2884 return NT_STATUS_INVALID_HANDLE;
2887 /* get the generic lsa account SD for this SID until we store it */
2888 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2889 &lsa_account_mapping,
2890 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2891 if (!NT_STATUS_IS_OK(status)) {
2896 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2897 * on the policy handle. If it does, ask for
2898 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2899 * on the account sid. We don't check here so just use the latter. JRA.
2902 status = access_check_object(psd, p->session_info->security_token,
2903 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2904 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2905 &acc_granted, "_lsa_AddAccountRights" );
2906 if (!NT_STATUS_IS_OK(status)) {
2910 /* according to an NT4 PDC, you can add privileges to SIDs even without
2911 call_lsa_create_account() first. And you can use any arbitrary SID. */
2913 sid_copy( &sid, r->in.sid );
2915 for ( i=0; i < r->in.rights->count; i++ ) {
2917 const char *privname = r->in.rights->names[i].string;
2919 /* only try to add non-null strings */
2924 if ( !grant_privilege_by_name( &sid, privname ) ) {
2925 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2927 return NT_STATUS_NO_SUCH_PRIVILEGE;
2931 return NT_STATUS_OK;
2934 /***************************************************************************
2935 _lsa_RemoveAccountRights
2936 ***************************************************************************/
2938 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
2939 struct lsa_RemoveAccountRights *r)
2941 struct lsa_info *info = NULL;
2943 struct security_descriptor *psd = NULL;
2946 const char *privname = NULL;
2947 uint32_t acc_granted = 0;
2950 /* find the connection policy handle. */
2951 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2952 return NT_STATUS_INVALID_HANDLE;
2954 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2955 return NT_STATUS_INVALID_HANDLE;
2958 /* get the generic lsa account SD for this SID until we store it */
2959 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2960 &lsa_account_mapping,
2961 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2962 if (!NT_STATUS_IS_OK(status)) {
2967 * From the MS DOCs. We need
2968 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2969 * and DELETE on the account sid.
2972 status = access_check_object(psd, p->session_info->security_token,
2973 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2974 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2975 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
2976 &acc_granted, "_lsa_RemoveAccountRights");
2977 if (!NT_STATUS_IS_OK(status)) {
2981 sid_copy( &sid, r->in.sid );
2983 if ( r->in.remove_all ) {
2984 if ( !revoke_all_privileges( &sid ) )
2985 return NT_STATUS_ACCESS_DENIED;
2987 return NT_STATUS_OK;
2990 for ( i=0; i < r->in.rights->count; i++ ) {
2992 privname = r->in.rights->names[i].string;
2994 /* only try to add non-null strings */
2999 if ( !revoke_privilege_by_name( &sid, privname ) ) {
3000 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3002 return NT_STATUS_NO_SUCH_PRIVILEGE;
3006 return NT_STATUS_OK;
3009 /*******************************************************************
3010 ********************************************************************/
3012 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3013 struct lsa_RightSet *r,
3014 PRIVILEGE_SET *privileges)
3017 const char *privname;
3018 const char **privname_array = NULL;
3021 for (i=0; i<privileges->count; i++) {
3022 if (privileges->set[i].luid.high) {
3025 privname = sec_privilege_name(privileges->set[i].luid.low);
3027 if (!add_string_to_array(mem_ctx, privname,
3028 &privname_array, &num_priv)) {
3029 return NT_STATUS_NO_MEMORY;
3036 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3039 return NT_STATUS_NO_MEMORY;
3042 for (i=0; i<num_priv; i++) {
3043 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3046 r->count = num_priv;
3049 return NT_STATUS_OK;
3052 /***************************************************************************
3053 _lsa_EnumAccountRights
3054 ***************************************************************************/
3056 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3057 struct lsa_EnumAccountRights *r)
3060 struct lsa_info *info = NULL;
3061 PRIVILEGE_SET *privileges;
3063 /* find the connection policy handle. */
3065 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3066 return NT_STATUS_INVALID_HANDLE;
3068 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3069 return NT_STATUS_INVALID_HANDLE;
3072 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3073 return NT_STATUS_ACCESS_DENIED;
3076 /* according to an NT4 PDC, you can add privileges to SIDs even without
3077 call_lsa_create_account() first. And you can use any arbitrary SID. */
3079 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3080 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3081 * the lsa database */
3083 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3084 if (!NT_STATUS_IS_OK(status)) {
3088 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3089 sid_string_dbg(r->in.sid), privileges->count));
3091 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3096 /***************************************************************************
3097 _lsa_LookupPrivValue
3098 ***************************************************************************/
3100 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3101 struct lsa_LookupPrivValue *r)
3103 struct lsa_info *info = NULL;
3104 const char *name = NULL;
3106 /* find the connection policy handle. */
3108 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3109 return NT_STATUS_INVALID_HANDLE;
3111 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3112 return NT_STATUS_INVALID_HANDLE;
3115 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3116 return NT_STATUS_ACCESS_DENIED;
3118 name = r->in.name->string;
3120 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3122 r->out.luid->low = sec_privilege_id(name);
3123 r->out.luid->high = 0;
3124 if (r->out.luid->low == SEC_PRIV_INVALID) {
3125 return NT_STATUS_NO_SUCH_PRIVILEGE;
3127 return NT_STATUS_OK;
3130 /***************************************************************************
3131 _lsa_EnumAccountsWithUserRight
3132 ***************************************************************************/
3134 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3135 struct lsa_EnumAccountsWithUserRight *r)
3138 struct lsa_info *info = NULL;
3139 struct dom_sid *sids = NULL;
3142 enum sec_privilege privilege;
3144 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3145 return NT_STATUS_INVALID_HANDLE;
3148 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3149 return NT_STATUS_INVALID_HANDLE;
3152 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3153 return NT_STATUS_ACCESS_DENIED;
3156 if (!r->in.name || !r->in.name->string) {
3157 return NT_STATUS_NO_SUCH_PRIVILEGE;
3160 privilege = sec_privilege_id(r->in.name->string);
3161 if (privilege == SEC_PRIV_INVALID) {
3162 return NT_STATUS_NO_SUCH_PRIVILEGE;
3165 status = privilege_enum_sids(privilege, p->mem_ctx,
3167 if (!NT_STATUS_IS_OK(status)) {
3171 r->out.sids->num_sids = num_sids;
3172 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3173 r->out.sids->num_sids);
3175 for (i=0; i < r->out.sids->num_sids; i++) {
3176 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3178 if (!r->out.sids->sids[i].sid) {
3179 TALLOC_FREE(r->out.sids->sids);
3180 r->out.sids->num_sids = 0;
3181 return NT_STATUS_NO_MEMORY;
3185 return NT_STATUS_OK;
3188 /***************************************************************************
3190 ***************************************************************************/
3192 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3193 struct lsa_Delete *r)
3195 return NT_STATUS_NOT_SUPPORTED;
3199 * From here on the server routines are just dummy ones to make smbd link with
3200 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3201 * pulling the server stubs across one by one.
3204 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3206 p->rng_fault_state = True;
3207 return NT_STATUS_NOT_IMPLEMENTED;
3210 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3211 struct lsa_ChangePassword *r)
3213 p->rng_fault_state = True;
3214 return NT_STATUS_NOT_IMPLEMENTED;
3217 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3219 p->rng_fault_state = True;
3220 return NT_STATUS_NOT_IMPLEMENTED;
3223 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3225 p->rng_fault_state = True;
3226 return NT_STATUS_NOT_IMPLEMENTED;
3229 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3230 struct lsa_GetQuotasForAccount *r)
3232 p->rng_fault_state = True;
3233 return NT_STATUS_NOT_IMPLEMENTED;
3236 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3237 struct lsa_SetQuotasForAccount *r)
3239 p->rng_fault_state = True;
3240 return NT_STATUS_NOT_IMPLEMENTED;
3243 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3244 struct lsa_SetInformationTrustedDomain *r)
3246 p->rng_fault_state = True;
3247 return NT_STATUS_NOT_IMPLEMENTED;
3250 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
3252 p->rng_fault_state = True;
3253 return NT_STATUS_NOT_IMPLEMENTED;
3256 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3257 struct lsa_SetTrustedDomainInfo *r)
3259 p->rng_fault_state = True;
3260 return NT_STATUS_NOT_IMPLEMENTED;
3263 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3264 struct lsa_StorePrivateData *r)
3266 p->rng_fault_state = True;
3267 return NT_STATUS_NOT_IMPLEMENTED;
3270 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3271 struct lsa_RetrievePrivateData *r)
3273 p->rng_fault_state = True;
3274 return NT_STATUS_NOT_IMPLEMENTED;
3277 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3278 struct lsa_SetInfoPolicy2 *r)
3280 p->rng_fault_state = True;
3281 return NT_STATUS_NOT_IMPLEMENTED;
3284 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3285 struct lsa_SetTrustedDomainInfoByName *r)
3287 p->rng_fault_state = True;
3288 return NT_STATUS_NOT_IMPLEMENTED;
3291 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3292 struct lsa_EnumTrustedDomainsEx *r)
3294 struct lsa_info *info;
3296 struct pdb_trusted_domain **domains;
3297 struct lsa_TrustDomainInfoInfoEx *entries;
3301 /* bail out early if pdb backend is not capable of ex trusted domains,
3302 * if we dont do that, the client might not call
3303 * _lsa_EnumTrustedDomains() afterwards - gd */
3305 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3306 p->rng_fault_state = True;
3307 return NT_STATUS_NOT_IMPLEMENTED;
3310 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3311 return NT_STATUS_INVALID_HANDLE;
3313 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3314 return NT_STATUS_INVALID_HANDLE;
3317 /* check if the user has enough rights */
3318 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3319 return NT_STATUS_ACCESS_DENIED;
3322 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3325 if (!NT_STATUS_IS_OK(nt_status)) {
3329 entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3332 return NT_STATUS_NO_MEMORY;
3335 for (i=0; i<count; i++) {
3336 init_lsa_StringLarge(&entries[i].netbios_name,
3337 domains[i]->netbios_name);
3338 entries[i].sid = &domains[i]->security_identifier;
3341 if (*r->in.resume_handle >= count) {
3342 *r->out.resume_handle = -1;
3343 TALLOC_FREE(entries);
3344 return NT_STATUS_NO_MORE_ENTRIES;
3347 /* return the rest, limit by max_size. Note that we
3348 use the w2k3 element size value of 60 */
3349 r->out.domains->count = count - *r->in.resume_handle;
3350 r->out.domains->count = MIN(r->out.domains->count,
3351 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3353 r->out.domains->domains = entries + *r->in.resume_handle;
3355 if (r->out.domains->count < count - *r->in.resume_handle) {
3356 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3357 return STATUS_MORE_ENTRIES;
3360 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3361 * always be larger than the previous input resume handle, in
3362 * particular when hitting the last query it is vital to set the
3363 * resume handle correctly to avoid infinite client loops, as
3364 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3365 * status is NT_STATUS_OK - gd */
3367 *r->out.resume_handle = (uint32_t)-1;
3369 return NT_STATUS_OK;
3372 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3373 struct lsa_QueryDomainInformationPolicy *r)
3375 p->rng_fault_state = True;
3376 return NT_STATUS_NOT_IMPLEMENTED;
3379 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3380 struct lsa_SetDomainInformationPolicy *r)
3382 p->rng_fault_state = True;
3383 return NT_STATUS_NOT_IMPLEMENTED;
3386 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3388 p->rng_fault_state = True;
3389 return NT_STATUS_NOT_IMPLEMENTED;
3392 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3394 p->rng_fault_state = True;
3395 return NT_STATUS_NOT_IMPLEMENTED;
3398 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3400 p->rng_fault_state = True;
3401 return NT_STATUS_NOT_IMPLEMENTED;
3404 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3406 p->rng_fault_state = True;
3407 return NT_STATUS_NOT_IMPLEMENTED;
3410 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3411 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3413 p->rng_fault_state = True;
3414 return NT_STATUS_NOT_IMPLEMENTED;
3417 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3418 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3420 p->rng_fault_state = True;
3421 return NT_STATUS_NOT_IMPLEMENTED;
3424 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3426 p->rng_fault_state = True;
3427 return NT_STATUS_NOT_IMPLEMENTED;
3430 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3431 struct lsa_CREDRGETTARGETINFO *r)
3433 p->rng_fault_state = True;
3434 return NT_STATUS_NOT_IMPLEMENTED;
3437 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3438 struct lsa_CREDRPROFILELOADED *r)
3440 p->rng_fault_state = True;
3441 return NT_STATUS_NOT_IMPLEMENTED;
3444 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3445 struct lsa_CREDRGETSESSIONTYPES *r)
3447 p->rng_fault_state = True;
3448 return NT_STATUS_NOT_IMPLEMENTED;
3451 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3452 struct lsa_LSARREGISTERAUDITEVENT *r)
3454 p->rng_fault_state = True;
3455 return NT_STATUS_NOT_IMPLEMENTED;
3458 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3459 struct lsa_LSARGENAUDITEVENT *r)
3461 p->rng_fault_state = True;
3462 return NT_STATUS_NOT_IMPLEMENTED;
3465 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3466 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3468 p->rng_fault_state = True;
3469 return NT_STATUS_NOT_IMPLEMENTED;
3472 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3473 struct lsa_lsaRQueryForestTrustInformation *r)
3475 p->rng_fault_state = True;
3476 return NT_STATUS_NOT_IMPLEMENTED;
3479 #define DNS_CMP_MATCH 0
3480 #define DNS_CMP_FIRST_IS_CHILD 1
3481 #define DNS_CMP_SECOND_IS_CHILD 2
3482 #define DNS_CMP_NO_MATCH 3
3484 /* this function assumes names are well formed DNS names.
3485 * it doesn't validate them */
3486 static int dns_cmp(const char *s1, size_t l1,
3487 const char *s2, size_t l2)
3489 const char *p1, *p2;
3494 if (strcasecmp_m(s1, s2) == 0) {
3495 return DNS_CMP_MATCH;
3497 return DNS_CMP_NO_MATCH;
3505 cret = DNS_CMP_FIRST_IS_CHILD;
3511 cret = DNS_CMP_SECOND_IS_CHILD;
3514 if (p1[t1 - t2 - 1] != '.') {
3515 return DNS_CMP_NO_MATCH;
3518 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
3522 return DNS_CMP_NO_MATCH;
3525 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3526 struct lsa_ForestTrustInformation *lfti,
3527 struct ForestTrustInfo *fti)
3529 struct lsa_ForestTrustRecord *lrec;
3530 struct ForestTrustInfoRecord *rec;
3531 struct lsa_StringLarge *tln;
3532 struct lsa_ForestTrustDomainInfo *info;
3536 fti->count = lfti->count;
3537 fti->records = talloc_array(mem_ctx,
3538 struct ForestTrustInfoRecordArmor,
3540 if (!fti->records) {
3541 return NT_STATUS_NO_MEMORY;
3543 for (i = 0; i < fti->count; i++) {
3544 lrec = lfti->entries[i];
3545 rec = &fti->records[i].record;
3547 rec->flags = lrec->flags;
3548 rec->timestamp = lrec->time;
3549 rec->type = lrec->type;
3551 switch (lrec->type) {
3552 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3553 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3554 tln = &lrec->forest_trust_data.top_level_name;
3555 rec->data.name.string =
3556 talloc_strdup(mem_ctx, tln->string);
3557 if (!rec->data.name.string) {
3558 return NT_STATUS_NO_MEMORY;
3560 rec->data.name.size = strlen(rec->data.name.string);
3562 case LSA_FOREST_TRUST_DOMAIN_INFO:
3563 info = &lrec->forest_trust_data.domain_info;
3564 rec->data.info.sid = *info->domain_sid;
3565 rec->data.info.dns_name.string =
3566 talloc_strdup(mem_ctx,
3567 info->dns_domain_name.string);
3568 if (!rec->data.info.dns_name.string) {
3569 return NT_STATUS_NO_MEMORY;
3571 rec->data.info.dns_name.size =
3572 strlen(rec->data.info.dns_name.string);
3573 rec->data.info.netbios_name.string =
3574 talloc_strdup(mem_ctx,
3575 info->netbios_domain_name.string);
3576 if (!rec->data.info.netbios_name.string) {
3577 return NT_STATUS_NO_MEMORY;
3579 rec->data.info.netbios_name.size =
3580 strlen(rec->data.info.netbios_name.string);
3583 return NT_STATUS_INVALID_DOMAIN_STATE;
3587 return NT_STATUS_OK;
3590 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3591 uint32_t index, uint32_t collision_type,
3592 uint32_t conflict_type, const char *tdo_name);
3594 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
3595 const char *tdo_name,
3596 struct ForestTrustInfo *tdo_fti,
3597 struct ForestTrustInfo *new_fti,
3598 struct lsa_ForestTrustCollisionInfo *c_info)
3600 struct ForestTrustInfoRecord *nrec;
3601 struct ForestTrustInfoRecord *trec;
3602 const char *dns_name;
3603 const char *nb_name = NULL;
3604 struct dom_sid *sid = NULL;
3605 const char *tname = NULL;
3610 uint32_t new_fti_idx;
3612 /* use always TDO type, until we understand when Xref can be used */
3613 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
3618 bool ex_rule = false;
3621 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
3623 nrec = &new_fti->records[new_fti_idx].record;
3625 tln_conflict = false;
3626 sid_conflict = false;
3627 nb_conflict = false;
3630 switch (nrec->type) {
3631 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3632 /* exclusions do not conflict by definition */
3635 case FOREST_TRUST_TOP_LEVEL_NAME:
3636 dns_name = nrec->data.name.string;
3637 dns_len = nrec->data.name.size;
3640 case LSA_FOREST_TRUST_DOMAIN_INFO:
3641 dns_name = nrec->data.info.dns_name.string;
3642 dns_len = nrec->data.info.dns_name.size;
3643 nb_name = nrec->data.info.netbios_name.string;
3644 nb_len = nrec->data.info.netbios_name.size;
3645 sid = &nrec->data.info.sid;
3649 if (!dns_name) continue;
3651 /* check if this is already taken and not excluded */
3652 for (i = 0; i < tdo_fti->count; i++) {
3653 trec = &tdo_fti->records[i].record;
3655 switch (trec->type) {
3656 case FOREST_TRUST_TOP_LEVEL_NAME:
3658 tname = trec->data.name.string;
3659 tlen = trec->data.name.size;
3661 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
3663 tname = trec->data.name.string;
3664 tlen = trec->data.name.size;
3666 case FOREST_TRUST_DOMAIN_INFO:
3668 tname = trec->data.info.dns_name.string;
3669 tlen = trec->data.info.dns_name.size;
3672 return NT_STATUS_INVALID_PARAMETER;
3674 ret = dns_cmp(dns_name, dns_len, tname, tlen);
3677 /* if it matches exclusion,
3678 * it doesn't conflict */
3684 case DNS_CMP_FIRST_IS_CHILD:
3685 case DNS_CMP_SECOND_IS_CHILD:
3686 tln_conflict = true;
3692 /* explicit exclusion, no dns name conflict here */
3694 tln_conflict = false;
3697 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
3701 /* also test for domain info */
3702 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
3703 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
3704 sid_conflict = true;
3706 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
3707 strcasecmp_m(trec->data.info.netbios_name.string,
3714 nt_status = add_collision(c_info, new_fti_idx,
3716 LSA_TLN_DISABLED_CONFLICT,
3720 nt_status = add_collision(c_info, new_fti_idx,
3722 LSA_SID_DISABLED_CONFLICT,
3726 nt_status = add_collision(c_info, new_fti_idx,
3728 LSA_NB_DISABLED_CONFLICT,
3733 return NT_STATUS_OK;
3736 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3737 uint32_t idx, uint32_t collision_type,
3738 uint32_t conflict_type, const char *tdo_name)
3740 struct lsa_ForestTrustCollisionRecord **es;
3741 uint32_t i = c_info->count;
3743 es = talloc_realloc(c_info, c_info->entries,
3744 struct lsa_ForestTrustCollisionRecord *, i + 1);
3746 return NT_STATUS_NO_MEMORY;
3748 c_info->entries = es;
3749 c_info->count = i + 1;
3751 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
3753 return NT_STATUS_NO_MEMORY;
3757 es[i]->type = collision_type;
3758 es[i]->flags.flags = conflict_type;
3759 es[i]->name.string = talloc_strdup(es[i], tdo_name);
3760 if (!es[i]->name.string) {
3761 return NT_STATUS_NO_MEMORY;
3763 es[i]->name.size = strlen(es[i]->name.string);
3765 return NT_STATUS_OK;
3768 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3769 struct pdb_trusted_domain *td,
3770 struct ForestTrustInfo *info)
3772 enum ndr_err_code ndr_err;
3774 if (td->trust_forest_trust_info.length == 0 ||
3775 td->trust_forest_trust_info.data == NULL) {
3776 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3778 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
3780 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3781 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3782 return NT_STATUS_INVALID_DOMAIN_STATE;
3785 return NT_STATUS_OK;
3788 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
3789 struct ForestTrustInfo *fti)
3791 struct ForestTrustDataDomainInfo *info;
3792 struct ForestTrustInfoRecord *rec;
3796 fti->records = talloc_array(fti,
3797 struct ForestTrustInfoRecordArmor, 2);
3798 if (!fti->records) {
3799 return NT_STATUS_NO_MEMORY;
3803 rec = &fti->records[0].record;
3807 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3809 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
3810 if (!rec->data.name.string) {
3811 return NT_STATUS_NO_MEMORY;
3813 rec->data.name.size = strlen(rec->data.name.string);
3816 rec = &fti->records[1].record;
3820 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3822 info = &rec->data.info;
3824 info->sid = dom_info->sid;
3825 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
3826 if (!info->dns_name.string) {
3827 return NT_STATUS_NO_MEMORY;
3829 info->dns_name.size = strlen(info->dns_name.string);
3830 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
3831 if (!info->netbios_name.string) {
3832 return NT_STATUS_NO_MEMORY;
3834 info->netbios_name.size = strlen(info->netbios_name.string);
3836 return NT_STATUS_OK;
3839 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
3840 struct lsa_lsaRSetForestTrustInformation *r)
3845 struct lsa_info *handle;
3846 uint32_t num_domains;
3847 struct pdb_trusted_domain **domains;
3848 struct ForestTrustInfo *nfti;
3849 struct ForestTrustInfo *fti;
3850 struct lsa_ForestTrustCollisionInfo *c_info;
3851 struct pdb_domain_info *dom_info;
3852 enum ndr_err_code ndr_err;
3855 return NT_STATUS_NOT_SUPPORTED;
3858 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
3859 return NT_STATUS_INVALID_HANDLE;
3862 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
3863 return NT_STATUS_INVALID_HANDLE;
3866 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
3867 return NT_STATUS_ACCESS_DENIED;
3870 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
3871 if (!NT_STATUS_IS_OK(status)) {
3874 if (num_domains == 0) {
3875 return NT_STATUS_NO_SUCH_DOMAIN;
3878 for (i = 0; i < num_domains; i++) {
3879 if (domains[i]->domain_name == NULL) {
3880 return NT_STATUS_INVALID_DOMAIN_STATE;
3882 if (strcasecmp_m(domains[i]->domain_name,
3883 r->in.trusted_domain_name->string) == 0) {
3887 if (i >= num_domains) {
3888 return NT_STATUS_NO_SUCH_DOMAIN;
3891 if (!(domains[i]->trust_attributes &
3892 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
3893 return NT_STATUS_INVALID_PARAMETER;
3896 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
3897 return NT_STATUS_INVALID_PARAMETER;
3900 /* The following section until COPY_END is a copy from
3901 * source4/rpmc_server/lsa/scesrc_lsa.c */
3902 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
3904 return NT_STATUS_NO_MEMORY;
3907 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
3908 if (!NT_STATUS_IS_OK(status)) {
3912 c_info = talloc_zero(r->out.collision_info,
3913 struct lsa_ForestTrustCollisionInfo);
3915 return NT_STATUS_NO_MEMORY;
3918 /* first check own info, then other domains */
3919 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3921 return NT_STATUS_NO_MEMORY;
3924 dom_info = pdb_get_domain_info(p->mem_ctx);
3926 status = own_ft_info(dom_info, fti);
3927 if (!NT_STATUS_IS_OK(status)) {
3931 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
3932 if (!NT_STATUS_IS_OK(status)) {
3936 for (j = 0; j < num_domains; j++) {
3937 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3939 return NT_STATUS_NO_MEMORY;
3942 status = get_ft_info(p->mem_ctx, domains[j], fti);
3943 if (!NT_STATUS_IS_OK(status)) {
3944 if (NT_STATUS_EQUAL(status,
3945 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3951 if (domains[j]->domain_name == NULL) {
3952 return NT_STATUS_INVALID_DOMAIN_STATE;
3955 status = check_ft_info(c_info, domains[j]->domain_name,
3957 if (!NT_STATUS_IS_OK(status)) {
3962 *r->out.collision_info = c_info;
3964 if (r->in.check_only != 0) {
3965 return NT_STATUS_OK;
3970 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
3972 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
3973 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3974 return NT_STATUS_INVALID_PARAMETER;
3977 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
3978 if (!NT_STATUS_IS_OK(status)) {
3982 return NT_STATUS_OK;
3985 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
3986 struct lsa_CREDRRENAME *r)
3988 p->rng_fault_state = True;
3989 return NT_STATUS_NOT_IMPLEMENTED;
3992 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
3993 struct lsa_LSAROPENPOLICYSCE *r)
3995 p->rng_fault_state = True;
3996 return NT_STATUS_NOT_IMPLEMENTED;
3999 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4000 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4002 p->rng_fault_state = True;
4003 return NT_STATUS_NOT_IMPLEMENTED;
4006 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4007 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4009 p->rng_fault_state = True;
4010 return NT_STATUS_NOT_IMPLEMENTED;
4013 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4014 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4016 p->rng_fault_state = True;
4017 return NT_STATUS_NOT_IMPLEMENTED;