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,
1651 return NT_STATUS_UNSUCCESSFUL;
1653 if (!pdb_set_plaintext_passwd(sam_acct, dummy)) {
1654 return NT_STATUS_UNSUCCESSFUL;
1662 status = pdb_add_sam_account(sam_acct);
1663 if (!NT_STATUS_IS_OK(status)) {
1667 return NT_STATUS_OK;
1670 /***************************************************************************
1671 _lsa_CreateTrustedDomainEx2
1672 ***************************************************************************/
1674 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1675 struct lsa_CreateTrustedDomainEx2 *r)
1677 struct lsa_info *policy;
1679 uint32_t acc_granted;
1680 struct security_descriptor *psd;
1682 struct pdb_trusted_domain td;
1683 struct trustDomainPasswords auth_struct;
1684 enum ndr_err_code ndr_err;
1685 DATA_BLOB auth_blob;
1688 return NT_STATUS_NOT_SUPPORTED;
1691 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1692 return NT_STATUS_INVALID_HANDLE;
1695 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1696 return NT_STATUS_ACCESS_DENIED;
1699 if (p->session_info->utok.uid != sec_initial_uid() &&
1700 !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1701 return NT_STATUS_ACCESS_DENIED;
1704 /* Work out max allowed. */
1705 map_max_allowed_access(p->session_info->security_token,
1706 &p->session_info->utok,
1707 &r->in.access_mask);
1709 /* map the generic bits to the lsa policy ones */
1710 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1712 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1713 &lsa_trusted_domain_mapping,
1715 if (!NT_STATUS_IS_OK(status)) {
1719 status = access_check_object(psd, p->session_info->security_token,
1720 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1721 r->in.access_mask, &acc_granted,
1722 "_lsa_CreateTrustedDomainEx2");
1723 if (!NT_STATUS_IS_OK(status)) {
1729 td.domain_name = talloc_strdup(p->mem_ctx,
1730 r->in.info->domain_name.string);
1731 if (td.domain_name == NULL) {
1732 return NT_STATUS_NO_MEMORY;
1734 td.netbios_name = talloc_strdup(p->mem_ctx,
1735 r->in.info->netbios_name.string);
1736 if (td.netbios_name == NULL) {
1737 return NT_STATUS_NO_MEMORY;
1739 sid_copy(&td.security_identifier, r->in.info->sid);
1740 td.trust_direction = r->in.info->trust_direction;
1741 td.trust_type = r->in.info->trust_type;
1742 td.trust_attributes = r->in.info->trust_attributes;
1744 if (r->in.auth_info->auth_blob.size != 0) {
1745 auth_blob.length = r->in.auth_info->auth_blob.size;
1746 auth_blob.data = r->in.auth_info->auth_blob.data;
1748 arcfour_crypt_blob(auth_blob.data, auth_blob.length,
1749 &p->session_info->user_session_key);
1751 ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
1753 (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
1754 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1755 return NT_STATUS_UNSUCCESSFUL;
1758 ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
1759 &auth_struct.incoming,
1760 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1761 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1762 return NT_STATUS_UNSUCCESSFUL;
1765 ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
1766 &auth_struct.outgoing,
1767 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1768 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1769 return NT_STATUS_UNSUCCESSFUL;
1772 td.trust_auth_incoming.data = NULL;
1773 td.trust_auth_incoming.length = 0;
1774 td.trust_auth_outgoing.data = NULL;
1775 td.trust_auth_outgoing.length = 0;
1778 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1779 if (!NT_STATUS_IS_OK(status)) {
1783 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1784 status = add_trusted_domain_user(p->mem_ctx,
1785 r->in.info->netbios_name.string,
1786 r->in.info->domain_name.string,
1788 if (!NT_STATUS_IS_OK(status)) {
1793 status = create_lsa_policy_handle(p->mem_ctx, p,
1794 LSA_HANDLE_TRUST_TYPE,
1797 r->in.info->netbios_name.string,
1799 r->out.trustdom_handle);
1800 if (!NT_STATUS_IS_OK(status)) {
1801 pdb_del_trusteddom_pw(r->in.info->netbios_name.string);
1802 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1805 return NT_STATUS_OK;
1808 /***************************************************************************
1809 _lsa_CreateTrustedDomainEx
1810 ***************************************************************************/
1812 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1813 struct lsa_CreateTrustedDomainEx *r)
1815 struct lsa_CreateTrustedDomainEx2 q;
1817 q.in.policy_handle = r->in.policy_handle;
1818 q.in.info = r->in.info;
1819 q.in.auth_info = r->in.auth_info;
1820 q.in.access_mask = r->in.access_mask;
1821 q.out.trustdom_handle = r->out.trustdom_handle;
1823 return _lsa_CreateTrustedDomainEx2(p, &q);
1826 /***************************************************************************
1827 _lsa_CreateTrustedDomain
1828 ***************************************************************************/
1830 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1831 struct lsa_CreateTrustedDomain *r)
1833 struct lsa_CreateTrustedDomainEx2 c;
1834 struct lsa_TrustDomainInfoInfoEx info;
1835 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1837 ZERO_STRUCT(auth_info);
1839 info.domain_name = r->in.info->name;
1840 info.netbios_name = r->in.info->name;
1841 info.sid = r->in.info->sid;
1842 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1843 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1844 info.trust_attributes = 0;
1846 c.in.policy_handle = r->in.policy_handle;
1848 c.in.auth_info = &auth_info;
1849 c.in.access_mask = r->in.access_mask;
1850 c.out.trustdom_handle = r->out.trustdom_handle;
1852 return _lsa_CreateTrustedDomainEx2(p, &c);
1855 /***************************************************************************
1856 _lsa_DeleteTrustedDomain
1857 ***************************************************************************/
1859 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1860 struct lsa_DeleteTrustedDomain *r)
1863 struct lsa_info *handle;
1864 struct pdb_trusted_domain *td;
1865 struct samu *sam_acct;
1868 /* find the connection policy handle. */
1869 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1870 return NT_STATUS_INVALID_HANDLE;
1873 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1874 return NT_STATUS_INVALID_HANDLE;
1877 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1878 return NT_STATUS_ACCESS_DENIED;
1881 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1882 if (!NT_STATUS_IS_OK(status)) {
1886 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1887 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1888 sid_string_tos(r->in.dom_sid)));
1889 return NT_STATUS_UNSUCCESSFUL;
1892 if (td->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1893 sam_acct = samu_new(p->mem_ctx);
1894 if (sam_acct == NULL) {
1895 return NT_STATUS_NO_MEMORY;
1898 acct_name = talloc_asprintf(p->mem_ctx, "%s$", td->netbios_name);
1899 if (acct_name == NULL) {
1900 return NT_STATUS_NO_MEMORY;
1902 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1903 return NT_STATUS_UNSUCCESSFUL;
1905 status = pdb_delete_sam_account(sam_acct);
1906 if (!NT_STATUS_IS_OK(status)) {
1911 status = pdb_del_trusted_domain(td->netbios_name);
1912 if (!NT_STATUS_IS_OK(status)) {
1916 return NT_STATUS_OK;
1919 /***************************************************************************
1920 _lsa_CloseTrustedDomainEx
1921 ***************************************************************************/
1923 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1924 struct lsa_CloseTrustedDomainEx *r)
1926 return NT_STATUS_NOT_IMPLEMENTED;
1929 /***************************************************************************
1930 _lsa_QueryTrustedDomainInfo
1931 ***************************************************************************/
1933 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
1934 struct lsa_QueryTrustedDomainInfo *r)
1937 struct lsa_info *handle;
1938 union lsa_TrustedDomainInfo *info;
1939 struct pdb_trusted_domain *td;
1940 uint32_t acc_required;
1942 /* find the connection policy handle. */
1943 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
1944 return NT_STATUS_INVALID_HANDLE;
1947 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
1948 return NT_STATUS_INVALID_HANDLE;
1951 switch (r->in.level) {
1952 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1953 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1955 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1956 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
1958 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1959 acc_required = LSA_TRUSTED_QUERY_POSIX;
1961 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
1962 acc_required = LSA_TRUSTED_QUERY_AUTH;
1964 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1965 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1967 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1968 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1970 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1971 acc_required = LSA_TRUSTED_QUERY_AUTH;
1973 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1974 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1975 LSA_TRUSTED_QUERY_POSIX |
1976 LSA_TRUSTED_QUERY_AUTH;
1978 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1979 acc_required = LSA_TRUSTED_QUERY_AUTH;
1981 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1982 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1983 LSA_TRUSTED_QUERY_POSIX |
1984 LSA_TRUSTED_QUERY_AUTH;
1986 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1987 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1989 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1990 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1991 LSA_TRUSTED_QUERY_POSIX |
1992 LSA_TRUSTED_QUERY_AUTH;
1994 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1995 acc_required = LSA_TRUSTED_QUERY_POSIX;
1998 return NT_STATUS_INVALID_PARAMETER;
2001 if (!(handle->access & acc_required)) {
2002 return NT_STATUS_ACCESS_DENIED;
2005 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2006 if (!NT_STATUS_IS_OK(status)) {
2010 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_TrustedDomainInfo);
2012 return NT_STATUS_NO_MEMORY;
2015 switch (r->in.level) {
2016 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2017 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2019 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2020 return NT_STATUS_INVALID_PARAMETER;
2021 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2023 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2024 return NT_STATUS_INVALID_INFO_CLASS;
2025 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2026 return NT_STATUS_INVALID_PARAMETER;
2027 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2028 init_lsa_StringLarge(&info->info_ex.domain_name, td->domain_name);
2029 init_lsa_StringLarge(&info->info_ex.netbios_name, td->netbios_name);
2030 info->info_ex.sid = dom_sid_dup(info, &td->security_identifier);
2031 if (!info->info_ex.sid) {
2032 return NT_STATUS_NO_MEMORY;
2034 info->info_ex.trust_direction = td->trust_direction;
2035 info->info_ex.trust_type = td->trust_type;
2036 info->info_ex.trust_attributes = td->trust_attributes;
2038 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2039 return NT_STATUS_INVALID_INFO_CLASS;
2040 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2042 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2043 return NT_STATUS_INVALID_INFO_CLASS;
2044 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2045 return NT_STATUS_INVALID_INFO_CLASS;
2046 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2047 return NT_STATUS_INVALID_PARAMETER;
2048 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2050 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2053 return NT_STATUS_INVALID_PARAMETER;
2056 *r->out.info = info;
2058 return NT_STATUS_OK;
2061 /***************************************************************************
2062 _lsa_QueryTrustedDomainInfoBySid
2063 ***************************************************************************/
2065 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2066 struct lsa_QueryTrustedDomainInfoBySid *r)
2069 struct policy_handle trustdom_handle;
2070 struct lsa_OpenTrustedDomain o;
2071 struct lsa_QueryTrustedDomainInfo q;
2074 o.in.handle = r->in.handle;
2075 o.in.sid = r->in.dom_sid;
2076 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2077 o.out.trustdom_handle = &trustdom_handle;
2079 status = _lsa_OpenTrustedDomain(p, &o);
2080 if (!NT_STATUS_IS_OK(status)) {
2084 q.in.trustdom_handle = &trustdom_handle;
2085 q.in.level = r->in.level;
2086 q.out.info = r->out.info;
2088 status = _lsa_QueryTrustedDomainInfo(p, &q);
2089 if (!NT_STATUS_IS_OK(status)) {
2093 c.in.handle = &trustdom_handle;
2094 c.out.handle = &trustdom_handle;
2096 return _lsa_Close(p, &c);
2099 /***************************************************************************
2100 _lsa_QueryTrustedDomainInfoByName
2101 ***************************************************************************/
2103 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2104 struct lsa_QueryTrustedDomainInfoByName *r)
2107 struct policy_handle trustdom_handle;
2108 struct lsa_OpenTrustedDomainByName o;
2109 struct lsa_QueryTrustedDomainInfo q;
2112 o.in.handle = r->in.handle;
2113 o.in.name.string = r->in.trusted_domain->string;
2114 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2115 o.out.trustdom_handle = &trustdom_handle;
2117 status = _lsa_OpenTrustedDomainByName(p, &o);
2118 if (!NT_STATUS_IS_OK(status)) {
2119 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2120 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2125 q.in.trustdom_handle = &trustdom_handle;
2126 q.in.level = r->in.level;
2127 q.out.info = r->out.info;
2129 status = _lsa_QueryTrustedDomainInfo(p, &q);
2130 if (!NT_STATUS_IS_OK(status)) {
2134 c.in.handle = &trustdom_handle;
2135 c.out.handle = &trustdom_handle;
2137 return _lsa_Close(p, &c);
2140 /***************************************************************************
2141 ***************************************************************************/
2143 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p, struct lsa_CreateSecret *r)
2145 return NT_STATUS_ACCESS_DENIED;
2148 /***************************************************************************
2149 ***************************************************************************/
2151 NTSTATUS _lsa_SetSecret(struct pipes_struct *p, struct lsa_SetSecret *r)
2153 return NT_STATUS_ACCESS_DENIED;
2156 /***************************************************************************
2158 ***************************************************************************/
2160 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2161 struct lsa_DeleteObject *r)
2164 struct lsa_info *info = NULL;
2166 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2167 return NT_STATUS_INVALID_HANDLE;
2170 if (!(info->access & SEC_STD_DELETE)) {
2171 return NT_STATUS_ACCESS_DENIED;
2174 switch (info->type) {
2175 case LSA_HANDLE_ACCOUNT_TYPE:
2176 status = privilege_delete_account(&info->sid);
2177 if (!NT_STATUS_IS_OK(status)) {
2178 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2179 nt_errstr(status)));
2184 return NT_STATUS_INVALID_HANDLE;
2187 close_policy_hnd(p, r->in.handle);
2188 ZERO_STRUCTP(r->out.handle);
2193 /***************************************************************************
2195 ***************************************************************************/
2197 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2198 struct lsa_EnumPrivs *r)
2200 struct lsa_info *handle;
2202 uint32 enum_context = *r->in.resume_handle;
2203 int num_privs = num_privileges_in_short_list();
2204 struct lsa_PrivEntry *entries = NULL;
2206 /* remember that the enum_context starts at 0 and not 1 */
2208 if ( enum_context >= num_privs )
2209 return NT_STATUS_NO_MORE_ENTRIES;
2211 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2212 enum_context, num_privs));
2214 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2215 return NT_STATUS_INVALID_HANDLE;
2217 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2218 return NT_STATUS_INVALID_HANDLE;
2221 /* check if the user has enough rights
2222 I don't know if it's the right one. not documented. */
2224 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2225 return NT_STATUS_ACCESS_DENIED;
2228 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2230 return NT_STATUS_NO_MEMORY;
2236 for (i = 0; i < num_privs; i++) {
2237 if( i < enum_context) {
2239 init_lsa_StringLarge(&entries[i].name, NULL);
2241 entries[i].luid.low = 0;
2242 entries[i].luid.high = 0;
2245 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2247 entries[i].luid.low = sec_privilege_from_index(i);
2248 entries[i].luid.high = 0;
2252 enum_context = num_privs;
2254 *r->out.resume_handle = enum_context;
2255 r->out.privs->count = num_privs;
2256 r->out.privs->privs = entries;
2258 return NT_STATUS_OK;
2261 /***************************************************************************
2262 _lsa_LookupPrivDisplayName
2263 ***************************************************************************/
2265 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2266 struct lsa_LookupPrivDisplayName *r)
2268 struct lsa_info *handle;
2269 const char *description;
2270 struct lsa_StringLarge *lsa_name;
2272 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2273 return NT_STATUS_INVALID_HANDLE;
2275 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2276 return NT_STATUS_INVALID_HANDLE;
2279 /* check if the user has enough rights */
2282 * I don't know if it's the right one. not documented.
2284 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2285 return NT_STATUS_ACCESS_DENIED;
2287 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2289 description = get_privilege_dispname(r->in.name->string);
2291 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2292 return NT_STATUS_NO_SUCH_PRIVILEGE;
2295 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2297 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2299 return NT_STATUS_NO_MEMORY;
2302 init_lsa_StringLarge(lsa_name, description);
2304 *r->out.returned_language_id = r->in.language_id;
2305 *r->out.disp_name = lsa_name;
2307 return NT_STATUS_OK;
2310 /***************************************************************************
2312 ***************************************************************************/
2314 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2315 struct lsa_EnumAccounts *r)
2317 struct lsa_info *handle;
2318 struct dom_sid *sid_list;
2319 int i, j, num_entries;
2321 struct lsa_SidPtr *sids = NULL;
2323 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2324 return NT_STATUS_INVALID_HANDLE;
2326 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2327 return NT_STATUS_INVALID_HANDLE;
2330 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2331 return NT_STATUS_ACCESS_DENIED;
2336 /* The only way we can currently find out all the SIDs that have been
2337 privileged is to scan all privileges */
2339 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2340 if (!NT_STATUS_IS_OK(status)) {
2344 if (*r->in.resume_handle >= num_entries) {
2345 return NT_STATUS_NO_MORE_ENTRIES;
2348 if (num_entries - *r->in.resume_handle) {
2349 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
2350 num_entries - *r->in.resume_handle);
2352 talloc_free(sid_list);
2353 return NT_STATUS_NO_MEMORY;
2356 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2357 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2359 talloc_free(sid_list);
2360 return NT_STATUS_NO_MEMORY;
2365 talloc_free(sid_list);
2367 *r->out.resume_handle = num_entries;
2368 r->out.sids->num_sids = num_entries;
2369 r->out.sids->sids = sids;
2371 return NT_STATUS_OK;
2374 /***************************************************************************
2376 ***************************************************************************/
2378 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2379 struct lsa_GetUserName *r)
2381 const char *username, *domname;
2382 struct lsa_String *account_name = NULL;
2383 struct lsa_String *authority_name = NULL;
2385 if (r->in.account_name &&
2386 *r->in.account_name) {
2387 return NT_STATUS_INVALID_PARAMETER;
2390 if (r->in.authority_name &&
2391 *r->in.authority_name) {
2392 return NT_STATUS_INVALID_PARAMETER;
2395 if (p->session_info->guest) {
2397 * I'm 99% sure this is not the right place to do this,
2398 * global_sid_Anonymous should probably be put into the token
2399 * instead of the guest id -- vl
2401 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2402 &domname, &username, NULL)) {
2403 return NT_STATUS_NO_MEMORY;
2406 username = p->session_info->sanitized_username;
2407 domname = p->session_info->info3->base.domain.string;
2410 account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2411 if (!account_name) {
2412 return NT_STATUS_NO_MEMORY;
2414 init_lsa_String(account_name, username);
2416 if (r->out.authority_name) {
2417 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2418 if (!authority_name) {
2419 return NT_STATUS_NO_MEMORY;
2421 init_lsa_String(authority_name, domname);
2424 *r->out.account_name = account_name;
2425 if (r->out.authority_name) {
2426 *r->out.authority_name = authority_name;
2429 return NT_STATUS_OK;
2432 /***************************************************************************
2434 ***************************************************************************/
2436 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2437 struct lsa_CreateAccount *r)
2440 struct lsa_info *handle;
2441 uint32_t acc_granted;
2442 struct security_descriptor *psd;
2445 /* find the connection policy handle. */
2446 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2447 return NT_STATUS_INVALID_HANDLE;
2449 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2450 return NT_STATUS_INVALID_HANDLE;
2453 /* check if the user has enough rights */
2455 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2456 return NT_STATUS_ACCESS_DENIED;
2459 /* Work out max allowed. */
2460 map_max_allowed_access(p->session_info->security_token,
2461 &p->session_info->utok,
2462 &r->in.access_mask);
2464 /* map the generic bits to the lsa policy ones */
2465 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2467 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2468 &lsa_account_mapping,
2469 r->in.sid, LSA_POLICY_ALL_ACCESS);
2470 if (!NT_STATUS_IS_OK(status)) {
2474 status = access_check_object(psd, p->session_info->security_token,
2475 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2476 &acc_granted, "_lsa_CreateAccount");
2477 if (!NT_STATUS_IS_OK(status)) {
2481 if ( is_privileged_sid( r->in.sid ) )
2482 return NT_STATUS_OBJECT_NAME_COLLISION;
2484 status = create_lsa_policy_handle(p->mem_ctx, p,
2485 LSA_HANDLE_ACCOUNT_TYPE,
2490 r->out.acct_handle);
2491 if (!NT_STATUS_IS_OK(status)) {
2492 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2495 return privilege_create_account(r->in.sid);
2498 /***************************************************************************
2500 ***************************************************************************/
2502 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2503 struct lsa_OpenAccount *r)
2505 struct lsa_info *handle;
2506 struct security_descriptor *psd = NULL;
2508 uint32_t des_access = r->in.access_mask;
2509 uint32_t acc_granted;
2512 /* find the connection policy handle. */
2513 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2514 return NT_STATUS_INVALID_HANDLE;
2516 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2517 return NT_STATUS_INVALID_HANDLE;
2520 /* des_access is for the account here, not the policy
2521 * handle - so don't check against policy handle. */
2523 /* Work out max allowed. */
2524 map_max_allowed_access(p->session_info->security_token,
2525 &p->session_info->utok,
2528 /* map the generic bits to the lsa account ones */
2529 se_map_generic(&des_access, &lsa_account_mapping);
2531 /* get the generic lsa account SD until we store it */
2532 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2533 &lsa_account_mapping,
2534 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2535 if (!NT_STATUS_IS_OK(status)) {
2539 status = access_check_object(psd, p->session_info->security_token,
2540 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2541 &acc_granted, "_lsa_OpenAccount" );
2542 if (!NT_STATUS_IS_OK(status)) {
2546 /* TODO: Fis the parsing routine before reenabling this check! */
2548 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2549 return NT_STATUS_ACCESS_DENIED;
2552 status = create_lsa_policy_handle(p->mem_ctx, p,
2553 LSA_HANDLE_ACCOUNT_TYPE,
2558 r->out.acct_handle);
2559 if (!NT_STATUS_IS_OK(status)) {
2560 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2563 return NT_STATUS_OK;
2566 /***************************************************************************
2567 _lsa_EnumPrivsAccount
2568 For a given SID, enumerate all the privilege this account has.
2569 ***************************************************************************/
2571 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2572 struct lsa_EnumPrivsAccount *r)
2574 NTSTATUS status = NT_STATUS_OK;
2575 struct lsa_info *info=NULL;
2576 PRIVILEGE_SET *privileges;
2577 struct lsa_PrivilegeSet *priv_set = NULL;
2579 /* find the connection policy handle. */
2580 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2581 return NT_STATUS_INVALID_HANDLE;
2583 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2584 return NT_STATUS_INVALID_HANDLE;
2587 if (!(info->access & LSA_ACCOUNT_VIEW))
2588 return NT_STATUS_ACCESS_DENIED;
2590 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2591 if (!NT_STATUS_IS_OK(status)) {
2595 *r->out.privs = priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
2597 return NT_STATUS_NO_MEMORY;
2600 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2601 sid_string_dbg(&info->sid),
2602 privileges->count));
2604 priv_set->count = privileges->count;
2605 priv_set->unknown = 0;
2606 priv_set->set = talloc_move(priv_set, &privileges->set);
2611 /***************************************************************************
2612 _lsa_GetSystemAccessAccount
2613 ***************************************************************************/
2615 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2616 struct lsa_GetSystemAccessAccount *r)
2619 struct lsa_info *info = NULL;
2620 struct lsa_EnumPrivsAccount e;
2621 struct lsa_PrivilegeSet *privset;
2623 /* find the connection policy handle. */
2625 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2626 return NT_STATUS_INVALID_HANDLE;
2628 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2629 return NT_STATUS_INVALID_HANDLE;
2632 if (!(info->access & LSA_ACCOUNT_VIEW))
2633 return NT_STATUS_ACCESS_DENIED;
2635 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2637 return NT_STATUS_NO_MEMORY;
2640 e.in.handle = r->in.handle;
2641 e.out.privs = &privset;
2643 status = _lsa_EnumPrivsAccount(p, &e);
2644 if (!NT_STATUS_IS_OK(status)) {
2645 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2646 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2647 nt_errstr(status)));
2651 /* Samba4 would iterate over the privset to merge the policy mode bits,
2652 * not sure samba3 can do the same here, so just return what we did in
2656 0x01 -> Log on locally
2657 0x02 -> Access this computer from network
2658 0x04 -> Log on as a batch job
2659 0x10 -> Log on as a service
2661 they can be ORed together
2664 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2665 LSA_POLICY_MODE_NETWORK;
2667 return NT_STATUS_OK;
2670 /***************************************************************************
2671 update the systemaccount information
2672 ***************************************************************************/
2674 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2675 struct lsa_SetSystemAccessAccount *r)
2677 struct lsa_info *info=NULL;
2680 /* find the connection policy handle. */
2681 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2682 return NT_STATUS_INVALID_HANDLE;
2684 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2685 return NT_STATUS_INVALID_HANDLE;
2688 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2689 return NT_STATUS_ACCESS_DENIED;
2692 if (!pdb_getgrsid(&map, info->sid))
2693 return NT_STATUS_NO_SUCH_GROUP;
2695 return pdb_update_group_mapping_entry(&map);
2698 /***************************************************************************
2699 _lsa_AddPrivilegesToAccount
2700 For a given SID, add some privileges.
2701 ***************************************************************************/
2703 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
2704 struct lsa_AddPrivilegesToAccount *r)
2706 struct lsa_info *info = NULL;
2707 struct lsa_PrivilegeSet *set = NULL;
2709 /* find the connection policy handle. */
2710 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2711 return NT_STATUS_INVALID_HANDLE;
2713 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2714 return NT_STATUS_INVALID_HANDLE;
2717 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2718 return NT_STATUS_ACCESS_DENIED;
2723 if ( !grant_privilege_set( &info->sid, set ) ) {
2724 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2725 sid_string_dbg(&info->sid) ));
2726 return NT_STATUS_NO_SUCH_PRIVILEGE;
2729 return NT_STATUS_OK;
2732 /***************************************************************************
2733 _lsa_RemovePrivilegesFromAccount
2734 For a given SID, remove some privileges.
2735 ***************************************************************************/
2737 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2738 struct lsa_RemovePrivilegesFromAccount *r)
2740 struct lsa_info *info = NULL;
2741 struct lsa_PrivilegeSet *set = NULL;
2743 /* find the connection policy handle. */
2744 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2745 return NT_STATUS_INVALID_HANDLE;
2747 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2748 return NT_STATUS_INVALID_HANDLE;
2751 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2752 return NT_STATUS_ACCESS_DENIED;
2757 if ( !revoke_privilege_set( &info->sid, set) ) {
2758 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2759 sid_string_dbg(&info->sid) ));
2760 return NT_STATUS_NO_SUCH_PRIVILEGE;
2763 return NT_STATUS_OK;
2766 /***************************************************************************
2768 ***************************************************************************/
2770 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2771 struct lsa_LookupPrivName *r)
2773 struct lsa_info *info = NULL;
2775 struct lsa_StringLarge *lsa_name;
2777 /* find the connection policy handle. */
2778 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2779 return NT_STATUS_INVALID_HANDLE;
2782 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2783 return NT_STATUS_INVALID_HANDLE;
2786 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2787 return NT_STATUS_ACCESS_DENIED;
2790 if (r->in.luid->high != 0) {
2791 return NT_STATUS_NO_SUCH_PRIVILEGE;
2794 name = sec_privilege_name(r->in.luid->low);
2796 return NT_STATUS_NO_SUCH_PRIVILEGE;
2799 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2801 return NT_STATUS_NO_MEMORY;
2804 lsa_name->string = talloc_strdup(lsa_name, name);
2805 if (!lsa_name->string) {
2806 TALLOC_FREE(lsa_name);
2807 return NT_STATUS_NO_MEMORY;
2810 *r->out.name = lsa_name;
2812 return NT_STATUS_OK;
2815 /***************************************************************************
2817 ***************************************************************************/
2819 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
2820 struct lsa_QuerySecurity *r)
2822 struct lsa_info *handle=NULL;
2823 struct security_descriptor *psd = NULL;
2827 /* find the connection policy handle. */
2828 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2829 return NT_STATUS_INVALID_HANDLE;
2831 switch (handle->type) {
2832 case LSA_HANDLE_POLICY_TYPE:
2833 case LSA_HANDLE_ACCOUNT_TYPE:
2834 case LSA_HANDLE_TRUST_TYPE:
2836 sd_size = ndr_size_security_descriptor(psd, 0);
2837 status = NT_STATUS_OK;
2840 status = NT_STATUS_INVALID_HANDLE;
2844 if (!NT_STATUS_IS_OK(status)) {
2848 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2849 if (!*r->out.sdbuf) {
2850 return NT_STATUS_NO_MEMORY;
2856 /***************************************************************************
2857 _lsa_AddAccountRights
2858 ***************************************************************************/
2860 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
2861 struct lsa_AddAccountRights *r)
2863 struct lsa_info *info = NULL;
2865 uint32_t acc_granted = 0;
2866 struct security_descriptor *psd = NULL;
2871 /* find the connection policy handle. */
2872 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2873 return NT_STATUS_INVALID_HANDLE;
2875 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2876 return NT_STATUS_INVALID_HANDLE;
2879 /* get the generic lsa account SD for this SID until we store it */
2880 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2881 &lsa_account_mapping,
2882 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2883 if (!NT_STATUS_IS_OK(status)) {
2888 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2889 * on the policy handle. If it does, ask for
2890 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2891 * on the account sid. We don't check here so just use the latter. JRA.
2894 status = access_check_object(psd, p->session_info->security_token,
2895 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2896 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2897 &acc_granted, "_lsa_AddAccountRights" );
2898 if (!NT_STATUS_IS_OK(status)) {
2902 /* according to an NT4 PDC, you can add privileges to SIDs even without
2903 call_lsa_create_account() first. And you can use any arbitrary SID. */
2905 sid_copy( &sid, r->in.sid );
2907 for ( i=0; i < r->in.rights->count; i++ ) {
2909 const char *privname = r->in.rights->names[i].string;
2911 /* only try to add non-null strings */
2916 if ( !grant_privilege_by_name( &sid, privname ) ) {
2917 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2919 return NT_STATUS_NO_SUCH_PRIVILEGE;
2923 return NT_STATUS_OK;
2926 /***************************************************************************
2927 _lsa_RemoveAccountRights
2928 ***************************************************************************/
2930 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
2931 struct lsa_RemoveAccountRights *r)
2933 struct lsa_info *info = NULL;
2935 struct security_descriptor *psd = NULL;
2938 const char *privname = NULL;
2939 uint32_t acc_granted = 0;
2942 /* find the connection policy handle. */
2943 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2944 return NT_STATUS_INVALID_HANDLE;
2946 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2947 return NT_STATUS_INVALID_HANDLE;
2950 /* get the generic lsa account SD for this SID until we store it */
2951 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2952 &lsa_account_mapping,
2953 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2954 if (!NT_STATUS_IS_OK(status)) {
2959 * From the MS DOCs. We need
2960 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2961 * and DELETE on the account sid.
2964 status = access_check_object(psd, p->session_info->security_token,
2965 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2966 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2967 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
2968 &acc_granted, "_lsa_RemoveAccountRights");
2969 if (!NT_STATUS_IS_OK(status)) {
2973 sid_copy( &sid, r->in.sid );
2975 if ( r->in.remove_all ) {
2976 if ( !revoke_all_privileges( &sid ) )
2977 return NT_STATUS_ACCESS_DENIED;
2979 return NT_STATUS_OK;
2982 for ( i=0; i < r->in.rights->count; i++ ) {
2984 privname = r->in.rights->names[i].string;
2986 /* only try to add non-null strings */
2991 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2992 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2994 return NT_STATUS_NO_SUCH_PRIVILEGE;
2998 return NT_STATUS_OK;
3001 /*******************************************************************
3002 ********************************************************************/
3004 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3005 struct lsa_RightSet *r,
3006 PRIVILEGE_SET *privileges)
3009 const char *privname;
3010 const char **privname_array = NULL;
3013 for (i=0; i<privileges->count; i++) {
3014 if (privileges->set[i].luid.high) {
3017 privname = sec_privilege_name(privileges->set[i].luid.low);
3019 if (!add_string_to_array(mem_ctx, privname,
3020 &privname_array, &num_priv)) {
3021 return NT_STATUS_NO_MEMORY;
3028 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
3031 return NT_STATUS_NO_MEMORY;
3034 for (i=0; i<num_priv; i++) {
3035 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3038 r->count = num_priv;
3041 return NT_STATUS_OK;
3044 /***************************************************************************
3045 _lsa_EnumAccountRights
3046 ***************************************************************************/
3048 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3049 struct lsa_EnumAccountRights *r)
3052 struct lsa_info *info = NULL;
3053 PRIVILEGE_SET *privileges;
3055 /* find the connection policy handle. */
3057 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3058 return NT_STATUS_INVALID_HANDLE;
3060 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3061 return NT_STATUS_INVALID_HANDLE;
3064 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3065 return NT_STATUS_ACCESS_DENIED;
3068 /* according to an NT4 PDC, you can add privileges to SIDs even without
3069 call_lsa_create_account() first. And you can use any arbitrary SID. */
3071 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3072 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3073 * the lsa database */
3075 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3076 if (!NT_STATUS_IS_OK(status)) {
3080 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3081 sid_string_dbg(r->in.sid), privileges->count));
3083 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3088 /***************************************************************************
3089 _lsa_LookupPrivValue
3090 ***************************************************************************/
3092 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3093 struct lsa_LookupPrivValue *r)
3095 struct lsa_info *info = NULL;
3096 const char *name = NULL;
3098 /* find the connection policy handle. */
3100 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3101 return NT_STATUS_INVALID_HANDLE;
3103 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3104 return NT_STATUS_INVALID_HANDLE;
3107 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3108 return NT_STATUS_ACCESS_DENIED;
3110 name = r->in.name->string;
3112 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3114 r->out.luid->low = sec_privilege_id(name);
3115 r->out.luid->high = 0;
3116 if (r->out.luid->low == SEC_PRIV_INVALID) {
3117 return NT_STATUS_NO_SUCH_PRIVILEGE;
3119 return NT_STATUS_OK;
3122 /***************************************************************************
3123 _lsa_EnumAccountsWithUserRight
3124 ***************************************************************************/
3126 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3127 struct lsa_EnumAccountsWithUserRight *r)
3130 struct lsa_info *info = NULL;
3131 struct dom_sid *sids = NULL;
3134 enum sec_privilege privilege;
3136 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3137 return NT_STATUS_INVALID_HANDLE;
3140 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3141 return NT_STATUS_INVALID_HANDLE;
3144 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3145 return NT_STATUS_ACCESS_DENIED;
3148 if (!r->in.name || !r->in.name->string) {
3149 return NT_STATUS_NO_SUCH_PRIVILEGE;
3152 privilege = sec_privilege_id(r->in.name->string);
3153 if (privilege == SEC_PRIV_INVALID) {
3154 return NT_STATUS_NO_SUCH_PRIVILEGE;
3157 status = privilege_enum_sids(privilege, p->mem_ctx,
3159 if (!NT_STATUS_IS_OK(status)) {
3163 r->out.sids->num_sids = num_sids;
3164 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3165 r->out.sids->num_sids);
3167 for (i=0; i < r->out.sids->num_sids; i++) {
3168 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3170 if (!r->out.sids->sids[i].sid) {
3171 TALLOC_FREE(r->out.sids->sids);
3172 r->out.sids->num_sids = 0;
3173 return NT_STATUS_NO_MEMORY;
3177 return NT_STATUS_OK;
3180 /***************************************************************************
3182 ***************************************************************************/
3184 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3185 struct lsa_Delete *r)
3187 return NT_STATUS_NOT_SUPPORTED;
3191 * From here on the server routines are just dummy ones to make smbd link with
3192 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3193 * pulling the server stubs across one by one.
3196 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3198 p->rng_fault_state = True;
3199 return NT_STATUS_NOT_IMPLEMENTED;
3202 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3203 struct lsa_ChangePassword *r)
3205 p->rng_fault_state = True;
3206 return NT_STATUS_NOT_IMPLEMENTED;
3209 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3211 p->rng_fault_state = True;
3212 return NT_STATUS_NOT_IMPLEMENTED;
3215 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3217 p->rng_fault_state = True;
3218 return NT_STATUS_NOT_IMPLEMENTED;
3221 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3222 struct lsa_GetQuotasForAccount *r)
3224 p->rng_fault_state = True;
3225 return NT_STATUS_NOT_IMPLEMENTED;
3228 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3229 struct lsa_SetQuotasForAccount *r)
3231 p->rng_fault_state = True;
3232 return NT_STATUS_NOT_IMPLEMENTED;
3235 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3236 struct lsa_SetInformationTrustedDomain *r)
3238 p->rng_fault_state = True;
3239 return NT_STATUS_NOT_IMPLEMENTED;
3242 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
3244 p->rng_fault_state = True;
3245 return NT_STATUS_NOT_IMPLEMENTED;
3248 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3249 struct lsa_SetTrustedDomainInfo *r)
3251 p->rng_fault_state = True;
3252 return NT_STATUS_NOT_IMPLEMENTED;
3255 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3256 struct lsa_StorePrivateData *r)
3258 p->rng_fault_state = True;
3259 return NT_STATUS_NOT_IMPLEMENTED;
3262 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3263 struct lsa_RetrievePrivateData *r)
3265 p->rng_fault_state = True;
3266 return NT_STATUS_NOT_IMPLEMENTED;
3269 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3270 struct lsa_SetInfoPolicy2 *r)
3272 p->rng_fault_state = True;
3273 return NT_STATUS_NOT_IMPLEMENTED;
3276 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3277 struct lsa_SetTrustedDomainInfoByName *r)
3279 p->rng_fault_state = True;
3280 return NT_STATUS_NOT_IMPLEMENTED;
3283 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3284 struct lsa_EnumTrustedDomainsEx *r)
3286 struct lsa_info *info;
3288 struct pdb_trusted_domain **domains;
3289 struct lsa_TrustDomainInfoInfoEx *entries;
3293 /* bail out early if pdb backend is not capable of ex trusted domains,
3294 * if we dont do that, the client might not call
3295 * _lsa_EnumTrustedDomains() afterwards - gd */
3297 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3298 p->rng_fault_state = True;
3299 return NT_STATUS_NOT_IMPLEMENTED;
3302 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3303 return NT_STATUS_INVALID_HANDLE;
3305 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3306 return NT_STATUS_INVALID_HANDLE;
3309 /* check if the user has enough rights */
3310 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3311 return NT_STATUS_ACCESS_DENIED;
3314 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3317 if (!NT_STATUS_IS_OK(nt_status)) {
3321 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3324 return NT_STATUS_NO_MEMORY;
3327 for (i=0; i<count; i++) {
3328 init_lsa_StringLarge(&entries[i].netbios_name,
3329 domains[i]->netbios_name);
3330 entries[i].sid = &domains[i]->security_identifier;
3333 if (*r->in.resume_handle >= count) {
3334 *r->out.resume_handle = -1;
3335 TALLOC_FREE(entries);
3336 return NT_STATUS_NO_MORE_ENTRIES;
3339 /* return the rest, limit by max_size. Note that we
3340 use the w2k3 element size value of 60 */
3341 r->out.domains->count = count - *r->in.resume_handle;
3342 r->out.domains->count = MIN(r->out.domains->count,
3343 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3345 r->out.domains->domains = entries + *r->in.resume_handle;
3347 if (r->out.domains->count < count - *r->in.resume_handle) {
3348 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3349 return STATUS_MORE_ENTRIES;
3352 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3353 * always be larger than the previous input resume handle, in
3354 * particular when hitting the last query it is vital to set the
3355 * resume handle correctly to avoid infinite client loops, as
3356 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3357 * status is NT_STATUS_OK - gd */
3359 *r->out.resume_handle = (uint32_t)-1;
3361 return NT_STATUS_OK;
3364 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3365 struct lsa_QueryDomainInformationPolicy *r)
3367 p->rng_fault_state = True;
3368 return NT_STATUS_NOT_IMPLEMENTED;
3371 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3372 struct lsa_SetDomainInformationPolicy *r)
3374 p->rng_fault_state = True;
3375 return NT_STATUS_NOT_IMPLEMENTED;
3378 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3380 p->rng_fault_state = True;
3381 return NT_STATUS_NOT_IMPLEMENTED;
3384 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3386 p->rng_fault_state = True;
3387 return NT_STATUS_NOT_IMPLEMENTED;
3390 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3392 p->rng_fault_state = True;
3393 return NT_STATUS_NOT_IMPLEMENTED;
3396 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3398 p->rng_fault_state = True;
3399 return NT_STATUS_NOT_IMPLEMENTED;
3402 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3403 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3405 p->rng_fault_state = True;
3406 return NT_STATUS_NOT_IMPLEMENTED;
3409 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3410 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3412 p->rng_fault_state = True;
3413 return NT_STATUS_NOT_IMPLEMENTED;
3416 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3418 p->rng_fault_state = True;
3419 return NT_STATUS_NOT_IMPLEMENTED;
3422 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3423 struct lsa_CREDRGETTARGETINFO *r)
3425 p->rng_fault_state = True;
3426 return NT_STATUS_NOT_IMPLEMENTED;
3429 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3430 struct lsa_CREDRPROFILELOADED *r)
3432 p->rng_fault_state = True;
3433 return NT_STATUS_NOT_IMPLEMENTED;
3436 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3437 struct lsa_CREDRGETSESSIONTYPES *r)
3439 p->rng_fault_state = True;
3440 return NT_STATUS_NOT_IMPLEMENTED;
3443 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3444 struct lsa_LSARREGISTERAUDITEVENT *r)
3446 p->rng_fault_state = True;
3447 return NT_STATUS_NOT_IMPLEMENTED;
3450 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3451 struct lsa_LSARGENAUDITEVENT *r)
3453 p->rng_fault_state = True;
3454 return NT_STATUS_NOT_IMPLEMENTED;
3457 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3458 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3460 p->rng_fault_state = True;
3461 return NT_STATUS_NOT_IMPLEMENTED;
3464 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3465 struct lsa_lsaRQueryForestTrustInformation *r)
3467 p->rng_fault_state = True;
3468 return NT_STATUS_NOT_IMPLEMENTED;
3471 #define DNS_CMP_MATCH 0
3472 #define DNS_CMP_FIRST_IS_CHILD 1
3473 #define DNS_CMP_SECOND_IS_CHILD 2
3474 #define DNS_CMP_NO_MATCH 3
3476 /* this function assumes names are well formed DNS names.
3477 * it doesn't validate them */
3478 static int dns_cmp(const char *s1, size_t l1,
3479 const char *s2, size_t l2)
3481 const char *p1, *p2;
3486 if (StrCaseCmp(s1, s2) == 0) {
3487 return DNS_CMP_MATCH;
3489 return DNS_CMP_NO_MATCH;
3497 cret = DNS_CMP_FIRST_IS_CHILD;
3503 cret = DNS_CMP_SECOND_IS_CHILD;
3506 if (p1[t1 - t2 - 1] != '.') {
3507 return DNS_CMP_NO_MATCH;
3510 if (StrCaseCmp(&p1[t1 - t2], p2) == 0) {
3514 return DNS_CMP_NO_MATCH;
3517 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3518 struct lsa_ForestTrustInformation *lfti,
3519 struct ForestTrustInfo *fti)
3521 struct lsa_ForestTrustRecord *lrec;
3522 struct ForestTrustInfoRecord *rec;
3523 struct lsa_StringLarge *tln;
3524 struct lsa_ForestTrustDomainInfo *info;
3528 fti->count = lfti->count;
3529 fti->records = talloc_array(mem_ctx,
3530 struct ForestTrustInfoRecordArmor,
3532 if (!fti->records) {
3533 return NT_STATUS_NO_MEMORY;
3535 for (i = 0; i < fti->count; i++) {
3536 lrec = lfti->entries[i];
3537 rec = &fti->records[i].record;
3539 rec->flags = lrec->flags;
3540 rec->timestamp = lrec->time;
3541 rec->type = lrec->type;
3543 switch (lrec->type) {
3544 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3545 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3546 tln = &lrec->forest_trust_data.top_level_name;
3547 rec->data.name.string =
3548 talloc_strdup(mem_ctx, tln->string);
3549 if (!rec->data.name.string) {
3550 return NT_STATUS_NO_MEMORY;
3552 rec->data.name.size = strlen(rec->data.name.string);
3554 case LSA_FOREST_TRUST_DOMAIN_INFO:
3555 info = &lrec->forest_trust_data.domain_info;
3556 rec->data.info.sid = *info->domain_sid;
3557 rec->data.info.dns_name.string =
3558 talloc_strdup(mem_ctx,
3559 info->dns_domain_name.string);
3560 if (!rec->data.info.dns_name.string) {
3561 return NT_STATUS_NO_MEMORY;
3563 rec->data.info.dns_name.size =
3564 strlen(rec->data.info.dns_name.string);
3565 rec->data.info.netbios_name.string =
3566 talloc_strdup(mem_ctx,
3567 info->netbios_domain_name.string);
3568 if (!rec->data.info.netbios_name.string) {
3569 return NT_STATUS_NO_MEMORY;
3571 rec->data.info.netbios_name.size =
3572 strlen(rec->data.info.netbios_name.string);
3575 return NT_STATUS_INVALID_DOMAIN_STATE;
3579 return NT_STATUS_OK;
3582 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3583 uint32_t index, uint32_t collision_type,
3584 uint32_t conflict_type, const char *tdo_name);
3586 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
3587 const char *tdo_name,
3588 struct ForestTrustInfo *tdo_fti,
3589 struct ForestTrustInfo *new_fti,
3590 struct lsa_ForestTrustCollisionInfo *c_info)
3592 struct ForestTrustInfoRecord *nrec;
3593 struct ForestTrustInfoRecord *trec;
3594 const char *dns_name;
3595 const char *nb_name = NULL;
3596 struct dom_sid *sid = NULL;
3597 const char *tname = NULL;
3602 uint32_t new_fti_idx;
3604 /* use always TDO type, until we understand when Xref can be used */
3605 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
3610 bool ex_rule = false;
3613 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
3615 nrec = &new_fti->records[new_fti_idx].record;
3617 tln_conflict = false;
3618 sid_conflict = false;
3619 nb_conflict = false;
3622 switch (nrec->type) {
3623 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3624 /* exclusions do not conflict by definition */
3627 case FOREST_TRUST_TOP_LEVEL_NAME:
3628 dns_name = nrec->data.name.string;
3629 dns_len = nrec->data.name.size;
3632 case LSA_FOREST_TRUST_DOMAIN_INFO:
3633 dns_name = nrec->data.info.dns_name.string;
3634 dns_len = nrec->data.info.dns_name.size;
3635 nb_name = nrec->data.info.netbios_name.string;
3636 nb_len = nrec->data.info.netbios_name.size;
3637 sid = &nrec->data.info.sid;
3641 if (!dns_name) continue;
3643 /* check if this is already taken and not excluded */
3644 for (i = 0; i < tdo_fti->count; i++) {
3645 trec = &tdo_fti->records[i].record;
3647 switch (trec->type) {
3648 case FOREST_TRUST_TOP_LEVEL_NAME:
3650 tname = trec->data.name.string;
3651 tlen = trec->data.name.size;
3653 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
3655 tname = trec->data.name.string;
3656 tlen = trec->data.name.size;
3658 case FOREST_TRUST_DOMAIN_INFO:
3660 tname = trec->data.info.dns_name.string;
3661 tlen = trec->data.info.dns_name.size;
3663 return NT_STATUS_INVALID_PARAMETER;
3665 ret = dns_cmp(dns_name, dns_len, tname, tlen);
3668 /* if it matches exclusion,
3669 * it doesn't conflict */
3675 case DNS_CMP_FIRST_IS_CHILD:
3676 case DNS_CMP_SECOND_IS_CHILD:
3677 tln_conflict = true;
3683 /* explicit exclusion, no dns name conflict here */
3685 tln_conflict = false;
3688 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
3692 /* also test for domain info */
3693 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
3694 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
3695 sid_conflict = true;
3697 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
3698 StrCaseCmp(trec->data.info.netbios_name.string,
3705 nt_status = add_collision(c_info, new_fti_idx,
3707 LSA_TLN_DISABLED_CONFLICT,
3711 nt_status = add_collision(c_info, new_fti_idx,
3713 LSA_SID_DISABLED_CONFLICT,
3717 nt_status = add_collision(c_info, new_fti_idx,
3719 LSA_NB_DISABLED_CONFLICT,
3724 return NT_STATUS_OK;
3727 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3728 uint32_t idx, uint32_t collision_type,
3729 uint32_t conflict_type, const char *tdo_name)
3731 struct lsa_ForestTrustCollisionRecord **es;
3732 uint32_t i = c_info->count;
3734 es = talloc_realloc(c_info, c_info->entries,
3735 struct lsa_ForestTrustCollisionRecord *, i + 1);
3737 return NT_STATUS_NO_MEMORY;
3739 c_info->entries = es;
3740 c_info->count = i + 1;
3742 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
3744 return NT_STATUS_NO_MEMORY;
3748 es[i]->type = collision_type;
3749 es[i]->flags.flags = conflict_type;
3750 es[i]->name.string = talloc_strdup(es[i], tdo_name);
3751 if (!es[i]->name.string) {
3752 return NT_STATUS_NO_MEMORY;
3754 es[i]->name.size = strlen(es[i]->name.string);
3756 return NT_STATUS_OK;
3759 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3760 struct pdb_trusted_domain *td,
3761 struct ForestTrustInfo *info)
3763 enum ndr_err_code ndr_err;
3765 if (td->trust_forest_trust_info.length == 0 ||
3766 td->trust_forest_trust_info.data == NULL) {
3767 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3769 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
3771 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3772 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3773 return NT_STATUS_INVALID_DOMAIN_STATE;
3776 return NT_STATUS_OK;
3779 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
3780 struct ForestTrustInfo *fti)
3782 struct ForestTrustDataDomainInfo *info;
3783 struct ForestTrustInfoRecord *rec;
3787 fti->records = talloc_array(fti,
3788 struct ForestTrustInfoRecordArmor, 2);
3789 if (!fti->records) {
3790 return NT_STATUS_NO_MEMORY;
3794 rec = &fti->records[0].record;
3798 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3800 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
3801 if (!rec->data.name.string) {
3802 return NT_STATUS_NO_MEMORY;
3804 rec->data.name.size = strlen(rec->data.name.string);
3807 rec = &fti->records[1].record;
3811 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3813 info = &rec->data.info;
3815 info->sid = dom_info->sid;
3816 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
3817 if (!info->dns_name.string) {
3818 return NT_STATUS_NO_MEMORY;
3820 info->dns_name.size = strlen(info->dns_name.string);
3821 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
3822 if (!info->netbios_name.string) {
3823 return NT_STATUS_NO_MEMORY;
3825 info->netbios_name.size = strlen(info->netbios_name.string);
3827 return NT_STATUS_OK;
3830 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
3831 struct lsa_lsaRSetForestTrustInformation *r)
3836 struct lsa_info *handle;
3837 uint32_t num_domains;
3838 struct pdb_trusted_domain **domains;
3839 struct ForestTrustInfo *nfti;
3840 struct ForestTrustInfo *fti;
3841 struct lsa_ForestTrustCollisionInfo *c_info;
3842 struct pdb_domain_info *dom_info;
3843 enum ndr_err_code ndr_err;
3846 return NT_STATUS_NOT_SUPPORTED;
3849 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
3850 return NT_STATUS_INVALID_HANDLE;
3853 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
3854 return NT_STATUS_INVALID_HANDLE;
3857 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
3858 return NT_STATUS_ACCESS_DENIED;
3861 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
3862 if (!NT_STATUS_IS_OK(status)) {
3865 if (num_domains == 0) {
3866 return NT_STATUS_NO_SUCH_DOMAIN;
3869 for (i = 0; i < num_domains; i++) {
3870 if (domains[i]->domain_name == NULL) {
3871 return NT_STATUS_INVALID_DOMAIN_STATE;
3873 if (StrCaseCmp(domains[i]->domain_name,
3874 r->in.trusted_domain_name->string) == 0) {
3878 if (i >= num_domains) {
3879 return NT_STATUS_NO_SUCH_DOMAIN;
3882 if (!(domains[i]->trust_attributes &
3883 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
3884 return NT_STATUS_INVALID_PARAMETER;
3887 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
3888 return NT_STATUS_INVALID_PARAMETER;
3891 /* The following section until COPY_END is a copy from
3892 * source4/rpmc_server/lsa/scesrc_lsa.c */
3893 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
3895 return NT_STATUS_NO_MEMORY;
3898 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
3899 if (!NT_STATUS_IS_OK(status)) {
3903 c_info = talloc_zero(r->out.collision_info,
3904 struct lsa_ForestTrustCollisionInfo);
3906 return NT_STATUS_NO_MEMORY;
3909 /* first check own info, then other domains */
3910 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3912 return NT_STATUS_NO_MEMORY;
3915 dom_info = pdb_get_domain_info(p->mem_ctx);
3917 status = own_ft_info(dom_info, fti);
3918 if (!NT_STATUS_IS_OK(status)) {
3922 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
3923 if (!NT_STATUS_IS_OK(status)) {
3927 for (j = 0; j < num_domains; j++) {
3928 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3930 return NT_STATUS_NO_MEMORY;
3933 status = get_ft_info(p->mem_ctx, domains[j], fti);
3934 if (!NT_STATUS_IS_OK(status)) {
3935 if (NT_STATUS_EQUAL(status,
3936 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3942 if (domains[j]->domain_name == NULL) {
3943 return NT_STATUS_INVALID_DOMAIN_STATE;
3946 status = check_ft_info(c_info, domains[j]->domain_name,
3948 if (!NT_STATUS_IS_OK(status)) {
3953 *r->out.collision_info = c_info;
3955 if (r->in.check_only != 0) {
3956 return NT_STATUS_OK;
3961 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
3963 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
3964 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3965 return NT_STATUS_INVALID_PARAMETER;
3968 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
3969 if (!NT_STATUS_IS_OK(status)) {
3973 return NT_STATUS_OK;
3976 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
3977 struct lsa_CREDRRENAME *r)
3979 p->rng_fault_state = True;
3980 return NT_STATUS_NOT_IMPLEMENTED;
3983 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
3984 struct lsa_LSAROPENPOLICYSCE *r)
3986 p->rng_fault_state = True;
3987 return NT_STATUS_NOT_IMPLEMENTED;
3990 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
3991 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3993 p->rng_fault_state = True;
3994 return NT_STATUS_NOT_IMPLEMENTED;
3997 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
3998 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4000 p->rng_fault_state = True;
4001 return NT_STATUS_NOT_IMPLEMENTED;
4004 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4005 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4007 p->rng_fault_state = True;
4008 return NT_STATUS_NOT_IMPLEMENTED;