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"
49 #define DBGC_CLASS DBGC_RPC_SRV
51 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
53 enum lsa_handle_type {
54 LSA_HANDLE_POLICY_TYPE = 1,
55 LSA_HANDLE_ACCOUNT_TYPE = 2,
56 LSA_HANDLE_TRUST_TYPE = 3};
62 enum lsa_handle_type type;
63 struct security_descriptor *sd;
66 const struct generic_mapping lsa_account_mapping = {
70 LSA_ACCOUNT_ALL_ACCESS
73 const struct generic_mapping lsa_policy_mapping = {
80 const struct generic_mapping lsa_secret_mapping = {
87 const struct generic_mapping lsa_trusted_domain_mapping = {
88 LSA_TRUSTED_DOMAIN_READ,
89 LSA_TRUSTED_DOMAIN_WRITE,
90 LSA_TRUSTED_DOMAIN_EXECUTE,
91 LSA_TRUSTED_DOMAIN_ALL_ACCESS
94 /***************************************************************************
95 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
96 ***************************************************************************/
98 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
99 struct lsa_RefDomainList *ref,
100 const char *dom_name,
101 struct dom_sid *dom_sid)
105 if (dom_name != NULL) {
106 for (num = 0; num < ref->count; num++) {
107 if (dom_sid_equal(dom_sid, ref->domains[num].sid)) {
115 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
116 /* index not found, already at maximum domain limit */
120 ref->count = num + 1;
121 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
123 ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains,
124 struct lsa_DomainInfo, ref->count);
129 ZERO_STRUCT(ref->domains[num]);
131 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
132 ref->domains[num].sid = dom_sid_dup(mem_ctx, dom_sid);
133 if (!ref->domains[num].sid) {
141 /***************************************************************************
142 initialize a lsa_DomainInfo structure.
143 ***************************************************************************/
145 static void init_dom_query_3(struct lsa_DomainInfo *r,
149 init_lsa_StringLarge(&r->name, name);
153 /***************************************************************************
154 initialize a lsa_DomainInfo structure.
155 ***************************************************************************/
157 static void init_dom_query_5(struct lsa_DomainInfo *r,
161 init_lsa_StringLarge(&r->name, name);
165 /***************************************************************************
166 lookup_lsa_rids. Must be called as root for lookup_name to work.
167 ***************************************************************************/
169 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
170 struct lsa_RefDomainList *ref,
171 struct lsa_TranslatedSid *prid,
172 uint32_t num_entries,
173 struct lsa_String *name,
175 uint32_t *pmapped_count)
177 uint32 mapped_count, i;
179 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
184 for (i = 0; i < num_entries; i++) {
188 const char *full_name;
190 enum lsa_SidType type;
192 /* Split name into domain and user component */
194 /* follow w2k8 behavior and return the builtin domain when no
195 * input has been passed in */
197 if (name[i].string) {
198 full_name = name[i].string;
200 full_name = "BUILTIN";
203 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
205 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
207 type = SID_NAME_UNKNOWN;
212 case SID_NAME_DOM_GRP:
213 case SID_NAME_DOMAIN:
215 case SID_NAME_WKN_GRP:
216 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
217 /* Leave these unchanged */
220 /* Don't hand out anything but the list above */
221 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
222 type = SID_NAME_UNKNOWN;
229 if (type != SID_NAME_UNKNOWN) {
230 if (type == SID_NAME_DOMAIN) {
233 sid_split_rid(&sid, &rid);
235 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
239 prid[i].sid_type = type;
241 prid[i].sid_index = dom_idx;
244 *pmapped_count = mapped_count;
248 /***************************************************************************
249 lookup_lsa_sids. Must be called as root for lookup_name to work.
250 ***************************************************************************/
252 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
253 struct lsa_RefDomainList *ref,
254 struct lsa_TranslatedSid3 *trans_sids,
255 uint32_t num_entries,
256 struct lsa_String *name,
258 uint32 *pmapped_count)
260 uint32 mapped_count, i;
262 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
267 for (i = 0; i < num_entries; i++) {
271 const char *full_name;
273 enum lsa_SidType type;
277 /* Split name into domain and user component */
279 full_name = name[i].string;
280 if (full_name == NULL) {
281 return NT_STATUS_NO_MEMORY;
284 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
286 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
288 type = SID_NAME_UNKNOWN;
293 case SID_NAME_DOM_GRP:
294 case SID_NAME_DOMAIN:
296 case SID_NAME_WKN_GRP:
297 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
298 /* Leave these unchanged */
301 /* Don't hand out anything but the list above */
302 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
303 type = SID_NAME_UNKNOWN;
310 if (type != SID_NAME_UNKNOWN) {
311 struct dom_sid domain_sid;
312 sid_copy(&domain_sid, &sid);
313 sid_split_rid(&domain_sid, &rid);
314 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
318 /* Initialize the lsa_TranslatedSid3 return. */
319 trans_sids[i].sid_type = type;
320 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
321 trans_sids[i].sid_index = dom_idx;
324 *pmapped_count = mapped_count;
328 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
329 const struct generic_mapping *map,
330 struct dom_sid *sid, uint32_t sid_access)
332 struct dom_sid adm_sid;
333 struct security_ace ace[5];
336 struct security_acl *psa = NULL;
338 /* READ|EXECUTE access for Everyone */
340 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
341 map->generic_execute | map->generic_read, 0);
343 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
345 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
346 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
347 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
348 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
350 /* Add Full Access for Domain Admins */
351 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
352 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
353 map->generic_all, 0);
355 /* If we have a sid, give it some special access */
358 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
362 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
363 return NT_STATUS_NO_MEMORY;
365 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
366 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
367 psa, sd_size)) == NULL)
368 return NT_STATUS_NO_MEMORY;
373 /***************************************************************************
374 ***************************************************************************/
376 static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
377 struct pipes_struct *p,
378 enum lsa_handle_type type,
379 uint32_t acc_granted,
382 const struct security_descriptor *sd,
383 struct policy_handle *handle)
385 struct lsa_info *info;
387 ZERO_STRUCTP(handle);
389 info = talloc_zero(mem_ctx, struct lsa_info);
391 return NT_STATUS_NO_MEMORY;
395 info->access = acc_granted;
398 sid_copy(&info->sid, sid);
401 info->name = talloc_strdup(info, name);
404 info->sd = dup_sec_desc(info, sd);
407 return NT_STATUS_NO_MEMORY;
411 if (!create_policy_hnd(p, handle, info)) {
413 ZERO_STRUCTP(handle);
414 return NT_STATUS_NO_MEMORY;
420 /***************************************************************************
422 ***************************************************************************/
424 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
425 struct lsa_OpenPolicy2 *r)
427 struct security_descriptor *psd = NULL;
429 uint32 des_access = r->in.access_mask;
433 /* Work out max allowed. */
434 map_max_allowed_access(p->session_info->security_token,
435 &p->session_info->utok,
438 /* map the generic bits to the lsa policy ones */
439 se_map_generic(&des_access, &lsa_policy_mapping);
441 /* get the generic lsa policy SD until we store it */
442 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
444 if (!NT_STATUS_IS_OK(status)) {
448 status = access_check_object(psd, p->session_info->security_token,
449 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
450 &acc_granted, "_lsa_OpenPolicy2" );
451 if (!NT_STATUS_IS_OK(status)) {
455 status = create_lsa_policy_handle(p->mem_ctx, p,
456 LSA_HANDLE_POLICY_TYPE,
458 get_global_sam_sid(),
462 if (!NT_STATUS_IS_OK(status)) {
463 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
469 /***************************************************************************
471 ***************************************************************************/
473 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
474 struct lsa_OpenPolicy *r)
476 struct lsa_OpenPolicy2 o;
478 o.in.system_name = NULL; /* should be ignored */
479 o.in.attr = r->in.attr;
480 o.in.access_mask = r->in.access_mask;
482 o.out.handle = r->out.handle;
484 return _lsa_OpenPolicy2(p, &o);
487 /***************************************************************************
488 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
490 ***************************************************************************/
492 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
493 struct lsa_EnumTrustDom *r)
495 struct lsa_info *info;
497 struct trustdom_info **domains;
498 struct lsa_DomainInfo *entries;
502 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
503 return NT_STATUS_INVALID_HANDLE;
505 if (info->type != LSA_HANDLE_POLICY_TYPE) {
506 return NT_STATUS_INVALID_HANDLE;
509 /* check if the user has enough rights */
510 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
511 return NT_STATUS_ACCESS_DENIED;
514 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
517 if (!NT_STATUS_IS_OK(nt_status)) {
521 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo, count);
523 return NT_STATUS_NO_MEMORY;
526 for (i=0; i<count; i++) {
527 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
528 entries[i].sid = &domains[i]->sid;
531 if (*r->in.resume_handle >= count) {
532 *r->out.resume_handle = -1;
533 TALLOC_FREE(entries);
534 return NT_STATUS_NO_MORE_ENTRIES;
537 /* return the rest, limit by max_size. Note that we
538 use the w2k3 element size value of 60 */
539 r->out.domains->count = count - *r->in.resume_handle;
540 r->out.domains->count = MIN(r->out.domains->count,
541 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
543 r->out.domains->domains = entries + *r->in.resume_handle;
545 if (r->out.domains->count < count - *r->in.resume_handle) {
546 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
547 return STATUS_MORE_ENTRIES;
550 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
551 * always be larger than the previous input resume handle, in
552 * particular when hitting the last query it is vital to set the
553 * resume handle correctly to avoid infinite client loops, as
554 * seen e.g. with Windows XP SP3 when resume handle is 0 and
555 * status is NT_STATUS_OK - gd */
557 *r->out.resume_handle = (uint32_t)-1;
562 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
563 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
564 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
566 /***************************************************************************
568 ***************************************************************************/
570 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
571 struct lsa_QueryInfoPolicy *r)
573 NTSTATUS status = NT_STATUS_OK;
574 struct lsa_info *handle;
575 struct dom_sid domain_sid;
577 struct dom_sid *sid = NULL;
578 union lsa_PolicyInformation *info = NULL;
579 uint32_t acc_required = 0;
581 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
582 return NT_STATUS_INVALID_HANDLE;
584 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
585 return NT_STATUS_INVALID_HANDLE;
588 switch (r->in.level) {
589 case LSA_POLICY_INFO_AUDIT_LOG:
590 case LSA_POLICY_INFO_AUDIT_EVENTS:
591 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
593 case LSA_POLICY_INFO_DOMAIN:
594 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
596 case LSA_POLICY_INFO_PD:
597 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
599 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
600 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
602 case LSA_POLICY_INFO_ROLE:
603 case LSA_POLICY_INFO_REPLICA:
604 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
606 case LSA_POLICY_INFO_QUOTA:
607 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
609 case LSA_POLICY_INFO_MOD:
610 case LSA_POLICY_INFO_AUDIT_FULL_SET:
611 /* according to MS-LSAD 3.1.4.4.3 */
612 return NT_STATUS_INVALID_PARAMETER;
613 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
614 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
616 case LSA_POLICY_INFO_DNS:
617 case LSA_POLICY_INFO_DNS_INT:
618 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
619 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
625 if (!(handle->access & acc_required)) {
626 /* return NT_STATUS_ACCESS_DENIED; */
629 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
631 return NT_STATUS_NO_MEMORY;
634 switch (r->in.level) {
635 /* according to MS-LSAD 3.1.4.4.3 */
636 case LSA_POLICY_INFO_MOD:
637 case LSA_POLICY_INFO_AUDIT_FULL_SET:
638 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
639 return NT_STATUS_INVALID_PARAMETER;
640 case LSA_POLICY_INFO_AUDIT_LOG:
641 info->audit_log.percent_full = 0;
642 info->audit_log.maximum_log_size = 0;
643 info->audit_log.retention_time = 0;
644 info->audit_log.shutdown_in_progress = 0;
645 info->audit_log.time_to_shutdown = 0;
646 info->audit_log.next_audit_record = 0;
647 status = NT_STATUS_OK;
649 case LSA_POLICY_INFO_PD:
650 info->pd.name.string = NULL;
651 status = NT_STATUS_OK;
653 case LSA_POLICY_INFO_REPLICA:
654 info->replica.source.string = NULL;
655 info->replica.account.string = NULL;
656 status = NT_STATUS_OK;
658 case LSA_POLICY_INFO_QUOTA:
659 info->quota.paged_pool = 0;
660 info->quota.non_paged_pool = 0;
661 info->quota.min_wss = 0;
662 info->quota.max_wss = 0;
663 info->quota.pagefile = 0;
664 info->quota.unknown = 0;
665 status = NT_STATUS_OK;
667 case LSA_POLICY_INFO_AUDIT_EVENTS:
670 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
672 /* check if the user has enough rights */
673 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
674 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
675 return NT_STATUS_ACCESS_DENIED;
678 /* fake info: We audit everything. ;) */
680 info->audit_events.auditing_mode = true;
681 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
682 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
683 enum lsa_PolicyAuditPolicy,
684 info->audit_events.count);
685 if (!info->audit_events.settings) {
686 return NT_STATUS_NO_MEMORY;
689 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
690 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
691 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
692 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
693 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
694 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
695 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
699 case LSA_POLICY_INFO_DOMAIN:
700 /* check if the user has enough rights */
701 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
702 return NT_STATUS_ACCESS_DENIED;
704 /* Request PolicyPrimaryDomainInformation. */
705 switch (lp_server_role()) {
706 case ROLE_DOMAIN_PDC:
707 case ROLE_DOMAIN_BDC:
708 name = get_global_sam_name();
709 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
711 return NT_STATUS_NO_MEMORY;
714 case ROLE_DOMAIN_MEMBER:
715 name = lp_workgroup();
716 /* We need to return the Domain SID here. */
717 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
718 sid = dom_sid_dup(p->mem_ctx, &domain_sid);
720 return NT_STATUS_NO_MEMORY;
723 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
726 case ROLE_STANDALONE:
727 name = lp_workgroup();
731 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
733 init_dom_query_3(&info->domain, name, sid);
735 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
736 /* check if the user has enough rights */
737 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
738 return NT_STATUS_ACCESS_DENIED;
740 /* Request PolicyAccountDomainInformation. */
741 name = get_global_sam_name();
742 sid = get_global_sam_sid();
744 init_dom_query_5(&info->account_domain, name, sid);
746 case LSA_POLICY_INFO_ROLE:
747 /* check if the user has enough rights */
748 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
749 return NT_STATUS_ACCESS_DENIED;
751 switch (lp_server_role()) {
752 case ROLE_DOMAIN_BDC:
754 * only a BDC is a backup controller
755 * of the domain, it controls.
757 info->role.role = LSA_ROLE_BACKUP;
761 * any other role is a primary
762 * of the domain, it controls.
764 info->role.role = LSA_ROLE_PRIMARY;
768 case LSA_POLICY_INFO_DNS:
769 case LSA_POLICY_INFO_DNS_INT: {
770 struct pdb_domain_info *dominfo;
772 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
773 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
774 "without ADS passdb backend\n"));
775 status = NT_STATUS_INVALID_INFO_CLASS;
779 dominfo = pdb_get_domain_info(info);
780 if (dominfo == NULL) {
781 status = NT_STATUS_NO_MEMORY;
785 init_lsa_StringLarge(&info->dns.name,
787 init_lsa_StringLarge(&info->dns.dns_domain,
788 dominfo->dns_domain);
789 init_lsa_StringLarge(&info->dns.dns_forest,
790 dominfo->dns_forest);
791 info->dns.domain_guid = dominfo->guid;
792 info->dns.sid = &dominfo->sid;
796 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
798 status = NT_STATUS_INVALID_INFO_CLASS;
807 /***************************************************************************
808 _lsa_QueryInfoPolicy2
809 ***************************************************************************/
811 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
812 struct lsa_QueryInfoPolicy2 *r2)
814 struct lsa_QueryInfoPolicy r;
816 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
817 p->rng_fault_state = True;
818 return NT_STATUS_NOT_IMPLEMENTED;
822 r.in.handle = r2->in.handle;
823 r.in.level = r2->in.level;
824 r.out.info = r2->out.info;
826 return _lsa_QueryInfoPolicy(p, &r);
829 /***************************************************************************
830 _lsa_lookup_sids_internal
831 ***************************************************************************/
833 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
835 uint16_t level, /* input */
836 int num_sids, /* input */
837 struct lsa_SidPtr *sid, /* input */
838 struct lsa_RefDomainList **pp_ref, /* input/output */
839 struct lsa_TranslatedName2 **pp_names,/* input/output */
840 uint32_t *pp_mapped_count) /* input/output */
844 const struct dom_sid **sids = NULL;
845 struct lsa_RefDomainList *ref = NULL;
846 uint32 mapped_count = 0;
847 struct lsa_dom_info *dom_infos = NULL;
848 struct lsa_name_info *name_infos = NULL;
849 struct lsa_TranslatedName2 *names = NULL;
851 *pp_mapped_count = 0;
859 sids = TALLOC_ARRAY(p->mem_ctx, const struct dom_sid *, num_sids);
860 ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
862 if (sids == NULL || ref == NULL) {
863 return NT_STATUS_NO_MEMORY;
866 for (i=0; i<num_sids; i++) {
867 sids[i] = sid[i].sid;
870 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
871 &dom_infos, &name_infos);
873 if (!NT_STATUS_IS_OK(status)) {
877 names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
879 return NT_STATUS_NO_MEMORY;
882 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
884 if (!dom_infos[i].valid) {
888 if (init_lsa_ref_domain_list(mem_ctx, ref,
890 &dom_infos[i].sid) != i) {
891 DEBUG(0, ("Domain %s mentioned twice??\n",
893 return NT_STATUS_INTERNAL_ERROR;
897 for (i=0; i<num_sids; i++) {
898 struct lsa_name_info *name = &name_infos[i];
900 if (name->type == SID_NAME_UNKNOWN) {
902 /* Unknown sids should return the string
903 * representation of the SID. Windows 2003 behaves
904 * rather erratic here, in many cases it returns the
905 * RID as 8 bytes hex, in others it returns the full
906 * SID. We (Jerry/VL) could not figure out which the
907 * hard cases are, so leave it with the SID. */
908 name->name = dom_sid_string(p->mem_ctx, sids[i]);
909 if (name->name == NULL) {
910 return NT_STATUS_NO_MEMORY;
916 names[i].sid_type = name->type;
917 names[i].name.string = name->name;
918 names[i].sid_index = name->dom_idx;
919 names[i].unknown = 0;
922 status = NT_STATUS_NONE_MAPPED;
923 if (mapped_count > 0) {
924 status = (mapped_count < num_sids) ?
925 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
928 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
929 num_sids, mapped_count, nt_errstr(status)));
931 *pp_mapped_count = mapped_count;
938 /***************************************************************************
940 ***************************************************************************/
942 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
943 struct lsa_LookupSids *r)
946 struct lsa_info *handle;
947 int num_sids = r->in.sids->num_sids;
948 uint32 mapped_count = 0;
949 struct lsa_RefDomainList *domains = NULL;
950 struct lsa_TranslatedName *names_out = NULL;
951 struct lsa_TranslatedName2 *names = NULL;
954 if ((r->in.level < 1) || (r->in.level > 6)) {
955 return NT_STATUS_INVALID_PARAMETER;
958 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
959 return NT_STATUS_INVALID_HANDLE;
962 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
963 return NT_STATUS_INVALID_HANDLE;
966 /* check if the user has enough rights */
967 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
968 return NT_STATUS_ACCESS_DENIED;
971 if (num_sids > MAX_LOOKUP_SIDS) {
972 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
973 MAX_LOOKUP_SIDS, num_sids));
974 return NT_STATUS_NONE_MAPPED;
977 status = _lsa_lookup_sids_internal(p,
986 /* Only return here when there is a real error.
987 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
988 the requested sids could be resolved. Older versions of XP (pre SP3)
989 rely that we return with the string representations of those SIDs in
990 that case. If we don't, XP crashes - Guenther
993 if (NT_STATUS_IS_ERR(status) &&
994 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
998 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
999 names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
1002 return NT_STATUS_NO_MEMORY;
1005 for (i=0; i<num_sids; i++) {
1006 names_out[i].sid_type = names[i].sid_type;
1007 names_out[i].name = names[i].name;
1008 names_out[i].sid_index = names[i].sid_index;
1011 *r->out.domains = domains;
1012 r->out.names->count = num_sids;
1013 r->out.names->names = names_out;
1014 *r->out.count = mapped_count;
1019 /***************************************************************************
1021 ***************************************************************************/
1023 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1024 struct lsa_LookupSids2 *r)
1027 struct lsa_info *handle;
1028 int num_sids = r->in.sids->num_sids;
1029 uint32 mapped_count = 0;
1030 struct lsa_RefDomainList *domains = NULL;
1031 struct lsa_TranslatedName2 *names = NULL;
1032 bool check_policy = true;
1035 case NDR_LSA_LOOKUPSIDS3:
1036 check_policy = false;
1038 case NDR_LSA_LOOKUPSIDS2:
1040 check_policy = true;
1043 if ((r->in.level < 1) || (r->in.level > 6)) {
1044 return NT_STATUS_INVALID_PARAMETER;
1048 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1049 return NT_STATUS_INVALID_HANDLE;
1052 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1053 return NT_STATUS_INVALID_HANDLE;
1056 /* check if the user has enough rights */
1057 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1058 return NT_STATUS_ACCESS_DENIED;
1062 if (num_sids > MAX_LOOKUP_SIDS) {
1063 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1064 MAX_LOOKUP_SIDS, num_sids));
1065 return NT_STATUS_NONE_MAPPED;
1068 status = _lsa_lookup_sids_internal(p,
1077 *r->out.domains = domains;
1078 r->out.names->count = num_sids;
1079 r->out.names->names = names;
1080 *r->out.count = mapped_count;
1085 /***************************************************************************
1087 ***************************************************************************/
1089 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1090 struct lsa_LookupSids3 *r)
1092 struct lsa_LookupSids2 q;
1094 /* No policy handle on this call. Restrict to crypto connections. */
1095 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1096 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1097 get_remote_machine_name() ));
1098 return NT_STATUS_INVALID_PARAMETER;
1102 q.in.sids = r->in.sids;
1103 q.in.level = r->in.level;
1104 q.in.lookup_options = r->in.lookup_options;
1105 q.in.client_revision = r->in.client_revision;
1106 q.in.names = r->in.names;
1107 q.in.count = r->in.count;
1109 q.out.domains = r->out.domains;
1110 q.out.names = r->out.names;
1111 q.out.count = r->out.count;
1113 return _lsa_LookupSids2(p, &q);
1116 /***************************************************************************
1117 ***************************************************************************/
1119 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1124 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1125 flags = LOOKUP_NAME_ALL;
1127 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1128 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1130 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1131 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1133 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1134 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1135 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1136 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1138 flags = LOOKUP_NAME_NONE;
1145 /***************************************************************************
1147 ***************************************************************************/
1149 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1150 struct lsa_LookupNames *r)
1152 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1153 struct lsa_info *handle;
1154 struct lsa_String *names = r->in.names;
1155 uint32 num_entries = r->in.num_names;
1156 struct lsa_RefDomainList *domains = NULL;
1157 struct lsa_TranslatedSid *rids = NULL;
1158 uint32 mapped_count = 0;
1161 if (num_entries > MAX_LOOKUP_SIDS) {
1162 num_entries = MAX_LOOKUP_SIDS;
1163 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1167 flags = lsa_lookup_level_to_flags(r->in.level);
1169 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1171 return NT_STATUS_NO_MEMORY;
1175 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1178 return NT_STATUS_NO_MEMORY;
1184 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1185 status = NT_STATUS_INVALID_HANDLE;
1189 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1190 return NT_STATUS_INVALID_HANDLE;
1193 /* check if the user has enough rights */
1194 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1195 status = NT_STATUS_ACCESS_DENIED;
1199 /* set up the LSA Lookup RIDs response */
1200 become_root(); /* lookup_name can require root privs */
1201 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1202 names, flags, &mapped_count);
1207 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1208 if (mapped_count == 0) {
1209 status = NT_STATUS_NONE_MAPPED;
1210 } else if (mapped_count != num_entries) {
1211 status = STATUS_SOME_UNMAPPED;
1215 *r->out.count = mapped_count;
1216 *r->out.domains = domains;
1217 r->out.sids->sids = rids;
1218 r->out.sids->count = num_entries;
1223 /***************************************************************************
1225 ***************************************************************************/
1227 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1228 struct lsa_LookupNames2 *r)
1231 struct lsa_LookupNames q;
1232 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1233 struct lsa_TransSidArray *sid_array = NULL;
1236 sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1238 return NT_STATUS_NO_MEMORY;
1241 q.in.handle = r->in.handle;
1242 q.in.num_names = r->in.num_names;
1243 q.in.names = r->in.names;
1244 q.in.level = r->in.level;
1245 q.in.sids = sid_array;
1246 q.in.count = r->in.count;
1247 /* we do not know what this is for */
1248 /* = r->in.unknown1; */
1249 /* = r->in.unknown2; */
1251 q.out.domains = r->out.domains;
1252 q.out.sids = sid_array;
1253 q.out.count = r->out.count;
1255 status = _lsa_LookupNames(p, &q);
1257 sid_array2->count = sid_array->count;
1258 sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1259 if (!sid_array2->sids) {
1260 return NT_STATUS_NO_MEMORY;
1263 for (i=0; i<sid_array->count; i++) {
1264 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1265 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1266 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1267 sid_array2->sids[i].unknown = 0;
1270 r->out.sids = sid_array2;
1275 /***************************************************************************
1277 ***************************************************************************/
1279 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1280 struct lsa_LookupNames3 *r)
1283 struct lsa_info *handle;
1284 struct lsa_String *names = r->in.names;
1285 uint32 num_entries = r->in.num_names;
1286 struct lsa_RefDomainList *domains = NULL;
1287 struct lsa_TranslatedSid3 *trans_sids = NULL;
1288 uint32 mapped_count = 0;
1290 bool check_policy = true;
1293 case NDR_LSA_LOOKUPNAMES4:
1294 check_policy = false;
1296 case NDR_LSA_LOOKUPNAMES3:
1298 check_policy = true;
1301 if (num_entries > MAX_LOOKUP_SIDS) {
1302 num_entries = MAX_LOOKUP_SIDS;
1303 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1306 /* Probably the lookup_level is some sort of bitmask. */
1307 if (r->in.level == 1) {
1308 flags = LOOKUP_NAME_ALL;
1311 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1313 return NT_STATUS_NO_MEMORY;
1317 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1320 return NT_STATUS_NO_MEMORY;
1328 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1329 status = NT_STATUS_INVALID_HANDLE;
1333 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1334 return NT_STATUS_INVALID_HANDLE;
1337 /* check if the user has enough rights */
1338 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1339 status = NT_STATUS_ACCESS_DENIED;
1344 /* set up the LSA Lookup SIDs response */
1345 become_root(); /* lookup_name can require root privs */
1346 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1347 names, flags, &mapped_count);
1352 if (NT_STATUS_IS_OK(status)) {
1353 if (mapped_count == 0) {
1354 status = NT_STATUS_NONE_MAPPED;
1355 } else if (mapped_count != num_entries) {
1356 status = STATUS_SOME_UNMAPPED;
1360 *r->out.count = mapped_count;
1361 *r->out.domains = domains;
1362 r->out.sids->sids = trans_sids;
1363 r->out.sids->count = num_entries;
1368 /***************************************************************************
1370 ***************************************************************************/
1372 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1373 struct lsa_LookupNames4 *r)
1375 struct lsa_LookupNames3 q;
1377 /* No policy handle on this call. Restrict to crypto connections. */
1378 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1379 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1380 get_remote_machine_name() ));
1381 return NT_STATUS_INVALID_PARAMETER;
1385 q.in.num_names = r->in.num_names;
1386 q.in.names = r->in.names;
1387 q.in.level = r->in.level;
1388 q.in.lookup_options = r->in.lookup_options;
1389 q.in.client_revision = r->in.client_revision;
1390 q.in.sids = r->in.sids;
1391 q.in.count = r->in.count;
1393 q.out.domains = r->out.domains;
1394 q.out.sids = r->out.sids;
1395 q.out.count = r->out.count;
1397 return _lsa_LookupNames3(p, &q);
1400 /***************************************************************************
1401 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1402 ***************************************************************************/
1404 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1406 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1407 return NT_STATUS_INVALID_HANDLE;
1410 close_policy_hnd(p, r->in.handle);
1411 ZERO_STRUCTP(r->out.handle);
1412 return NT_STATUS_OK;
1415 /***************************************************************************
1416 ***************************************************************************/
1418 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1419 const struct dom_sid *sid,
1420 struct trustdom_info **info)
1423 uint32_t num_domains = 0;
1424 struct trustdom_info **domains = NULL;
1427 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1428 if (!NT_STATUS_IS_OK(status)) {
1432 for (i=0; i < num_domains; i++) {
1433 if (dom_sid_equal(&domains[i]->sid, sid)) {
1438 if (i == num_domains) {
1439 return NT_STATUS_INVALID_PARAMETER;
1444 return NT_STATUS_OK;
1447 /***************************************************************************
1448 ***************************************************************************/
1450 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1451 const char *netbios_domain_name,
1452 struct trustdom_info **info_p)
1455 struct trustdom_info *info;
1456 struct pdb_trusted_domain *td;
1458 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1459 if (!NT_STATUS_IS_OK(status)) {
1463 info = talloc(mem_ctx, struct trustdom_info);
1465 return NT_STATUS_NO_MEMORY;
1468 info->name = talloc_strdup(info, netbios_domain_name);
1469 NT_STATUS_HAVE_NO_MEMORY(info->name);
1471 sid_copy(&info->sid, &td->security_identifier);
1475 return NT_STATUS_OK;
1478 /***************************************************************************
1479 ***************************************************************************/
1481 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p, struct lsa_OpenSecret *r)
1483 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1486 /***************************************************************************
1487 _lsa_OpenTrustedDomain_base
1488 ***************************************************************************/
1490 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1491 uint32_t access_mask,
1492 struct trustdom_info *info,
1493 struct policy_handle *handle)
1495 struct security_descriptor *psd = NULL;
1497 uint32_t acc_granted;
1500 /* des_access is for the account here, not the policy
1501 * handle - so don't check against policy handle. */
1503 /* Work out max allowed. */
1504 map_max_allowed_access(p->session_info->security_token,
1505 &p->session_info->utok,
1508 /* map the generic bits to the lsa account ones */
1509 se_map_generic(&access_mask, &lsa_account_mapping);
1511 /* get the generic lsa account SD until we store it */
1512 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1513 &lsa_trusted_domain_mapping,
1515 if (!NT_STATUS_IS_OK(status)) {
1519 status = access_check_object(psd, p->session_info->security_token,
1520 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1521 access_mask, &acc_granted,
1522 "_lsa_OpenTrustedDomain");
1523 if (!NT_STATUS_IS_OK(status)) {
1527 status = create_lsa_policy_handle(p->mem_ctx, p,
1528 LSA_HANDLE_TRUST_TYPE,
1534 if (!NT_STATUS_IS_OK(status)) {
1535 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1538 return NT_STATUS_OK;
1541 /***************************************************************************
1542 _lsa_OpenTrustedDomain
1543 ***************************************************************************/
1545 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1546 struct lsa_OpenTrustedDomain *r)
1548 struct lsa_info *handle = NULL;
1549 struct trustdom_info *info = NULL;
1552 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1553 return NT_STATUS_INVALID_HANDLE;
1556 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1557 return NT_STATUS_INVALID_HANDLE;
1560 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1563 if (!NT_STATUS_IS_OK(status)) {
1567 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1568 r->out.trustdom_handle);
1571 /***************************************************************************
1572 _lsa_OpenTrustedDomainByName
1573 ***************************************************************************/
1575 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1576 struct lsa_OpenTrustedDomainByName *r)
1578 struct lsa_info *handle = NULL;
1579 struct trustdom_info *info = NULL;
1582 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1583 return NT_STATUS_INVALID_HANDLE;
1586 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1587 return NT_STATUS_INVALID_HANDLE;
1590 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1593 if (!NT_STATUS_IS_OK(status)) {
1597 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1598 r->out.trustdom_handle);
1601 static NTSTATUS add_trusted_domain_user(TALLOC_CTX *mem_ctx,
1602 const char *netbios_name,
1603 const char *domain_name,
1604 const struct trustDomainPasswords *auth_struct)
1607 struct samu *sam_acct;
1610 struct dom_sid user_sid;
1615 sam_acct = samu_new(mem_ctx);
1616 if (sam_acct == NULL) {
1617 return NT_STATUS_NO_MEMORY;
1620 acct_name = talloc_asprintf(mem_ctx, "%s$", netbios_name);
1621 if (acct_name == NULL) {
1622 return NT_STATUS_NO_MEMORY;
1624 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1625 return NT_STATUS_UNSUCCESSFUL;
1628 if (!pdb_set_domain(sam_acct, domain_name, PDB_SET)) {
1629 return NT_STATUS_UNSUCCESSFUL;
1632 if (!pdb_set_acct_ctrl(sam_acct, ACB_DOMTRUST, PDB_SET)) {
1633 return NT_STATUS_UNSUCCESSFUL;
1636 if (!pdb_new_rid(&rid)) {
1637 return NT_STATUS_DS_NO_MORE_RIDS;
1639 sid_compose(&user_sid, get_global_sam_sid(), rid);
1640 if (!pdb_set_user_sid(sam_acct, &user_sid, PDB_SET)) {
1641 return NT_STATUS_UNSUCCESSFUL;
1644 for (i = 0; i < auth_struct->incoming.count; i++) {
1645 switch (auth_struct->incoming.current.array[i].AuthType) {
1646 case TRUST_AUTH_TYPE_CLEAR:
1647 if (!convert_string_talloc(mem_ctx,
1650 auth_struct->incoming.current.array[i].AuthInfo.clear.password,
1651 auth_struct->incoming.current.array[i].AuthInfo.clear.size,
1654 return NT_STATUS_UNSUCCESSFUL;
1656 if (!pdb_set_plaintext_passwd(sam_acct, dummy)) {
1657 return NT_STATUS_UNSUCCESSFUL;
1665 status = pdb_add_sam_account(sam_acct);
1666 if (!NT_STATUS_IS_OK(status)) {
1670 return NT_STATUS_OK;
1673 /***************************************************************************
1674 _lsa_CreateTrustedDomainEx2
1675 ***************************************************************************/
1677 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1678 struct lsa_CreateTrustedDomainEx2 *r)
1680 struct lsa_info *policy;
1682 uint32_t acc_granted;
1683 struct security_descriptor *psd;
1685 struct pdb_trusted_domain td;
1686 struct trustDomainPasswords auth_struct;
1687 enum ndr_err_code ndr_err;
1688 DATA_BLOB auth_blob;
1691 return NT_STATUS_NOT_SUPPORTED;
1694 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1695 return NT_STATUS_INVALID_HANDLE;
1698 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1699 return NT_STATUS_ACCESS_DENIED;
1702 if (p->session_info->utok.uid != sec_initial_uid() &&
1703 !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1704 return NT_STATUS_ACCESS_DENIED;
1707 /* Work out max allowed. */
1708 map_max_allowed_access(p->session_info->security_token,
1709 &p->session_info->utok,
1710 &r->in.access_mask);
1712 /* map the generic bits to the lsa policy ones */
1713 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1715 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1716 &lsa_trusted_domain_mapping,
1718 if (!NT_STATUS_IS_OK(status)) {
1722 status = access_check_object(psd, p->session_info->security_token,
1723 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1724 r->in.access_mask, &acc_granted,
1725 "_lsa_CreateTrustedDomainEx2");
1726 if (!NT_STATUS_IS_OK(status)) {
1732 td.domain_name = talloc_strdup(p->mem_ctx,
1733 r->in.info->domain_name.string);
1734 if (td.domain_name == NULL) {
1735 return NT_STATUS_NO_MEMORY;
1737 td.netbios_name = talloc_strdup(p->mem_ctx,
1738 r->in.info->netbios_name.string);
1739 if (td.netbios_name == NULL) {
1740 return NT_STATUS_NO_MEMORY;
1742 sid_copy(&td.security_identifier, r->in.info->sid);
1743 td.trust_direction = r->in.info->trust_direction;
1744 td.trust_type = r->in.info->trust_type;
1745 td.trust_attributes = r->in.info->trust_attributes;
1747 if (r->in.auth_info->auth_blob.size != 0) {
1748 auth_blob.length = r->in.auth_info->auth_blob.size;
1749 auth_blob.data = r->in.auth_info->auth_blob.data;
1751 arcfour_crypt_blob(auth_blob.data, auth_blob.length,
1752 &p->session_info->user_session_key);
1754 ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
1756 (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
1757 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1758 return NT_STATUS_UNSUCCESSFUL;
1761 ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
1762 &auth_struct.incoming,
1763 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1764 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1765 return NT_STATUS_UNSUCCESSFUL;
1768 ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
1769 &auth_struct.outgoing,
1770 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1771 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1772 return NT_STATUS_UNSUCCESSFUL;
1775 td.trust_auth_incoming.data = NULL;
1776 td.trust_auth_incoming.length = 0;
1777 td.trust_auth_outgoing.data = NULL;
1778 td.trust_auth_outgoing.length = 0;
1781 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1782 if (!NT_STATUS_IS_OK(status)) {
1786 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1787 status = add_trusted_domain_user(p->mem_ctx,
1788 r->in.info->netbios_name.string,
1789 r->in.info->domain_name.string,
1791 if (!NT_STATUS_IS_OK(status)) {
1796 status = create_lsa_policy_handle(p->mem_ctx, p,
1797 LSA_HANDLE_TRUST_TYPE,
1800 r->in.info->netbios_name.string,
1802 r->out.trustdom_handle);
1803 if (!NT_STATUS_IS_OK(status)) {
1804 pdb_del_trusteddom_pw(r->in.info->netbios_name.string);
1805 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1808 return NT_STATUS_OK;
1811 /***************************************************************************
1812 _lsa_CreateTrustedDomainEx
1813 ***************************************************************************/
1815 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1816 struct lsa_CreateTrustedDomainEx *r)
1818 struct lsa_CreateTrustedDomainEx2 q;
1820 q.in.policy_handle = r->in.policy_handle;
1821 q.in.info = r->in.info;
1822 q.in.auth_info = r->in.auth_info;
1823 q.in.access_mask = r->in.access_mask;
1824 q.out.trustdom_handle = r->out.trustdom_handle;
1826 return _lsa_CreateTrustedDomainEx2(p, &q);
1829 /***************************************************************************
1830 _lsa_CreateTrustedDomain
1831 ***************************************************************************/
1833 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1834 struct lsa_CreateTrustedDomain *r)
1836 struct lsa_CreateTrustedDomainEx2 c;
1837 struct lsa_TrustDomainInfoInfoEx info;
1838 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1840 ZERO_STRUCT(auth_info);
1842 info.domain_name = r->in.info->name;
1843 info.netbios_name = r->in.info->name;
1844 info.sid = r->in.info->sid;
1845 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1846 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1847 info.trust_attributes = 0;
1849 c.in.policy_handle = r->in.policy_handle;
1851 c.in.auth_info = &auth_info;
1852 c.in.access_mask = r->in.access_mask;
1853 c.out.trustdom_handle = r->out.trustdom_handle;
1855 return _lsa_CreateTrustedDomainEx2(p, &c);
1858 /***************************************************************************
1859 _lsa_DeleteTrustedDomain
1860 ***************************************************************************/
1862 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1863 struct lsa_DeleteTrustedDomain *r)
1866 struct lsa_info *handle;
1867 struct pdb_trusted_domain *td;
1868 struct samu *sam_acct;
1871 /* find the connection policy handle. */
1872 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1873 return NT_STATUS_INVALID_HANDLE;
1876 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1877 return NT_STATUS_INVALID_HANDLE;
1880 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1881 return NT_STATUS_ACCESS_DENIED;
1884 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1885 if (!NT_STATUS_IS_OK(status)) {
1889 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1890 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1891 sid_string_tos(r->in.dom_sid)));
1892 return NT_STATUS_UNSUCCESSFUL;
1895 if (td->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1896 sam_acct = samu_new(p->mem_ctx);
1897 if (sam_acct == NULL) {
1898 return NT_STATUS_NO_MEMORY;
1901 acct_name = talloc_asprintf(p->mem_ctx, "%s$", td->netbios_name);
1902 if (acct_name == NULL) {
1903 return NT_STATUS_NO_MEMORY;
1905 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1906 return NT_STATUS_UNSUCCESSFUL;
1908 status = pdb_delete_sam_account(sam_acct);
1909 if (!NT_STATUS_IS_OK(status)) {
1914 status = pdb_del_trusted_domain(td->netbios_name);
1915 if (!NT_STATUS_IS_OK(status)) {
1919 return NT_STATUS_OK;
1922 /***************************************************************************
1923 _lsa_CloseTrustedDomainEx
1924 ***************************************************************************/
1926 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1927 struct lsa_CloseTrustedDomainEx *r)
1929 return NT_STATUS_NOT_IMPLEMENTED;
1932 /***************************************************************************
1933 _lsa_QueryTrustedDomainInfo
1934 ***************************************************************************/
1936 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
1937 struct lsa_QueryTrustedDomainInfo *r)
1940 struct lsa_info *handle;
1941 union lsa_TrustedDomainInfo *info;
1942 struct pdb_trusted_domain *td;
1943 uint32_t acc_required;
1945 /* find the connection policy handle. */
1946 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
1947 return NT_STATUS_INVALID_HANDLE;
1950 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
1951 return NT_STATUS_INVALID_HANDLE;
1954 switch (r->in.level) {
1955 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1956 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1958 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1959 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
1961 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1962 acc_required = LSA_TRUSTED_QUERY_POSIX;
1964 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
1965 acc_required = LSA_TRUSTED_QUERY_AUTH;
1967 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1968 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1970 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1971 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1973 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1974 acc_required = LSA_TRUSTED_QUERY_AUTH;
1976 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1977 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1978 LSA_TRUSTED_QUERY_POSIX |
1979 LSA_TRUSTED_QUERY_AUTH;
1981 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1982 acc_required = LSA_TRUSTED_QUERY_AUTH;
1984 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1985 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1986 LSA_TRUSTED_QUERY_POSIX |
1987 LSA_TRUSTED_QUERY_AUTH;
1989 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1990 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1992 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1993 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1994 LSA_TRUSTED_QUERY_POSIX |
1995 LSA_TRUSTED_QUERY_AUTH;
1997 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1998 acc_required = LSA_TRUSTED_QUERY_POSIX;
2001 return NT_STATUS_INVALID_PARAMETER;
2004 if (!(handle->access & acc_required)) {
2005 return NT_STATUS_ACCESS_DENIED;
2008 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2009 if (!NT_STATUS_IS_OK(status)) {
2013 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_TrustedDomainInfo);
2015 return NT_STATUS_NO_MEMORY;
2018 switch (r->in.level) {
2019 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2020 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2022 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2023 return NT_STATUS_INVALID_PARAMETER;
2024 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2026 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2027 return NT_STATUS_INVALID_INFO_CLASS;
2028 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2029 return NT_STATUS_INVALID_PARAMETER;
2030 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2031 init_lsa_StringLarge(&info->info_ex.domain_name, td->domain_name);
2032 init_lsa_StringLarge(&info->info_ex.netbios_name, td->netbios_name);
2033 info->info_ex.sid = dom_sid_dup(info, &td->security_identifier);
2034 if (!info->info_ex.sid) {
2035 return NT_STATUS_NO_MEMORY;
2037 info->info_ex.trust_direction = td->trust_direction;
2038 info->info_ex.trust_type = td->trust_type;
2039 info->info_ex.trust_attributes = td->trust_attributes;
2041 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2042 return NT_STATUS_INVALID_INFO_CLASS;
2043 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2045 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2046 return NT_STATUS_INVALID_INFO_CLASS;
2047 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2048 return NT_STATUS_INVALID_INFO_CLASS;
2049 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2050 return NT_STATUS_INVALID_PARAMETER;
2051 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2053 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2056 return NT_STATUS_INVALID_PARAMETER;
2059 *r->out.info = info;
2061 return NT_STATUS_OK;
2064 /***************************************************************************
2065 _lsa_QueryTrustedDomainInfoBySid
2066 ***************************************************************************/
2068 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2069 struct lsa_QueryTrustedDomainInfoBySid *r)
2072 struct policy_handle trustdom_handle;
2073 struct lsa_OpenTrustedDomain o;
2074 struct lsa_QueryTrustedDomainInfo q;
2077 o.in.handle = r->in.handle;
2078 o.in.sid = r->in.dom_sid;
2079 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2080 o.out.trustdom_handle = &trustdom_handle;
2082 status = _lsa_OpenTrustedDomain(p, &o);
2083 if (!NT_STATUS_IS_OK(status)) {
2087 q.in.trustdom_handle = &trustdom_handle;
2088 q.in.level = r->in.level;
2089 q.out.info = r->out.info;
2091 status = _lsa_QueryTrustedDomainInfo(p, &q);
2092 if (!NT_STATUS_IS_OK(status)) {
2096 c.in.handle = &trustdom_handle;
2097 c.out.handle = &trustdom_handle;
2099 return _lsa_Close(p, &c);
2102 /***************************************************************************
2103 _lsa_QueryTrustedDomainInfoByName
2104 ***************************************************************************/
2106 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2107 struct lsa_QueryTrustedDomainInfoByName *r)
2110 struct policy_handle trustdom_handle;
2111 struct lsa_OpenTrustedDomainByName o;
2112 struct lsa_QueryTrustedDomainInfo q;
2115 o.in.handle = r->in.handle;
2116 o.in.name.string = r->in.trusted_domain->string;
2117 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2118 o.out.trustdom_handle = &trustdom_handle;
2120 status = _lsa_OpenTrustedDomainByName(p, &o);
2121 if (!NT_STATUS_IS_OK(status)) {
2122 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2123 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2128 q.in.trustdom_handle = &trustdom_handle;
2129 q.in.level = r->in.level;
2130 q.out.info = r->out.info;
2132 status = _lsa_QueryTrustedDomainInfo(p, &q);
2133 if (!NT_STATUS_IS_OK(status)) {
2137 c.in.handle = &trustdom_handle;
2138 c.out.handle = &trustdom_handle;
2140 return _lsa_Close(p, &c);
2143 /***************************************************************************
2144 ***************************************************************************/
2146 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p, struct lsa_CreateSecret *r)
2148 return NT_STATUS_ACCESS_DENIED;
2151 /***************************************************************************
2152 ***************************************************************************/
2154 NTSTATUS _lsa_SetSecret(struct pipes_struct *p, struct lsa_SetSecret *r)
2156 return NT_STATUS_ACCESS_DENIED;
2159 /***************************************************************************
2161 ***************************************************************************/
2163 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2164 struct lsa_DeleteObject *r)
2167 struct lsa_info *info = NULL;
2169 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2170 return NT_STATUS_INVALID_HANDLE;
2173 if (!(info->access & SEC_STD_DELETE)) {
2174 return NT_STATUS_ACCESS_DENIED;
2177 switch (info->type) {
2178 case LSA_HANDLE_ACCOUNT_TYPE:
2179 status = privilege_delete_account(&info->sid);
2180 if (!NT_STATUS_IS_OK(status)) {
2181 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2182 nt_errstr(status)));
2187 return NT_STATUS_INVALID_HANDLE;
2190 close_policy_hnd(p, r->in.handle);
2191 ZERO_STRUCTP(r->out.handle);
2196 /***************************************************************************
2198 ***************************************************************************/
2200 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2201 struct lsa_EnumPrivs *r)
2203 struct lsa_info *handle;
2205 uint32 enum_context = *r->in.resume_handle;
2206 int num_privs = num_privileges_in_short_list();
2207 struct lsa_PrivEntry *entries = NULL;
2209 /* remember that the enum_context starts at 0 and not 1 */
2211 if ( enum_context >= num_privs )
2212 return NT_STATUS_NO_MORE_ENTRIES;
2214 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2215 enum_context, num_privs));
2217 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2218 return NT_STATUS_INVALID_HANDLE;
2220 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2221 return NT_STATUS_INVALID_HANDLE;
2224 /* check if the user has enough rights
2225 I don't know if it's the right one. not documented. */
2227 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2228 return NT_STATUS_ACCESS_DENIED;
2231 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2233 return NT_STATUS_NO_MEMORY;
2239 for (i = 0; i < num_privs; i++) {
2240 if( i < enum_context) {
2242 init_lsa_StringLarge(&entries[i].name, NULL);
2244 entries[i].luid.low = 0;
2245 entries[i].luid.high = 0;
2248 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2250 entries[i].luid.low = sec_privilege_from_index(i);
2251 entries[i].luid.high = 0;
2255 enum_context = num_privs;
2257 *r->out.resume_handle = enum_context;
2258 r->out.privs->count = num_privs;
2259 r->out.privs->privs = entries;
2261 return NT_STATUS_OK;
2264 /***************************************************************************
2265 _lsa_LookupPrivDisplayName
2266 ***************************************************************************/
2268 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2269 struct lsa_LookupPrivDisplayName *r)
2271 struct lsa_info *handle;
2272 const char *description;
2273 struct lsa_StringLarge *lsa_name;
2275 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2276 return NT_STATUS_INVALID_HANDLE;
2278 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2279 return NT_STATUS_INVALID_HANDLE;
2282 /* check if the user has enough rights */
2285 * I don't know if it's the right one. not documented.
2287 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2288 return NT_STATUS_ACCESS_DENIED;
2290 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2292 description = get_privilege_dispname(r->in.name->string);
2294 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2295 return NT_STATUS_NO_SUCH_PRIVILEGE;
2298 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2300 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2302 return NT_STATUS_NO_MEMORY;
2305 init_lsa_StringLarge(lsa_name, description);
2307 *r->out.returned_language_id = r->in.language_id;
2308 *r->out.disp_name = lsa_name;
2310 return NT_STATUS_OK;
2313 /***************************************************************************
2315 ***************************************************************************/
2317 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2318 struct lsa_EnumAccounts *r)
2320 struct lsa_info *handle;
2321 struct dom_sid *sid_list;
2322 int i, j, num_entries;
2324 struct lsa_SidPtr *sids = NULL;
2326 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2327 return NT_STATUS_INVALID_HANDLE;
2329 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2330 return NT_STATUS_INVALID_HANDLE;
2333 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2334 return NT_STATUS_ACCESS_DENIED;
2339 /* The only way we can currently find out all the SIDs that have been
2340 privileged is to scan all privileges */
2342 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2343 if (!NT_STATUS_IS_OK(status)) {
2347 if (*r->in.resume_handle >= num_entries) {
2348 return NT_STATUS_NO_MORE_ENTRIES;
2351 if (num_entries - *r->in.resume_handle) {
2352 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
2353 num_entries - *r->in.resume_handle);
2355 talloc_free(sid_list);
2356 return NT_STATUS_NO_MEMORY;
2359 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2360 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2362 talloc_free(sid_list);
2363 return NT_STATUS_NO_MEMORY;
2368 talloc_free(sid_list);
2370 *r->out.resume_handle = num_entries;
2371 r->out.sids->num_sids = num_entries;
2372 r->out.sids->sids = sids;
2374 return NT_STATUS_OK;
2377 /***************************************************************************
2379 ***************************************************************************/
2381 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2382 struct lsa_GetUserName *r)
2384 const char *username, *domname;
2385 struct lsa_String *account_name = NULL;
2386 struct lsa_String *authority_name = NULL;
2388 if (r->in.account_name &&
2389 *r->in.account_name) {
2390 return NT_STATUS_INVALID_PARAMETER;
2393 if (r->in.authority_name &&
2394 *r->in.authority_name) {
2395 return NT_STATUS_INVALID_PARAMETER;
2398 if (p->session_info->guest) {
2400 * I'm 99% sure this is not the right place to do this,
2401 * global_sid_Anonymous should probably be put into the token
2402 * instead of the guest id -- vl
2404 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2405 &domname, &username, NULL)) {
2406 return NT_STATUS_NO_MEMORY;
2409 username = p->session_info->sanitized_username;
2410 domname = p->session_info->info3->base.domain.string;
2413 account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2414 if (!account_name) {
2415 return NT_STATUS_NO_MEMORY;
2417 init_lsa_String(account_name, username);
2419 if (r->out.authority_name) {
2420 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2421 if (!authority_name) {
2422 return NT_STATUS_NO_MEMORY;
2424 init_lsa_String(authority_name, domname);
2427 *r->out.account_name = account_name;
2428 if (r->out.authority_name) {
2429 *r->out.authority_name = authority_name;
2432 return NT_STATUS_OK;
2435 /***************************************************************************
2437 ***************************************************************************/
2439 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2440 struct lsa_CreateAccount *r)
2443 struct lsa_info *handle;
2444 uint32_t acc_granted;
2445 struct security_descriptor *psd;
2448 /* find the connection policy handle. */
2449 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2450 return NT_STATUS_INVALID_HANDLE;
2452 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2453 return NT_STATUS_INVALID_HANDLE;
2456 /* check if the user has enough rights */
2458 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2459 return NT_STATUS_ACCESS_DENIED;
2462 /* Work out max allowed. */
2463 map_max_allowed_access(p->session_info->security_token,
2464 &p->session_info->utok,
2465 &r->in.access_mask);
2467 /* map the generic bits to the lsa policy ones */
2468 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2470 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2471 &lsa_account_mapping,
2472 r->in.sid, LSA_POLICY_ALL_ACCESS);
2473 if (!NT_STATUS_IS_OK(status)) {
2477 status = access_check_object(psd, p->session_info->security_token,
2478 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2479 &acc_granted, "_lsa_CreateAccount");
2480 if (!NT_STATUS_IS_OK(status)) {
2484 if ( is_privileged_sid( r->in.sid ) )
2485 return NT_STATUS_OBJECT_NAME_COLLISION;
2487 status = create_lsa_policy_handle(p->mem_ctx, p,
2488 LSA_HANDLE_ACCOUNT_TYPE,
2493 r->out.acct_handle);
2494 if (!NT_STATUS_IS_OK(status)) {
2495 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2498 return privilege_create_account(r->in.sid);
2501 /***************************************************************************
2503 ***************************************************************************/
2505 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2506 struct lsa_OpenAccount *r)
2508 struct lsa_info *handle;
2509 struct security_descriptor *psd = NULL;
2511 uint32_t des_access = r->in.access_mask;
2512 uint32_t acc_granted;
2515 /* find the connection policy handle. */
2516 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2517 return NT_STATUS_INVALID_HANDLE;
2519 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2520 return NT_STATUS_INVALID_HANDLE;
2523 /* des_access is for the account here, not the policy
2524 * handle - so don't check against policy handle. */
2526 /* Work out max allowed. */
2527 map_max_allowed_access(p->session_info->security_token,
2528 &p->session_info->utok,
2531 /* map the generic bits to the lsa account ones */
2532 se_map_generic(&des_access, &lsa_account_mapping);
2534 /* get the generic lsa account SD until we store it */
2535 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2536 &lsa_account_mapping,
2537 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2538 if (!NT_STATUS_IS_OK(status)) {
2542 status = access_check_object(psd, p->session_info->security_token,
2543 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2544 &acc_granted, "_lsa_OpenAccount" );
2545 if (!NT_STATUS_IS_OK(status)) {
2549 /* TODO: Fis the parsing routine before reenabling this check! */
2551 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2552 return NT_STATUS_ACCESS_DENIED;
2555 status = create_lsa_policy_handle(p->mem_ctx, p,
2556 LSA_HANDLE_ACCOUNT_TYPE,
2561 r->out.acct_handle);
2562 if (!NT_STATUS_IS_OK(status)) {
2563 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2566 return NT_STATUS_OK;
2569 /***************************************************************************
2570 _lsa_EnumPrivsAccount
2571 For a given SID, enumerate all the privilege this account has.
2572 ***************************************************************************/
2574 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2575 struct lsa_EnumPrivsAccount *r)
2577 NTSTATUS status = NT_STATUS_OK;
2578 struct lsa_info *info=NULL;
2579 PRIVILEGE_SET *privileges;
2580 struct lsa_PrivilegeSet *priv_set = NULL;
2582 /* find the connection policy handle. */
2583 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2584 return NT_STATUS_INVALID_HANDLE;
2586 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2587 return NT_STATUS_INVALID_HANDLE;
2590 if (!(info->access & LSA_ACCOUNT_VIEW))
2591 return NT_STATUS_ACCESS_DENIED;
2593 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2594 if (!NT_STATUS_IS_OK(status)) {
2598 *r->out.privs = priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
2600 return NT_STATUS_NO_MEMORY;
2603 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2604 sid_string_dbg(&info->sid),
2605 privileges->count));
2607 priv_set->count = privileges->count;
2608 priv_set->unknown = 0;
2609 priv_set->set = talloc_move(priv_set, &privileges->set);
2614 /***************************************************************************
2615 _lsa_GetSystemAccessAccount
2616 ***************************************************************************/
2618 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2619 struct lsa_GetSystemAccessAccount *r)
2622 struct lsa_info *info = NULL;
2623 struct lsa_EnumPrivsAccount e;
2624 struct lsa_PrivilegeSet *privset;
2626 /* find the connection policy handle. */
2628 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2629 return NT_STATUS_INVALID_HANDLE;
2631 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2632 return NT_STATUS_INVALID_HANDLE;
2635 if (!(info->access & LSA_ACCOUNT_VIEW))
2636 return NT_STATUS_ACCESS_DENIED;
2638 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2640 return NT_STATUS_NO_MEMORY;
2643 e.in.handle = r->in.handle;
2644 e.out.privs = &privset;
2646 status = _lsa_EnumPrivsAccount(p, &e);
2647 if (!NT_STATUS_IS_OK(status)) {
2648 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2649 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2650 nt_errstr(status)));
2654 /* Samba4 would iterate over the privset to merge the policy mode bits,
2655 * not sure samba3 can do the same here, so just return what we did in
2659 0x01 -> Log on locally
2660 0x02 -> Access this computer from network
2661 0x04 -> Log on as a batch job
2662 0x10 -> Log on as a service
2664 they can be ORed together
2667 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2668 LSA_POLICY_MODE_NETWORK;
2670 return NT_STATUS_OK;
2673 /***************************************************************************
2674 update the systemaccount information
2675 ***************************************************************************/
2677 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2678 struct lsa_SetSystemAccessAccount *r)
2680 struct lsa_info *info=NULL;
2683 /* find the connection policy handle. */
2684 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2685 return NT_STATUS_INVALID_HANDLE;
2687 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2688 return NT_STATUS_INVALID_HANDLE;
2691 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2692 return NT_STATUS_ACCESS_DENIED;
2695 if (!pdb_getgrsid(&map, info->sid))
2696 return NT_STATUS_NO_SUCH_GROUP;
2698 return pdb_update_group_mapping_entry(&map);
2701 /***************************************************************************
2702 _lsa_AddPrivilegesToAccount
2703 For a given SID, add some privileges.
2704 ***************************************************************************/
2706 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
2707 struct lsa_AddPrivilegesToAccount *r)
2709 struct lsa_info *info = NULL;
2710 struct lsa_PrivilegeSet *set = NULL;
2712 /* find the connection policy handle. */
2713 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2714 return NT_STATUS_INVALID_HANDLE;
2716 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2717 return NT_STATUS_INVALID_HANDLE;
2720 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2721 return NT_STATUS_ACCESS_DENIED;
2726 if ( !grant_privilege_set( &info->sid, set ) ) {
2727 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2728 sid_string_dbg(&info->sid) ));
2729 return NT_STATUS_NO_SUCH_PRIVILEGE;
2732 return NT_STATUS_OK;
2735 /***************************************************************************
2736 _lsa_RemovePrivilegesFromAccount
2737 For a given SID, remove some privileges.
2738 ***************************************************************************/
2740 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2741 struct lsa_RemovePrivilegesFromAccount *r)
2743 struct lsa_info *info = NULL;
2744 struct lsa_PrivilegeSet *set = NULL;
2746 /* find the connection policy handle. */
2747 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2748 return NT_STATUS_INVALID_HANDLE;
2750 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2751 return NT_STATUS_INVALID_HANDLE;
2754 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2755 return NT_STATUS_ACCESS_DENIED;
2760 if ( !revoke_privilege_set( &info->sid, set) ) {
2761 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2762 sid_string_dbg(&info->sid) ));
2763 return NT_STATUS_NO_SUCH_PRIVILEGE;
2766 return NT_STATUS_OK;
2769 /***************************************************************************
2771 ***************************************************************************/
2773 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2774 struct lsa_LookupPrivName *r)
2776 struct lsa_info *info = NULL;
2778 struct lsa_StringLarge *lsa_name;
2780 /* find the connection policy handle. */
2781 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2782 return NT_STATUS_INVALID_HANDLE;
2785 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2786 return NT_STATUS_INVALID_HANDLE;
2789 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2790 return NT_STATUS_ACCESS_DENIED;
2793 if (r->in.luid->high != 0) {
2794 return NT_STATUS_NO_SUCH_PRIVILEGE;
2797 name = sec_privilege_name(r->in.luid->low);
2799 return NT_STATUS_NO_SUCH_PRIVILEGE;
2802 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2804 return NT_STATUS_NO_MEMORY;
2807 lsa_name->string = talloc_strdup(lsa_name, name);
2808 if (!lsa_name->string) {
2809 TALLOC_FREE(lsa_name);
2810 return NT_STATUS_NO_MEMORY;
2813 *r->out.name = lsa_name;
2815 return NT_STATUS_OK;
2818 /***************************************************************************
2820 ***************************************************************************/
2822 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
2823 struct lsa_QuerySecurity *r)
2825 struct lsa_info *handle=NULL;
2826 struct security_descriptor *psd = NULL;
2830 /* find the connection policy handle. */
2831 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2832 return NT_STATUS_INVALID_HANDLE;
2834 switch (handle->type) {
2835 case LSA_HANDLE_POLICY_TYPE:
2836 case LSA_HANDLE_ACCOUNT_TYPE:
2837 case LSA_HANDLE_TRUST_TYPE:
2839 sd_size = ndr_size_security_descriptor(psd, 0);
2840 status = NT_STATUS_OK;
2843 status = NT_STATUS_INVALID_HANDLE;
2847 if (!NT_STATUS_IS_OK(status)) {
2851 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2852 if (!*r->out.sdbuf) {
2853 return NT_STATUS_NO_MEMORY;
2859 /***************************************************************************
2860 _lsa_AddAccountRights
2861 ***************************************************************************/
2863 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
2864 struct lsa_AddAccountRights *r)
2866 struct lsa_info *info = NULL;
2868 uint32_t acc_granted = 0;
2869 struct security_descriptor *psd = NULL;
2874 /* find the connection policy handle. */
2875 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2876 return NT_STATUS_INVALID_HANDLE;
2878 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2879 return NT_STATUS_INVALID_HANDLE;
2882 /* get the generic lsa account SD for this SID until we store it */
2883 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2884 &lsa_account_mapping,
2885 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2886 if (!NT_STATUS_IS_OK(status)) {
2891 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2892 * on the policy handle. If it does, ask for
2893 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2894 * on the account sid. We don't check here so just use the latter. JRA.
2897 status = access_check_object(psd, p->session_info->security_token,
2898 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2899 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2900 &acc_granted, "_lsa_AddAccountRights" );
2901 if (!NT_STATUS_IS_OK(status)) {
2905 /* according to an NT4 PDC, you can add privileges to SIDs even without
2906 call_lsa_create_account() first. And you can use any arbitrary SID. */
2908 sid_copy( &sid, r->in.sid );
2910 for ( i=0; i < r->in.rights->count; i++ ) {
2912 const char *privname = r->in.rights->names[i].string;
2914 /* only try to add non-null strings */
2919 if ( !grant_privilege_by_name( &sid, privname ) ) {
2920 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2922 return NT_STATUS_NO_SUCH_PRIVILEGE;
2926 return NT_STATUS_OK;
2929 /***************************************************************************
2930 _lsa_RemoveAccountRights
2931 ***************************************************************************/
2933 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
2934 struct lsa_RemoveAccountRights *r)
2936 struct lsa_info *info = NULL;
2938 struct security_descriptor *psd = NULL;
2941 const char *privname = NULL;
2942 uint32_t acc_granted = 0;
2945 /* find the connection policy handle. */
2946 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2947 return NT_STATUS_INVALID_HANDLE;
2949 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2950 return NT_STATUS_INVALID_HANDLE;
2953 /* get the generic lsa account SD for this SID until we store it */
2954 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2955 &lsa_account_mapping,
2956 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2957 if (!NT_STATUS_IS_OK(status)) {
2962 * From the MS DOCs. We need
2963 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2964 * and DELETE on the account sid.
2967 status = access_check_object(psd, p->session_info->security_token,
2968 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2969 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2970 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
2971 &acc_granted, "_lsa_RemoveAccountRights");
2972 if (!NT_STATUS_IS_OK(status)) {
2976 sid_copy( &sid, r->in.sid );
2978 if ( r->in.remove_all ) {
2979 if ( !revoke_all_privileges( &sid ) )
2980 return NT_STATUS_ACCESS_DENIED;
2982 return NT_STATUS_OK;
2985 for ( i=0; i < r->in.rights->count; i++ ) {
2987 privname = r->in.rights->names[i].string;
2989 /* only try to add non-null strings */
2994 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2995 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2997 return NT_STATUS_NO_SUCH_PRIVILEGE;
3001 return NT_STATUS_OK;
3004 /*******************************************************************
3005 ********************************************************************/
3007 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3008 struct lsa_RightSet *r,
3009 PRIVILEGE_SET *privileges)
3012 const char *privname;
3013 const char **privname_array = NULL;
3016 for (i=0; i<privileges->count; i++) {
3017 if (privileges->set[i].luid.high) {
3020 privname = sec_privilege_name(privileges->set[i].luid.low);
3022 if (!add_string_to_array(mem_ctx, privname,
3023 &privname_array, &num_priv)) {
3024 return NT_STATUS_NO_MEMORY;
3031 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
3034 return NT_STATUS_NO_MEMORY;
3037 for (i=0; i<num_priv; i++) {
3038 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3041 r->count = num_priv;
3044 return NT_STATUS_OK;
3047 /***************************************************************************
3048 _lsa_EnumAccountRights
3049 ***************************************************************************/
3051 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3052 struct lsa_EnumAccountRights *r)
3055 struct lsa_info *info = NULL;
3056 PRIVILEGE_SET *privileges;
3058 /* find the connection policy handle. */
3060 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3061 return NT_STATUS_INVALID_HANDLE;
3063 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3064 return NT_STATUS_INVALID_HANDLE;
3067 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3068 return NT_STATUS_ACCESS_DENIED;
3071 /* according to an NT4 PDC, you can add privileges to SIDs even without
3072 call_lsa_create_account() first. And you can use any arbitrary SID. */
3074 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3075 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3076 * the lsa database */
3078 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3079 if (!NT_STATUS_IS_OK(status)) {
3083 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3084 sid_string_dbg(r->in.sid), privileges->count));
3086 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3091 /***************************************************************************
3092 _lsa_LookupPrivValue
3093 ***************************************************************************/
3095 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3096 struct lsa_LookupPrivValue *r)
3098 struct lsa_info *info = NULL;
3099 const char *name = NULL;
3101 /* find the connection policy handle. */
3103 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3104 return NT_STATUS_INVALID_HANDLE;
3106 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3107 return NT_STATUS_INVALID_HANDLE;
3110 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3111 return NT_STATUS_ACCESS_DENIED;
3113 name = r->in.name->string;
3115 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3117 r->out.luid->low = sec_privilege_id(name);
3118 r->out.luid->high = 0;
3119 if (r->out.luid->low == SEC_PRIV_INVALID) {
3120 return NT_STATUS_NO_SUCH_PRIVILEGE;
3122 return NT_STATUS_OK;
3125 /***************************************************************************
3126 _lsa_EnumAccountsWithUserRight
3127 ***************************************************************************/
3129 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3130 struct lsa_EnumAccountsWithUserRight *r)
3133 struct lsa_info *info = NULL;
3134 struct dom_sid *sids = NULL;
3137 enum sec_privilege privilege;
3139 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3140 return NT_STATUS_INVALID_HANDLE;
3143 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3144 return NT_STATUS_INVALID_HANDLE;
3147 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3148 return NT_STATUS_ACCESS_DENIED;
3151 if (!r->in.name || !r->in.name->string) {
3152 return NT_STATUS_NO_SUCH_PRIVILEGE;
3155 privilege = sec_privilege_id(r->in.name->string);
3156 if (privilege == SEC_PRIV_INVALID) {
3157 return NT_STATUS_NO_SUCH_PRIVILEGE;
3160 status = privilege_enum_sids(privilege, p->mem_ctx,
3162 if (!NT_STATUS_IS_OK(status)) {
3166 r->out.sids->num_sids = num_sids;
3167 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3168 r->out.sids->num_sids);
3170 for (i=0; i < r->out.sids->num_sids; i++) {
3171 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3173 if (!r->out.sids->sids[i].sid) {
3174 TALLOC_FREE(r->out.sids->sids);
3175 r->out.sids->num_sids = 0;
3176 return NT_STATUS_NO_MEMORY;
3180 return NT_STATUS_OK;
3183 /***************************************************************************
3185 ***************************************************************************/
3187 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3188 struct lsa_Delete *r)
3190 return NT_STATUS_NOT_SUPPORTED;
3194 * From here on the server routines are just dummy ones to make smbd link with
3195 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3196 * pulling the server stubs across one by one.
3199 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3201 p->rng_fault_state = True;
3202 return NT_STATUS_NOT_IMPLEMENTED;
3205 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3206 struct lsa_ChangePassword *r)
3208 p->rng_fault_state = True;
3209 return NT_STATUS_NOT_IMPLEMENTED;
3212 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3214 p->rng_fault_state = True;
3215 return NT_STATUS_NOT_IMPLEMENTED;
3218 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3220 p->rng_fault_state = True;
3221 return NT_STATUS_NOT_IMPLEMENTED;
3224 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3225 struct lsa_GetQuotasForAccount *r)
3227 p->rng_fault_state = True;
3228 return NT_STATUS_NOT_IMPLEMENTED;
3231 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3232 struct lsa_SetQuotasForAccount *r)
3234 p->rng_fault_state = True;
3235 return NT_STATUS_NOT_IMPLEMENTED;
3238 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3239 struct lsa_SetInformationTrustedDomain *r)
3241 p->rng_fault_state = True;
3242 return NT_STATUS_NOT_IMPLEMENTED;
3245 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
3247 p->rng_fault_state = True;
3248 return NT_STATUS_NOT_IMPLEMENTED;
3251 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3252 struct lsa_SetTrustedDomainInfo *r)
3254 p->rng_fault_state = True;
3255 return NT_STATUS_NOT_IMPLEMENTED;
3258 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3259 struct lsa_StorePrivateData *r)
3261 p->rng_fault_state = True;
3262 return NT_STATUS_NOT_IMPLEMENTED;
3265 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3266 struct lsa_RetrievePrivateData *r)
3268 p->rng_fault_state = True;
3269 return NT_STATUS_NOT_IMPLEMENTED;
3272 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3273 struct lsa_SetInfoPolicy2 *r)
3275 p->rng_fault_state = True;
3276 return NT_STATUS_NOT_IMPLEMENTED;
3279 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3280 struct lsa_SetTrustedDomainInfoByName *r)
3282 p->rng_fault_state = True;
3283 return NT_STATUS_NOT_IMPLEMENTED;
3286 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3287 struct lsa_EnumTrustedDomainsEx *r)
3289 struct lsa_info *info;
3291 struct pdb_trusted_domain **domains;
3292 struct lsa_TrustDomainInfoInfoEx *entries;
3296 /* bail out early if pdb backend is not capable of ex trusted domains,
3297 * if we dont do that, the client might not call
3298 * _lsa_EnumTrustedDomains() afterwards - gd */
3300 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3301 p->rng_fault_state = True;
3302 return NT_STATUS_NOT_IMPLEMENTED;
3305 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3306 return NT_STATUS_INVALID_HANDLE;
3308 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3309 return NT_STATUS_INVALID_HANDLE;
3312 /* check if the user has enough rights */
3313 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3314 return NT_STATUS_ACCESS_DENIED;
3317 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3320 if (!NT_STATUS_IS_OK(nt_status)) {
3324 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3327 return NT_STATUS_NO_MEMORY;
3330 for (i=0; i<count; i++) {
3331 init_lsa_StringLarge(&entries[i].netbios_name,
3332 domains[i]->netbios_name);
3333 entries[i].sid = &domains[i]->security_identifier;
3336 if (*r->in.resume_handle >= count) {
3337 *r->out.resume_handle = -1;
3338 TALLOC_FREE(entries);
3339 return NT_STATUS_NO_MORE_ENTRIES;
3342 /* return the rest, limit by max_size. Note that we
3343 use the w2k3 element size value of 60 */
3344 r->out.domains->count = count - *r->in.resume_handle;
3345 r->out.domains->count = MIN(r->out.domains->count,
3346 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3348 r->out.domains->domains = entries + *r->in.resume_handle;
3350 if (r->out.domains->count < count - *r->in.resume_handle) {
3351 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3352 return STATUS_MORE_ENTRIES;
3355 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3356 * always be larger than the previous input resume handle, in
3357 * particular when hitting the last query it is vital to set the
3358 * resume handle correctly to avoid infinite client loops, as
3359 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3360 * status is NT_STATUS_OK - gd */
3362 *r->out.resume_handle = (uint32_t)-1;
3364 return NT_STATUS_OK;
3367 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3368 struct lsa_QueryDomainInformationPolicy *r)
3370 p->rng_fault_state = True;
3371 return NT_STATUS_NOT_IMPLEMENTED;
3374 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3375 struct lsa_SetDomainInformationPolicy *r)
3377 p->rng_fault_state = True;
3378 return NT_STATUS_NOT_IMPLEMENTED;
3381 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3383 p->rng_fault_state = True;
3384 return NT_STATUS_NOT_IMPLEMENTED;
3387 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3389 p->rng_fault_state = True;
3390 return NT_STATUS_NOT_IMPLEMENTED;
3393 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3395 p->rng_fault_state = True;
3396 return NT_STATUS_NOT_IMPLEMENTED;
3399 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3401 p->rng_fault_state = True;
3402 return NT_STATUS_NOT_IMPLEMENTED;
3405 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3406 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3408 p->rng_fault_state = True;
3409 return NT_STATUS_NOT_IMPLEMENTED;
3412 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3413 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3415 p->rng_fault_state = True;
3416 return NT_STATUS_NOT_IMPLEMENTED;
3419 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3421 p->rng_fault_state = True;
3422 return NT_STATUS_NOT_IMPLEMENTED;
3425 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3426 struct lsa_CREDRGETTARGETINFO *r)
3428 p->rng_fault_state = True;
3429 return NT_STATUS_NOT_IMPLEMENTED;
3432 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3433 struct lsa_CREDRPROFILELOADED *r)
3435 p->rng_fault_state = True;
3436 return NT_STATUS_NOT_IMPLEMENTED;
3439 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3440 struct lsa_CREDRGETSESSIONTYPES *r)
3442 p->rng_fault_state = True;
3443 return NT_STATUS_NOT_IMPLEMENTED;
3446 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3447 struct lsa_LSARREGISTERAUDITEVENT *r)
3449 p->rng_fault_state = True;
3450 return NT_STATUS_NOT_IMPLEMENTED;
3453 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3454 struct lsa_LSARGENAUDITEVENT *r)
3456 p->rng_fault_state = True;
3457 return NT_STATUS_NOT_IMPLEMENTED;
3460 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3461 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3463 p->rng_fault_state = True;
3464 return NT_STATUS_NOT_IMPLEMENTED;
3467 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3468 struct lsa_lsaRQueryForestTrustInformation *r)
3470 p->rng_fault_state = True;
3471 return NT_STATUS_NOT_IMPLEMENTED;
3474 #define DNS_CMP_MATCH 0
3475 #define DNS_CMP_FIRST_IS_CHILD 1
3476 #define DNS_CMP_SECOND_IS_CHILD 2
3477 #define DNS_CMP_NO_MATCH 3
3479 /* this function assumes names are well formed DNS names.
3480 * it doesn't validate them */
3481 static int dns_cmp(const char *s1, size_t l1,
3482 const char *s2, size_t l2)
3484 const char *p1, *p2;
3489 if (StrCaseCmp(s1, s2) == 0) {
3490 return DNS_CMP_MATCH;
3492 return DNS_CMP_NO_MATCH;
3500 cret = DNS_CMP_FIRST_IS_CHILD;
3506 cret = DNS_CMP_SECOND_IS_CHILD;
3509 if (p1[t1 - t2 - 1] != '.') {
3510 return DNS_CMP_NO_MATCH;
3513 if (StrCaseCmp(&p1[t1 - t2], p2) == 0) {
3517 return DNS_CMP_NO_MATCH;
3520 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3521 struct lsa_ForestTrustInformation *lfti,
3522 struct ForestTrustInfo *fti)
3524 struct lsa_ForestTrustRecord *lrec;
3525 struct ForestTrustInfoRecord *rec;
3526 struct lsa_StringLarge *tln;
3527 struct lsa_ForestTrustDomainInfo *info;
3531 fti->count = lfti->count;
3532 fti->records = talloc_array(mem_ctx,
3533 struct ForestTrustInfoRecordArmor,
3535 if (!fti->records) {
3536 return NT_STATUS_NO_MEMORY;
3538 for (i = 0; i < fti->count; i++) {
3539 lrec = lfti->entries[i];
3540 rec = &fti->records[i].record;
3542 rec->flags = lrec->flags;
3543 rec->timestamp = lrec->time;
3544 rec->type = lrec->type;
3546 switch (lrec->type) {
3547 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3548 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3549 tln = &lrec->forest_trust_data.top_level_name;
3550 rec->data.name.string =
3551 talloc_strdup(mem_ctx, tln->string);
3552 if (!rec->data.name.string) {
3553 return NT_STATUS_NO_MEMORY;
3555 rec->data.name.size = strlen(rec->data.name.string);
3557 case LSA_FOREST_TRUST_DOMAIN_INFO:
3558 info = &lrec->forest_trust_data.domain_info;
3559 rec->data.info.sid = *info->domain_sid;
3560 rec->data.info.dns_name.string =
3561 talloc_strdup(mem_ctx,
3562 info->dns_domain_name.string);
3563 if (!rec->data.info.dns_name.string) {
3564 return NT_STATUS_NO_MEMORY;
3566 rec->data.info.dns_name.size =
3567 strlen(rec->data.info.dns_name.string);
3568 rec->data.info.netbios_name.string =
3569 talloc_strdup(mem_ctx,
3570 info->netbios_domain_name.string);
3571 if (!rec->data.info.netbios_name.string) {
3572 return NT_STATUS_NO_MEMORY;
3574 rec->data.info.netbios_name.size =
3575 strlen(rec->data.info.netbios_name.string);
3578 return NT_STATUS_INVALID_DOMAIN_STATE;
3582 return NT_STATUS_OK;
3585 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3586 uint32_t index, uint32_t collision_type,
3587 uint32_t conflict_type, const char *tdo_name);
3589 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
3590 const char *tdo_name,
3591 struct ForestTrustInfo *tdo_fti,
3592 struct ForestTrustInfo *new_fti,
3593 struct lsa_ForestTrustCollisionInfo *c_info)
3595 struct ForestTrustInfoRecord *nrec;
3596 struct ForestTrustInfoRecord *trec;
3597 const char *dns_name;
3598 const char *nb_name = NULL;
3599 struct dom_sid *sid = NULL;
3600 const char *tname = NULL;
3605 uint32_t new_fti_idx;
3607 /* use always TDO type, until we understand when Xref can be used */
3608 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
3613 bool ex_rule = false;
3616 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
3618 nrec = &new_fti->records[new_fti_idx].record;
3620 tln_conflict = false;
3621 sid_conflict = false;
3622 nb_conflict = false;
3625 switch (nrec->type) {
3626 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3627 /* exclusions do not conflict by definition */
3630 case FOREST_TRUST_TOP_LEVEL_NAME:
3631 dns_name = nrec->data.name.string;
3632 dns_len = nrec->data.name.size;
3635 case LSA_FOREST_TRUST_DOMAIN_INFO:
3636 dns_name = nrec->data.info.dns_name.string;
3637 dns_len = nrec->data.info.dns_name.size;
3638 nb_name = nrec->data.info.netbios_name.string;
3639 nb_len = nrec->data.info.netbios_name.size;
3640 sid = &nrec->data.info.sid;
3644 if (!dns_name) continue;
3646 /* check if this is already taken and not excluded */
3647 for (i = 0; i < tdo_fti->count; i++) {
3648 trec = &tdo_fti->records[i].record;
3650 switch (trec->type) {
3651 case FOREST_TRUST_TOP_LEVEL_NAME:
3653 tname = trec->data.name.string;
3654 tlen = trec->data.name.size;
3656 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
3658 tname = trec->data.name.string;
3659 tlen = trec->data.name.size;
3661 case FOREST_TRUST_DOMAIN_INFO:
3663 tname = trec->data.info.dns_name.string;
3664 tlen = trec->data.info.dns_name.size;
3666 return NT_STATUS_INVALID_PARAMETER;
3668 ret = dns_cmp(dns_name, dns_len, tname, tlen);
3671 /* if it matches exclusion,
3672 * it doesn't conflict */
3678 case DNS_CMP_FIRST_IS_CHILD:
3679 case DNS_CMP_SECOND_IS_CHILD:
3680 tln_conflict = true;
3686 /* explicit exclusion, no dns name conflict here */
3688 tln_conflict = false;
3691 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
3695 /* also test for domain info */
3696 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
3697 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
3698 sid_conflict = true;
3700 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
3701 StrCaseCmp(trec->data.info.netbios_name.string,
3708 nt_status = add_collision(c_info, new_fti_idx,
3710 LSA_TLN_DISABLED_CONFLICT,
3714 nt_status = add_collision(c_info, new_fti_idx,
3716 LSA_SID_DISABLED_CONFLICT,
3720 nt_status = add_collision(c_info, new_fti_idx,
3722 LSA_NB_DISABLED_CONFLICT,
3727 return NT_STATUS_OK;
3730 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3731 uint32_t idx, uint32_t collision_type,
3732 uint32_t conflict_type, const char *tdo_name)
3734 struct lsa_ForestTrustCollisionRecord **es;
3735 uint32_t i = c_info->count;
3737 es = talloc_realloc(c_info, c_info->entries,
3738 struct lsa_ForestTrustCollisionRecord *, i + 1);
3740 return NT_STATUS_NO_MEMORY;
3742 c_info->entries = es;
3743 c_info->count = i + 1;
3745 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
3747 return NT_STATUS_NO_MEMORY;
3751 es[i]->type = collision_type;
3752 es[i]->flags.flags = conflict_type;
3753 es[i]->name.string = talloc_strdup(es[i], tdo_name);
3754 if (!es[i]->name.string) {
3755 return NT_STATUS_NO_MEMORY;
3757 es[i]->name.size = strlen(es[i]->name.string);
3759 return NT_STATUS_OK;
3762 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3763 struct pdb_trusted_domain *td,
3764 struct ForestTrustInfo *info)
3766 enum ndr_err_code ndr_err;
3768 if (td->trust_forest_trust_info.length == 0 ||
3769 td->trust_forest_trust_info.data == NULL) {
3770 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3772 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
3774 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3775 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3776 return NT_STATUS_INVALID_DOMAIN_STATE;
3779 return NT_STATUS_OK;
3782 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
3783 struct ForestTrustInfo *fti)
3785 struct ForestTrustDataDomainInfo *info;
3786 struct ForestTrustInfoRecord *rec;
3790 fti->records = talloc_array(fti,
3791 struct ForestTrustInfoRecordArmor, 2);
3792 if (!fti->records) {
3793 return NT_STATUS_NO_MEMORY;
3797 rec = &fti->records[0].record;
3801 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3803 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
3804 if (!rec->data.name.string) {
3805 return NT_STATUS_NO_MEMORY;
3807 rec->data.name.size = strlen(rec->data.name.string);
3810 rec = &fti->records[1].record;
3814 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3816 info = &rec->data.info;
3818 info->sid = dom_info->sid;
3819 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
3820 if (!info->dns_name.string) {
3821 return NT_STATUS_NO_MEMORY;
3823 info->dns_name.size = strlen(info->dns_name.string);
3824 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
3825 if (!info->netbios_name.string) {
3826 return NT_STATUS_NO_MEMORY;
3828 info->netbios_name.size = strlen(info->netbios_name.string);
3830 return NT_STATUS_OK;
3833 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
3834 struct lsa_lsaRSetForestTrustInformation *r)
3839 struct lsa_info *handle;
3840 uint32_t num_domains;
3841 struct pdb_trusted_domain **domains;
3842 struct ForestTrustInfo *nfti;
3843 struct ForestTrustInfo *fti;
3844 struct lsa_ForestTrustCollisionInfo *c_info;
3845 struct pdb_domain_info *dom_info;
3846 enum ndr_err_code ndr_err;
3849 return NT_STATUS_NOT_SUPPORTED;
3852 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
3853 return NT_STATUS_INVALID_HANDLE;
3856 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
3857 return NT_STATUS_INVALID_HANDLE;
3860 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
3861 return NT_STATUS_ACCESS_DENIED;
3864 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
3865 if (!NT_STATUS_IS_OK(status)) {
3868 if (num_domains == 0) {
3869 return NT_STATUS_NO_SUCH_DOMAIN;
3872 for (i = 0; i < num_domains; i++) {
3873 if (domains[i]->domain_name == NULL) {
3874 return NT_STATUS_INVALID_DOMAIN_STATE;
3876 if (StrCaseCmp(domains[i]->domain_name,
3877 r->in.trusted_domain_name->string) == 0) {
3881 if (i >= num_domains) {
3882 return NT_STATUS_NO_SUCH_DOMAIN;
3885 if (!(domains[i]->trust_attributes &
3886 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
3887 return NT_STATUS_INVALID_PARAMETER;
3890 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
3891 return NT_STATUS_INVALID_PARAMETER;
3894 /* The following section until COPY_END is a copy from
3895 * source4/rpmc_server/lsa/scesrc_lsa.c */
3896 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
3898 return NT_STATUS_NO_MEMORY;
3901 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
3902 if (!NT_STATUS_IS_OK(status)) {
3906 c_info = talloc_zero(r->out.collision_info,
3907 struct lsa_ForestTrustCollisionInfo);
3909 return NT_STATUS_NO_MEMORY;
3912 /* first check own info, then other domains */
3913 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3915 return NT_STATUS_NO_MEMORY;
3918 dom_info = pdb_get_domain_info(p->mem_ctx);
3920 status = own_ft_info(dom_info, fti);
3921 if (!NT_STATUS_IS_OK(status)) {
3925 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
3926 if (!NT_STATUS_IS_OK(status)) {
3930 for (j = 0; j < num_domains; j++) {
3931 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3933 return NT_STATUS_NO_MEMORY;
3936 status = get_ft_info(p->mem_ctx, domains[j], fti);
3937 if (!NT_STATUS_IS_OK(status)) {
3938 if (NT_STATUS_EQUAL(status,
3939 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3945 if (domains[j]->domain_name == NULL) {
3946 return NT_STATUS_INVALID_DOMAIN_STATE;
3949 status = check_ft_info(c_info, domains[j]->domain_name,
3951 if (!NT_STATUS_IS_OK(status)) {
3956 *r->out.collision_info = c_info;
3958 if (r->in.check_only != 0) {
3959 return NT_STATUS_OK;
3964 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
3966 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
3967 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3968 return NT_STATUS_INVALID_PARAMETER;
3971 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
3972 if (!NT_STATUS_IS_OK(status)) {
3976 return NT_STATUS_OK;
3979 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
3980 struct lsa_CREDRRENAME *r)
3982 p->rng_fault_state = True;
3983 return NT_STATUS_NOT_IMPLEMENTED;
3986 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
3987 struct lsa_LSAROPENPOLICYSCE *r)
3989 p->rng_fault_state = True;
3990 return NT_STATUS_NOT_IMPLEMENTED;
3993 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
3994 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3996 p->rng_fault_state = True;
3997 return NT_STATUS_NOT_IMPLEMENTED;
4000 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4001 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4003 p->rng_fault_state = True;
4004 return NT_STATUS_NOT_IMPLEMENTED;
4007 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4008 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4010 p->rng_fault_state = True;
4011 return NT_STATUS_NOT_IMPLEMENTED;