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->utok,
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->utok,
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->utok.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->utok,
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->auth_blob.size != 0) {
1750 auth_blob.length = r->in.auth_info->auth_blob.size;
1751 auth_blob.data = r->in.auth_info->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;
1822 q.in.policy_handle = r->in.policy_handle;
1823 q.in.info = r->in.info;
1824 q.in.auth_info = r->in.auth_info;
1825 q.in.access_mask = r->in.access_mask;
1826 q.out.trustdom_handle = r->out.trustdom_handle;
1828 return _lsa_CreateTrustedDomainEx2(p, &q);
1831 /***************************************************************************
1832 _lsa_CreateTrustedDomain
1833 ***************************************************************************/
1835 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1836 struct lsa_CreateTrustedDomain *r)
1838 struct lsa_CreateTrustedDomainEx2 c;
1839 struct lsa_TrustDomainInfoInfoEx info;
1840 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1842 ZERO_STRUCT(auth_info);
1844 info.domain_name = r->in.info->name;
1845 info.netbios_name = r->in.info->name;
1846 info.sid = r->in.info->sid;
1847 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1848 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1849 info.trust_attributes = 0;
1851 c.in.policy_handle = r->in.policy_handle;
1853 c.in.auth_info = &auth_info;
1854 c.in.access_mask = r->in.access_mask;
1855 c.out.trustdom_handle = r->out.trustdom_handle;
1857 return _lsa_CreateTrustedDomainEx2(p, &c);
1860 /***************************************************************************
1861 _lsa_DeleteTrustedDomain
1862 ***************************************************************************/
1864 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1865 struct lsa_DeleteTrustedDomain *r)
1868 struct lsa_info *handle;
1869 struct pdb_trusted_domain *td;
1870 struct samu *sam_acct;
1873 /* find the connection policy handle. */
1874 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1875 return NT_STATUS_INVALID_HANDLE;
1878 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1879 return NT_STATUS_INVALID_HANDLE;
1882 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1883 return NT_STATUS_ACCESS_DENIED;
1886 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1887 if (!NT_STATUS_IS_OK(status)) {
1891 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1892 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1893 sid_string_tos(r->in.dom_sid)));
1894 return NT_STATUS_UNSUCCESSFUL;
1897 if (td->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1898 sam_acct = samu_new(p->mem_ctx);
1899 if (sam_acct == NULL) {
1900 return NT_STATUS_NO_MEMORY;
1903 acct_name = talloc_asprintf(p->mem_ctx, "%s$", td->netbios_name);
1904 if (acct_name == NULL) {
1905 return NT_STATUS_NO_MEMORY;
1907 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1908 return NT_STATUS_UNSUCCESSFUL;
1910 status = pdb_delete_sam_account(sam_acct);
1911 if (!NT_STATUS_IS_OK(status)) {
1916 status = pdb_del_trusted_domain(td->netbios_name);
1917 if (!NT_STATUS_IS_OK(status)) {
1921 return NT_STATUS_OK;
1924 /***************************************************************************
1925 _lsa_CloseTrustedDomainEx
1926 ***************************************************************************/
1928 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1929 struct lsa_CloseTrustedDomainEx *r)
1931 return NT_STATUS_NOT_IMPLEMENTED;
1934 /***************************************************************************
1935 _lsa_QueryTrustedDomainInfo
1936 ***************************************************************************/
1938 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
1939 struct lsa_QueryTrustedDomainInfo *r)
1942 struct lsa_info *handle;
1943 union lsa_TrustedDomainInfo *info;
1944 struct pdb_trusted_domain *td;
1945 uint32_t acc_required;
1947 /* find the connection policy handle. */
1948 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
1949 return NT_STATUS_INVALID_HANDLE;
1952 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
1953 return NT_STATUS_INVALID_HANDLE;
1956 switch (r->in.level) {
1957 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1958 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1960 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1961 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
1963 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1964 acc_required = LSA_TRUSTED_QUERY_POSIX;
1966 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
1967 acc_required = LSA_TRUSTED_QUERY_AUTH;
1969 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1970 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1972 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1973 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1975 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1976 acc_required = LSA_TRUSTED_QUERY_AUTH;
1978 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1979 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1980 LSA_TRUSTED_QUERY_POSIX |
1981 LSA_TRUSTED_QUERY_AUTH;
1983 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1984 acc_required = LSA_TRUSTED_QUERY_AUTH;
1986 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1987 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1988 LSA_TRUSTED_QUERY_POSIX |
1989 LSA_TRUSTED_QUERY_AUTH;
1991 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1992 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1994 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1995 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1996 LSA_TRUSTED_QUERY_POSIX |
1997 LSA_TRUSTED_QUERY_AUTH;
1999 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2000 acc_required = LSA_TRUSTED_QUERY_POSIX;
2003 return NT_STATUS_INVALID_PARAMETER;
2006 if (!(handle->access & acc_required)) {
2007 return NT_STATUS_ACCESS_DENIED;
2010 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2011 if (!NT_STATUS_IS_OK(status)) {
2015 info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
2017 return NT_STATUS_NO_MEMORY;
2020 switch (r->in.level) {
2021 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2022 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2024 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2025 return NT_STATUS_INVALID_PARAMETER;
2026 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2028 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2029 return NT_STATUS_INVALID_INFO_CLASS;
2030 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2031 return NT_STATUS_INVALID_PARAMETER;
2032 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2033 init_lsa_StringLarge(&info->info_ex.domain_name, td->domain_name);
2034 init_lsa_StringLarge(&info->info_ex.netbios_name, td->netbios_name);
2035 info->info_ex.sid = dom_sid_dup(info, &td->security_identifier);
2036 if (!info->info_ex.sid) {
2037 return NT_STATUS_NO_MEMORY;
2039 info->info_ex.trust_direction = td->trust_direction;
2040 info->info_ex.trust_type = td->trust_type;
2041 info->info_ex.trust_attributes = td->trust_attributes;
2043 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2044 return NT_STATUS_INVALID_INFO_CLASS;
2045 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2047 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2048 return NT_STATUS_INVALID_INFO_CLASS;
2049 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2050 return NT_STATUS_INVALID_INFO_CLASS;
2051 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2052 return NT_STATUS_INVALID_PARAMETER;
2053 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2055 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2058 return NT_STATUS_INVALID_PARAMETER;
2061 *r->out.info = info;
2063 return NT_STATUS_OK;
2066 /***************************************************************************
2067 _lsa_QueryTrustedDomainInfoBySid
2068 ***************************************************************************/
2070 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2071 struct lsa_QueryTrustedDomainInfoBySid *r)
2074 struct policy_handle trustdom_handle;
2075 struct lsa_OpenTrustedDomain o;
2076 struct lsa_QueryTrustedDomainInfo q;
2079 o.in.handle = r->in.handle;
2080 o.in.sid = r->in.dom_sid;
2081 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2082 o.out.trustdom_handle = &trustdom_handle;
2084 status = _lsa_OpenTrustedDomain(p, &o);
2085 if (!NT_STATUS_IS_OK(status)) {
2089 q.in.trustdom_handle = &trustdom_handle;
2090 q.in.level = r->in.level;
2091 q.out.info = r->out.info;
2093 status = _lsa_QueryTrustedDomainInfo(p, &q);
2094 if (!NT_STATUS_IS_OK(status)) {
2098 c.in.handle = &trustdom_handle;
2099 c.out.handle = &trustdom_handle;
2101 return _lsa_Close(p, &c);
2104 /***************************************************************************
2105 _lsa_QueryTrustedDomainInfoByName
2106 ***************************************************************************/
2108 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2109 struct lsa_QueryTrustedDomainInfoByName *r)
2112 struct policy_handle trustdom_handle;
2113 struct lsa_OpenTrustedDomainByName o;
2114 struct lsa_QueryTrustedDomainInfo q;
2117 o.in.handle = r->in.handle;
2118 o.in.name.string = r->in.trusted_domain->string;
2119 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2120 o.out.trustdom_handle = &trustdom_handle;
2122 status = _lsa_OpenTrustedDomainByName(p, &o);
2123 if (!NT_STATUS_IS_OK(status)) {
2124 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2125 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2130 q.in.trustdom_handle = &trustdom_handle;
2131 q.in.level = r->in.level;
2132 q.out.info = r->out.info;
2134 status = _lsa_QueryTrustedDomainInfo(p, &q);
2135 if (!NT_STATUS_IS_OK(status)) {
2139 c.in.handle = &trustdom_handle;
2140 c.out.handle = &trustdom_handle;
2142 return _lsa_Close(p, &c);
2145 /***************************************************************************
2146 ***************************************************************************/
2148 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p, struct lsa_CreateSecret *r)
2150 return NT_STATUS_ACCESS_DENIED;
2153 /***************************************************************************
2154 ***************************************************************************/
2156 NTSTATUS _lsa_SetSecret(struct pipes_struct *p, struct lsa_SetSecret *r)
2158 return NT_STATUS_ACCESS_DENIED;
2161 /***************************************************************************
2163 ***************************************************************************/
2165 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2166 struct lsa_DeleteObject *r)
2169 struct lsa_info *info = NULL;
2171 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2172 return NT_STATUS_INVALID_HANDLE;
2175 if (!(info->access & SEC_STD_DELETE)) {
2176 return NT_STATUS_ACCESS_DENIED;
2179 switch (info->type) {
2180 case LSA_HANDLE_ACCOUNT_TYPE:
2181 status = privilege_delete_account(&info->sid);
2182 if (!NT_STATUS_IS_OK(status)) {
2183 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2184 nt_errstr(status)));
2189 return NT_STATUS_INVALID_HANDLE;
2192 close_policy_hnd(p, r->in.handle);
2193 ZERO_STRUCTP(r->out.handle);
2198 /***************************************************************************
2200 ***************************************************************************/
2202 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2203 struct lsa_EnumPrivs *r)
2205 struct lsa_info *handle;
2207 uint32 enum_context = *r->in.resume_handle;
2208 int num_privs = num_privileges_in_short_list();
2209 struct lsa_PrivEntry *entries = NULL;
2211 /* remember that the enum_context starts at 0 and not 1 */
2213 if ( enum_context >= num_privs )
2214 return NT_STATUS_NO_MORE_ENTRIES;
2216 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2217 enum_context, num_privs));
2219 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2220 return NT_STATUS_INVALID_HANDLE;
2222 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2223 return NT_STATUS_INVALID_HANDLE;
2226 /* check if the user has enough rights
2227 I don't know if it's the right one. not documented. */
2229 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2230 return NT_STATUS_ACCESS_DENIED;
2233 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2235 return NT_STATUS_NO_MEMORY;
2241 for (i = 0; i < num_privs; i++) {
2242 if( i < enum_context) {
2244 init_lsa_StringLarge(&entries[i].name, NULL);
2246 entries[i].luid.low = 0;
2247 entries[i].luid.high = 0;
2250 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2252 entries[i].luid.low = sec_privilege_from_index(i);
2253 entries[i].luid.high = 0;
2257 enum_context = num_privs;
2259 *r->out.resume_handle = enum_context;
2260 r->out.privs->count = num_privs;
2261 r->out.privs->privs = entries;
2263 return NT_STATUS_OK;
2266 /***************************************************************************
2267 _lsa_LookupPrivDisplayName
2268 ***************************************************************************/
2270 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2271 struct lsa_LookupPrivDisplayName *r)
2273 struct lsa_info *handle;
2274 const char *description;
2275 struct lsa_StringLarge *lsa_name;
2277 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2278 return NT_STATUS_INVALID_HANDLE;
2280 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2281 return NT_STATUS_INVALID_HANDLE;
2284 /* check if the user has enough rights */
2287 * I don't know if it's the right one. not documented.
2289 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2290 return NT_STATUS_ACCESS_DENIED;
2292 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2294 description = get_privilege_dispname(r->in.name->string);
2296 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2297 return NT_STATUS_NO_SUCH_PRIVILEGE;
2300 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2302 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2304 return NT_STATUS_NO_MEMORY;
2307 init_lsa_StringLarge(lsa_name, description);
2309 *r->out.returned_language_id = r->in.language_id;
2310 *r->out.disp_name = lsa_name;
2312 return NT_STATUS_OK;
2315 /***************************************************************************
2317 ***************************************************************************/
2319 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2320 struct lsa_EnumAccounts *r)
2322 struct lsa_info *handle;
2323 struct dom_sid *sid_list;
2324 int i, j, num_entries;
2326 struct lsa_SidPtr *sids = NULL;
2328 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2329 return NT_STATUS_INVALID_HANDLE;
2331 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2332 return NT_STATUS_INVALID_HANDLE;
2335 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2336 return NT_STATUS_ACCESS_DENIED;
2341 /* The only way we can currently find out all the SIDs that have been
2342 privileged is to scan all privileges */
2344 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2345 if (!NT_STATUS_IS_OK(status)) {
2349 if (*r->in.resume_handle >= num_entries) {
2350 return NT_STATUS_NO_MORE_ENTRIES;
2353 if (num_entries - *r->in.resume_handle) {
2354 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2355 num_entries - *r->in.resume_handle);
2357 talloc_free(sid_list);
2358 return NT_STATUS_NO_MEMORY;
2361 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2362 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2364 talloc_free(sid_list);
2365 return NT_STATUS_NO_MEMORY;
2370 talloc_free(sid_list);
2372 *r->out.resume_handle = num_entries;
2373 r->out.sids->num_sids = num_entries;
2374 r->out.sids->sids = sids;
2376 return NT_STATUS_OK;
2379 /***************************************************************************
2381 ***************************************************************************/
2383 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2384 struct lsa_GetUserName *r)
2386 const char *username, *domname;
2387 struct lsa_String *account_name = NULL;
2388 struct lsa_String *authority_name = NULL;
2390 if (r->in.account_name &&
2391 *r->in.account_name) {
2392 return NT_STATUS_INVALID_PARAMETER;
2395 if (r->in.authority_name &&
2396 *r->in.authority_name) {
2397 return NT_STATUS_INVALID_PARAMETER;
2400 if (p->session_info->guest) {
2402 * I'm 99% sure this is not the right place to do this,
2403 * global_sid_Anonymous should probably be put into the token
2404 * instead of the guest id -- vl
2406 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2407 &domname, &username, NULL)) {
2408 return NT_STATUS_NO_MEMORY;
2411 username = p->session_info->sanitized_username;
2412 domname = p->session_info->info3->base.domain.string;
2415 account_name = talloc(p->mem_ctx, struct lsa_String);
2416 if (!account_name) {
2417 return NT_STATUS_NO_MEMORY;
2419 init_lsa_String(account_name, username);
2421 if (r->out.authority_name) {
2422 authority_name = talloc(p->mem_ctx, struct lsa_String);
2423 if (!authority_name) {
2424 return NT_STATUS_NO_MEMORY;
2426 init_lsa_String(authority_name, domname);
2429 *r->out.account_name = account_name;
2430 if (r->out.authority_name) {
2431 *r->out.authority_name = authority_name;
2434 return NT_STATUS_OK;
2437 /***************************************************************************
2439 ***************************************************************************/
2441 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2442 struct lsa_CreateAccount *r)
2445 struct lsa_info *handle;
2446 uint32_t acc_granted;
2447 struct security_descriptor *psd;
2450 /* find the connection policy handle. */
2451 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2452 return NT_STATUS_INVALID_HANDLE;
2454 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2455 return NT_STATUS_INVALID_HANDLE;
2458 /* check if the user has enough rights */
2460 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2461 return NT_STATUS_ACCESS_DENIED;
2464 /* Work out max allowed. */
2465 map_max_allowed_access(p->session_info->security_token,
2466 &p->session_info->utok,
2467 &r->in.access_mask);
2469 /* map the generic bits to the lsa policy ones */
2470 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2472 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2473 &lsa_account_mapping,
2474 r->in.sid, LSA_POLICY_ALL_ACCESS);
2475 if (!NT_STATUS_IS_OK(status)) {
2479 status = access_check_object(psd, p->session_info->security_token,
2480 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2481 &acc_granted, "_lsa_CreateAccount");
2482 if (!NT_STATUS_IS_OK(status)) {
2486 if ( is_privileged_sid( r->in.sid ) )
2487 return NT_STATUS_OBJECT_NAME_COLLISION;
2489 status = create_lsa_policy_handle(p->mem_ctx, p,
2490 LSA_HANDLE_ACCOUNT_TYPE,
2495 r->out.acct_handle);
2496 if (!NT_STATUS_IS_OK(status)) {
2497 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2500 return privilege_create_account(r->in.sid);
2503 /***************************************************************************
2505 ***************************************************************************/
2507 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2508 struct lsa_OpenAccount *r)
2510 struct lsa_info *handle;
2511 struct security_descriptor *psd = NULL;
2513 uint32_t des_access = r->in.access_mask;
2514 uint32_t acc_granted;
2517 /* find the connection policy handle. */
2518 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2519 return NT_STATUS_INVALID_HANDLE;
2521 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2522 return NT_STATUS_INVALID_HANDLE;
2525 /* des_access is for the account here, not the policy
2526 * handle - so don't check against policy handle. */
2528 /* Work out max allowed. */
2529 map_max_allowed_access(p->session_info->security_token,
2530 &p->session_info->utok,
2533 /* map the generic bits to the lsa account ones */
2534 se_map_generic(&des_access, &lsa_account_mapping);
2536 /* get the generic lsa account SD until we store it */
2537 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2538 &lsa_account_mapping,
2539 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2540 if (!NT_STATUS_IS_OK(status)) {
2544 status = access_check_object(psd, p->session_info->security_token,
2545 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2546 &acc_granted, "_lsa_OpenAccount" );
2547 if (!NT_STATUS_IS_OK(status)) {
2551 /* TODO: Fis the parsing routine before reenabling this check! */
2553 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2554 return NT_STATUS_ACCESS_DENIED;
2557 status = create_lsa_policy_handle(p->mem_ctx, p,
2558 LSA_HANDLE_ACCOUNT_TYPE,
2563 r->out.acct_handle);
2564 if (!NT_STATUS_IS_OK(status)) {
2565 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2568 return NT_STATUS_OK;
2571 /***************************************************************************
2572 _lsa_EnumPrivsAccount
2573 For a given SID, enumerate all the privilege this account has.
2574 ***************************************************************************/
2576 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2577 struct lsa_EnumPrivsAccount *r)
2579 NTSTATUS status = NT_STATUS_OK;
2580 struct lsa_info *info=NULL;
2581 PRIVILEGE_SET *privileges;
2582 struct lsa_PrivilegeSet *priv_set = NULL;
2584 /* find the connection policy handle. */
2585 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2586 return NT_STATUS_INVALID_HANDLE;
2588 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2589 return NT_STATUS_INVALID_HANDLE;
2592 if (!(info->access & LSA_ACCOUNT_VIEW))
2593 return NT_STATUS_ACCESS_DENIED;
2595 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2596 if (!NT_STATUS_IS_OK(status)) {
2600 *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2602 return NT_STATUS_NO_MEMORY;
2605 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2606 sid_string_dbg(&info->sid),
2607 privileges->count));
2609 priv_set->count = privileges->count;
2610 priv_set->unknown = 0;
2611 priv_set->set = talloc_move(priv_set, &privileges->set);
2616 /***************************************************************************
2617 _lsa_GetSystemAccessAccount
2618 ***************************************************************************/
2620 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2621 struct lsa_GetSystemAccessAccount *r)
2624 struct lsa_info *info = NULL;
2625 struct lsa_EnumPrivsAccount e;
2626 struct lsa_PrivilegeSet *privset;
2628 /* find the connection policy handle. */
2630 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2631 return NT_STATUS_INVALID_HANDLE;
2633 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2634 return NT_STATUS_INVALID_HANDLE;
2637 if (!(info->access & LSA_ACCOUNT_VIEW))
2638 return NT_STATUS_ACCESS_DENIED;
2640 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2642 return NT_STATUS_NO_MEMORY;
2645 e.in.handle = r->in.handle;
2646 e.out.privs = &privset;
2648 status = _lsa_EnumPrivsAccount(p, &e);
2649 if (!NT_STATUS_IS_OK(status)) {
2650 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2651 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2652 nt_errstr(status)));
2656 /* Samba4 would iterate over the privset to merge the policy mode bits,
2657 * not sure samba3 can do the same here, so just return what we did in
2661 0x01 -> Log on locally
2662 0x02 -> Access this computer from network
2663 0x04 -> Log on as a batch job
2664 0x10 -> Log on as a service
2666 they can be ORed together
2669 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2670 LSA_POLICY_MODE_NETWORK;
2672 return NT_STATUS_OK;
2675 /***************************************************************************
2676 update the systemaccount information
2677 ***************************************************************************/
2679 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2680 struct lsa_SetSystemAccessAccount *r)
2682 struct lsa_info *info=NULL;
2685 /* find the connection policy handle. */
2686 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2687 return NT_STATUS_INVALID_HANDLE;
2689 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2690 return NT_STATUS_INVALID_HANDLE;
2693 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2694 return NT_STATUS_ACCESS_DENIED;
2697 if (!pdb_getgrsid(&map, info->sid))
2698 return NT_STATUS_NO_SUCH_GROUP;
2700 return pdb_update_group_mapping_entry(&map);
2703 /***************************************************************************
2704 _lsa_AddPrivilegesToAccount
2705 For a given SID, add some privileges.
2706 ***************************************************************************/
2708 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
2709 struct lsa_AddPrivilegesToAccount *r)
2711 struct lsa_info *info = NULL;
2712 struct lsa_PrivilegeSet *set = NULL;
2714 /* find the connection policy handle. */
2715 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2716 return NT_STATUS_INVALID_HANDLE;
2718 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2719 return NT_STATUS_INVALID_HANDLE;
2722 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2723 return NT_STATUS_ACCESS_DENIED;
2728 if ( !grant_privilege_set( &info->sid, set ) ) {
2729 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2730 sid_string_dbg(&info->sid) ));
2731 return NT_STATUS_NO_SUCH_PRIVILEGE;
2734 return NT_STATUS_OK;
2737 /***************************************************************************
2738 _lsa_RemovePrivilegesFromAccount
2739 For a given SID, remove some privileges.
2740 ***************************************************************************/
2742 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2743 struct lsa_RemovePrivilegesFromAccount *r)
2745 struct lsa_info *info = NULL;
2746 struct lsa_PrivilegeSet *set = NULL;
2748 /* find the connection policy handle. */
2749 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2750 return NT_STATUS_INVALID_HANDLE;
2752 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2753 return NT_STATUS_INVALID_HANDLE;
2756 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2757 return NT_STATUS_ACCESS_DENIED;
2762 if ( !revoke_privilege_set( &info->sid, set) ) {
2763 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2764 sid_string_dbg(&info->sid) ));
2765 return NT_STATUS_NO_SUCH_PRIVILEGE;
2768 return NT_STATUS_OK;
2771 /***************************************************************************
2773 ***************************************************************************/
2775 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2776 struct lsa_LookupPrivName *r)
2778 struct lsa_info *info = NULL;
2780 struct lsa_StringLarge *lsa_name;
2782 /* find the connection policy handle. */
2783 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2784 return NT_STATUS_INVALID_HANDLE;
2787 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2788 return NT_STATUS_INVALID_HANDLE;
2791 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2792 return NT_STATUS_ACCESS_DENIED;
2795 if (r->in.luid->high != 0) {
2796 return NT_STATUS_NO_SUCH_PRIVILEGE;
2799 name = sec_privilege_name(r->in.luid->low);
2801 return NT_STATUS_NO_SUCH_PRIVILEGE;
2804 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2806 return NT_STATUS_NO_MEMORY;
2809 lsa_name->string = talloc_strdup(lsa_name, name);
2810 if (!lsa_name->string) {
2811 TALLOC_FREE(lsa_name);
2812 return NT_STATUS_NO_MEMORY;
2815 *r->out.name = lsa_name;
2817 return NT_STATUS_OK;
2820 /***************************************************************************
2822 ***************************************************************************/
2824 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
2825 struct lsa_QuerySecurity *r)
2827 struct lsa_info *handle=NULL;
2828 struct security_descriptor *psd = NULL;
2832 /* find the connection policy handle. */
2833 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2834 return NT_STATUS_INVALID_HANDLE;
2836 switch (handle->type) {
2837 case LSA_HANDLE_POLICY_TYPE:
2838 case LSA_HANDLE_ACCOUNT_TYPE:
2839 case LSA_HANDLE_TRUST_TYPE:
2841 sd_size = ndr_size_security_descriptor(psd, 0);
2842 status = NT_STATUS_OK;
2845 status = NT_STATUS_INVALID_HANDLE;
2849 if (!NT_STATUS_IS_OK(status)) {
2853 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2854 if (!*r->out.sdbuf) {
2855 return NT_STATUS_NO_MEMORY;
2861 /***************************************************************************
2862 _lsa_AddAccountRights
2863 ***************************************************************************/
2865 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
2866 struct lsa_AddAccountRights *r)
2868 struct lsa_info *info = NULL;
2870 uint32_t acc_granted = 0;
2871 struct security_descriptor *psd = NULL;
2876 /* find the connection policy handle. */
2877 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2878 return NT_STATUS_INVALID_HANDLE;
2880 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2881 return NT_STATUS_INVALID_HANDLE;
2884 /* get the generic lsa account SD for this SID until we store it */
2885 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2886 &lsa_account_mapping,
2887 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2888 if (!NT_STATUS_IS_OK(status)) {
2893 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2894 * on the policy handle. If it does, ask for
2895 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2896 * on the account sid. We don't check here so just use the latter. JRA.
2899 status = access_check_object(psd, p->session_info->security_token,
2900 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2901 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2902 &acc_granted, "_lsa_AddAccountRights" );
2903 if (!NT_STATUS_IS_OK(status)) {
2907 /* according to an NT4 PDC, you can add privileges to SIDs even without
2908 call_lsa_create_account() first. And you can use any arbitrary SID. */
2910 sid_copy( &sid, r->in.sid );
2912 for ( i=0; i < r->in.rights->count; i++ ) {
2914 const char *privname = r->in.rights->names[i].string;
2916 /* only try to add non-null strings */
2921 if ( !grant_privilege_by_name( &sid, privname ) ) {
2922 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2924 return NT_STATUS_NO_SUCH_PRIVILEGE;
2928 return NT_STATUS_OK;
2931 /***************************************************************************
2932 _lsa_RemoveAccountRights
2933 ***************************************************************************/
2935 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
2936 struct lsa_RemoveAccountRights *r)
2938 struct lsa_info *info = NULL;
2940 struct security_descriptor *psd = NULL;
2943 const char *privname = NULL;
2944 uint32_t acc_granted = 0;
2947 /* find the connection policy handle. */
2948 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2949 return NT_STATUS_INVALID_HANDLE;
2951 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2952 return NT_STATUS_INVALID_HANDLE;
2955 /* get the generic lsa account SD for this SID until we store it */
2956 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2957 &lsa_account_mapping,
2958 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2959 if (!NT_STATUS_IS_OK(status)) {
2964 * From the MS DOCs. We need
2965 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2966 * and DELETE on the account sid.
2969 status = access_check_object(psd, p->session_info->security_token,
2970 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2971 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2972 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
2973 &acc_granted, "_lsa_RemoveAccountRights");
2974 if (!NT_STATUS_IS_OK(status)) {
2978 sid_copy( &sid, r->in.sid );
2980 if ( r->in.remove_all ) {
2981 if ( !revoke_all_privileges( &sid ) )
2982 return NT_STATUS_ACCESS_DENIED;
2984 return NT_STATUS_OK;
2987 for ( i=0; i < r->in.rights->count; i++ ) {
2989 privname = r->in.rights->names[i].string;
2991 /* only try to add non-null strings */
2996 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2997 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2999 return NT_STATUS_NO_SUCH_PRIVILEGE;
3003 return NT_STATUS_OK;
3006 /*******************************************************************
3007 ********************************************************************/
3009 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3010 struct lsa_RightSet *r,
3011 PRIVILEGE_SET *privileges)
3014 const char *privname;
3015 const char **privname_array = NULL;
3018 for (i=0; i<privileges->count; i++) {
3019 if (privileges->set[i].luid.high) {
3022 privname = sec_privilege_name(privileges->set[i].luid.low);
3024 if (!add_string_to_array(mem_ctx, privname,
3025 &privname_array, &num_priv)) {
3026 return NT_STATUS_NO_MEMORY;
3033 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3036 return NT_STATUS_NO_MEMORY;
3039 for (i=0; i<num_priv; i++) {
3040 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3043 r->count = num_priv;
3046 return NT_STATUS_OK;
3049 /***************************************************************************
3050 _lsa_EnumAccountRights
3051 ***************************************************************************/
3053 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3054 struct lsa_EnumAccountRights *r)
3057 struct lsa_info *info = NULL;
3058 PRIVILEGE_SET *privileges;
3060 /* find the connection policy handle. */
3062 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3063 return NT_STATUS_INVALID_HANDLE;
3065 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3066 return NT_STATUS_INVALID_HANDLE;
3069 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3070 return NT_STATUS_ACCESS_DENIED;
3073 /* according to an NT4 PDC, you can add privileges to SIDs even without
3074 call_lsa_create_account() first. And you can use any arbitrary SID. */
3076 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3077 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3078 * the lsa database */
3080 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3081 if (!NT_STATUS_IS_OK(status)) {
3085 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3086 sid_string_dbg(r->in.sid), privileges->count));
3088 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3093 /***************************************************************************
3094 _lsa_LookupPrivValue
3095 ***************************************************************************/
3097 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3098 struct lsa_LookupPrivValue *r)
3100 struct lsa_info *info = NULL;
3101 const char *name = NULL;
3103 /* find the connection policy handle. */
3105 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3106 return NT_STATUS_INVALID_HANDLE;
3108 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3109 return NT_STATUS_INVALID_HANDLE;
3112 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3113 return NT_STATUS_ACCESS_DENIED;
3115 name = r->in.name->string;
3117 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3119 r->out.luid->low = sec_privilege_id(name);
3120 r->out.luid->high = 0;
3121 if (r->out.luid->low == SEC_PRIV_INVALID) {
3122 return NT_STATUS_NO_SUCH_PRIVILEGE;
3124 return NT_STATUS_OK;
3127 /***************************************************************************
3128 _lsa_EnumAccountsWithUserRight
3129 ***************************************************************************/
3131 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3132 struct lsa_EnumAccountsWithUserRight *r)
3135 struct lsa_info *info = NULL;
3136 struct dom_sid *sids = NULL;
3139 enum sec_privilege privilege;
3141 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3142 return NT_STATUS_INVALID_HANDLE;
3145 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3146 return NT_STATUS_INVALID_HANDLE;
3149 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3150 return NT_STATUS_ACCESS_DENIED;
3153 if (!r->in.name || !r->in.name->string) {
3154 return NT_STATUS_NO_SUCH_PRIVILEGE;
3157 privilege = sec_privilege_id(r->in.name->string);
3158 if (privilege == SEC_PRIV_INVALID) {
3159 return NT_STATUS_NO_SUCH_PRIVILEGE;
3162 status = privilege_enum_sids(privilege, p->mem_ctx,
3164 if (!NT_STATUS_IS_OK(status)) {
3168 r->out.sids->num_sids = num_sids;
3169 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3170 r->out.sids->num_sids);
3172 for (i=0; i < r->out.sids->num_sids; i++) {
3173 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3175 if (!r->out.sids->sids[i].sid) {
3176 TALLOC_FREE(r->out.sids->sids);
3177 r->out.sids->num_sids = 0;
3178 return NT_STATUS_NO_MEMORY;
3182 return NT_STATUS_OK;
3185 /***************************************************************************
3187 ***************************************************************************/
3189 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3190 struct lsa_Delete *r)
3192 return NT_STATUS_NOT_SUPPORTED;
3196 * From here on the server routines are just dummy ones to make smbd link with
3197 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3198 * pulling the server stubs across one by one.
3201 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3203 p->rng_fault_state = True;
3204 return NT_STATUS_NOT_IMPLEMENTED;
3207 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3208 struct lsa_ChangePassword *r)
3210 p->rng_fault_state = True;
3211 return NT_STATUS_NOT_IMPLEMENTED;
3214 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3216 p->rng_fault_state = True;
3217 return NT_STATUS_NOT_IMPLEMENTED;
3220 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3222 p->rng_fault_state = True;
3223 return NT_STATUS_NOT_IMPLEMENTED;
3226 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3227 struct lsa_GetQuotasForAccount *r)
3229 p->rng_fault_state = True;
3230 return NT_STATUS_NOT_IMPLEMENTED;
3233 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3234 struct lsa_SetQuotasForAccount *r)
3236 p->rng_fault_state = True;
3237 return NT_STATUS_NOT_IMPLEMENTED;
3240 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3241 struct lsa_SetInformationTrustedDomain *r)
3243 p->rng_fault_state = True;
3244 return NT_STATUS_NOT_IMPLEMENTED;
3247 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
3249 p->rng_fault_state = True;
3250 return NT_STATUS_NOT_IMPLEMENTED;
3253 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3254 struct lsa_SetTrustedDomainInfo *r)
3256 p->rng_fault_state = True;
3257 return NT_STATUS_NOT_IMPLEMENTED;
3260 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3261 struct lsa_StorePrivateData *r)
3263 p->rng_fault_state = True;
3264 return NT_STATUS_NOT_IMPLEMENTED;
3267 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3268 struct lsa_RetrievePrivateData *r)
3270 p->rng_fault_state = True;
3271 return NT_STATUS_NOT_IMPLEMENTED;
3274 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3275 struct lsa_SetInfoPolicy2 *r)
3277 p->rng_fault_state = True;
3278 return NT_STATUS_NOT_IMPLEMENTED;
3281 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3282 struct lsa_SetTrustedDomainInfoByName *r)
3284 p->rng_fault_state = True;
3285 return NT_STATUS_NOT_IMPLEMENTED;
3288 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3289 struct lsa_EnumTrustedDomainsEx *r)
3291 struct lsa_info *info;
3293 struct pdb_trusted_domain **domains;
3294 struct lsa_TrustDomainInfoInfoEx *entries;
3298 /* bail out early if pdb backend is not capable of ex trusted domains,
3299 * if we dont do that, the client might not call
3300 * _lsa_EnumTrustedDomains() afterwards - gd */
3302 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3303 p->rng_fault_state = True;
3304 return NT_STATUS_NOT_IMPLEMENTED;
3307 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3308 return NT_STATUS_INVALID_HANDLE;
3310 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3311 return NT_STATUS_INVALID_HANDLE;
3314 /* check if the user has enough rights */
3315 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3316 return NT_STATUS_ACCESS_DENIED;
3319 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3322 if (!NT_STATUS_IS_OK(nt_status)) {
3326 entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3329 return NT_STATUS_NO_MEMORY;
3332 for (i=0; i<count; i++) {
3333 init_lsa_StringLarge(&entries[i].netbios_name,
3334 domains[i]->netbios_name);
3335 entries[i].sid = &domains[i]->security_identifier;
3338 if (*r->in.resume_handle >= count) {
3339 *r->out.resume_handle = -1;
3340 TALLOC_FREE(entries);
3341 return NT_STATUS_NO_MORE_ENTRIES;
3344 /* return the rest, limit by max_size. Note that we
3345 use the w2k3 element size value of 60 */
3346 r->out.domains->count = count - *r->in.resume_handle;
3347 r->out.domains->count = MIN(r->out.domains->count,
3348 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3350 r->out.domains->domains = entries + *r->in.resume_handle;
3352 if (r->out.domains->count < count - *r->in.resume_handle) {
3353 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3354 return STATUS_MORE_ENTRIES;
3357 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3358 * always be larger than the previous input resume handle, in
3359 * particular when hitting the last query it is vital to set the
3360 * resume handle correctly to avoid infinite client loops, as
3361 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3362 * status is NT_STATUS_OK - gd */
3364 *r->out.resume_handle = (uint32_t)-1;
3366 return NT_STATUS_OK;
3369 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3370 struct lsa_QueryDomainInformationPolicy *r)
3372 p->rng_fault_state = True;
3373 return NT_STATUS_NOT_IMPLEMENTED;
3376 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3377 struct lsa_SetDomainInformationPolicy *r)
3379 p->rng_fault_state = True;
3380 return NT_STATUS_NOT_IMPLEMENTED;
3383 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3385 p->rng_fault_state = True;
3386 return NT_STATUS_NOT_IMPLEMENTED;
3389 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3391 p->rng_fault_state = True;
3392 return NT_STATUS_NOT_IMPLEMENTED;
3395 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3397 p->rng_fault_state = True;
3398 return NT_STATUS_NOT_IMPLEMENTED;
3401 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3403 p->rng_fault_state = True;
3404 return NT_STATUS_NOT_IMPLEMENTED;
3407 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3408 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3410 p->rng_fault_state = True;
3411 return NT_STATUS_NOT_IMPLEMENTED;
3414 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3415 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3417 p->rng_fault_state = True;
3418 return NT_STATUS_NOT_IMPLEMENTED;
3421 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3423 p->rng_fault_state = True;
3424 return NT_STATUS_NOT_IMPLEMENTED;
3427 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3428 struct lsa_CREDRGETTARGETINFO *r)
3430 p->rng_fault_state = True;
3431 return NT_STATUS_NOT_IMPLEMENTED;
3434 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3435 struct lsa_CREDRPROFILELOADED *r)
3437 p->rng_fault_state = True;
3438 return NT_STATUS_NOT_IMPLEMENTED;
3441 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3442 struct lsa_CREDRGETSESSIONTYPES *r)
3444 p->rng_fault_state = True;
3445 return NT_STATUS_NOT_IMPLEMENTED;
3448 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3449 struct lsa_LSARREGISTERAUDITEVENT *r)
3451 p->rng_fault_state = True;
3452 return NT_STATUS_NOT_IMPLEMENTED;
3455 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3456 struct lsa_LSARGENAUDITEVENT *r)
3458 p->rng_fault_state = True;
3459 return NT_STATUS_NOT_IMPLEMENTED;
3462 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3463 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3465 p->rng_fault_state = True;
3466 return NT_STATUS_NOT_IMPLEMENTED;
3469 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3470 struct lsa_lsaRQueryForestTrustInformation *r)
3472 p->rng_fault_state = True;
3473 return NT_STATUS_NOT_IMPLEMENTED;
3476 #define DNS_CMP_MATCH 0
3477 #define DNS_CMP_FIRST_IS_CHILD 1
3478 #define DNS_CMP_SECOND_IS_CHILD 2
3479 #define DNS_CMP_NO_MATCH 3
3481 /* this function assumes names are well formed DNS names.
3482 * it doesn't validate them */
3483 static int dns_cmp(const char *s1, size_t l1,
3484 const char *s2, size_t l2)
3486 const char *p1, *p2;
3491 if (strcasecmp_m(s1, s2) == 0) {
3492 return DNS_CMP_MATCH;
3494 return DNS_CMP_NO_MATCH;
3502 cret = DNS_CMP_FIRST_IS_CHILD;
3508 cret = DNS_CMP_SECOND_IS_CHILD;
3511 if (p1[t1 - t2 - 1] != '.') {
3512 return DNS_CMP_NO_MATCH;
3515 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
3519 return DNS_CMP_NO_MATCH;
3522 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3523 struct lsa_ForestTrustInformation *lfti,
3524 struct ForestTrustInfo *fti)
3526 struct lsa_ForestTrustRecord *lrec;
3527 struct ForestTrustInfoRecord *rec;
3528 struct lsa_StringLarge *tln;
3529 struct lsa_ForestTrustDomainInfo *info;
3533 fti->count = lfti->count;
3534 fti->records = talloc_array(mem_ctx,
3535 struct ForestTrustInfoRecordArmor,
3537 if (!fti->records) {
3538 return NT_STATUS_NO_MEMORY;
3540 for (i = 0; i < fti->count; i++) {
3541 lrec = lfti->entries[i];
3542 rec = &fti->records[i].record;
3544 rec->flags = lrec->flags;
3545 rec->timestamp = lrec->time;
3546 rec->type = lrec->type;
3548 switch (lrec->type) {
3549 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3550 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3551 tln = &lrec->forest_trust_data.top_level_name;
3552 rec->data.name.string =
3553 talloc_strdup(mem_ctx, tln->string);
3554 if (!rec->data.name.string) {
3555 return NT_STATUS_NO_MEMORY;
3557 rec->data.name.size = strlen(rec->data.name.string);
3559 case LSA_FOREST_TRUST_DOMAIN_INFO:
3560 info = &lrec->forest_trust_data.domain_info;
3561 rec->data.info.sid = *info->domain_sid;
3562 rec->data.info.dns_name.string =
3563 talloc_strdup(mem_ctx,
3564 info->dns_domain_name.string);
3565 if (!rec->data.info.dns_name.string) {
3566 return NT_STATUS_NO_MEMORY;
3568 rec->data.info.dns_name.size =
3569 strlen(rec->data.info.dns_name.string);
3570 rec->data.info.netbios_name.string =
3571 talloc_strdup(mem_ctx,
3572 info->netbios_domain_name.string);
3573 if (!rec->data.info.netbios_name.string) {
3574 return NT_STATUS_NO_MEMORY;
3576 rec->data.info.netbios_name.size =
3577 strlen(rec->data.info.netbios_name.string);
3580 return NT_STATUS_INVALID_DOMAIN_STATE;
3584 return NT_STATUS_OK;
3587 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3588 uint32_t index, uint32_t collision_type,
3589 uint32_t conflict_type, const char *tdo_name);
3591 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
3592 const char *tdo_name,
3593 struct ForestTrustInfo *tdo_fti,
3594 struct ForestTrustInfo *new_fti,
3595 struct lsa_ForestTrustCollisionInfo *c_info)
3597 struct ForestTrustInfoRecord *nrec;
3598 struct ForestTrustInfoRecord *trec;
3599 const char *dns_name;
3600 const char *nb_name = NULL;
3601 struct dom_sid *sid = NULL;
3602 const char *tname = NULL;
3607 uint32_t new_fti_idx;
3609 /* use always TDO type, until we understand when Xref can be used */
3610 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
3615 bool ex_rule = false;
3618 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
3620 nrec = &new_fti->records[new_fti_idx].record;
3622 tln_conflict = false;
3623 sid_conflict = false;
3624 nb_conflict = false;
3627 switch (nrec->type) {
3628 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3629 /* exclusions do not conflict by definition */
3632 case FOREST_TRUST_TOP_LEVEL_NAME:
3633 dns_name = nrec->data.name.string;
3634 dns_len = nrec->data.name.size;
3637 case LSA_FOREST_TRUST_DOMAIN_INFO:
3638 dns_name = nrec->data.info.dns_name.string;
3639 dns_len = nrec->data.info.dns_name.size;
3640 nb_name = nrec->data.info.netbios_name.string;
3641 nb_len = nrec->data.info.netbios_name.size;
3642 sid = &nrec->data.info.sid;
3646 if (!dns_name) continue;
3648 /* check if this is already taken and not excluded */
3649 for (i = 0; i < tdo_fti->count; i++) {
3650 trec = &tdo_fti->records[i].record;
3652 switch (trec->type) {
3653 case FOREST_TRUST_TOP_LEVEL_NAME:
3655 tname = trec->data.name.string;
3656 tlen = trec->data.name.size;
3658 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
3660 tname = trec->data.name.string;
3661 tlen = trec->data.name.size;
3663 case FOREST_TRUST_DOMAIN_INFO:
3665 tname = trec->data.info.dns_name.string;
3666 tlen = trec->data.info.dns_name.size;
3669 return NT_STATUS_INVALID_PARAMETER;
3671 ret = dns_cmp(dns_name, dns_len, tname, tlen);
3674 /* if it matches exclusion,
3675 * it doesn't conflict */
3681 case DNS_CMP_FIRST_IS_CHILD:
3682 case DNS_CMP_SECOND_IS_CHILD:
3683 tln_conflict = true;
3689 /* explicit exclusion, no dns name conflict here */
3691 tln_conflict = false;
3694 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
3698 /* also test for domain info */
3699 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
3700 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
3701 sid_conflict = true;
3703 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
3704 strcasecmp_m(trec->data.info.netbios_name.string,
3711 nt_status = add_collision(c_info, new_fti_idx,
3713 LSA_TLN_DISABLED_CONFLICT,
3717 nt_status = add_collision(c_info, new_fti_idx,
3719 LSA_SID_DISABLED_CONFLICT,
3723 nt_status = add_collision(c_info, new_fti_idx,
3725 LSA_NB_DISABLED_CONFLICT,
3730 return NT_STATUS_OK;
3733 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3734 uint32_t idx, uint32_t collision_type,
3735 uint32_t conflict_type, const char *tdo_name)
3737 struct lsa_ForestTrustCollisionRecord **es;
3738 uint32_t i = c_info->count;
3740 es = talloc_realloc(c_info, c_info->entries,
3741 struct lsa_ForestTrustCollisionRecord *, i + 1);
3743 return NT_STATUS_NO_MEMORY;
3745 c_info->entries = es;
3746 c_info->count = i + 1;
3748 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
3750 return NT_STATUS_NO_MEMORY;
3754 es[i]->type = collision_type;
3755 es[i]->flags.flags = conflict_type;
3756 es[i]->name.string = talloc_strdup(es[i], tdo_name);
3757 if (!es[i]->name.string) {
3758 return NT_STATUS_NO_MEMORY;
3760 es[i]->name.size = strlen(es[i]->name.string);
3762 return NT_STATUS_OK;
3765 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3766 struct pdb_trusted_domain *td,
3767 struct ForestTrustInfo *info)
3769 enum ndr_err_code ndr_err;
3771 if (td->trust_forest_trust_info.length == 0 ||
3772 td->trust_forest_trust_info.data == NULL) {
3773 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3775 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
3777 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3778 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3779 return NT_STATUS_INVALID_DOMAIN_STATE;
3782 return NT_STATUS_OK;
3785 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
3786 struct ForestTrustInfo *fti)
3788 struct ForestTrustDataDomainInfo *info;
3789 struct ForestTrustInfoRecord *rec;
3793 fti->records = talloc_array(fti,
3794 struct ForestTrustInfoRecordArmor, 2);
3795 if (!fti->records) {
3796 return NT_STATUS_NO_MEMORY;
3800 rec = &fti->records[0].record;
3804 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3806 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
3807 if (!rec->data.name.string) {
3808 return NT_STATUS_NO_MEMORY;
3810 rec->data.name.size = strlen(rec->data.name.string);
3813 rec = &fti->records[1].record;
3817 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3819 info = &rec->data.info;
3821 info->sid = dom_info->sid;
3822 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
3823 if (!info->dns_name.string) {
3824 return NT_STATUS_NO_MEMORY;
3826 info->dns_name.size = strlen(info->dns_name.string);
3827 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
3828 if (!info->netbios_name.string) {
3829 return NT_STATUS_NO_MEMORY;
3831 info->netbios_name.size = strlen(info->netbios_name.string);
3833 return NT_STATUS_OK;
3836 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
3837 struct lsa_lsaRSetForestTrustInformation *r)
3842 struct lsa_info *handle;
3843 uint32_t num_domains;
3844 struct pdb_trusted_domain **domains;
3845 struct ForestTrustInfo *nfti;
3846 struct ForestTrustInfo *fti;
3847 struct lsa_ForestTrustCollisionInfo *c_info;
3848 struct pdb_domain_info *dom_info;
3849 enum ndr_err_code ndr_err;
3852 return NT_STATUS_NOT_SUPPORTED;
3855 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
3856 return NT_STATUS_INVALID_HANDLE;
3859 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
3860 return NT_STATUS_INVALID_HANDLE;
3863 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
3864 return NT_STATUS_ACCESS_DENIED;
3867 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
3868 if (!NT_STATUS_IS_OK(status)) {
3871 if (num_domains == 0) {
3872 return NT_STATUS_NO_SUCH_DOMAIN;
3875 for (i = 0; i < num_domains; i++) {
3876 if (domains[i]->domain_name == NULL) {
3877 return NT_STATUS_INVALID_DOMAIN_STATE;
3879 if (strcasecmp_m(domains[i]->domain_name,
3880 r->in.trusted_domain_name->string) == 0) {
3884 if (i >= num_domains) {
3885 return NT_STATUS_NO_SUCH_DOMAIN;
3888 if (!(domains[i]->trust_attributes &
3889 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
3890 return NT_STATUS_INVALID_PARAMETER;
3893 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
3894 return NT_STATUS_INVALID_PARAMETER;
3897 /* The following section until COPY_END is a copy from
3898 * source4/rpmc_server/lsa/scesrc_lsa.c */
3899 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
3901 return NT_STATUS_NO_MEMORY;
3904 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
3905 if (!NT_STATUS_IS_OK(status)) {
3909 c_info = talloc_zero(r->out.collision_info,
3910 struct lsa_ForestTrustCollisionInfo);
3912 return NT_STATUS_NO_MEMORY;
3915 /* first check own info, then other domains */
3916 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3918 return NT_STATUS_NO_MEMORY;
3921 dom_info = pdb_get_domain_info(p->mem_ctx);
3923 status = own_ft_info(dom_info, fti);
3924 if (!NT_STATUS_IS_OK(status)) {
3928 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
3929 if (!NT_STATUS_IS_OK(status)) {
3933 for (j = 0; j < num_domains; j++) {
3934 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3936 return NT_STATUS_NO_MEMORY;
3939 status = get_ft_info(p->mem_ctx, domains[j], fti);
3940 if (!NT_STATUS_IS_OK(status)) {
3941 if (NT_STATUS_EQUAL(status,
3942 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3948 if (domains[j]->domain_name == NULL) {
3949 return NT_STATUS_INVALID_DOMAIN_STATE;
3952 status = check_ft_info(c_info, domains[j]->domain_name,
3954 if (!NT_STATUS_IS_OK(status)) {
3959 *r->out.collision_info = c_info;
3961 if (r->in.check_only != 0) {
3962 return NT_STATUS_OK;
3967 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
3969 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
3970 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3971 return NT_STATUS_INVALID_PARAMETER;
3974 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
3975 if (!NT_STATUS_IS_OK(status)) {
3979 return NT_STATUS_OK;
3982 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
3983 struct lsa_CREDRRENAME *r)
3985 p->rng_fault_state = True;
3986 return NT_STATUS_NOT_IMPLEMENTED;
3989 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
3990 struct lsa_LSAROPENPOLICYSCE *r)
3992 p->rng_fault_state = True;
3993 return NT_STATUS_NOT_IMPLEMENTED;
3996 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
3997 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3999 p->rng_fault_state = True;
4000 return NT_STATUS_NOT_IMPLEMENTED;
4003 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4004 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4006 p->rng_fault_state = True;
4007 return NT_STATUS_NOT_IMPLEMENTED;
4010 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4011 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4013 p->rng_fault_state = True;
4014 return NT_STATUS_NOT_IMPLEMENTED;