2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Jeremy Allison 2001, 2006.
8 * Copyright (C) Rafal Szczesniak 2002,
9 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
10 * Copyright (C) Simo Sorce 2003.
11 * Copyright (C) Gerald (Jerry) Carter 2005.
12 * Copyright (C) Volker Lendecke 2005.
13 * Copyright (C) Guenther Deschner 2008.
14 * Copyright (C) Andrew Bartlett 2010.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
30 /* This is the implementation of the lsa server code. */
33 #include "../librpc/gen_ndr/srv_lsa.h"
35 #include "../librpc/gen_ndr/netlogon.h"
36 #include "rpc_client/init_lsa.h"
37 #include "../libcli/security/security.h"
38 #include "../libcli/security/dom_sid.h"
39 #include "../librpc/gen_ndr/drsblobs.h"
40 #include "../librpc/gen_ndr/ndr_drsblobs.h"
41 #include "../lib/crypto/arcfour.h"
42 #include "../libcli/security/dom_sid.h"
43 #include "../librpc/gen_ndr/ndr_security.h"
46 #define DBGC_CLASS DBGC_RPC_SRV
48 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
50 enum lsa_handle_type {
51 LSA_HANDLE_POLICY_TYPE = 1,
52 LSA_HANDLE_ACCOUNT_TYPE = 2,
53 LSA_HANDLE_TRUST_TYPE = 3};
59 enum lsa_handle_type type;
60 struct security_descriptor *sd;
63 const struct generic_mapping lsa_account_mapping = {
67 LSA_ACCOUNT_ALL_ACCESS
70 const struct generic_mapping lsa_policy_mapping = {
77 const struct generic_mapping lsa_secret_mapping = {
84 const struct generic_mapping lsa_trusted_domain_mapping = {
85 LSA_TRUSTED_DOMAIN_READ,
86 LSA_TRUSTED_DOMAIN_WRITE,
87 LSA_TRUSTED_DOMAIN_EXECUTE,
88 LSA_TRUSTED_DOMAIN_ALL_ACCESS
91 /***************************************************************************
92 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
93 ***************************************************************************/
95 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
96 struct lsa_RefDomainList *ref,
98 struct dom_sid *dom_sid)
102 if (dom_name != NULL) {
103 for (num = 0; num < ref->count; num++) {
104 if (dom_sid_equal(dom_sid, ref->domains[num].sid)) {
112 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
113 /* index not found, already at maximum domain limit */
117 ref->count = num + 1;
118 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
120 ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains,
121 struct lsa_DomainInfo, ref->count);
126 ZERO_STRUCT(ref->domains[num]);
128 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
129 ref->domains[num].sid = dom_sid_dup(mem_ctx, dom_sid);
130 if (!ref->domains[num].sid) {
138 /***************************************************************************
139 initialize a lsa_DomainInfo structure.
140 ***************************************************************************/
142 static void init_dom_query_3(struct lsa_DomainInfo *r,
146 init_lsa_StringLarge(&r->name, name);
150 /***************************************************************************
151 initialize a lsa_DomainInfo structure.
152 ***************************************************************************/
154 static void init_dom_query_5(struct lsa_DomainInfo *r,
158 init_lsa_StringLarge(&r->name, name);
162 /***************************************************************************
163 lookup_lsa_rids. Must be called as root for lookup_name to work.
164 ***************************************************************************/
166 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
167 struct lsa_RefDomainList *ref,
168 struct lsa_TranslatedSid *prid,
169 uint32_t num_entries,
170 struct lsa_String *name,
172 uint32_t *pmapped_count)
174 uint32 mapped_count, i;
176 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
181 for (i = 0; i < num_entries; i++) {
185 const char *full_name;
187 enum lsa_SidType type;
189 /* Split name into domain and user component */
191 /* follow w2k8 behavior and return the builtin domain when no
192 * input has been passed in */
194 if (name[i].string) {
195 full_name = name[i].string;
197 full_name = "BUILTIN";
200 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
202 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
204 type = SID_NAME_UNKNOWN;
209 case SID_NAME_DOM_GRP:
210 case SID_NAME_DOMAIN:
212 case SID_NAME_WKN_GRP:
213 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
214 /* Leave these unchanged */
217 /* Don't hand out anything but the list above */
218 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
219 type = SID_NAME_UNKNOWN;
226 if (type != SID_NAME_UNKNOWN) {
227 if (type == SID_NAME_DOMAIN) {
230 sid_split_rid(&sid, &rid);
232 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
236 prid[i].sid_type = type;
238 prid[i].sid_index = dom_idx;
241 *pmapped_count = mapped_count;
245 /***************************************************************************
246 lookup_lsa_sids. Must be called as root for lookup_name to work.
247 ***************************************************************************/
249 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
250 struct lsa_RefDomainList *ref,
251 struct lsa_TranslatedSid3 *trans_sids,
252 uint32_t num_entries,
253 struct lsa_String *name,
255 uint32 *pmapped_count)
257 uint32 mapped_count, i;
259 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
264 for (i = 0; i < num_entries; i++) {
268 const char *full_name;
270 enum lsa_SidType type;
274 /* Split name into domain and user component */
276 full_name = name[i].string;
277 if (full_name == NULL) {
278 return NT_STATUS_NO_MEMORY;
281 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
283 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
285 type = SID_NAME_UNKNOWN;
290 case SID_NAME_DOM_GRP:
291 case SID_NAME_DOMAIN:
293 case SID_NAME_WKN_GRP:
294 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
295 /* Leave these unchanged */
298 /* Don't hand out anything but the list above */
299 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
300 type = SID_NAME_UNKNOWN;
307 if (type != SID_NAME_UNKNOWN) {
308 struct dom_sid domain_sid;
309 sid_copy(&domain_sid, &sid);
310 sid_split_rid(&domain_sid, &rid);
311 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
315 /* Initialize the lsa_TranslatedSid3 return. */
316 trans_sids[i].sid_type = type;
317 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
318 trans_sids[i].sid_index = dom_idx;
321 *pmapped_count = mapped_count;
325 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
326 const struct generic_mapping *map,
327 struct dom_sid *sid, uint32_t sid_access)
329 struct dom_sid adm_sid;
330 struct security_ace ace[5];
333 struct security_acl *psa = NULL;
335 /* READ|EXECUTE access for Everyone */
337 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
338 map->generic_execute | map->generic_read, 0);
340 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
342 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
343 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
344 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
345 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
347 /* Add Full Access for Domain Admins */
348 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
349 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
350 map->generic_all, 0);
352 /* If we have a sid, give it some special access */
355 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
359 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
360 return NT_STATUS_NO_MEMORY;
362 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
363 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
364 psa, sd_size)) == NULL)
365 return NT_STATUS_NO_MEMORY;
370 /***************************************************************************
371 ***************************************************************************/
373 static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
374 struct pipes_struct *p,
375 enum lsa_handle_type type,
376 uint32_t acc_granted,
379 const struct security_descriptor *sd,
380 struct policy_handle *handle)
382 struct lsa_info *info;
384 ZERO_STRUCTP(handle);
386 info = talloc_zero(mem_ctx, struct lsa_info);
388 return NT_STATUS_NO_MEMORY;
392 info->access = acc_granted;
395 sid_copy(&info->sid, sid);
398 info->name = talloc_strdup(info, name);
401 info->sd = dup_sec_desc(info, sd);
404 return NT_STATUS_NO_MEMORY;
408 if (!create_policy_hnd(p, handle, info)) {
410 ZERO_STRUCTP(handle);
411 return NT_STATUS_NO_MEMORY;
417 /***************************************************************************
419 ***************************************************************************/
421 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
422 struct lsa_OpenPolicy2 *r)
424 struct security_descriptor *psd = NULL;
426 uint32 des_access = r->in.access_mask;
430 /* Work out max allowed. */
431 map_max_allowed_access(p->session_info->security_token,
432 &p->session_info->utok,
435 /* map the generic bits to the lsa policy ones */
436 se_map_generic(&des_access, &lsa_policy_mapping);
438 /* get the generic lsa policy SD until we store it */
439 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
441 if (!NT_STATUS_IS_OK(status)) {
445 status = access_check_object(psd, p->session_info->security_token,
446 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
447 &acc_granted, "_lsa_OpenPolicy2" );
448 if (!NT_STATUS_IS_OK(status)) {
452 status = create_lsa_policy_handle(p->mem_ctx, p,
453 LSA_HANDLE_POLICY_TYPE,
455 get_global_sam_sid(),
459 if (!NT_STATUS_IS_OK(status)) {
460 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
466 /***************************************************************************
468 ***************************************************************************/
470 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
471 struct lsa_OpenPolicy *r)
473 struct lsa_OpenPolicy2 o;
475 o.in.system_name = NULL; /* should be ignored */
476 o.in.attr = r->in.attr;
477 o.in.access_mask = r->in.access_mask;
479 o.out.handle = r->out.handle;
481 return _lsa_OpenPolicy2(p, &o);
484 /***************************************************************************
485 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
487 ***************************************************************************/
489 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
490 struct lsa_EnumTrustDom *r)
492 struct lsa_info *info;
494 struct trustdom_info **domains;
495 struct lsa_DomainInfo *entries;
499 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
500 return NT_STATUS_INVALID_HANDLE;
502 if (info->type != LSA_HANDLE_POLICY_TYPE) {
503 return NT_STATUS_INVALID_HANDLE;
506 /* check if the user has enough rights */
507 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
508 return NT_STATUS_ACCESS_DENIED;
511 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
514 if (!NT_STATUS_IS_OK(nt_status)) {
518 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo, count);
520 return NT_STATUS_NO_MEMORY;
523 for (i=0; i<count; i++) {
524 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
525 entries[i].sid = &domains[i]->sid;
528 if (*r->in.resume_handle >= count) {
529 *r->out.resume_handle = -1;
530 TALLOC_FREE(entries);
531 return NT_STATUS_NO_MORE_ENTRIES;
534 /* return the rest, limit by max_size. Note that we
535 use the w2k3 element size value of 60 */
536 r->out.domains->count = count - *r->in.resume_handle;
537 r->out.domains->count = MIN(r->out.domains->count,
538 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
540 r->out.domains->domains = entries + *r->in.resume_handle;
542 if (r->out.domains->count < count - *r->in.resume_handle) {
543 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
544 return STATUS_MORE_ENTRIES;
547 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
548 * always be larger than the previous input resume handle, in
549 * particular when hitting the last query it is vital to set the
550 * resume handle correctly to avoid infinite client loops, as
551 * seen e.g. with Windows XP SP3 when resume handle is 0 and
552 * status is NT_STATUS_OK - gd */
554 *r->out.resume_handle = (uint32_t)-1;
559 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
560 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
561 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
563 /***************************************************************************
565 ***************************************************************************/
567 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
568 struct lsa_QueryInfoPolicy *r)
570 NTSTATUS status = NT_STATUS_OK;
571 struct lsa_info *handle;
572 struct dom_sid domain_sid;
574 struct dom_sid *sid = NULL;
575 union lsa_PolicyInformation *info = NULL;
576 uint32_t acc_required = 0;
578 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
579 return NT_STATUS_INVALID_HANDLE;
581 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
582 return NT_STATUS_INVALID_HANDLE;
585 switch (r->in.level) {
586 case LSA_POLICY_INFO_AUDIT_LOG:
587 case LSA_POLICY_INFO_AUDIT_EVENTS:
588 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
590 case LSA_POLICY_INFO_DOMAIN:
591 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
593 case LSA_POLICY_INFO_PD:
594 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
596 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
597 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
599 case LSA_POLICY_INFO_ROLE:
600 case LSA_POLICY_INFO_REPLICA:
601 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
603 case LSA_POLICY_INFO_QUOTA:
604 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
606 case LSA_POLICY_INFO_MOD:
607 case LSA_POLICY_INFO_AUDIT_FULL_SET:
608 /* according to MS-LSAD 3.1.4.4.3 */
609 return NT_STATUS_INVALID_PARAMETER;
610 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
611 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
613 case LSA_POLICY_INFO_DNS:
614 case LSA_POLICY_INFO_DNS_INT:
615 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
616 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
622 if (!(handle->access & acc_required)) {
623 /* return NT_STATUS_ACCESS_DENIED; */
626 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
628 return NT_STATUS_NO_MEMORY;
631 switch (r->in.level) {
632 /* according to MS-LSAD 3.1.4.4.3 */
633 case LSA_POLICY_INFO_MOD:
634 case LSA_POLICY_INFO_AUDIT_FULL_SET:
635 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
636 return NT_STATUS_INVALID_PARAMETER;
637 case LSA_POLICY_INFO_AUDIT_LOG:
638 info->audit_log.percent_full = 0;
639 info->audit_log.maximum_log_size = 0;
640 info->audit_log.retention_time = 0;
641 info->audit_log.shutdown_in_progress = 0;
642 info->audit_log.time_to_shutdown = 0;
643 info->audit_log.next_audit_record = 0;
644 status = NT_STATUS_OK;
646 case LSA_POLICY_INFO_PD:
647 info->pd.name.string = NULL;
648 status = NT_STATUS_OK;
650 case LSA_POLICY_INFO_REPLICA:
651 info->replica.source.string = NULL;
652 info->replica.account.string = NULL;
653 status = NT_STATUS_OK;
655 case LSA_POLICY_INFO_QUOTA:
656 info->quota.paged_pool = 0;
657 info->quota.non_paged_pool = 0;
658 info->quota.min_wss = 0;
659 info->quota.max_wss = 0;
660 info->quota.pagefile = 0;
661 info->quota.unknown = 0;
662 status = NT_STATUS_OK;
664 case LSA_POLICY_INFO_AUDIT_EVENTS:
667 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
669 /* check if the user has enough rights */
670 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
671 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
672 return NT_STATUS_ACCESS_DENIED;
675 /* fake info: We audit everything. ;) */
677 info->audit_events.auditing_mode = true;
678 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
679 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
680 enum lsa_PolicyAuditPolicy,
681 info->audit_events.count);
682 if (!info->audit_events.settings) {
683 return NT_STATUS_NO_MEMORY;
686 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
687 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
688 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
689 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
690 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
691 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
692 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
696 case LSA_POLICY_INFO_DOMAIN:
697 /* check if the user has enough rights */
698 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
699 return NT_STATUS_ACCESS_DENIED;
701 /* Request PolicyPrimaryDomainInformation. */
702 switch (lp_server_role()) {
703 case ROLE_DOMAIN_PDC:
704 case ROLE_DOMAIN_BDC:
705 name = get_global_sam_name();
706 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
708 return NT_STATUS_NO_MEMORY;
711 case ROLE_DOMAIN_MEMBER:
712 name = lp_workgroup();
713 /* We need to return the Domain SID here. */
714 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
715 sid = dom_sid_dup(p->mem_ctx, &domain_sid);
717 return NT_STATUS_NO_MEMORY;
720 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
723 case ROLE_STANDALONE:
724 name = lp_workgroup();
728 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
730 init_dom_query_3(&info->domain, name, sid);
732 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
733 /* check if the user has enough rights */
734 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
735 return NT_STATUS_ACCESS_DENIED;
737 /* Request PolicyAccountDomainInformation. */
738 name = get_global_sam_name();
739 sid = get_global_sam_sid();
741 init_dom_query_5(&info->account_domain, name, sid);
743 case LSA_POLICY_INFO_ROLE:
744 /* check if the user has enough rights */
745 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
746 return NT_STATUS_ACCESS_DENIED;
748 switch (lp_server_role()) {
749 case ROLE_DOMAIN_BDC:
751 * only a BDC is a backup controller
752 * of the domain, it controls.
754 info->role.role = LSA_ROLE_BACKUP;
758 * any other role is a primary
759 * of the domain, it controls.
761 info->role.role = LSA_ROLE_PRIMARY;
765 case LSA_POLICY_INFO_DNS:
766 case LSA_POLICY_INFO_DNS_INT: {
767 struct pdb_domain_info *dominfo;
769 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
770 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
771 "without ADS passdb backend\n"));
772 status = NT_STATUS_INVALID_INFO_CLASS;
776 dominfo = pdb_get_domain_info(info);
777 if (dominfo == NULL) {
778 status = NT_STATUS_NO_MEMORY;
782 init_lsa_StringLarge(&info->dns.name,
784 init_lsa_StringLarge(&info->dns.dns_domain,
785 dominfo->dns_domain);
786 init_lsa_StringLarge(&info->dns.dns_forest,
787 dominfo->dns_forest);
788 info->dns.domain_guid = dominfo->guid;
789 info->dns.sid = &dominfo->sid;
793 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
795 status = NT_STATUS_INVALID_INFO_CLASS;
804 /***************************************************************************
805 _lsa_QueryInfoPolicy2
806 ***************************************************************************/
808 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
809 struct lsa_QueryInfoPolicy2 *r2)
811 struct lsa_QueryInfoPolicy r;
813 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
814 p->rng_fault_state = True;
815 return NT_STATUS_NOT_IMPLEMENTED;
819 r.in.handle = r2->in.handle;
820 r.in.level = r2->in.level;
821 r.out.info = r2->out.info;
823 return _lsa_QueryInfoPolicy(p, &r);
826 /***************************************************************************
827 _lsa_lookup_sids_internal
828 ***************************************************************************/
830 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
832 uint16_t level, /* input */
833 int num_sids, /* input */
834 struct lsa_SidPtr *sid, /* input */
835 struct lsa_RefDomainList **pp_ref, /* input/output */
836 struct lsa_TranslatedName2 **pp_names,/* input/output */
837 uint32_t *pp_mapped_count) /* input/output */
841 const struct dom_sid **sids = NULL;
842 struct lsa_RefDomainList *ref = NULL;
843 uint32 mapped_count = 0;
844 struct lsa_dom_info *dom_infos = NULL;
845 struct lsa_name_info *name_infos = NULL;
846 struct lsa_TranslatedName2 *names = NULL;
848 *pp_mapped_count = 0;
856 sids = TALLOC_ARRAY(p->mem_ctx, const struct dom_sid *, num_sids);
857 ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
859 if (sids == NULL || ref == NULL) {
860 return NT_STATUS_NO_MEMORY;
863 for (i=0; i<num_sids; i++) {
864 sids[i] = sid[i].sid;
867 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
868 &dom_infos, &name_infos);
870 if (!NT_STATUS_IS_OK(status)) {
874 names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
876 return NT_STATUS_NO_MEMORY;
879 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
881 if (!dom_infos[i].valid) {
885 if (init_lsa_ref_domain_list(mem_ctx, ref,
887 &dom_infos[i].sid) != i) {
888 DEBUG(0, ("Domain %s mentioned twice??\n",
890 return NT_STATUS_INTERNAL_ERROR;
894 for (i=0; i<num_sids; i++) {
895 struct lsa_name_info *name = &name_infos[i];
897 if (name->type == SID_NAME_UNKNOWN) {
899 /* Unknown sids should return the string
900 * representation of the SID. Windows 2003 behaves
901 * rather erratic here, in many cases it returns the
902 * RID as 8 bytes hex, in others it returns the full
903 * SID. We (Jerry/VL) could not figure out which the
904 * hard cases are, so leave it with the SID. */
905 name->name = dom_sid_string(p->mem_ctx, sids[i]);
906 if (name->name == NULL) {
907 return NT_STATUS_NO_MEMORY;
913 names[i].sid_type = name->type;
914 names[i].name.string = name->name;
915 names[i].sid_index = name->dom_idx;
916 names[i].unknown = 0;
919 status = NT_STATUS_NONE_MAPPED;
920 if (mapped_count > 0) {
921 status = (mapped_count < num_sids) ?
922 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
925 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
926 num_sids, mapped_count, nt_errstr(status)));
928 *pp_mapped_count = mapped_count;
935 /***************************************************************************
937 ***************************************************************************/
939 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
940 struct lsa_LookupSids *r)
943 struct lsa_info *handle;
944 int num_sids = r->in.sids->num_sids;
945 uint32 mapped_count = 0;
946 struct lsa_RefDomainList *domains = NULL;
947 struct lsa_TranslatedName *names_out = NULL;
948 struct lsa_TranslatedName2 *names = NULL;
951 if ((r->in.level < 1) || (r->in.level > 6)) {
952 return NT_STATUS_INVALID_PARAMETER;
955 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
956 return NT_STATUS_INVALID_HANDLE;
959 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
960 return NT_STATUS_INVALID_HANDLE;
963 /* check if the user has enough rights */
964 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
965 return NT_STATUS_ACCESS_DENIED;
968 if (num_sids > MAX_LOOKUP_SIDS) {
969 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
970 MAX_LOOKUP_SIDS, num_sids));
971 return NT_STATUS_NONE_MAPPED;
974 status = _lsa_lookup_sids_internal(p,
983 /* Only return here when there is a real error.
984 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
985 the requested sids could be resolved. Older versions of XP (pre SP3)
986 rely that we return with the string representations of those SIDs in
987 that case. If we don't, XP crashes - Guenther
990 if (NT_STATUS_IS_ERR(status) &&
991 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
995 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
996 names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
999 return NT_STATUS_NO_MEMORY;
1002 for (i=0; i<num_sids; i++) {
1003 names_out[i].sid_type = names[i].sid_type;
1004 names_out[i].name = names[i].name;
1005 names_out[i].sid_index = names[i].sid_index;
1008 *r->out.domains = domains;
1009 r->out.names->count = num_sids;
1010 r->out.names->names = names_out;
1011 *r->out.count = mapped_count;
1016 /***************************************************************************
1018 ***************************************************************************/
1020 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1021 struct lsa_LookupSids2 *r)
1024 struct lsa_info *handle;
1025 int num_sids = r->in.sids->num_sids;
1026 uint32 mapped_count = 0;
1027 struct lsa_RefDomainList *domains = NULL;
1028 struct lsa_TranslatedName2 *names = NULL;
1029 bool check_policy = true;
1032 case NDR_LSA_LOOKUPSIDS3:
1033 check_policy = false;
1035 case NDR_LSA_LOOKUPSIDS2:
1037 check_policy = true;
1040 if ((r->in.level < 1) || (r->in.level > 6)) {
1041 return NT_STATUS_INVALID_PARAMETER;
1045 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1046 return NT_STATUS_INVALID_HANDLE;
1049 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1050 return NT_STATUS_INVALID_HANDLE;
1053 /* check if the user has enough rights */
1054 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1055 return NT_STATUS_ACCESS_DENIED;
1059 if (num_sids > MAX_LOOKUP_SIDS) {
1060 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1061 MAX_LOOKUP_SIDS, num_sids));
1062 return NT_STATUS_NONE_MAPPED;
1065 status = _lsa_lookup_sids_internal(p,
1074 *r->out.domains = domains;
1075 r->out.names->count = num_sids;
1076 r->out.names->names = names;
1077 *r->out.count = mapped_count;
1082 /***************************************************************************
1084 ***************************************************************************/
1086 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1087 struct lsa_LookupSids3 *r)
1089 struct lsa_LookupSids2 q;
1091 /* No policy handle on this call. Restrict to crypto connections. */
1092 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1093 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1094 get_remote_machine_name() ));
1095 return NT_STATUS_INVALID_PARAMETER;
1099 q.in.sids = r->in.sids;
1100 q.in.level = r->in.level;
1101 q.in.lookup_options = r->in.lookup_options;
1102 q.in.client_revision = r->in.client_revision;
1103 q.in.names = r->in.names;
1104 q.in.count = r->in.count;
1106 q.out.domains = r->out.domains;
1107 q.out.names = r->out.names;
1108 q.out.count = r->out.count;
1110 return _lsa_LookupSids2(p, &q);
1113 /***************************************************************************
1114 ***************************************************************************/
1116 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1121 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1122 flags = LOOKUP_NAME_ALL;
1124 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1125 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1127 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1128 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1130 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1131 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1132 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1133 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1135 flags = LOOKUP_NAME_NONE;
1142 /***************************************************************************
1144 ***************************************************************************/
1146 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1147 struct lsa_LookupNames *r)
1149 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1150 struct lsa_info *handle;
1151 struct lsa_String *names = r->in.names;
1152 uint32 num_entries = r->in.num_names;
1153 struct lsa_RefDomainList *domains = NULL;
1154 struct lsa_TranslatedSid *rids = NULL;
1155 uint32 mapped_count = 0;
1158 if (num_entries > MAX_LOOKUP_SIDS) {
1159 num_entries = MAX_LOOKUP_SIDS;
1160 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1164 flags = lsa_lookup_level_to_flags(r->in.level);
1166 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1168 return NT_STATUS_NO_MEMORY;
1172 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1175 return NT_STATUS_NO_MEMORY;
1181 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1182 status = NT_STATUS_INVALID_HANDLE;
1186 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1187 return NT_STATUS_INVALID_HANDLE;
1190 /* check if the user has enough rights */
1191 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1192 status = NT_STATUS_ACCESS_DENIED;
1196 /* set up the LSA Lookup RIDs response */
1197 become_root(); /* lookup_name can require root privs */
1198 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1199 names, flags, &mapped_count);
1204 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1205 if (mapped_count == 0) {
1206 status = NT_STATUS_NONE_MAPPED;
1207 } else if (mapped_count != num_entries) {
1208 status = STATUS_SOME_UNMAPPED;
1212 *r->out.count = mapped_count;
1213 *r->out.domains = domains;
1214 r->out.sids->sids = rids;
1215 r->out.sids->count = num_entries;
1220 /***************************************************************************
1222 ***************************************************************************/
1224 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1225 struct lsa_LookupNames2 *r)
1228 struct lsa_LookupNames q;
1229 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1230 struct lsa_TransSidArray *sid_array = NULL;
1233 sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1235 return NT_STATUS_NO_MEMORY;
1238 q.in.handle = r->in.handle;
1239 q.in.num_names = r->in.num_names;
1240 q.in.names = r->in.names;
1241 q.in.level = r->in.level;
1242 q.in.sids = sid_array;
1243 q.in.count = r->in.count;
1244 /* we do not know what this is for */
1245 /* = r->in.unknown1; */
1246 /* = r->in.unknown2; */
1248 q.out.domains = r->out.domains;
1249 q.out.sids = sid_array;
1250 q.out.count = r->out.count;
1252 status = _lsa_LookupNames(p, &q);
1254 sid_array2->count = sid_array->count;
1255 sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1256 if (!sid_array2->sids) {
1257 return NT_STATUS_NO_MEMORY;
1260 for (i=0; i<sid_array->count; i++) {
1261 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1262 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1263 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1264 sid_array2->sids[i].unknown = 0;
1267 r->out.sids = sid_array2;
1272 /***************************************************************************
1274 ***************************************************************************/
1276 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1277 struct lsa_LookupNames3 *r)
1280 struct lsa_info *handle;
1281 struct lsa_String *names = r->in.names;
1282 uint32 num_entries = r->in.num_names;
1283 struct lsa_RefDomainList *domains = NULL;
1284 struct lsa_TranslatedSid3 *trans_sids = NULL;
1285 uint32 mapped_count = 0;
1287 bool check_policy = true;
1290 case NDR_LSA_LOOKUPNAMES4:
1291 check_policy = false;
1293 case NDR_LSA_LOOKUPNAMES3:
1295 check_policy = true;
1298 if (num_entries > MAX_LOOKUP_SIDS) {
1299 num_entries = MAX_LOOKUP_SIDS;
1300 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1303 /* Probably the lookup_level is some sort of bitmask. */
1304 if (r->in.level == 1) {
1305 flags = LOOKUP_NAME_ALL;
1308 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1310 return NT_STATUS_NO_MEMORY;
1314 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1317 return NT_STATUS_NO_MEMORY;
1325 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1326 status = NT_STATUS_INVALID_HANDLE;
1330 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1331 return NT_STATUS_INVALID_HANDLE;
1334 /* check if the user has enough rights */
1335 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1336 status = NT_STATUS_ACCESS_DENIED;
1341 /* set up the LSA Lookup SIDs response */
1342 become_root(); /* lookup_name can require root privs */
1343 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1344 names, flags, &mapped_count);
1349 if (NT_STATUS_IS_OK(status)) {
1350 if (mapped_count == 0) {
1351 status = NT_STATUS_NONE_MAPPED;
1352 } else if (mapped_count != num_entries) {
1353 status = STATUS_SOME_UNMAPPED;
1357 *r->out.count = mapped_count;
1358 *r->out.domains = domains;
1359 r->out.sids->sids = trans_sids;
1360 r->out.sids->count = num_entries;
1365 /***************************************************************************
1367 ***************************************************************************/
1369 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1370 struct lsa_LookupNames4 *r)
1372 struct lsa_LookupNames3 q;
1374 /* No policy handle on this call. Restrict to crypto connections. */
1375 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1376 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1377 get_remote_machine_name() ));
1378 return NT_STATUS_INVALID_PARAMETER;
1382 q.in.num_names = r->in.num_names;
1383 q.in.names = r->in.names;
1384 q.in.level = r->in.level;
1385 q.in.lookup_options = r->in.lookup_options;
1386 q.in.client_revision = r->in.client_revision;
1387 q.in.sids = r->in.sids;
1388 q.in.count = r->in.count;
1390 q.out.domains = r->out.domains;
1391 q.out.sids = r->out.sids;
1392 q.out.count = r->out.count;
1394 return _lsa_LookupNames3(p, &q);
1397 /***************************************************************************
1398 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1399 ***************************************************************************/
1401 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1403 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1404 return NT_STATUS_INVALID_HANDLE;
1407 close_policy_hnd(p, r->in.handle);
1408 ZERO_STRUCTP(r->out.handle);
1409 return NT_STATUS_OK;
1412 /***************************************************************************
1413 ***************************************************************************/
1415 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1416 const struct dom_sid *sid,
1417 struct trustdom_info **info)
1420 uint32_t num_domains = 0;
1421 struct trustdom_info **domains = NULL;
1424 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1425 if (!NT_STATUS_IS_OK(status)) {
1429 for (i=0; i < num_domains; i++) {
1430 if (dom_sid_equal(&domains[i]->sid, sid)) {
1435 if (i == num_domains) {
1436 return NT_STATUS_INVALID_PARAMETER;
1441 return NT_STATUS_OK;
1444 /***************************************************************************
1445 ***************************************************************************/
1447 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1448 const char *netbios_domain_name,
1449 struct trustdom_info **info_p)
1452 struct trustdom_info *info;
1453 struct pdb_trusted_domain *td;
1455 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1456 if (!NT_STATUS_IS_OK(status)) {
1460 info = talloc(mem_ctx, struct trustdom_info);
1462 return NT_STATUS_NO_MEMORY;
1465 info->name = talloc_strdup(info, netbios_domain_name);
1466 NT_STATUS_HAVE_NO_MEMORY(info->name);
1468 sid_copy(&info->sid, &td->security_identifier);
1472 return NT_STATUS_OK;
1475 /***************************************************************************
1476 ***************************************************************************/
1478 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p, struct lsa_OpenSecret *r)
1480 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1483 /***************************************************************************
1484 _lsa_OpenTrustedDomain_base
1485 ***************************************************************************/
1487 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1488 uint32_t access_mask,
1489 struct trustdom_info *info,
1490 struct policy_handle *handle)
1492 struct security_descriptor *psd = NULL;
1494 uint32_t acc_granted;
1497 /* des_access is for the account here, not the policy
1498 * handle - so don't check against policy handle. */
1500 /* Work out max allowed. */
1501 map_max_allowed_access(p->session_info->security_token,
1502 &p->session_info->utok,
1505 /* map the generic bits to the lsa account ones */
1506 se_map_generic(&access_mask, &lsa_account_mapping);
1508 /* get the generic lsa account SD until we store it */
1509 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1510 &lsa_trusted_domain_mapping,
1512 if (!NT_STATUS_IS_OK(status)) {
1516 status = access_check_object(psd, p->session_info->security_token,
1517 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1518 access_mask, &acc_granted,
1519 "_lsa_OpenTrustedDomain");
1520 if (!NT_STATUS_IS_OK(status)) {
1524 status = create_lsa_policy_handle(p->mem_ctx, p,
1525 LSA_HANDLE_TRUST_TYPE,
1531 if (!NT_STATUS_IS_OK(status)) {
1532 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1535 return NT_STATUS_OK;
1538 /***************************************************************************
1539 _lsa_OpenTrustedDomain
1540 ***************************************************************************/
1542 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1543 struct lsa_OpenTrustedDomain *r)
1545 struct lsa_info *handle = NULL;
1546 struct trustdom_info *info = NULL;
1549 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1550 return NT_STATUS_INVALID_HANDLE;
1553 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1554 return NT_STATUS_INVALID_HANDLE;
1557 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1560 if (!NT_STATUS_IS_OK(status)) {
1564 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1565 r->out.trustdom_handle);
1568 /***************************************************************************
1569 _lsa_OpenTrustedDomainByName
1570 ***************************************************************************/
1572 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1573 struct lsa_OpenTrustedDomainByName *r)
1575 struct lsa_info *handle = NULL;
1576 struct trustdom_info *info = NULL;
1579 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1580 return NT_STATUS_INVALID_HANDLE;
1583 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1584 return NT_STATUS_INVALID_HANDLE;
1587 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1590 if (!NT_STATUS_IS_OK(status)) {
1594 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1595 r->out.trustdom_handle);
1598 static NTSTATUS add_trusted_domain_user(TALLOC_CTX *mem_ctx,
1599 const char *netbios_name,
1600 const char *domain_name,
1601 const struct trustDomainPasswords *auth_struct)
1604 struct samu *sam_acct;
1607 struct dom_sid user_sid;
1612 sam_acct = samu_new(mem_ctx);
1613 if (sam_acct == NULL) {
1614 return NT_STATUS_NO_MEMORY;
1617 acct_name = talloc_asprintf(mem_ctx, "%s$", netbios_name);
1618 if (acct_name == NULL) {
1619 return NT_STATUS_NO_MEMORY;
1621 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1622 return NT_STATUS_UNSUCCESSFUL;
1625 if (!pdb_set_domain(sam_acct, domain_name, PDB_SET)) {
1626 return NT_STATUS_UNSUCCESSFUL;
1629 if (!pdb_set_acct_ctrl(sam_acct, ACB_DOMTRUST, PDB_SET)) {
1630 return NT_STATUS_UNSUCCESSFUL;
1633 if (!pdb_new_rid(&rid)) {
1634 return NT_STATUS_DS_NO_MORE_RIDS;
1636 sid_compose(&user_sid, get_global_sam_sid(), rid);
1637 if (!pdb_set_user_sid(sam_acct, &user_sid, PDB_SET)) {
1638 return NT_STATUS_UNSUCCESSFUL;
1641 for (i = 0; i < auth_struct->incoming.count; i++) {
1642 switch (auth_struct->incoming.current.array[i].AuthType) {
1643 case TRUST_AUTH_TYPE_CLEAR:
1644 if (!convert_string_talloc(mem_ctx,
1647 auth_struct->incoming.current.array[i].AuthInfo.clear.password,
1648 auth_struct->incoming.current.array[i].AuthInfo.clear.size,
1652 return NT_STATUS_UNSUCCESSFUL;
1654 if (!pdb_set_plaintext_passwd(sam_acct, dummy)) {
1655 return NT_STATUS_UNSUCCESSFUL;
1663 status = pdb_add_sam_account(sam_acct);
1664 if (!NT_STATUS_IS_OK(status)) {
1668 return NT_STATUS_OK;
1671 /***************************************************************************
1672 _lsa_CreateTrustedDomainEx2
1673 ***************************************************************************/
1675 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1676 struct lsa_CreateTrustedDomainEx2 *r)
1678 struct lsa_info *policy;
1680 uint32_t acc_granted;
1681 struct security_descriptor *psd;
1683 struct pdb_trusted_domain td;
1684 struct trustDomainPasswords auth_struct;
1685 enum ndr_err_code ndr_err;
1686 DATA_BLOB auth_blob;
1689 return NT_STATUS_NOT_SUPPORTED;
1692 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1693 return NT_STATUS_INVALID_HANDLE;
1696 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1697 return NT_STATUS_ACCESS_DENIED;
1700 if (p->session_info->utok.uid != sec_initial_uid() &&
1701 !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1702 return NT_STATUS_ACCESS_DENIED;
1705 /* Work out max allowed. */
1706 map_max_allowed_access(p->session_info->security_token,
1707 &p->session_info->utok,
1708 &r->in.access_mask);
1710 /* map the generic bits to the lsa policy ones */
1711 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1713 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1714 &lsa_trusted_domain_mapping,
1716 if (!NT_STATUS_IS_OK(status)) {
1720 status = access_check_object(psd, p->session_info->security_token,
1721 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1722 r->in.access_mask, &acc_granted,
1723 "_lsa_CreateTrustedDomainEx2");
1724 if (!NT_STATUS_IS_OK(status)) {
1730 td.domain_name = talloc_strdup(p->mem_ctx,
1731 r->in.info->domain_name.string);
1732 if (td.domain_name == NULL) {
1733 return NT_STATUS_NO_MEMORY;
1735 td.netbios_name = talloc_strdup(p->mem_ctx,
1736 r->in.info->netbios_name.string);
1737 if (td.netbios_name == NULL) {
1738 return NT_STATUS_NO_MEMORY;
1740 sid_copy(&td.security_identifier, r->in.info->sid);
1741 td.trust_direction = r->in.info->trust_direction;
1742 td.trust_type = r->in.info->trust_type;
1743 td.trust_attributes = r->in.info->trust_attributes;
1745 if (r->in.auth_info->auth_blob.size != 0) {
1746 auth_blob.length = r->in.auth_info->auth_blob.size;
1747 auth_blob.data = r->in.auth_info->auth_blob.data;
1749 arcfour_crypt_blob(auth_blob.data, auth_blob.length,
1750 &p->session_info->user_session_key);
1752 ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
1754 (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
1755 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1756 return NT_STATUS_UNSUCCESSFUL;
1759 ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
1760 &auth_struct.incoming,
1761 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1762 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1763 return NT_STATUS_UNSUCCESSFUL;
1766 ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
1767 &auth_struct.outgoing,
1768 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1769 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1770 return NT_STATUS_UNSUCCESSFUL;
1773 td.trust_auth_incoming.data = NULL;
1774 td.trust_auth_incoming.length = 0;
1775 td.trust_auth_outgoing.data = NULL;
1776 td.trust_auth_outgoing.length = 0;
1779 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1780 if (!NT_STATUS_IS_OK(status)) {
1784 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1785 status = add_trusted_domain_user(p->mem_ctx,
1786 r->in.info->netbios_name.string,
1787 r->in.info->domain_name.string,
1789 if (!NT_STATUS_IS_OK(status)) {
1794 status = create_lsa_policy_handle(p->mem_ctx, p,
1795 LSA_HANDLE_TRUST_TYPE,
1798 r->in.info->netbios_name.string,
1800 r->out.trustdom_handle);
1801 if (!NT_STATUS_IS_OK(status)) {
1802 pdb_del_trusteddom_pw(r->in.info->netbios_name.string);
1803 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1806 return NT_STATUS_OK;
1809 /***************************************************************************
1810 _lsa_CreateTrustedDomainEx
1811 ***************************************************************************/
1813 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1814 struct lsa_CreateTrustedDomainEx *r)
1816 struct lsa_CreateTrustedDomainEx2 q;
1818 q.in.policy_handle = r->in.policy_handle;
1819 q.in.info = r->in.info;
1820 q.in.auth_info = r->in.auth_info;
1821 q.in.access_mask = r->in.access_mask;
1822 q.out.trustdom_handle = r->out.trustdom_handle;
1824 return _lsa_CreateTrustedDomainEx2(p, &q);
1827 /***************************************************************************
1828 _lsa_CreateTrustedDomain
1829 ***************************************************************************/
1831 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1832 struct lsa_CreateTrustedDomain *r)
1834 struct lsa_CreateTrustedDomainEx2 c;
1835 struct lsa_TrustDomainInfoInfoEx info;
1836 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1838 ZERO_STRUCT(auth_info);
1840 info.domain_name = r->in.info->name;
1841 info.netbios_name = r->in.info->name;
1842 info.sid = r->in.info->sid;
1843 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1844 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1845 info.trust_attributes = 0;
1847 c.in.policy_handle = r->in.policy_handle;
1849 c.in.auth_info = &auth_info;
1850 c.in.access_mask = r->in.access_mask;
1851 c.out.trustdom_handle = r->out.trustdom_handle;
1853 return _lsa_CreateTrustedDomainEx2(p, &c);
1856 /***************************************************************************
1857 _lsa_DeleteTrustedDomain
1858 ***************************************************************************/
1860 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1861 struct lsa_DeleteTrustedDomain *r)
1864 struct lsa_info *handle;
1865 struct pdb_trusted_domain *td;
1866 struct samu *sam_acct;
1869 /* find the connection policy handle. */
1870 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1871 return NT_STATUS_INVALID_HANDLE;
1874 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1875 return NT_STATUS_INVALID_HANDLE;
1878 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1879 return NT_STATUS_ACCESS_DENIED;
1882 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1883 if (!NT_STATUS_IS_OK(status)) {
1887 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1888 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1889 sid_string_tos(r->in.dom_sid)));
1890 return NT_STATUS_UNSUCCESSFUL;
1893 if (td->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1894 sam_acct = samu_new(p->mem_ctx);
1895 if (sam_acct == NULL) {
1896 return NT_STATUS_NO_MEMORY;
1899 acct_name = talloc_asprintf(p->mem_ctx, "%s$", td->netbios_name);
1900 if (acct_name == NULL) {
1901 return NT_STATUS_NO_MEMORY;
1903 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1904 return NT_STATUS_UNSUCCESSFUL;
1906 status = pdb_delete_sam_account(sam_acct);
1907 if (!NT_STATUS_IS_OK(status)) {
1912 status = pdb_del_trusted_domain(td->netbios_name);
1913 if (!NT_STATUS_IS_OK(status)) {
1917 return NT_STATUS_OK;
1920 /***************************************************************************
1921 _lsa_CloseTrustedDomainEx
1922 ***************************************************************************/
1924 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1925 struct lsa_CloseTrustedDomainEx *r)
1927 return NT_STATUS_NOT_IMPLEMENTED;
1930 /***************************************************************************
1931 _lsa_QueryTrustedDomainInfo
1932 ***************************************************************************/
1934 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
1935 struct lsa_QueryTrustedDomainInfo *r)
1938 struct lsa_info *handle;
1939 union lsa_TrustedDomainInfo *info;
1940 struct pdb_trusted_domain *td;
1941 uint32_t acc_required;
1943 /* find the connection policy handle. */
1944 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
1945 return NT_STATUS_INVALID_HANDLE;
1948 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
1949 return NT_STATUS_INVALID_HANDLE;
1952 switch (r->in.level) {
1953 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1954 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1956 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1957 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
1959 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1960 acc_required = LSA_TRUSTED_QUERY_POSIX;
1962 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
1963 acc_required = LSA_TRUSTED_QUERY_AUTH;
1965 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1966 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1968 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1969 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1971 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1972 acc_required = LSA_TRUSTED_QUERY_AUTH;
1974 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1975 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1976 LSA_TRUSTED_QUERY_POSIX |
1977 LSA_TRUSTED_QUERY_AUTH;
1979 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1980 acc_required = LSA_TRUSTED_QUERY_AUTH;
1982 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1983 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1984 LSA_TRUSTED_QUERY_POSIX |
1985 LSA_TRUSTED_QUERY_AUTH;
1987 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1988 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1990 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1991 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1992 LSA_TRUSTED_QUERY_POSIX |
1993 LSA_TRUSTED_QUERY_AUTH;
1995 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1996 acc_required = LSA_TRUSTED_QUERY_POSIX;
1999 return NT_STATUS_INVALID_PARAMETER;
2002 if (!(handle->access & acc_required)) {
2003 return NT_STATUS_ACCESS_DENIED;
2006 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2007 if (!NT_STATUS_IS_OK(status)) {
2011 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_TrustedDomainInfo);
2013 return NT_STATUS_NO_MEMORY;
2016 switch (r->in.level) {
2017 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2018 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2020 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2021 return NT_STATUS_INVALID_PARAMETER;
2022 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2024 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2025 return NT_STATUS_INVALID_INFO_CLASS;
2026 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2027 return NT_STATUS_INVALID_PARAMETER;
2028 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2029 init_lsa_StringLarge(&info->info_ex.domain_name, td->domain_name);
2030 init_lsa_StringLarge(&info->info_ex.netbios_name, td->netbios_name);
2031 info->info_ex.sid = dom_sid_dup(info, &td->security_identifier);
2032 if (!info->info_ex.sid) {
2033 return NT_STATUS_NO_MEMORY;
2035 info->info_ex.trust_direction = td->trust_direction;
2036 info->info_ex.trust_type = td->trust_type;
2037 info->info_ex.trust_attributes = td->trust_attributes;
2039 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2040 return NT_STATUS_INVALID_INFO_CLASS;
2041 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2043 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2044 return NT_STATUS_INVALID_INFO_CLASS;
2045 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2046 return NT_STATUS_INVALID_INFO_CLASS;
2047 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2048 return NT_STATUS_INVALID_PARAMETER;
2049 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2051 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2054 return NT_STATUS_INVALID_PARAMETER;
2057 *r->out.info = info;
2059 return NT_STATUS_OK;
2062 /***************************************************************************
2063 _lsa_QueryTrustedDomainInfoBySid
2064 ***************************************************************************/
2066 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2067 struct lsa_QueryTrustedDomainInfoBySid *r)
2070 struct policy_handle trustdom_handle;
2071 struct lsa_OpenTrustedDomain o;
2072 struct lsa_QueryTrustedDomainInfo q;
2075 o.in.handle = r->in.handle;
2076 o.in.sid = r->in.dom_sid;
2077 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2078 o.out.trustdom_handle = &trustdom_handle;
2080 status = _lsa_OpenTrustedDomain(p, &o);
2081 if (!NT_STATUS_IS_OK(status)) {
2085 q.in.trustdom_handle = &trustdom_handle;
2086 q.in.level = r->in.level;
2087 q.out.info = r->out.info;
2089 status = _lsa_QueryTrustedDomainInfo(p, &q);
2090 if (!NT_STATUS_IS_OK(status)) {
2094 c.in.handle = &trustdom_handle;
2095 c.out.handle = &trustdom_handle;
2097 return _lsa_Close(p, &c);
2100 /***************************************************************************
2101 _lsa_QueryTrustedDomainInfoByName
2102 ***************************************************************************/
2104 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2105 struct lsa_QueryTrustedDomainInfoByName *r)
2108 struct policy_handle trustdom_handle;
2109 struct lsa_OpenTrustedDomainByName o;
2110 struct lsa_QueryTrustedDomainInfo q;
2113 o.in.handle = r->in.handle;
2114 o.in.name.string = r->in.trusted_domain->string;
2115 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2116 o.out.trustdom_handle = &trustdom_handle;
2118 status = _lsa_OpenTrustedDomainByName(p, &o);
2119 if (!NT_STATUS_IS_OK(status)) {
2120 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2121 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2126 q.in.trustdom_handle = &trustdom_handle;
2127 q.in.level = r->in.level;
2128 q.out.info = r->out.info;
2130 status = _lsa_QueryTrustedDomainInfo(p, &q);
2131 if (!NT_STATUS_IS_OK(status)) {
2135 c.in.handle = &trustdom_handle;
2136 c.out.handle = &trustdom_handle;
2138 return _lsa_Close(p, &c);
2141 /***************************************************************************
2142 ***************************************************************************/
2144 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p, struct lsa_CreateSecret *r)
2146 return NT_STATUS_ACCESS_DENIED;
2149 /***************************************************************************
2150 ***************************************************************************/
2152 NTSTATUS _lsa_SetSecret(struct pipes_struct *p, struct lsa_SetSecret *r)
2154 return NT_STATUS_ACCESS_DENIED;
2157 /***************************************************************************
2159 ***************************************************************************/
2161 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2162 struct lsa_DeleteObject *r)
2165 struct lsa_info *info = NULL;
2167 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2168 return NT_STATUS_INVALID_HANDLE;
2171 if (!(info->access & SEC_STD_DELETE)) {
2172 return NT_STATUS_ACCESS_DENIED;
2175 switch (info->type) {
2176 case LSA_HANDLE_ACCOUNT_TYPE:
2177 status = privilege_delete_account(&info->sid);
2178 if (!NT_STATUS_IS_OK(status)) {
2179 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2180 nt_errstr(status)));
2185 return NT_STATUS_INVALID_HANDLE;
2188 close_policy_hnd(p, r->in.handle);
2189 ZERO_STRUCTP(r->out.handle);
2194 /***************************************************************************
2196 ***************************************************************************/
2198 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2199 struct lsa_EnumPrivs *r)
2201 struct lsa_info *handle;
2203 uint32 enum_context = *r->in.resume_handle;
2204 int num_privs = num_privileges_in_short_list();
2205 struct lsa_PrivEntry *entries = NULL;
2207 /* remember that the enum_context starts at 0 and not 1 */
2209 if ( enum_context >= num_privs )
2210 return NT_STATUS_NO_MORE_ENTRIES;
2212 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2213 enum_context, num_privs));
2215 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2216 return NT_STATUS_INVALID_HANDLE;
2218 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2219 return NT_STATUS_INVALID_HANDLE;
2222 /* check if the user has enough rights
2223 I don't know if it's the right one. not documented. */
2225 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2226 return NT_STATUS_ACCESS_DENIED;
2229 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2231 return NT_STATUS_NO_MEMORY;
2237 for (i = 0; i < num_privs; i++) {
2238 if( i < enum_context) {
2240 init_lsa_StringLarge(&entries[i].name, NULL);
2242 entries[i].luid.low = 0;
2243 entries[i].luid.high = 0;
2246 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2248 entries[i].luid.low = sec_privilege_from_index(i);
2249 entries[i].luid.high = 0;
2253 enum_context = num_privs;
2255 *r->out.resume_handle = enum_context;
2256 r->out.privs->count = num_privs;
2257 r->out.privs->privs = entries;
2259 return NT_STATUS_OK;
2262 /***************************************************************************
2263 _lsa_LookupPrivDisplayName
2264 ***************************************************************************/
2266 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2267 struct lsa_LookupPrivDisplayName *r)
2269 struct lsa_info *handle;
2270 const char *description;
2271 struct lsa_StringLarge *lsa_name;
2273 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2274 return NT_STATUS_INVALID_HANDLE;
2276 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2277 return NT_STATUS_INVALID_HANDLE;
2280 /* check if the user has enough rights */
2283 * I don't know if it's the right one. not documented.
2285 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2286 return NT_STATUS_ACCESS_DENIED;
2288 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2290 description = get_privilege_dispname(r->in.name->string);
2292 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2293 return NT_STATUS_NO_SUCH_PRIVILEGE;
2296 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2298 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2300 return NT_STATUS_NO_MEMORY;
2303 init_lsa_StringLarge(lsa_name, description);
2305 *r->out.returned_language_id = r->in.language_id;
2306 *r->out.disp_name = lsa_name;
2308 return NT_STATUS_OK;
2311 /***************************************************************************
2313 ***************************************************************************/
2315 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2316 struct lsa_EnumAccounts *r)
2318 struct lsa_info *handle;
2319 struct dom_sid *sid_list;
2320 int i, j, num_entries;
2322 struct lsa_SidPtr *sids = NULL;
2324 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2325 return NT_STATUS_INVALID_HANDLE;
2327 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2328 return NT_STATUS_INVALID_HANDLE;
2331 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2332 return NT_STATUS_ACCESS_DENIED;
2337 /* The only way we can currently find out all the SIDs that have been
2338 privileged is to scan all privileges */
2340 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2341 if (!NT_STATUS_IS_OK(status)) {
2345 if (*r->in.resume_handle >= num_entries) {
2346 return NT_STATUS_NO_MORE_ENTRIES;
2349 if (num_entries - *r->in.resume_handle) {
2350 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
2351 num_entries - *r->in.resume_handle);
2353 talloc_free(sid_list);
2354 return NT_STATUS_NO_MEMORY;
2357 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2358 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2360 talloc_free(sid_list);
2361 return NT_STATUS_NO_MEMORY;
2366 talloc_free(sid_list);
2368 *r->out.resume_handle = num_entries;
2369 r->out.sids->num_sids = num_entries;
2370 r->out.sids->sids = sids;
2372 return NT_STATUS_OK;
2375 /***************************************************************************
2377 ***************************************************************************/
2379 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2380 struct lsa_GetUserName *r)
2382 const char *username, *domname;
2383 struct lsa_String *account_name = NULL;
2384 struct lsa_String *authority_name = NULL;
2386 if (r->in.account_name &&
2387 *r->in.account_name) {
2388 return NT_STATUS_INVALID_PARAMETER;
2391 if (r->in.authority_name &&
2392 *r->in.authority_name) {
2393 return NT_STATUS_INVALID_PARAMETER;
2396 if (p->session_info->guest) {
2398 * I'm 99% sure this is not the right place to do this,
2399 * global_sid_Anonymous should probably be put into the token
2400 * instead of the guest id -- vl
2402 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2403 &domname, &username, NULL)) {
2404 return NT_STATUS_NO_MEMORY;
2407 username = p->session_info->sanitized_username;
2408 domname = p->session_info->info3->base.domain.string;
2411 account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2412 if (!account_name) {
2413 return NT_STATUS_NO_MEMORY;
2415 init_lsa_String(account_name, username);
2417 if (r->out.authority_name) {
2418 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2419 if (!authority_name) {
2420 return NT_STATUS_NO_MEMORY;
2422 init_lsa_String(authority_name, domname);
2425 *r->out.account_name = account_name;
2426 if (r->out.authority_name) {
2427 *r->out.authority_name = authority_name;
2430 return NT_STATUS_OK;
2433 /***************************************************************************
2435 ***************************************************************************/
2437 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2438 struct lsa_CreateAccount *r)
2441 struct lsa_info *handle;
2442 uint32_t acc_granted;
2443 struct security_descriptor *psd;
2446 /* find the connection policy handle. */
2447 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2448 return NT_STATUS_INVALID_HANDLE;
2450 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2451 return NT_STATUS_INVALID_HANDLE;
2454 /* check if the user has enough rights */
2456 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2457 return NT_STATUS_ACCESS_DENIED;
2460 /* Work out max allowed. */
2461 map_max_allowed_access(p->session_info->security_token,
2462 &p->session_info->utok,
2463 &r->in.access_mask);
2465 /* map the generic bits to the lsa policy ones */
2466 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2468 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2469 &lsa_account_mapping,
2470 r->in.sid, LSA_POLICY_ALL_ACCESS);
2471 if (!NT_STATUS_IS_OK(status)) {
2475 status = access_check_object(psd, p->session_info->security_token,
2476 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2477 &acc_granted, "_lsa_CreateAccount");
2478 if (!NT_STATUS_IS_OK(status)) {
2482 if ( is_privileged_sid( r->in.sid ) )
2483 return NT_STATUS_OBJECT_NAME_COLLISION;
2485 status = create_lsa_policy_handle(p->mem_ctx, p,
2486 LSA_HANDLE_ACCOUNT_TYPE,
2491 r->out.acct_handle);
2492 if (!NT_STATUS_IS_OK(status)) {
2493 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2496 return privilege_create_account(r->in.sid);
2499 /***************************************************************************
2501 ***************************************************************************/
2503 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2504 struct lsa_OpenAccount *r)
2506 struct lsa_info *handle;
2507 struct security_descriptor *psd = NULL;
2509 uint32_t des_access = r->in.access_mask;
2510 uint32_t acc_granted;
2513 /* find the connection policy handle. */
2514 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2515 return NT_STATUS_INVALID_HANDLE;
2517 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2518 return NT_STATUS_INVALID_HANDLE;
2521 /* des_access is for the account here, not the policy
2522 * handle - so don't check against policy handle. */
2524 /* Work out max allowed. */
2525 map_max_allowed_access(p->session_info->security_token,
2526 &p->session_info->utok,
2529 /* map the generic bits to the lsa account ones */
2530 se_map_generic(&des_access, &lsa_account_mapping);
2532 /* get the generic lsa account SD until we store it */
2533 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2534 &lsa_account_mapping,
2535 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2536 if (!NT_STATUS_IS_OK(status)) {
2540 status = access_check_object(psd, p->session_info->security_token,
2541 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2542 &acc_granted, "_lsa_OpenAccount" );
2543 if (!NT_STATUS_IS_OK(status)) {
2547 /* TODO: Fis the parsing routine before reenabling this check! */
2549 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2550 return NT_STATUS_ACCESS_DENIED;
2553 status = create_lsa_policy_handle(p->mem_ctx, p,
2554 LSA_HANDLE_ACCOUNT_TYPE,
2559 r->out.acct_handle);
2560 if (!NT_STATUS_IS_OK(status)) {
2561 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2564 return NT_STATUS_OK;
2567 /***************************************************************************
2568 _lsa_EnumPrivsAccount
2569 For a given SID, enumerate all the privilege this account has.
2570 ***************************************************************************/
2572 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2573 struct lsa_EnumPrivsAccount *r)
2575 NTSTATUS status = NT_STATUS_OK;
2576 struct lsa_info *info=NULL;
2577 PRIVILEGE_SET *privileges;
2578 struct lsa_PrivilegeSet *priv_set = NULL;
2580 /* find the connection policy handle. */
2581 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2582 return NT_STATUS_INVALID_HANDLE;
2584 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2585 return NT_STATUS_INVALID_HANDLE;
2588 if (!(info->access & LSA_ACCOUNT_VIEW))
2589 return NT_STATUS_ACCESS_DENIED;
2591 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2592 if (!NT_STATUS_IS_OK(status)) {
2596 *r->out.privs = priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
2598 return NT_STATUS_NO_MEMORY;
2601 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2602 sid_string_dbg(&info->sid),
2603 privileges->count));
2605 priv_set->count = privileges->count;
2606 priv_set->unknown = 0;
2607 priv_set->set = talloc_move(priv_set, &privileges->set);
2612 /***************************************************************************
2613 _lsa_GetSystemAccessAccount
2614 ***************************************************************************/
2616 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2617 struct lsa_GetSystemAccessAccount *r)
2620 struct lsa_info *info = NULL;
2621 struct lsa_EnumPrivsAccount e;
2622 struct lsa_PrivilegeSet *privset;
2624 /* find the connection policy handle. */
2626 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2627 return NT_STATUS_INVALID_HANDLE;
2629 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2630 return NT_STATUS_INVALID_HANDLE;
2633 if (!(info->access & LSA_ACCOUNT_VIEW))
2634 return NT_STATUS_ACCESS_DENIED;
2636 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2638 return NT_STATUS_NO_MEMORY;
2641 e.in.handle = r->in.handle;
2642 e.out.privs = &privset;
2644 status = _lsa_EnumPrivsAccount(p, &e);
2645 if (!NT_STATUS_IS_OK(status)) {
2646 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2647 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2648 nt_errstr(status)));
2652 /* Samba4 would iterate over the privset to merge the policy mode bits,
2653 * not sure samba3 can do the same here, so just return what we did in
2657 0x01 -> Log on locally
2658 0x02 -> Access this computer from network
2659 0x04 -> Log on as a batch job
2660 0x10 -> Log on as a service
2662 they can be ORed together
2665 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2666 LSA_POLICY_MODE_NETWORK;
2668 return NT_STATUS_OK;
2671 /***************************************************************************
2672 update the systemaccount information
2673 ***************************************************************************/
2675 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2676 struct lsa_SetSystemAccessAccount *r)
2678 struct lsa_info *info=NULL;
2681 /* find the connection policy handle. */
2682 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2683 return NT_STATUS_INVALID_HANDLE;
2685 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2686 return NT_STATUS_INVALID_HANDLE;
2689 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2690 return NT_STATUS_ACCESS_DENIED;
2693 if (!pdb_getgrsid(&map, info->sid))
2694 return NT_STATUS_NO_SUCH_GROUP;
2696 return pdb_update_group_mapping_entry(&map);
2699 /***************************************************************************
2700 _lsa_AddPrivilegesToAccount
2701 For a given SID, add some privileges.
2702 ***************************************************************************/
2704 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
2705 struct lsa_AddPrivilegesToAccount *r)
2707 struct lsa_info *info = NULL;
2708 struct lsa_PrivilegeSet *set = NULL;
2710 /* find the connection policy handle. */
2711 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2712 return NT_STATUS_INVALID_HANDLE;
2714 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2715 return NT_STATUS_INVALID_HANDLE;
2718 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2719 return NT_STATUS_ACCESS_DENIED;
2724 if ( !grant_privilege_set( &info->sid, set ) ) {
2725 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2726 sid_string_dbg(&info->sid) ));
2727 return NT_STATUS_NO_SUCH_PRIVILEGE;
2730 return NT_STATUS_OK;
2733 /***************************************************************************
2734 _lsa_RemovePrivilegesFromAccount
2735 For a given SID, remove some privileges.
2736 ***************************************************************************/
2738 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2739 struct lsa_RemovePrivilegesFromAccount *r)
2741 struct lsa_info *info = NULL;
2742 struct lsa_PrivilegeSet *set = NULL;
2744 /* find the connection policy handle. */
2745 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2746 return NT_STATUS_INVALID_HANDLE;
2748 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2749 return NT_STATUS_INVALID_HANDLE;
2752 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2753 return NT_STATUS_ACCESS_DENIED;
2758 if ( !revoke_privilege_set( &info->sid, set) ) {
2759 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2760 sid_string_dbg(&info->sid) ));
2761 return NT_STATUS_NO_SUCH_PRIVILEGE;
2764 return NT_STATUS_OK;
2767 /***************************************************************************
2769 ***************************************************************************/
2771 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2772 struct lsa_LookupPrivName *r)
2774 struct lsa_info *info = NULL;
2776 struct lsa_StringLarge *lsa_name;
2778 /* find the connection policy handle. */
2779 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2780 return NT_STATUS_INVALID_HANDLE;
2783 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2784 return NT_STATUS_INVALID_HANDLE;
2787 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2788 return NT_STATUS_ACCESS_DENIED;
2791 if (r->in.luid->high != 0) {
2792 return NT_STATUS_NO_SUCH_PRIVILEGE;
2795 name = sec_privilege_name(r->in.luid->low);
2797 return NT_STATUS_NO_SUCH_PRIVILEGE;
2800 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2802 return NT_STATUS_NO_MEMORY;
2805 lsa_name->string = talloc_strdup(lsa_name, name);
2806 if (!lsa_name->string) {
2807 TALLOC_FREE(lsa_name);
2808 return NT_STATUS_NO_MEMORY;
2811 *r->out.name = lsa_name;
2813 return NT_STATUS_OK;
2816 /***************************************************************************
2818 ***************************************************************************/
2820 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
2821 struct lsa_QuerySecurity *r)
2823 struct lsa_info *handle=NULL;
2824 struct security_descriptor *psd = NULL;
2828 /* find the connection policy handle. */
2829 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2830 return NT_STATUS_INVALID_HANDLE;
2832 switch (handle->type) {
2833 case LSA_HANDLE_POLICY_TYPE:
2834 case LSA_HANDLE_ACCOUNT_TYPE:
2835 case LSA_HANDLE_TRUST_TYPE:
2837 sd_size = ndr_size_security_descriptor(psd, 0);
2838 status = NT_STATUS_OK;
2841 status = NT_STATUS_INVALID_HANDLE;
2845 if (!NT_STATUS_IS_OK(status)) {
2849 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2850 if (!*r->out.sdbuf) {
2851 return NT_STATUS_NO_MEMORY;
2857 /***************************************************************************
2858 _lsa_AddAccountRights
2859 ***************************************************************************/
2861 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
2862 struct lsa_AddAccountRights *r)
2864 struct lsa_info *info = NULL;
2866 uint32_t acc_granted = 0;
2867 struct security_descriptor *psd = NULL;
2872 /* find the connection policy handle. */
2873 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2874 return NT_STATUS_INVALID_HANDLE;
2876 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2877 return NT_STATUS_INVALID_HANDLE;
2880 /* get the generic lsa account SD for this SID until we store it */
2881 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2882 &lsa_account_mapping,
2883 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2884 if (!NT_STATUS_IS_OK(status)) {
2889 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2890 * on the policy handle. If it does, ask for
2891 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2892 * on the account sid. We don't check here so just use the latter. JRA.
2895 status = access_check_object(psd, p->session_info->security_token,
2896 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2897 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2898 &acc_granted, "_lsa_AddAccountRights" );
2899 if (!NT_STATUS_IS_OK(status)) {
2903 /* according to an NT4 PDC, you can add privileges to SIDs even without
2904 call_lsa_create_account() first. And you can use any arbitrary SID. */
2906 sid_copy( &sid, r->in.sid );
2908 for ( i=0; i < r->in.rights->count; i++ ) {
2910 const char *privname = r->in.rights->names[i].string;
2912 /* only try to add non-null strings */
2917 if ( !grant_privilege_by_name( &sid, privname ) ) {
2918 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2920 return NT_STATUS_NO_SUCH_PRIVILEGE;
2924 return NT_STATUS_OK;
2927 /***************************************************************************
2928 _lsa_RemoveAccountRights
2929 ***************************************************************************/
2931 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
2932 struct lsa_RemoveAccountRights *r)
2934 struct lsa_info *info = NULL;
2936 struct security_descriptor *psd = NULL;
2939 const char *privname = NULL;
2940 uint32_t acc_granted = 0;
2943 /* find the connection policy handle. */
2944 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2945 return NT_STATUS_INVALID_HANDLE;
2947 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2948 return NT_STATUS_INVALID_HANDLE;
2951 /* get the generic lsa account SD for this SID until we store it */
2952 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2953 &lsa_account_mapping,
2954 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2955 if (!NT_STATUS_IS_OK(status)) {
2960 * From the MS DOCs. We need
2961 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2962 * and DELETE on the account sid.
2965 status = access_check_object(psd, p->session_info->security_token,
2966 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2967 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2968 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
2969 &acc_granted, "_lsa_RemoveAccountRights");
2970 if (!NT_STATUS_IS_OK(status)) {
2974 sid_copy( &sid, r->in.sid );
2976 if ( r->in.remove_all ) {
2977 if ( !revoke_all_privileges( &sid ) )
2978 return NT_STATUS_ACCESS_DENIED;
2980 return NT_STATUS_OK;
2983 for ( i=0; i < r->in.rights->count; i++ ) {
2985 privname = r->in.rights->names[i].string;
2987 /* only try to add non-null strings */
2992 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2993 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2995 return NT_STATUS_NO_SUCH_PRIVILEGE;
2999 return NT_STATUS_OK;
3002 /*******************************************************************
3003 ********************************************************************/
3005 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3006 struct lsa_RightSet *r,
3007 PRIVILEGE_SET *privileges)
3010 const char *privname;
3011 const char **privname_array = NULL;
3014 for (i=0; i<privileges->count; i++) {
3015 if (privileges->set[i].luid.high) {
3018 privname = sec_privilege_name(privileges->set[i].luid.low);
3020 if (!add_string_to_array(mem_ctx, privname,
3021 &privname_array, &num_priv)) {
3022 return NT_STATUS_NO_MEMORY;
3029 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
3032 return NT_STATUS_NO_MEMORY;
3035 for (i=0; i<num_priv; i++) {
3036 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3039 r->count = num_priv;
3042 return NT_STATUS_OK;
3045 /***************************************************************************
3046 _lsa_EnumAccountRights
3047 ***************************************************************************/
3049 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3050 struct lsa_EnumAccountRights *r)
3053 struct lsa_info *info = NULL;
3054 PRIVILEGE_SET *privileges;
3056 /* find the connection policy handle. */
3058 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3059 return NT_STATUS_INVALID_HANDLE;
3061 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3062 return NT_STATUS_INVALID_HANDLE;
3065 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3066 return NT_STATUS_ACCESS_DENIED;
3069 /* according to an NT4 PDC, you can add privileges to SIDs even without
3070 call_lsa_create_account() first. And you can use any arbitrary SID. */
3072 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3073 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3074 * the lsa database */
3076 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3077 if (!NT_STATUS_IS_OK(status)) {
3081 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3082 sid_string_dbg(r->in.sid), privileges->count));
3084 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3089 /***************************************************************************
3090 _lsa_LookupPrivValue
3091 ***************************************************************************/
3093 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3094 struct lsa_LookupPrivValue *r)
3096 struct lsa_info *info = NULL;
3097 const char *name = NULL;
3099 /* find the connection policy handle. */
3101 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3102 return NT_STATUS_INVALID_HANDLE;
3104 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3105 return NT_STATUS_INVALID_HANDLE;
3108 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3109 return NT_STATUS_ACCESS_DENIED;
3111 name = r->in.name->string;
3113 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3115 r->out.luid->low = sec_privilege_id(name);
3116 r->out.luid->high = 0;
3117 if (r->out.luid->low == SEC_PRIV_INVALID) {
3118 return NT_STATUS_NO_SUCH_PRIVILEGE;
3120 return NT_STATUS_OK;
3123 /***************************************************************************
3124 _lsa_EnumAccountsWithUserRight
3125 ***************************************************************************/
3127 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3128 struct lsa_EnumAccountsWithUserRight *r)
3131 struct lsa_info *info = NULL;
3132 struct dom_sid *sids = NULL;
3135 enum sec_privilege privilege;
3137 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3138 return NT_STATUS_INVALID_HANDLE;
3141 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3142 return NT_STATUS_INVALID_HANDLE;
3145 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3146 return NT_STATUS_ACCESS_DENIED;
3149 if (!r->in.name || !r->in.name->string) {
3150 return NT_STATUS_NO_SUCH_PRIVILEGE;
3153 privilege = sec_privilege_id(r->in.name->string);
3154 if (privilege == SEC_PRIV_INVALID) {
3155 return NT_STATUS_NO_SUCH_PRIVILEGE;
3158 status = privilege_enum_sids(privilege, p->mem_ctx,
3160 if (!NT_STATUS_IS_OK(status)) {
3164 r->out.sids->num_sids = num_sids;
3165 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3166 r->out.sids->num_sids);
3168 for (i=0; i < r->out.sids->num_sids; i++) {
3169 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3171 if (!r->out.sids->sids[i].sid) {
3172 TALLOC_FREE(r->out.sids->sids);
3173 r->out.sids->num_sids = 0;
3174 return NT_STATUS_NO_MEMORY;
3178 return NT_STATUS_OK;
3181 /***************************************************************************
3183 ***************************************************************************/
3185 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3186 struct lsa_Delete *r)
3188 return NT_STATUS_NOT_SUPPORTED;
3192 * From here on the server routines are just dummy ones to make smbd link with
3193 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3194 * pulling the server stubs across one by one.
3197 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3199 p->rng_fault_state = True;
3200 return NT_STATUS_NOT_IMPLEMENTED;
3203 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3204 struct lsa_ChangePassword *r)
3206 p->rng_fault_state = True;
3207 return NT_STATUS_NOT_IMPLEMENTED;
3210 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3212 p->rng_fault_state = True;
3213 return NT_STATUS_NOT_IMPLEMENTED;
3216 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3218 p->rng_fault_state = True;
3219 return NT_STATUS_NOT_IMPLEMENTED;
3222 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3223 struct lsa_GetQuotasForAccount *r)
3225 p->rng_fault_state = True;
3226 return NT_STATUS_NOT_IMPLEMENTED;
3229 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3230 struct lsa_SetQuotasForAccount *r)
3232 p->rng_fault_state = True;
3233 return NT_STATUS_NOT_IMPLEMENTED;
3236 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3237 struct lsa_SetInformationTrustedDomain *r)
3239 p->rng_fault_state = True;
3240 return NT_STATUS_NOT_IMPLEMENTED;
3243 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
3245 p->rng_fault_state = True;
3246 return NT_STATUS_NOT_IMPLEMENTED;
3249 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3250 struct lsa_SetTrustedDomainInfo *r)
3252 p->rng_fault_state = True;
3253 return NT_STATUS_NOT_IMPLEMENTED;
3256 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3257 struct lsa_StorePrivateData *r)
3259 p->rng_fault_state = True;
3260 return NT_STATUS_NOT_IMPLEMENTED;
3263 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3264 struct lsa_RetrievePrivateData *r)
3266 p->rng_fault_state = True;
3267 return NT_STATUS_NOT_IMPLEMENTED;
3270 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3271 struct lsa_SetInfoPolicy2 *r)
3273 p->rng_fault_state = True;
3274 return NT_STATUS_NOT_IMPLEMENTED;
3277 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3278 struct lsa_SetTrustedDomainInfoByName *r)
3280 p->rng_fault_state = True;
3281 return NT_STATUS_NOT_IMPLEMENTED;
3284 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3285 struct lsa_EnumTrustedDomainsEx *r)
3287 struct lsa_info *info;
3289 struct pdb_trusted_domain **domains;
3290 struct lsa_TrustDomainInfoInfoEx *entries;
3294 /* bail out early if pdb backend is not capable of ex trusted domains,
3295 * if we dont do that, the client might not call
3296 * _lsa_EnumTrustedDomains() afterwards - gd */
3298 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3299 p->rng_fault_state = True;
3300 return NT_STATUS_NOT_IMPLEMENTED;
3303 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3304 return NT_STATUS_INVALID_HANDLE;
3306 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3307 return NT_STATUS_INVALID_HANDLE;
3310 /* check if the user has enough rights */
3311 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3312 return NT_STATUS_ACCESS_DENIED;
3315 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3318 if (!NT_STATUS_IS_OK(nt_status)) {
3322 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3325 return NT_STATUS_NO_MEMORY;
3328 for (i=0; i<count; i++) {
3329 init_lsa_StringLarge(&entries[i].netbios_name,
3330 domains[i]->netbios_name);
3331 entries[i].sid = &domains[i]->security_identifier;
3334 if (*r->in.resume_handle >= count) {
3335 *r->out.resume_handle = -1;
3336 TALLOC_FREE(entries);
3337 return NT_STATUS_NO_MORE_ENTRIES;
3340 /* return the rest, limit by max_size. Note that we
3341 use the w2k3 element size value of 60 */
3342 r->out.domains->count = count - *r->in.resume_handle;
3343 r->out.domains->count = MIN(r->out.domains->count,
3344 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3346 r->out.domains->domains = entries + *r->in.resume_handle;
3348 if (r->out.domains->count < count - *r->in.resume_handle) {
3349 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3350 return STATUS_MORE_ENTRIES;
3353 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3354 * always be larger than the previous input resume handle, in
3355 * particular when hitting the last query it is vital to set the
3356 * resume handle correctly to avoid infinite client loops, as
3357 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3358 * status is NT_STATUS_OK - gd */
3360 *r->out.resume_handle = (uint32_t)-1;
3362 return NT_STATUS_OK;
3365 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3366 struct lsa_QueryDomainInformationPolicy *r)
3368 p->rng_fault_state = True;
3369 return NT_STATUS_NOT_IMPLEMENTED;
3372 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3373 struct lsa_SetDomainInformationPolicy *r)
3375 p->rng_fault_state = True;
3376 return NT_STATUS_NOT_IMPLEMENTED;
3379 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3381 p->rng_fault_state = True;
3382 return NT_STATUS_NOT_IMPLEMENTED;
3385 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3387 p->rng_fault_state = True;
3388 return NT_STATUS_NOT_IMPLEMENTED;
3391 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3393 p->rng_fault_state = True;
3394 return NT_STATUS_NOT_IMPLEMENTED;
3397 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3399 p->rng_fault_state = True;
3400 return NT_STATUS_NOT_IMPLEMENTED;
3403 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3404 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3406 p->rng_fault_state = True;
3407 return NT_STATUS_NOT_IMPLEMENTED;
3410 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3411 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3413 p->rng_fault_state = True;
3414 return NT_STATUS_NOT_IMPLEMENTED;
3417 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3419 p->rng_fault_state = True;
3420 return NT_STATUS_NOT_IMPLEMENTED;
3423 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3424 struct lsa_CREDRGETTARGETINFO *r)
3426 p->rng_fault_state = True;
3427 return NT_STATUS_NOT_IMPLEMENTED;
3430 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3431 struct lsa_CREDRPROFILELOADED *r)
3433 p->rng_fault_state = True;
3434 return NT_STATUS_NOT_IMPLEMENTED;
3437 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3438 struct lsa_CREDRGETSESSIONTYPES *r)
3440 p->rng_fault_state = True;
3441 return NT_STATUS_NOT_IMPLEMENTED;
3444 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3445 struct lsa_LSARREGISTERAUDITEVENT *r)
3447 p->rng_fault_state = True;
3448 return NT_STATUS_NOT_IMPLEMENTED;
3451 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3452 struct lsa_LSARGENAUDITEVENT *r)
3454 p->rng_fault_state = True;
3455 return NT_STATUS_NOT_IMPLEMENTED;
3458 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3459 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3461 p->rng_fault_state = True;
3462 return NT_STATUS_NOT_IMPLEMENTED;
3465 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3466 struct lsa_lsaRQueryForestTrustInformation *r)
3468 p->rng_fault_state = True;
3469 return NT_STATUS_NOT_IMPLEMENTED;
3472 #define DNS_CMP_MATCH 0
3473 #define DNS_CMP_FIRST_IS_CHILD 1
3474 #define DNS_CMP_SECOND_IS_CHILD 2
3475 #define DNS_CMP_NO_MATCH 3
3477 /* this function assumes names are well formed DNS names.
3478 * it doesn't validate them */
3479 static int dns_cmp(const char *s1, size_t l1,
3480 const char *s2, size_t l2)
3482 const char *p1, *p2;
3487 if (StrCaseCmp(s1, s2) == 0) {
3488 return DNS_CMP_MATCH;
3490 return DNS_CMP_NO_MATCH;
3498 cret = DNS_CMP_FIRST_IS_CHILD;
3504 cret = DNS_CMP_SECOND_IS_CHILD;
3507 if (p1[t1 - t2 - 1] != '.') {
3508 return DNS_CMP_NO_MATCH;
3511 if (StrCaseCmp(&p1[t1 - t2], p2) == 0) {
3515 return DNS_CMP_NO_MATCH;
3518 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3519 struct lsa_ForestTrustInformation *lfti,
3520 struct ForestTrustInfo *fti)
3522 struct lsa_ForestTrustRecord *lrec;
3523 struct ForestTrustInfoRecord *rec;
3524 struct lsa_StringLarge *tln;
3525 struct lsa_ForestTrustDomainInfo *info;
3529 fti->count = lfti->count;
3530 fti->records = talloc_array(mem_ctx,
3531 struct ForestTrustInfoRecordArmor,
3533 if (!fti->records) {
3534 return NT_STATUS_NO_MEMORY;
3536 for (i = 0; i < fti->count; i++) {
3537 lrec = lfti->entries[i];
3538 rec = &fti->records[i].record;
3540 rec->flags = lrec->flags;
3541 rec->timestamp = lrec->time;
3542 rec->type = lrec->type;
3544 switch (lrec->type) {
3545 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3546 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3547 tln = &lrec->forest_trust_data.top_level_name;
3548 rec->data.name.string =
3549 talloc_strdup(mem_ctx, tln->string);
3550 if (!rec->data.name.string) {
3551 return NT_STATUS_NO_MEMORY;
3553 rec->data.name.size = strlen(rec->data.name.string);
3555 case LSA_FOREST_TRUST_DOMAIN_INFO:
3556 info = &lrec->forest_trust_data.domain_info;
3557 rec->data.info.sid = *info->domain_sid;
3558 rec->data.info.dns_name.string =
3559 talloc_strdup(mem_ctx,
3560 info->dns_domain_name.string);
3561 if (!rec->data.info.dns_name.string) {
3562 return NT_STATUS_NO_MEMORY;
3564 rec->data.info.dns_name.size =
3565 strlen(rec->data.info.dns_name.string);
3566 rec->data.info.netbios_name.string =
3567 talloc_strdup(mem_ctx,
3568 info->netbios_domain_name.string);
3569 if (!rec->data.info.netbios_name.string) {
3570 return NT_STATUS_NO_MEMORY;
3572 rec->data.info.netbios_name.size =
3573 strlen(rec->data.info.netbios_name.string);
3576 return NT_STATUS_INVALID_DOMAIN_STATE;
3580 return NT_STATUS_OK;
3583 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3584 uint32_t index, uint32_t collision_type,
3585 uint32_t conflict_type, const char *tdo_name);
3587 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
3588 const char *tdo_name,
3589 struct ForestTrustInfo *tdo_fti,
3590 struct ForestTrustInfo *new_fti,
3591 struct lsa_ForestTrustCollisionInfo *c_info)
3593 struct ForestTrustInfoRecord *nrec;
3594 struct ForestTrustInfoRecord *trec;
3595 const char *dns_name;
3596 const char *nb_name = NULL;
3597 struct dom_sid *sid = NULL;
3598 const char *tname = NULL;
3603 uint32_t new_fti_idx;
3605 /* use always TDO type, until we understand when Xref can be used */
3606 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
3611 bool ex_rule = false;
3614 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
3616 nrec = &new_fti->records[new_fti_idx].record;
3618 tln_conflict = false;
3619 sid_conflict = false;
3620 nb_conflict = false;
3623 switch (nrec->type) {
3624 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3625 /* exclusions do not conflict by definition */
3628 case FOREST_TRUST_TOP_LEVEL_NAME:
3629 dns_name = nrec->data.name.string;
3630 dns_len = nrec->data.name.size;
3633 case LSA_FOREST_TRUST_DOMAIN_INFO:
3634 dns_name = nrec->data.info.dns_name.string;
3635 dns_len = nrec->data.info.dns_name.size;
3636 nb_name = nrec->data.info.netbios_name.string;
3637 nb_len = nrec->data.info.netbios_name.size;
3638 sid = &nrec->data.info.sid;
3642 if (!dns_name) continue;
3644 /* check if this is already taken and not excluded */
3645 for (i = 0; i < tdo_fti->count; i++) {
3646 trec = &tdo_fti->records[i].record;
3648 switch (trec->type) {
3649 case FOREST_TRUST_TOP_LEVEL_NAME:
3651 tname = trec->data.name.string;
3652 tlen = trec->data.name.size;
3654 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
3656 tname = trec->data.name.string;
3657 tlen = trec->data.name.size;
3659 case FOREST_TRUST_DOMAIN_INFO:
3661 tname = trec->data.info.dns_name.string;
3662 tlen = trec->data.info.dns_name.size;
3664 ret = dns_cmp(dns_name, dns_len, tname, tlen);
3667 /* if it matches exclusion,
3668 * it doesn't conflict */
3674 case DNS_CMP_FIRST_IS_CHILD:
3675 case DNS_CMP_SECOND_IS_CHILD:
3676 tln_conflict = true;
3682 /* explicit exclusion, no dns name conflict here */
3684 tln_conflict = false;
3687 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
3691 /* also test for domain info */
3692 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
3693 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
3694 sid_conflict = true;
3696 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
3697 StrCaseCmp(trec->data.info.netbios_name.string,
3704 nt_status = add_collision(c_info, new_fti_idx,
3706 LSA_TLN_DISABLED_CONFLICT,
3710 nt_status = add_collision(c_info, new_fti_idx,
3712 LSA_SID_DISABLED_CONFLICT,
3716 nt_status = add_collision(c_info, new_fti_idx,
3718 LSA_NB_DISABLED_CONFLICT,
3723 return NT_STATUS_OK;
3726 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3727 uint32_t idx, uint32_t collision_type,
3728 uint32_t conflict_type, const char *tdo_name)
3730 struct lsa_ForestTrustCollisionRecord **es;
3731 uint32_t i = c_info->count;
3733 es = talloc_realloc(c_info, c_info->entries,
3734 struct lsa_ForestTrustCollisionRecord *, i + 1);
3736 return NT_STATUS_NO_MEMORY;
3738 c_info->entries = es;
3739 c_info->count = i + 1;
3741 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
3743 return NT_STATUS_NO_MEMORY;
3747 es[i]->type = collision_type;
3748 es[i]->flags.flags = conflict_type;
3749 es[i]->name.string = talloc_strdup(es[i], tdo_name);
3750 if (!es[i]->name.string) {
3751 return NT_STATUS_NO_MEMORY;
3753 es[i]->name.size = strlen(es[i]->name.string);
3755 return NT_STATUS_OK;
3758 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3759 struct pdb_trusted_domain *td,
3760 struct ForestTrustInfo *info)
3762 enum ndr_err_code ndr_err;
3764 if (td->trust_forest_trust_info.length == 0 ||
3765 td->trust_forest_trust_info.data == NULL) {
3766 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3768 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
3770 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3771 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3772 return NT_STATUS_INVALID_DOMAIN_STATE;
3775 return NT_STATUS_OK;
3778 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
3779 struct ForestTrustInfo *fti)
3781 struct ForestTrustDataDomainInfo *info;
3782 struct ForestTrustInfoRecord *rec;
3786 fti->records = talloc_array(fti,
3787 struct ForestTrustInfoRecordArmor, 2);
3788 if (!fti->records) {
3789 return NT_STATUS_NO_MEMORY;
3793 rec = &fti->records[0].record;
3797 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3799 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
3800 if (!rec->data.name.string) {
3801 return NT_STATUS_NO_MEMORY;
3803 rec->data.name.size = strlen(rec->data.name.string);
3806 rec = &fti->records[1].record;
3810 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3812 info = &rec->data.info;
3814 info->sid = dom_info->sid;
3815 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
3816 if (!info->dns_name.string) {
3817 return NT_STATUS_NO_MEMORY;
3819 info->dns_name.size = strlen(info->dns_name.string);
3820 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
3821 if (!info->netbios_name.string) {
3822 return NT_STATUS_NO_MEMORY;
3824 info->netbios_name.size = strlen(info->netbios_name.string);
3826 return NT_STATUS_OK;
3829 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
3830 struct lsa_lsaRSetForestTrustInformation *r)
3835 struct lsa_info *handle;
3836 uint32_t num_domains;
3837 struct pdb_trusted_domain **domains;
3838 struct ForestTrustInfo *nfti;
3839 struct ForestTrustInfo *fti;
3840 struct lsa_ForestTrustCollisionInfo *c_info;
3841 struct pdb_domain_info *dom_info;
3842 enum ndr_err_code ndr_err;
3845 return NT_STATUS_NOT_SUPPORTED;
3848 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
3849 return NT_STATUS_INVALID_HANDLE;
3852 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
3853 return NT_STATUS_INVALID_HANDLE;
3856 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
3857 return NT_STATUS_ACCESS_DENIED;
3860 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
3861 if (!NT_STATUS_IS_OK(status)) {
3864 if (num_domains == 0) {
3865 return NT_STATUS_NO_SUCH_DOMAIN;
3868 for (i = 0; i < num_domains; i++) {
3869 if (domains[i]->domain_name == NULL) {
3870 return NT_STATUS_INVALID_DOMAIN_STATE;
3872 if (StrCaseCmp(domains[i]->domain_name,
3873 r->in.trusted_domain_name->string) == 0) {
3877 if (i >= num_domains) {
3878 return NT_STATUS_NO_SUCH_DOMAIN;
3881 if (!(domains[i]->trust_attributes &
3882 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
3883 return NT_STATUS_INVALID_PARAMETER;
3886 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
3887 return NT_STATUS_INVALID_PARAMETER;
3890 /* The following section until COPY_END is a copy from
3891 * source4/rpmc_server/lsa/scesrc_lsa.c */
3892 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
3894 return NT_STATUS_NO_MEMORY;
3897 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
3898 if (!NT_STATUS_IS_OK(status)) {
3902 c_info = talloc_zero(r->out.collision_info,
3903 struct lsa_ForestTrustCollisionInfo);
3905 return NT_STATUS_NO_MEMORY;
3908 /* first check own info, then other domains */
3909 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3911 return NT_STATUS_NO_MEMORY;
3914 dom_info = pdb_get_domain_info(p->mem_ctx);
3916 status = own_ft_info(dom_info, fti);
3917 if (!NT_STATUS_IS_OK(status)) {
3921 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
3922 if (!NT_STATUS_IS_OK(status)) {
3926 for (j = 0; j < num_domains; j++) {
3927 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3929 return NT_STATUS_NO_MEMORY;
3932 status = get_ft_info(p->mem_ctx, domains[j], fti);
3933 if (!NT_STATUS_IS_OK(status)) {
3934 if (NT_STATUS_EQUAL(status,
3935 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3941 if (domains[j]->domain_name == NULL) {
3942 return NT_STATUS_INVALID_DOMAIN_STATE;
3945 status = check_ft_info(c_info, domains[j]->domain_name,
3947 if (!NT_STATUS_IS_OK(status)) {
3952 *r->out.collision_info = c_info;
3954 if (r->in.check_only != 0) {
3955 return NT_STATUS_OK;
3960 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
3962 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
3963 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3964 return NT_STATUS_INVALID_PARAMETER;
3967 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
3968 if (!NT_STATUS_IS_OK(status)) {
3972 return NT_STATUS_OK;
3975 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
3976 struct lsa_CREDRRENAME *r)
3978 p->rng_fault_state = True;
3979 return NT_STATUS_NOT_IMPLEMENTED;
3982 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
3983 struct lsa_LSAROPENPOLICYSCE *r)
3985 p->rng_fault_state = True;
3986 return NT_STATUS_NOT_IMPLEMENTED;
3989 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
3990 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3992 p->rng_fault_state = True;
3993 return NT_STATUS_NOT_IMPLEMENTED;
3996 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
3997 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3999 p->rng_fault_state = True;
4000 return NT_STATUS_NOT_IMPLEMENTED;
4003 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4004 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4006 p->rng_fault_state = True;
4007 return NT_STATUS_NOT_IMPLEMENTED;