2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Jeremy Allison 2001, 2006.
8 * Copyright (C) Rafal Szczesniak 2002,
9 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
10 * Copyright (C) Simo Sorce 2003.
11 * Copyright (C) Gerald (Jerry) Carter 2005.
12 * Copyright (C) Volker Lendecke 2005.
13 * Copyright (C) Guenther Deschner 2008.
14 * Copyright (C) Andrew Bartlett 2010.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
30 /* This is the implementation of the lsa server code. */
33 #include "../librpc/gen_ndr/srv_lsa.h"
35 #include "../librpc/gen_ndr/netlogon.h"
36 #include "rpc_client/init_lsa.h"
37 #include "../libcli/security/security.h"
38 #include "../libcli/security/dom_sid.h"
39 #include "../librpc/gen_ndr/drsblobs.h"
40 #include "../librpc/gen_ndr/ndr_drsblobs.h"
41 #include "../lib/crypto/arcfour.h"
42 #include "../libcli/security/dom_sid.h"
43 #include "../librpc/gen_ndr/ndr_security.h"
46 #define DBGC_CLASS DBGC_RPC_SRV
48 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
50 enum lsa_handle_type {
51 LSA_HANDLE_POLICY_TYPE = 1,
52 LSA_HANDLE_ACCOUNT_TYPE = 2,
53 LSA_HANDLE_TRUST_TYPE = 3};
59 enum lsa_handle_type type;
60 struct security_descriptor *sd;
63 const struct generic_mapping lsa_account_mapping = {
67 LSA_ACCOUNT_ALL_ACCESS
70 const struct generic_mapping lsa_policy_mapping = {
77 const struct generic_mapping lsa_secret_mapping = {
84 const struct generic_mapping lsa_trusted_domain_mapping = {
85 LSA_TRUSTED_DOMAIN_READ,
86 LSA_TRUSTED_DOMAIN_WRITE,
87 LSA_TRUSTED_DOMAIN_EXECUTE,
88 LSA_TRUSTED_DOMAIN_ALL_ACCESS
91 /***************************************************************************
92 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
93 ***************************************************************************/
95 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
96 struct lsa_RefDomainList *ref,
98 struct dom_sid *dom_sid)
102 if (dom_name != NULL) {
103 for (num = 0; num < ref->count; num++) {
104 if (dom_sid_equal(dom_sid, ref->domains[num].sid)) {
112 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
113 /* index not found, already at maximum domain limit */
117 ref->count = num + 1;
118 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
120 ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains,
121 struct lsa_DomainInfo, ref->count);
126 ZERO_STRUCT(ref->domains[num]);
128 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
129 ref->domains[num].sid = dom_sid_dup(mem_ctx, dom_sid);
130 if (!ref->domains[num].sid) {
138 /***************************************************************************
139 initialize a lsa_DomainInfo structure.
140 ***************************************************************************/
142 static void init_dom_query_3(struct lsa_DomainInfo *r,
146 init_lsa_StringLarge(&r->name, name);
150 /***************************************************************************
151 initialize a lsa_DomainInfo structure.
152 ***************************************************************************/
154 static void init_dom_query_5(struct lsa_DomainInfo *r,
158 init_lsa_StringLarge(&r->name, name);
162 /***************************************************************************
163 lookup_lsa_rids. Must be called as root for lookup_name to work.
164 ***************************************************************************/
166 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
167 struct lsa_RefDomainList *ref,
168 struct lsa_TranslatedSid *prid,
169 uint32_t num_entries,
170 struct lsa_String *name,
172 uint32_t *pmapped_count)
174 uint32 mapped_count, i;
176 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
181 for (i = 0; i < num_entries; i++) {
185 const char *full_name;
187 enum lsa_SidType type = SID_NAME_UNKNOWN;
189 /* Split name into domain and user component */
191 /* follow w2k8 behavior and return the builtin domain when no
192 * input has been passed in */
194 if (name[i].string) {
195 full_name = name[i].string;
197 full_name = "BUILTIN";
200 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
202 /* We can ignore the result of lookup_name, it will not touch
203 "type" if it's not successful */
205 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
210 case SID_NAME_DOM_GRP:
211 case SID_NAME_DOMAIN:
213 case SID_NAME_WKN_GRP:
214 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
215 /* Leave these unchanged */
218 /* Don't hand out anything but the list above */
219 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
220 type = SID_NAME_UNKNOWN;
227 if (type != SID_NAME_UNKNOWN) {
228 if (type == SID_NAME_DOMAIN) {
231 sid_split_rid(&sid, &rid);
233 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
237 prid[i].sid_type = type;
239 prid[i].sid_index = dom_idx;
242 *pmapped_count = mapped_count;
246 /***************************************************************************
247 lookup_lsa_sids. Must be called as root for lookup_name to work.
248 ***************************************************************************/
250 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
251 struct lsa_RefDomainList *ref,
252 struct lsa_TranslatedSid3 *trans_sids,
253 uint32_t num_entries,
254 struct lsa_String *name,
256 uint32 *pmapped_count)
258 uint32 mapped_count, i;
260 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
265 for (i = 0; i < num_entries; i++) {
269 const char *full_name;
271 enum lsa_SidType type = SID_NAME_UNKNOWN;
275 /* Split name into domain and user component */
277 full_name = name[i].string;
278 if (full_name == NULL) {
279 return NT_STATUS_NO_MEMORY;
282 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
284 /* We can ignore the result of lookup_name, it will not touch
285 "type" if it's not successful */
287 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
292 case SID_NAME_DOM_GRP:
293 case SID_NAME_DOMAIN:
295 case SID_NAME_WKN_GRP:
296 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
297 /* Leave these unchanged */
300 /* Don't hand out anything but the list above */
301 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
302 type = SID_NAME_UNKNOWN;
309 if (type != SID_NAME_UNKNOWN) {
310 struct dom_sid domain_sid;
311 sid_copy(&domain_sid, &sid);
312 sid_split_rid(&domain_sid, &rid);
313 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
317 /* Initialize the lsa_TranslatedSid3 return. */
318 trans_sids[i].sid_type = type;
319 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
320 trans_sids[i].sid_index = dom_idx;
323 *pmapped_count = mapped_count;
327 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
328 const struct generic_mapping *map,
329 struct dom_sid *sid, uint32_t sid_access)
331 struct dom_sid adm_sid;
332 struct security_ace ace[5];
335 struct security_acl *psa = NULL;
337 /* READ|EXECUTE access for Everyone */
339 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
340 map->generic_execute | map->generic_read, 0);
342 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
344 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
345 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
346 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
347 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
349 /* Add Full Access for Domain Admins */
350 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
351 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
352 map->generic_all, 0);
354 /* If we have a sid, give it some special access */
357 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
361 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
362 return NT_STATUS_NO_MEMORY;
364 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
365 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
366 psa, sd_size)) == NULL)
367 return NT_STATUS_NO_MEMORY;
372 /***************************************************************************
373 ***************************************************************************/
375 static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
376 struct pipes_struct *p,
377 enum lsa_handle_type type,
378 uint32_t acc_granted,
381 const struct security_descriptor *sd,
382 struct policy_handle *handle)
384 struct lsa_info *info;
386 ZERO_STRUCTP(handle);
388 info = talloc_zero(mem_ctx, struct lsa_info);
390 return NT_STATUS_NO_MEMORY;
394 info->access = acc_granted;
397 sid_copy(&info->sid, sid);
400 info->name = talloc_strdup(info, name);
403 info->sd = dup_sec_desc(info, sd);
406 return NT_STATUS_NO_MEMORY;
410 if (!create_policy_hnd(p, handle, info)) {
412 ZERO_STRUCTP(handle);
413 return NT_STATUS_NO_MEMORY;
419 /***************************************************************************
421 ***************************************************************************/
423 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
424 struct lsa_OpenPolicy2 *r)
426 struct security_descriptor *psd = NULL;
428 uint32 des_access = r->in.access_mask;
432 /* Work out max allowed. */
433 map_max_allowed_access(p->server_info->security_token,
434 &p->server_info->utok,
437 /* map the generic bits to the lsa policy ones */
438 se_map_generic(&des_access, &lsa_policy_mapping);
440 /* get the generic lsa policy SD until we store it */
441 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
443 if (!NT_STATUS_IS_OK(status)) {
447 status = access_check_object(psd, p->server_info->security_token,
448 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
449 &acc_granted, "_lsa_OpenPolicy2" );
450 if (!NT_STATUS_IS_OK(status)) {
454 status = create_lsa_policy_handle(p->mem_ctx, p,
455 LSA_HANDLE_POLICY_TYPE,
457 get_global_sam_sid(),
461 if (!NT_STATUS_IS_OK(status)) {
462 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
468 /***************************************************************************
470 ***************************************************************************/
472 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
473 struct lsa_OpenPolicy *r)
475 struct lsa_OpenPolicy2 o;
477 o.in.system_name = NULL; /* should be ignored */
478 o.in.attr = r->in.attr;
479 o.in.access_mask = r->in.access_mask;
481 o.out.handle = r->out.handle;
483 return _lsa_OpenPolicy2(p, &o);
486 /***************************************************************************
487 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
489 ***************************************************************************/
491 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
492 struct lsa_EnumTrustDom *r)
494 struct lsa_info *info;
496 struct trustdom_info **domains;
497 struct lsa_DomainInfo *entries;
501 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
502 return NT_STATUS_INVALID_HANDLE;
504 if (info->type != LSA_HANDLE_POLICY_TYPE) {
505 return NT_STATUS_INVALID_HANDLE;
508 /* check if the user has enough rights */
509 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
510 return NT_STATUS_ACCESS_DENIED;
513 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
516 if (!NT_STATUS_IS_OK(nt_status)) {
520 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo, count);
522 return NT_STATUS_NO_MEMORY;
525 for (i=0; i<count; i++) {
526 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
527 entries[i].sid = &domains[i]->sid;
530 if (*r->in.resume_handle >= count) {
531 *r->out.resume_handle = -1;
532 TALLOC_FREE(entries);
533 return NT_STATUS_NO_MORE_ENTRIES;
536 /* return the rest, limit by max_size. Note that we
537 use the w2k3 element size value of 60 */
538 r->out.domains->count = count - *r->in.resume_handle;
539 r->out.domains->count = MIN(r->out.domains->count,
540 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
542 r->out.domains->domains = entries + *r->in.resume_handle;
544 if (r->out.domains->count < count - *r->in.resume_handle) {
545 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
546 return STATUS_MORE_ENTRIES;
549 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
550 * always be larger than the previous input resume handle, in
551 * particular when hitting the last query it is vital to set the
552 * resume handle correctly to avoid infinite client loops, as
553 * seen e.g. with Windows XP SP3 when resume handle is 0 and
554 * status is NT_STATUS_OK - gd */
556 *r->out.resume_handle = (uint32_t)-1;
561 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
562 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
563 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
565 /***************************************************************************
567 ***************************************************************************/
569 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
570 struct lsa_QueryInfoPolicy *r)
572 NTSTATUS status = NT_STATUS_OK;
573 struct lsa_info *handle;
574 struct dom_sid domain_sid;
576 struct dom_sid *sid = NULL;
577 union lsa_PolicyInformation *info = NULL;
578 uint32_t acc_required = 0;
580 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
581 return NT_STATUS_INVALID_HANDLE;
583 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
584 return NT_STATUS_INVALID_HANDLE;
587 switch (r->in.level) {
588 case LSA_POLICY_INFO_AUDIT_LOG:
589 case LSA_POLICY_INFO_AUDIT_EVENTS:
590 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
592 case LSA_POLICY_INFO_DOMAIN:
593 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
595 case LSA_POLICY_INFO_PD:
596 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
598 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
599 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
601 case LSA_POLICY_INFO_ROLE:
602 case LSA_POLICY_INFO_REPLICA:
603 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
605 case LSA_POLICY_INFO_QUOTA:
606 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
608 case LSA_POLICY_INFO_MOD:
609 case LSA_POLICY_INFO_AUDIT_FULL_SET:
610 /* according to MS-LSAD 3.1.4.4.3 */
611 return NT_STATUS_INVALID_PARAMETER;
612 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
613 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
615 case LSA_POLICY_INFO_DNS:
616 case LSA_POLICY_INFO_DNS_INT:
617 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
618 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
624 if (!(handle->access & acc_required)) {
625 /* return NT_STATUS_ACCESS_DENIED; */
628 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
630 return NT_STATUS_NO_MEMORY;
633 switch (r->in.level) {
634 /* according to MS-LSAD 3.1.4.4.3 */
635 case LSA_POLICY_INFO_MOD:
636 case LSA_POLICY_INFO_AUDIT_FULL_SET:
637 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
638 return NT_STATUS_INVALID_PARAMETER;
639 case LSA_POLICY_INFO_AUDIT_LOG:
640 info->audit_log.percent_full = 0;
641 info->audit_log.maximum_log_size = 0;
642 info->audit_log.retention_time = 0;
643 info->audit_log.shutdown_in_progress = 0;
644 info->audit_log.time_to_shutdown = 0;
645 info->audit_log.next_audit_record = 0;
646 status = NT_STATUS_OK;
648 case LSA_POLICY_INFO_PD:
649 info->pd.name.string = NULL;
650 status = NT_STATUS_OK;
652 case LSA_POLICY_INFO_REPLICA:
653 info->replica.source.string = NULL;
654 info->replica.account.string = NULL;
655 status = NT_STATUS_OK;
657 case LSA_POLICY_INFO_QUOTA:
658 info->quota.paged_pool = 0;
659 info->quota.non_paged_pool = 0;
660 info->quota.min_wss = 0;
661 info->quota.max_wss = 0;
662 info->quota.pagefile = 0;
663 info->quota.unknown = 0;
664 status = NT_STATUS_OK;
666 case LSA_POLICY_INFO_AUDIT_EVENTS:
669 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
671 /* check if the user has enough rights */
672 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
673 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
674 return NT_STATUS_ACCESS_DENIED;
677 /* fake info: We audit everything. ;) */
679 info->audit_events.auditing_mode = true;
680 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
681 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
682 enum lsa_PolicyAuditPolicy,
683 info->audit_events.count);
684 if (!info->audit_events.settings) {
685 return NT_STATUS_NO_MEMORY;
688 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
689 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
690 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
691 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
692 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
693 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
694 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
698 case LSA_POLICY_INFO_DOMAIN:
699 /* check if the user has enough rights */
700 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
701 return NT_STATUS_ACCESS_DENIED;
703 /* Request PolicyPrimaryDomainInformation. */
704 switch (lp_server_role()) {
705 case ROLE_DOMAIN_PDC:
706 case ROLE_DOMAIN_BDC:
707 name = get_global_sam_name();
708 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
710 return NT_STATUS_NO_MEMORY;
713 case ROLE_DOMAIN_MEMBER:
714 name = lp_workgroup();
715 /* We need to return the Domain SID here. */
716 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
717 sid = dom_sid_dup(p->mem_ctx, &domain_sid);
719 return NT_STATUS_NO_MEMORY;
722 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
725 case ROLE_STANDALONE:
726 name = lp_workgroup();
730 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
732 init_dom_query_3(&info->domain, name, sid);
734 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
735 /* check if the user has enough rights */
736 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
737 return NT_STATUS_ACCESS_DENIED;
739 /* Request PolicyAccountDomainInformation. */
740 name = get_global_sam_name();
741 sid = get_global_sam_sid();
743 init_dom_query_5(&info->account_domain, name, sid);
745 case LSA_POLICY_INFO_ROLE:
746 /* check if the user has enough rights */
747 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
748 return NT_STATUS_ACCESS_DENIED;
750 switch (lp_server_role()) {
751 case ROLE_DOMAIN_BDC:
753 * only a BDC is a backup controller
754 * of the domain, it controls.
756 info->role.role = LSA_ROLE_BACKUP;
760 * any other role is a primary
761 * of the domain, it controls.
763 info->role.role = LSA_ROLE_PRIMARY;
767 case LSA_POLICY_INFO_DNS:
768 case LSA_POLICY_INFO_DNS_INT: {
769 struct pdb_domain_info *dominfo;
771 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
772 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
773 "without ADS passdb backend\n"));
774 status = NT_STATUS_INVALID_INFO_CLASS;
778 dominfo = pdb_get_domain_info(info);
779 if (dominfo == NULL) {
780 status = NT_STATUS_NO_MEMORY;
784 init_lsa_StringLarge(&info->dns.name,
786 init_lsa_StringLarge(&info->dns.dns_domain,
787 dominfo->dns_domain);
788 init_lsa_StringLarge(&info->dns.dns_forest,
789 dominfo->dns_forest);
790 info->dns.domain_guid = dominfo->guid;
791 info->dns.sid = &dominfo->sid;
795 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
797 status = NT_STATUS_INVALID_INFO_CLASS;
806 /***************************************************************************
807 _lsa_QueryInfoPolicy2
808 ***************************************************************************/
810 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
811 struct lsa_QueryInfoPolicy2 *r2)
813 struct lsa_QueryInfoPolicy r;
815 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
816 p->rng_fault_state = True;
817 return NT_STATUS_NOT_IMPLEMENTED;
821 r.in.handle = r2->in.handle;
822 r.in.level = r2->in.level;
823 r.out.info = r2->out.info;
825 return _lsa_QueryInfoPolicy(p, &r);
828 /***************************************************************************
829 _lsa_lookup_sids_internal
830 ***************************************************************************/
832 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
834 uint16_t level, /* input */
835 int num_sids, /* input */
836 struct lsa_SidPtr *sid, /* input */
837 struct lsa_RefDomainList **pp_ref, /* input/output */
838 struct lsa_TranslatedName2 **pp_names,/* input/output */
839 uint32_t *pp_mapped_count) /* input/output */
843 const struct dom_sid **sids = NULL;
844 struct lsa_RefDomainList *ref = NULL;
845 uint32 mapped_count = 0;
846 struct lsa_dom_info *dom_infos = NULL;
847 struct lsa_name_info *name_infos = NULL;
848 struct lsa_TranslatedName2 *names = NULL;
850 *pp_mapped_count = 0;
858 sids = TALLOC_ARRAY(p->mem_ctx, const struct dom_sid *, num_sids);
859 ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
861 if (sids == NULL || ref == NULL) {
862 return NT_STATUS_NO_MEMORY;
865 for (i=0; i<num_sids; i++) {
866 sids[i] = sid[i].sid;
869 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
870 &dom_infos, &name_infos);
872 if (!NT_STATUS_IS_OK(status)) {
876 names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
878 return NT_STATUS_NO_MEMORY;
881 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
883 if (!dom_infos[i].valid) {
887 if (init_lsa_ref_domain_list(mem_ctx, ref,
889 &dom_infos[i].sid) != i) {
890 DEBUG(0, ("Domain %s mentioned twice??\n",
892 return NT_STATUS_INTERNAL_ERROR;
896 for (i=0; i<num_sids; i++) {
897 struct lsa_name_info *name = &name_infos[i];
899 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 = talloc_asprintf(p->mem_ctx, "%s",
911 if (name->name == NULL) {
912 return NT_STATUS_NO_MEMORY;
918 names[i].sid_type = name->type;
919 names[i].name.string = name->name;
920 names[i].sid_index = name->dom_idx;
921 names[i].unknown = 0;
924 status = NT_STATUS_NONE_MAPPED;
925 if (mapped_count > 0) {
926 status = (mapped_count < num_sids) ?
927 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
930 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
931 num_sids, mapped_count, nt_errstr(status)));
933 *pp_mapped_count = mapped_count;
940 /***************************************************************************
942 ***************************************************************************/
944 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
945 struct lsa_LookupSids *r)
948 struct lsa_info *handle;
949 int num_sids = r->in.sids->num_sids;
950 uint32 mapped_count = 0;
951 struct lsa_RefDomainList *domains = NULL;
952 struct lsa_TranslatedName *names_out = NULL;
953 struct lsa_TranslatedName2 *names = NULL;
956 if ((r->in.level < 1) || (r->in.level > 6)) {
957 return NT_STATUS_INVALID_PARAMETER;
960 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
961 return NT_STATUS_INVALID_HANDLE;
964 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
965 return NT_STATUS_INVALID_HANDLE;
968 /* check if the user has enough rights */
969 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
970 return NT_STATUS_ACCESS_DENIED;
973 if (num_sids > MAX_LOOKUP_SIDS) {
974 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
975 MAX_LOOKUP_SIDS, num_sids));
976 return NT_STATUS_NONE_MAPPED;
979 status = _lsa_lookup_sids_internal(p,
988 /* Only return here when there is a real error.
989 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
990 the requested sids could be resolved. Older versions of XP (pre SP3)
991 rely that we return with the string representations of those SIDs in
992 that case. If we don't, XP crashes - Guenther
995 if (NT_STATUS_IS_ERR(status) &&
996 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1000 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
1001 names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
1004 return NT_STATUS_NO_MEMORY;
1007 for (i=0; i<num_sids; i++) {
1008 names_out[i].sid_type = names[i].sid_type;
1009 names_out[i].name = names[i].name;
1010 names_out[i].sid_index = names[i].sid_index;
1013 *r->out.domains = domains;
1014 r->out.names->count = num_sids;
1015 r->out.names->names = names_out;
1016 *r->out.count = mapped_count;
1021 /***************************************************************************
1023 ***************************************************************************/
1025 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1026 struct lsa_LookupSids2 *r)
1029 struct lsa_info *handle;
1030 int num_sids = r->in.sids->num_sids;
1031 uint32 mapped_count = 0;
1032 struct lsa_RefDomainList *domains = NULL;
1033 struct lsa_TranslatedName2 *names = NULL;
1034 bool check_policy = true;
1037 case NDR_LSA_LOOKUPSIDS3:
1038 check_policy = false;
1040 case NDR_LSA_LOOKUPSIDS2:
1042 check_policy = true;
1045 if ((r->in.level < 1) || (r->in.level > 6)) {
1046 return NT_STATUS_INVALID_PARAMETER;
1050 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1051 return NT_STATUS_INVALID_HANDLE;
1054 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1055 return NT_STATUS_INVALID_HANDLE;
1058 /* check if the user has enough rights */
1059 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1060 return NT_STATUS_ACCESS_DENIED;
1064 if (num_sids > MAX_LOOKUP_SIDS) {
1065 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1066 MAX_LOOKUP_SIDS, num_sids));
1067 return NT_STATUS_NONE_MAPPED;
1070 status = _lsa_lookup_sids_internal(p,
1079 *r->out.domains = domains;
1080 r->out.names->count = num_sids;
1081 r->out.names->names = names;
1082 *r->out.count = mapped_count;
1087 /***************************************************************************
1089 ***************************************************************************/
1091 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1092 struct lsa_LookupSids3 *r)
1094 struct lsa_LookupSids2 q;
1096 /* No policy handle on this call. Restrict to crypto connections. */
1097 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1098 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1099 get_remote_machine_name() ));
1100 return NT_STATUS_INVALID_PARAMETER;
1104 q.in.sids = r->in.sids;
1105 q.in.level = r->in.level;
1106 q.in.lookup_options = r->in.lookup_options;
1107 q.in.client_revision = r->in.client_revision;
1108 q.in.names = r->in.names;
1109 q.in.count = r->in.count;
1111 q.out.domains = r->out.domains;
1112 q.out.names = r->out.names;
1113 q.out.count = r->out.count;
1115 return _lsa_LookupSids2(p, &q);
1118 /***************************************************************************
1119 ***************************************************************************/
1121 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1126 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1127 flags = LOOKUP_NAME_ALL;
1129 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1130 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1132 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1133 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1135 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1136 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1137 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1138 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1140 flags = LOOKUP_NAME_NONE;
1147 /***************************************************************************
1149 ***************************************************************************/
1151 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1152 struct lsa_LookupNames *r)
1154 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1155 struct lsa_info *handle;
1156 struct lsa_String *names = r->in.names;
1157 uint32 num_entries = r->in.num_names;
1158 struct lsa_RefDomainList *domains = NULL;
1159 struct lsa_TranslatedSid *rids = NULL;
1160 uint32 mapped_count = 0;
1163 if (num_entries > MAX_LOOKUP_SIDS) {
1164 num_entries = MAX_LOOKUP_SIDS;
1165 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1169 flags = lsa_lookup_level_to_flags(r->in.level);
1171 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1173 return NT_STATUS_NO_MEMORY;
1177 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1180 return NT_STATUS_NO_MEMORY;
1186 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1187 status = NT_STATUS_INVALID_HANDLE;
1191 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1192 return NT_STATUS_INVALID_HANDLE;
1195 /* check if the user has enough rights */
1196 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1197 status = NT_STATUS_ACCESS_DENIED;
1201 /* set up the LSA Lookup RIDs response */
1202 become_root(); /* lookup_name can require root privs */
1203 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1204 names, flags, &mapped_count);
1209 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1210 if (mapped_count == 0) {
1211 status = NT_STATUS_NONE_MAPPED;
1212 } else if (mapped_count != num_entries) {
1213 status = STATUS_SOME_UNMAPPED;
1217 *r->out.count = mapped_count;
1218 *r->out.domains = domains;
1219 r->out.sids->sids = rids;
1220 r->out.sids->count = num_entries;
1225 /***************************************************************************
1227 ***************************************************************************/
1229 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1230 struct lsa_LookupNames2 *r)
1233 struct lsa_LookupNames q;
1234 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1235 struct lsa_TransSidArray *sid_array = NULL;
1238 sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1240 return NT_STATUS_NO_MEMORY;
1243 q.in.handle = r->in.handle;
1244 q.in.num_names = r->in.num_names;
1245 q.in.names = r->in.names;
1246 q.in.level = r->in.level;
1247 q.in.sids = sid_array;
1248 q.in.count = r->in.count;
1249 /* we do not know what this is for */
1250 /* = r->in.unknown1; */
1251 /* = r->in.unknown2; */
1253 q.out.domains = r->out.domains;
1254 q.out.sids = sid_array;
1255 q.out.count = r->out.count;
1257 status = _lsa_LookupNames(p, &q);
1259 sid_array2->count = sid_array->count;
1260 sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1261 if (!sid_array2->sids) {
1262 return NT_STATUS_NO_MEMORY;
1265 for (i=0; i<sid_array->count; i++) {
1266 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1267 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1268 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1269 sid_array2->sids[i].unknown = 0;
1272 r->out.sids = sid_array2;
1277 /***************************************************************************
1279 ***************************************************************************/
1281 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1282 struct lsa_LookupNames3 *r)
1285 struct lsa_info *handle;
1286 struct lsa_String *names = r->in.names;
1287 uint32 num_entries = r->in.num_names;
1288 struct lsa_RefDomainList *domains = NULL;
1289 struct lsa_TranslatedSid3 *trans_sids = NULL;
1290 uint32 mapped_count = 0;
1292 bool check_policy = true;
1295 case NDR_LSA_LOOKUPNAMES4:
1296 check_policy = false;
1298 case NDR_LSA_LOOKUPNAMES3:
1300 check_policy = true;
1303 if (num_entries > MAX_LOOKUP_SIDS) {
1304 num_entries = MAX_LOOKUP_SIDS;
1305 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1308 /* Probably the lookup_level is some sort of bitmask. */
1309 if (r->in.level == 1) {
1310 flags = LOOKUP_NAME_ALL;
1313 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1315 return NT_STATUS_NO_MEMORY;
1319 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1322 return NT_STATUS_NO_MEMORY;
1330 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1331 status = NT_STATUS_INVALID_HANDLE;
1335 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1336 return NT_STATUS_INVALID_HANDLE;
1339 /* check if the user has enough rights */
1340 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1341 status = NT_STATUS_ACCESS_DENIED;
1346 /* set up the LSA Lookup SIDs response */
1347 become_root(); /* lookup_name can require root privs */
1348 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1349 names, flags, &mapped_count);
1354 if (NT_STATUS_IS_OK(status)) {
1355 if (mapped_count == 0) {
1356 status = NT_STATUS_NONE_MAPPED;
1357 } else if (mapped_count != num_entries) {
1358 status = STATUS_SOME_UNMAPPED;
1362 *r->out.count = mapped_count;
1363 *r->out.domains = domains;
1364 r->out.sids->sids = trans_sids;
1365 r->out.sids->count = num_entries;
1370 /***************************************************************************
1372 ***************************************************************************/
1374 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1375 struct lsa_LookupNames4 *r)
1377 struct lsa_LookupNames3 q;
1379 /* No policy handle on this call. Restrict to crypto connections. */
1380 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1381 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1382 get_remote_machine_name() ));
1383 return NT_STATUS_INVALID_PARAMETER;
1387 q.in.num_names = r->in.num_names;
1388 q.in.names = r->in.names;
1389 q.in.level = r->in.level;
1390 q.in.lookup_options = r->in.lookup_options;
1391 q.in.client_revision = r->in.client_revision;
1392 q.in.sids = r->in.sids;
1393 q.in.count = r->in.count;
1395 q.out.domains = r->out.domains;
1396 q.out.sids = r->out.sids;
1397 q.out.count = r->out.count;
1399 return _lsa_LookupNames3(p, &q);
1402 /***************************************************************************
1403 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1404 ***************************************************************************/
1406 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1408 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1409 return NT_STATUS_INVALID_HANDLE;
1412 close_policy_hnd(p, r->in.handle);
1413 ZERO_STRUCTP(r->out.handle);
1414 return NT_STATUS_OK;
1417 /***************************************************************************
1418 ***************************************************************************/
1420 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1421 const struct dom_sid *sid,
1422 struct trustdom_info **info)
1425 uint32_t num_domains = 0;
1426 struct trustdom_info **domains = NULL;
1429 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1430 if (!NT_STATUS_IS_OK(status)) {
1434 for (i=0; i < num_domains; i++) {
1435 if (dom_sid_equal(&domains[i]->sid, sid)) {
1440 if (i == num_domains) {
1441 return NT_STATUS_INVALID_PARAMETER;
1446 return NT_STATUS_OK;
1449 /***************************************************************************
1450 ***************************************************************************/
1452 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1453 const char *netbios_domain_name,
1454 struct trustdom_info **info_p)
1457 struct trustdom_info *info;
1458 struct pdb_trusted_domain *td;
1460 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1461 if (!NT_STATUS_IS_OK(status)) {
1465 info = talloc(mem_ctx, struct trustdom_info);
1467 return NT_STATUS_NO_MEMORY;
1470 info->name = talloc_strdup(info, netbios_domain_name);
1471 NT_STATUS_HAVE_NO_MEMORY(info->name);
1473 sid_copy(&info->sid, &td->security_identifier);
1477 return NT_STATUS_OK;
1480 /***************************************************************************
1481 ***************************************************************************/
1483 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p, struct lsa_OpenSecret *r)
1485 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1488 /***************************************************************************
1489 _lsa_OpenTrustedDomain_base
1490 ***************************************************************************/
1492 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1493 uint32_t access_mask,
1494 struct trustdom_info *info,
1495 struct policy_handle *handle)
1497 struct security_descriptor *psd = NULL;
1499 uint32_t acc_granted;
1502 /* des_access is for the account here, not the policy
1503 * handle - so don't check against policy handle. */
1505 /* Work out max allowed. */
1506 map_max_allowed_access(p->server_info->security_token,
1507 &p->server_info->utok,
1510 /* map the generic bits to the lsa account ones */
1511 se_map_generic(&access_mask, &lsa_account_mapping);
1513 /* get the generic lsa account SD until we store it */
1514 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1515 &lsa_trusted_domain_mapping,
1517 if (!NT_STATUS_IS_OK(status)) {
1521 status = access_check_object(psd, p->server_info->security_token,
1522 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1523 access_mask, &acc_granted,
1524 "_lsa_OpenTrustedDomain");
1525 if (!NT_STATUS_IS_OK(status)) {
1529 status = create_lsa_policy_handle(p->mem_ctx, p,
1530 LSA_HANDLE_TRUST_TYPE,
1536 if (!NT_STATUS_IS_OK(status)) {
1537 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1540 return NT_STATUS_OK;
1543 /***************************************************************************
1544 _lsa_OpenTrustedDomain
1545 ***************************************************************************/
1547 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1548 struct lsa_OpenTrustedDomain *r)
1550 struct lsa_info *handle = NULL;
1551 struct trustdom_info *info = NULL;
1554 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1555 return NT_STATUS_INVALID_HANDLE;
1558 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1559 return NT_STATUS_INVALID_HANDLE;
1562 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1565 if (!NT_STATUS_IS_OK(status)) {
1569 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1570 r->out.trustdom_handle);
1573 /***************************************************************************
1574 _lsa_OpenTrustedDomainByName
1575 ***************************************************************************/
1577 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1578 struct lsa_OpenTrustedDomainByName *r)
1580 struct lsa_info *handle = NULL;
1581 struct trustdom_info *info = NULL;
1584 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1585 return NT_STATUS_INVALID_HANDLE;
1588 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1589 return NT_STATUS_INVALID_HANDLE;
1592 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1595 if (!NT_STATUS_IS_OK(status)) {
1599 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1600 r->out.trustdom_handle);
1603 static NTSTATUS add_trusted_domain_user(TALLOC_CTX *mem_ctx,
1604 const char *netbios_name,
1605 const char *domain_name,
1606 struct trustDomainPasswords auth_struct)
1609 struct samu *sam_acct;
1612 struct dom_sid user_sid;
1617 sam_acct = samu_new(mem_ctx);
1618 if (sam_acct == NULL) {
1619 return NT_STATUS_NO_MEMORY;
1622 acct_name = talloc_asprintf(mem_ctx, "%s$", netbios_name);
1623 if (acct_name == NULL) {
1624 return NT_STATUS_NO_MEMORY;
1626 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1627 return NT_STATUS_UNSUCCESSFUL;
1630 if (!pdb_set_domain(sam_acct, domain_name, PDB_SET)) {
1631 return NT_STATUS_UNSUCCESSFUL;
1634 if (!pdb_set_acct_ctrl(sam_acct, ACB_DOMTRUST, PDB_SET)) {
1635 return NT_STATUS_UNSUCCESSFUL;
1638 if (!pdb_new_rid(&rid)) {
1639 return NT_STATUS_DS_NO_MORE_RIDS;
1641 sid_compose(&user_sid, get_global_sam_sid(), rid);
1642 if (!pdb_set_user_sid(sam_acct, &user_sid, PDB_SET)) {
1643 return NT_STATUS_UNSUCCESSFUL;
1646 for (i = 0; i < auth_struct.incoming.count; i++) {
1647 switch (auth_struct.incoming.current.array[i].AuthType) {
1648 case TRUST_AUTH_TYPE_CLEAR:
1649 if (!convert_string_talloc(mem_ctx,
1652 auth_struct.incoming.current.array[i].AuthInfo.clear.password,
1653 auth_struct.incoming.current.array[i].AuthInfo.clear.size,
1657 return NT_STATUS_UNSUCCESSFUL;
1659 if (!pdb_set_plaintext_passwd(sam_acct, dummy)) {
1660 return NT_STATUS_UNSUCCESSFUL;
1668 status = pdb_add_sam_account(sam_acct);
1669 if (!NT_STATUS_IS_OK(status)) {
1673 return NT_STATUS_OK;
1676 /***************************************************************************
1677 _lsa_CreateTrustedDomainEx2
1678 ***************************************************************************/
1680 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1681 struct lsa_CreateTrustedDomainEx2 *r)
1683 struct lsa_info *policy;
1685 uint32_t acc_granted;
1686 struct security_descriptor *psd;
1688 struct pdb_trusted_domain td;
1689 struct trustDomainPasswords auth_struct;
1690 enum ndr_err_code ndr_err;
1691 DATA_BLOB auth_blob;
1694 return NT_STATUS_NOT_SUPPORTED;
1697 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1698 return NT_STATUS_INVALID_HANDLE;
1701 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1702 return NT_STATUS_ACCESS_DENIED;
1705 if (p->server_info->utok.uid != sec_initial_uid() &&
1706 !nt_token_check_domain_rid(p->server_info->security_token, DOMAIN_RID_ADMINS)) {
1707 return NT_STATUS_ACCESS_DENIED;
1710 /* Work out max allowed. */
1711 map_max_allowed_access(p->server_info->security_token,
1712 &p->server_info->utok,
1713 &r->in.access_mask);
1715 /* map the generic bits to the lsa policy ones */
1716 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1718 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1719 &lsa_trusted_domain_mapping,
1721 if (!NT_STATUS_IS_OK(status)) {
1725 status = access_check_object(psd, p->server_info->security_token,
1726 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1727 r->in.access_mask, &acc_granted,
1728 "_lsa_CreateTrustedDomainEx2");
1729 if (!NT_STATUS_IS_OK(status)) {
1735 td.domain_name = talloc_strdup(p->mem_ctx,
1736 r->in.info->domain_name.string);
1737 if (td.domain_name == NULL) {
1738 return NT_STATUS_NO_MEMORY;
1740 td.netbios_name = talloc_strdup(p->mem_ctx,
1741 r->in.info->netbios_name.string);
1742 if (td.netbios_name == NULL) {
1743 return NT_STATUS_NO_MEMORY;
1745 sid_copy(&td.security_identifier, r->in.info->sid);
1746 td.trust_direction = r->in.info->trust_direction;
1747 td.trust_type = r->in.info->trust_type;
1748 td.trust_attributes = r->in.info->trust_attributes;
1750 if (r->in.auth_info->auth_blob.size != 0) {
1751 auth_blob.length = r->in.auth_info->auth_blob.size;
1752 auth_blob.data = r->in.auth_info->auth_blob.data;
1754 arcfour_crypt_blob(auth_blob.data, auth_blob.length,
1755 &p->server_info->user_session_key);
1757 ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
1759 (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
1760 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1761 return NT_STATUS_UNSUCCESSFUL;
1764 ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
1765 &auth_struct.incoming,
1766 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1767 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1768 return NT_STATUS_UNSUCCESSFUL;
1771 ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
1772 &auth_struct.outgoing,
1773 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1774 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1775 return NT_STATUS_UNSUCCESSFUL;
1778 td.trust_auth_incoming.data = NULL;
1779 td.trust_auth_incoming.length = 0;
1780 td.trust_auth_outgoing.data = NULL;
1781 td.trust_auth_outgoing.length = 0;
1784 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1785 if (!NT_STATUS_IS_OK(status)) {
1789 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1790 status = add_trusted_domain_user(p->mem_ctx,
1791 r->in.info->netbios_name.string,
1792 r->in.info->domain_name.string,
1794 if (!NT_STATUS_IS_OK(status)) {
1799 status = create_lsa_policy_handle(p->mem_ctx, p,
1800 LSA_HANDLE_TRUST_TYPE,
1803 r->in.info->netbios_name.string,
1805 r->out.trustdom_handle);
1806 if (!NT_STATUS_IS_OK(status)) {
1807 pdb_del_trusteddom_pw(r->in.info->netbios_name.string);
1808 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1811 return NT_STATUS_OK;
1814 /***************************************************************************
1815 _lsa_CreateTrustedDomainEx
1816 ***************************************************************************/
1818 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1819 struct lsa_CreateTrustedDomainEx *r)
1821 struct lsa_CreateTrustedDomainEx2 q;
1823 q.in.policy_handle = r->in.policy_handle;
1824 q.in.info = r->in.info;
1825 q.in.auth_info = r->in.auth_info;
1826 q.in.access_mask = r->in.access_mask;
1827 q.out.trustdom_handle = r->out.trustdom_handle;
1829 return _lsa_CreateTrustedDomainEx2(p, &q);
1832 /***************************************************************************
1833 _lsa_CreateTrustedDomain
1834 ***************************************************************************/
1836 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1837 struct lsa_CreateTrustedDomain *r)
1839 struct lsa_CreateTrustedDomainEx2 c;
1840 struct lsa_TrustDomainInfoInfoEx info;
1841 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1843 ZERO_STRUCT(auth_info);
1845 info.domain_name = r->in.info->name;
1846 info.netbios_name = r->in.info->name;
1847 info.sid = r->in.info->sid;
1848 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1849 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1850 info.trust_attributes = 0;
1852 c.in.policy_handle = r->in.policy_handle;
1854 c.in.auth_info = &auth_info;
1855 c.in.access_mask = r->in.access_mask;
1856 c.out.trustdom_handle = r->out.trustdom_handle;
1858 return _lsa_CreateTrustedDomainEx2(p, &c);
1861 /***************************************************************************
1862 _lsa_DeleteTrustedDomain
1863 ***************************************************************************/
1865 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1866 struct lsa_DeleteTrustedDomain *r)
1869 struct lsa_info *handle;
1870 struct pdb_trusted_domain *td;
1871 struct samu *sam_acct;
1874 /* find the connection policy handle. */
1875 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1876 return NT_STATUS_INVALID_HANDLE;
1879 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1880 return NT_STATUS_INVALID_HANDLE;
1883 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1884 return NT_STATUS_ACCESS_DENIED;
1887 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1888 if (!NT_STATUS_IS_OK(status)) {
1892 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1893 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1894 sid_string_tos(r->in.dom_sid)));
1895 return NT_STATUS_UNSUCCESSFUL;
1898 if (td->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1899 sam_acct = samu_new(p->mem_ctx);
1900 if (sam_acct == NULL) {
1901 return NT_STATUS_NO_MEMORY;
1904 acct_name = talloc_asprintf(p->mem_ctx, "%s$", td->netbios_name);
1905 if (acct_name == NULL) {
1906 return NT_STATUS_NO_MEMORY;
1908 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1909 return NT_STATUS_UNSUCCESSFUL;
1911 status = pdb_delete_sam_account(sam_acct);
1912 if (!NT_STATUS_IS_OK(status)) {
1917 status = pdb_del_trusted_domain(td->netbios_name);
1918 if (!NT_STATUS_IS_OK(status)) {
1922 return NT_STATUS_OK;
1925 /***************************************************************************
1926 _lsa_CloseTrustedDomainEx
1927 ***************************************************************************/
1929 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1930 struct lsa_CloseTrustedDomainEx *r)
1932 return NT_STATUS_NOT_IMPLEMENTED;
1935 /***************************************************************************
1936 _lsa_QueryTrustedDomainInfo
1937 ***************************************************************************/
1939 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
1940 struct lsa_QueryTrustedDomainInfo *r)
1943 struct lsa_info *handle;
1944 union lsa_TrustedDomainInfo *info;
1945 struct pdb_trusted_domain *td;
1946 uint32_t acc_required;
1948 /* find the connection policy handle. */
1949 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
1950 return NT_STATUS_INVALID_HANDLE;
1953 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
1954 return NT_STATUS_INVALID_HANDLE;
1957 switch (r->in.level) {
1958 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1959 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1961 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1962 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
1964 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1965 acc_required = LSA_TRUSTED_QUERY_POSIX;
1967 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
1968 acc_required = LSA_TRUSTED_QUERY_AUTH;
1970 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1971 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1973 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1974 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1976 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1977 acc_required = LSA_TRUSTED_QUERY_AUTH;
1979 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1980 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1981 LSA_TRUSTED_QUERY_POSIX |
1982 LSA_TRUSTED_QUERY_AUTH;
1984 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1985 acc_required = LSA_TRUSTED_QUERY_AUTH;
1987 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1988 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1989 LSA_TRUSTED_QUERY_POSIX |
1990 LSA_TRUSTED_QUERY_AUTH;
1992 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1993 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1995 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1996 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1997 LSA_TRUSTED_QUERY_POSIX |
1998 LSA_TRUSTED_QUERY_AUTH;
2000 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2001 acc_required = LSA_TRUSTED_QUERY_POSIX;
2004 return NT_STATUS_INVALID_PARAMETER;
2007 if (!(handle->access & acc_required)) {
2008 return NT_STATUS_ACCESS_DENIED;
2011 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2012 if (!NT_STATUS_IS_OK(status)) {
2016 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_TrustedDomainInfo);
2018 return NT_STATUS_NO_MEMORY;
2021 switch (r->in.level) {
2022 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2023 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2025 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2026 return NT_STATUS_INVALID_PARAMETER;
2027 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2029 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2030 return NT_STATUS_INVALID_INFO_CLASS;
2031 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2032 return NT_STATUS_INVALID_PARAMETER;
2033 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2034 init_lsa_StringLarge(&info->info_ex.domain_name, td->domain_name);
2035 init_lsa_StringLarge(&info->info_ex.netbios_name, td->netbios_name);
2036 info->info_ex.sid = dom_sid_dup(info, &td->security_identifier);
2037 if (!info->info_ex.sid) {
2038 return NT_STATUS_NO_MEMORY;
2040 info->info_ex.trust_direction = td->trust_direction;
2041 info->info_ex.trust_type = td->trust_type;
2042 info->info_ex.trust_attributes = td->trust_attributes;
2044 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2045 return NT_STATUS_INVALID_INFO_CLASS;
2046 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2048 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2049 return NT_STATUS_INVALID_INFO_CLASS;
2050 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2051 return NT_STATUS_INVALID_INFO_CLASS;
2052 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2053 return NT_STATUS_INVALID_PARAMETER;
2054 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2056 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2059 return NT_STATUS_INVALID_PARAMETER;
2062 *r->out.info = info;
2064 return NT_STATUS_OK;
2067 /***************************************************************************
2068 _lsa_QueryTrustedDomainInfoBySid
2069 ***************************************************************************/
2071 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2072 struct lsa_QueryTrustedDomainInfoBySid *r)
2075 struct policy_handle trustdom_handle;
2076 struct lsa_OpenTrustedDomain o;
2077 struct lsa_QueryTrustedDomainInfo q;
2080 o.in.handle = r->in.handle;
2081 o.in.sid = r->in.dom_sid;
2082 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2083 o.out.trustdom_handle = &trustdom_handle;
2085 status = _lsa_OpenTrustedDomain(p, &o);
2086 if (!NT_STATUS_IS_OK(status)) {
2090 q.in.trustdom_handle = &trustdom_handle;
2091 q.in.level = r->in.level;
2092 q.out.info = r->out.info;
2094 status = _lsa_QueryTrustedDomainInfo(p, &q);
2095 if (!NT_STATUS_IS_OK(status)) {
2099 c.in.handle = &trustdom_handle;
2100 c.out.handle = &trustdom_handle;
2102 return _lsa_Close(p, &c);
2105 /***************************************************************************
2106 _lsa_QueryTrustedDomainInfoByName
2107 ***************************************************************************/
2109 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2110 struct lsa_QueryTrustedDomainInfoByName *r)
2113 struct policy_handle trustdom_handle;
2114 struct lsa_OpenTrustedDomainByName o;
2115 struct lsa_QueryTrustedDomainInfo q;
2118 o.in.handle = r->in.handle;
2119 o.in.name.string = r->in.trusted_domain->string;
2120 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2121 o.out.trustdom_handle = &trustdom_handle;
2123 status = _lsa_OpenTrustedDomainByName(p, &o);
2124 if (!NT_STATUS_IS_OK(status)) {
2125 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2126 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2131 q.in.trustdom_handle = &trustdom_handle;
2132 q.in.level = r->in.level;
2133 q.out.info = r->out.info;
2135 status = _lsa_QueryTrustedDomainInfo(p, &q);
2136 if (!NT_STATUS_IS_OK(status)) {
2140 c.in.handle = &trustdom_handle;
2141 c.out.handle = &trustdom_handle;
2143 return _lsa_Close(p, &c);
2146 /***************************************************************************
2147 ***************************************************************************/
2149 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p, struct lsa_CreateSecret *r)
2151 return NT_STATUS_ACCESS_DENIED;
2154 /***************************************************************************
2155 ***************************************************************************/
2157 NTSTATUS _lsa_SetSecret(struct pipes_struct *p, struct lsa_SetSecret *r)
2159 return NT_STATUS_ACCESS_DENIED;
2162 /***************************************************************************
2164 ***************************************************************************/
2166 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2167 struct lsa_DeleteObject *r)
2170 struct lsa_info *info = NULL;
2172 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2173 return NT_STATUS_INVALID_HANDLE;
2176 if (!(info->access & SEC_STD_DELETE)) {
2177 return NT_STATUS_ACCESS_DENIED;
2180 switch (info->type) {
2181 case LSA_HANDLE_ACCOUNT_TYPE:
2182 status = privilege_delete_account(&info->sid);
2183 if (!NT_STATUS_IS_OK(status)) {
2184 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2185 nt_errstr(status)));
2190 return NT_STATUS_INVALID_HANDLE;
2193 close_policy_hnd(p, r->in.handle);
2194 ZERO_STRUCTP(r->out.handle);
2199 /***************************************************************************
2201 ***************************************************************************/
2203 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2204 struct lsa_EnumPrivs *r)
2206 struct lsa_info *handle;
2208 uint32 enum_context = *r->in.resume_handle;
2209 int num_privs = num_privileges_in_short_list();
2210 struct lsa_PrivEntry *entries = NULL;
2212 /* remember that the enum_context starts at 0 and not 1 */
2214 if ( enum_context >= num_privs )
2215 return NT_STATUS_NO_MORE_ENTRIES;
2217 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2218 enum_context, num_privs));
2220 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2221 return NT_STATUS_INVALID_HANDLE;
2223 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2224 return NT_STATUS_INVALID_HANDLE;
2227 /* check if the user has enough rights
2228 I don't know if it's the right one. not documented. */
2230 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2231 return NT_STATUS_ACCESS_DENIED;
2234 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2236 return NT_STATUS_NO_MEMORY;
2242 for (i = 0; i < num_privs; i++) {
2243 if( i < enum_context) {
2245 init_lsa_StringLarge(&entries[i].name, NULL);
2247 entries[i].luid.low = 0;
2248 entries[i].luid.high = 0;
2251 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2253 entries[i].luid.low = sec_privilege_from_index(i);
2254 entries[i].luid.high = 0;
2258 enum_context = num_privs;
2260 *r->out.resume_handle = enum_context;
2261 r->out.privs->count = num_privs;
2262 r->out.privs->privs = entries;
2264 return NT_STATUS_OK;
2267 /***************************************************************************
2268 _lsa_LookupPrivDisplayName
2269 ***************************************************************************/
2271 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2272 struct lsa_LookupPrivDisplayName *r)
2274 struct lsa_info *handle;
2275 const char *description;
2276 struct lsa_StringLarge *lsa_name;
2278 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2279 return NT_STATUS_INVALID_HANDLE;
2281 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2282 return NT_STATUS_INVALID_HANDLE;
2285 /* check if the user has enough rights */
2288 * I don't know if it's the right one. not documented.
2290 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2291 return NT_STATUS_ACCESS_DENIED;
2293 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2295 description = get_privilege_dispname(r->in.name->string);
2297 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2298 return NT_STATUS_NO_SUCH_PRIVILEGE;
2301 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2303 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2305 return NT_STATUS_NO_MEMORY;
2308 init_lsa_StringLarge(lsa_name, description);
2310 *r->out.returned_language_id = r->in.language_id;
2311 *r->out.disp_name = lsa_name;
2313 return NT_STATUS_OK;
2316 /***************************************************************************
2318 ***************************************************************************/
2320 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2321 struct lsa_EnumAccounts *r)
2323 struct lsa_info *handle;
2324 struct dom_sid *sid_list;
2325 int i, j, num_entries;
2327 struct lsa_SidPtr *sids = NULL;
2329 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2330 return NT_STATUS_INVALID_HANDLE;
2332 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2333 return NT_STATUS_INVALID_HANDLE;
2336 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2337 return NT_STATUS_ACCESS_DENIED;
2342 /* The only way we can currently find out all the SIDs that have been
2343 privileged is to scan all privileges */
2345 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2346 if (!NT_STATUS_IS_OK(status)) {
2350 if (*r->in.resume_handle >= num_entries) {
2351 return NT_STATUS_NO_MORE_ENTRIES;
2354 if (num_entries - *r->in.resume_handle) {
2355 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
2356 num_entries - *r->in.resume_handle);
2358 talloc_free(sid_list);
2359 return NT_STATUS_NO_MEMORY;
2362 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2363 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2365 talloc_free(sid_list);
2366 return NT_STATUS_NO_MEMORY;
2371 talloc_free(sid_list);
2373 *r->out.resume_handle = num_entries;
2374 r->out.sids->num_sids = num_entries;
2375 r->out.sids->sids = sids;
2377 return NT_STATUS_OK;
2380 /***************************************************************************
2382 ***************************************************************************/
2384 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2385 struct lsa_GetUserName *r)
2387 const char *username, *domname;
2388 struct lsa_String *account_name = NULL;
2389 struct lsa_String *authority_name = NULL;
2391 if (r->in.account_name &&
2392 *r->in.account_name) {
2393 return NT_STATUS_INVALID_PARAMETER;
2396 if (r->in.authority_name &&
2397 *r->in.authority_name) {
2398 return NT_STATUS_INVALID_PARAMETER;
2401 if (p->server_info->guest) {
2403 * I'm 99% sure this is not the right place to do this,
2404 * global_sid_Anonymous should probably be put into the token
2405 * instead of the guest id -- vl
2407 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2408 &domname, &username, NULL)) {
2409 return NT_STATUS_NO_MEMORY;
2412 username = p->server_info->sanitized_username;
2413 domname = p->server_info->info3->base.domain.string;
2416 account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2417 if (!account_name) {
2418 return NT_STATUS_NO_MEMORY;
2420 init_lsa_String(account_name, username);
2422 if (r->out.authority_name) {
2423 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2424 if (!authority_name) {
2425 return NT_STATUS_NO_MEMORY;
2427 init_lsa_String(authority_name, domname);
2430 *r->out.account_name = account_name;
2431 if (r->out.authority_name) {
2432 *r->out.authority_name = authority_name;
2435 return NT_STATUS_OK;
2438 /***************************************************************************
2440 ***************************************************************************/
2442 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2443 struct lsa_CreateAccount *r)
2446 struct lsa_info *handle;
2447 uint32_t acc_granted;
2448 struct security_descriptor *psd;
2451 /* find the connection policy handle. */
2452 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2453 return NT_STATUS_INVALID_HANDLE;
2455 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2456 return NT_STATUS_INVALID_HANDLE;
2459 /* check if the user has enough rights */
2461 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2462 return NT_STATUS_ACCESS_DENIED;
2465 /* Work out max allowed. */
2466 map_max_allowed_access(p->server_info->security_token,
2467 &p->server_info->utok,
2468 &r->in.access_mask);
2470 /* map the generic bits to the lsa policy ones */
2471 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2473 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2474 &lsa_account_mapping,
2475 r->in.sid, LSA_POLICY_ALL_ACCESS);
2476 if (!NT_STATUS_IS_OK(status)) {
2480 status = access_check_object(psd, p->server_info->security_token,
2481 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2482 &acc_granted, "_lsa_CreateAccount");
2483 if (!NT_STATUS_IS_OK(status)) {
2487 if ( is_privileged_sid( r->in.sid ) )
2488 return NT_STATUS_OBJECT_NAME_COLLISION;
2490 status = create_lsa_policy_handle(p->mem_ctx, p,
2491 LSA_HANDLE_ACCOUNT_TYPE,
2496 r->out.acct_handle);
2497 if (!NT_STATUS_IS_OK(status)) {
2498 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2501 return privilege_create_account(r->in.sid);
2504 /***************************************************************************
2506 ***************************************************************************/
2508 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2509 struct lsa_OpenAccount *r)
2511 struct lsa_info *handle;
2512 struct security_descriptor *psd = NULL;
2514 uint32_t des_access = r->in.access_mask;
2515 uint32_t acc_granted;
2518 /* find the connection policy handle. */
2519 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2520 return NT_STATUS_INVALID_HANDLE;
2522 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2523 return NT_STATUS_INVALID_HANDLE;
2526 /* des_access is for the account here, not the policy
2527 * handle - so don't check against policy handle. */
2529 /* Work out max allowed. */
2530 map_max_allowed_access(p->server_info->security_token,
2531 &p->server_info->utok,
2534 /* map the generic bits to the lsa account ones */
2535 se_map_generic(&des_access, &lsa_account_mapping);
2537 /* get the generic lsa account SD until we store it */
2538 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2539 &lsa_account_mapping,
2540 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2541 if (!NT_STATUS_IS_OK(status)) {
2545 status = access_check_object(psd, p->server_info->security_token,
2546 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2547 &acc_granted, "_lsa_OpenAccount" );
2548 if (!NT_STATUS_IS_OK(status)) {
2552 /* TODO: Fis the parsing routine before reenabling this check! */
2554 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2555 return NT_STATUS_ACCESS_DENIED;
2558 status = create_lsa_policy_handle(p->mem_ctx, p,
2559 LSA_HANDLE_ACCOUNT_TYPE,
2564 r->out.acct_handle);
2565 if (!NT_STATUS_IS_OK(status)) {
2566 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2569 return NT_STATUS_OK;
2572 /***************************************************************************
2573 _lsa_EnumPrivsAccount
2574 For a given SID, enumerate all the privilege this account has.
2575 ***************************************************************************/
2577 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2578 struct lsa_EnumPrivsAccount *r)
2580 NTSTATUS status = NT_STATUS_OK;
2581 struct lsa_info *info=NULL;
2582 PRIVILEGE_SET *privileges;
2583 struct lsa_PrivilegeSet *priv_set = NULL;
2585 /* find the connection policy handle. */
2586 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2587 return NT_STATUS_INVALID_HANDLE;
2589 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2590 return NT_STATUS_INVALID_HANDLE;
2593 if (!(info->access & LSA_ACCOUNT_VIEW))
2594 return NT_STATUS_ACCESS_DENIED;
2596 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2597 if (!NT_STATUS_IS_OK(status)) {
2601 *r->out.privs = priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
2603 return NT_STATUS_NO_MEMORY;
2606 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2607 sid_string_dbg(&info->sid),
2608 privileges->count));
2610 priv_set->count = privileges->count;
2611 priv_set->unknown = 0;
2612 priv_set->set = talloc_move(priv_set, &privileges->set);
2617 /***************************************************************************
2618 _lsa_GetSystemAccessAccount
2619 ***************************************************************************/
2621 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2622 struct lsa_GetSystemAccessAccount *r)
2625 struct lsa_info *info = NULL;
2626 struct lsa_EnumPrivsAccount e;
2627 struct lsa_PrivilegeSet *privset;
2629 /* find the connection policy handle. */
2631 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2632 return NT_STATUS_INVALID_HANDLE;
2634 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2635 return NT_STATUS_INVALID_HANDLE;
2638 if (!(info->access & LSA_ACCOUNT_VIEW))
2639 return NT_STATUS_ACCESS_DENIED;
2641 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2643 return NT_STATUS_NO_MEMORY;
2646 e.in.handle = r->in.handle;
2647 e.out.privs = &privset;
2649 status = _lsa_EnumPrivsAccount(p, &e);
2650 if (!NT_STATUS_IS_OK(status)) {
2651 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2652 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2653 nt_errstr(status)));
2657 /* Samba4 would iterate over the privset to merge the policy mode bits,
2658 * not sure samba3 can do the same here, so just return what we did in
2662 0x01 -> Log on locally
2663 0x02 -> Access this computer from network
2664 0x04 -> Log on as a batch job
2665 0x10 -> Log on as a service
2667 they can be ORed together
2670 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2671 LSA_POLICY_MODE_NETWORK;
2673 return NT_STATUS_OK;
2676 /***************************************************************************
2677 update the systemaccount information
2678 ***************************************************************************/
2680 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2681 struct lsa_SetSystemAccessAccount *r)
2683 struct lsa_info *info=NULL;
2686 /* find the connection policy handle. */
2687 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2688 return NT_STATUS_INVALID_HANDLE;
2690 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2691 return NT_STATUS_INVALID_HANDLE;
2694 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2695 return NT_STATUS_ACCESS_DENIED;
2698 if (!pdb_getgrsid(&map, info->sid))
2699 return NT_STATUS_NO_SUCH_GROUP;
2701 return pdb_update_group_mapping_entry(&map);
2704 /***************************************************************************
2705 _lsa_AddPrivilegesToAccount
2706 For a given SID, add some privileges.
2707 ***************************************************************************/
2709 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
2710 struct lsa_AddPrivilegesToAccount *r)
2712 struct lsa_info *info = NULL;
2713 struct lsa_PrivilegeSet *set = NULL;
2715 /* find the connection policy handle. */
2716 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2717 return NT_STATUS_INVALID_HANDLE;
2719 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2720 return NT_STATUS_INVALID_HANDLE;
2723 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2724 return NT_STATUS_ACCESS_DENIED;
2729 if ( !grant_privilege_set( &info->sid, set ) ) {
2730 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2731 sid_string_dbg(&info->sid) ));
2732 return NT_STATUS_NO_SUCH_PRIVILEGE;
2735 return NT_STATUS_OK;
2738 /***************************************************************************
2739 _lsa_RemovePrivilegesFromAccount
2740 For a given SID, remove some privileges.
2741 ***************************************************************************/
2743 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2744 struct lsa_RemovePrivilegesFromAccount *r)
2746 struct lsa_info *info = NULL;
2747 struct lsa_PrivilegeSet *set = NULL;
2749 /* find the connection policy handle. */
2750 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2751 return NT_STATUS_INVALID_HANDLE;
2753 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2754 return NT_STATUS_INVALID_HANDLE;
2757 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2758 return NT_STATUS_ACCESS_DENIED;
2763 if ( !revoke_privilege_set( &info->sid, set) ) {
2764 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2765 sid_string_dbg(&info->sid) ));
2766 return NT_STATUS_NO_SUCH_PRIVILEGE;
2769 return NT_STATUS_OK;
2772 /***************************************************************************
2774 ***************************************************************************/
2776 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2777 struct lsa_LookupPrivName *r)
2779 struct lsa_info *info = NULL;
2781 struct lsa_StringLarge *lsa_name;
2783 /* find the connection policy handle. */
2784 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2785 return NT_STATUS_INVALID_HANDLE;
2788 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2789 return NT_STATUS_INVALID_HANDLE;
2792 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2793 return NT_STATUS_ACCESS_DENIED;
2796 if (r->in.luid->high != 0) {
2797 return NT_STATUS_NO_SUCH_PRIVILEGE;
2800 name = sec_privilege_name(r->in.luid->low);
2802 return NT_STATUS_NO_SUCH_PRIVILEGE;
2805 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2807 return NT_STATUS_NO_MEMORY;
2810 lsa_name->string = talloc_strdup(lsa_name, name);
2811 if (!lsa_name->string) {
2812 TALLOC_FREE(lsa_name);
2813 return NT_STATUS_NO_MEMORY;
2816 *r->out.name = lsa_name;
2818 return NT_STATUS_OK;
2821 /***************************************************************************
2823 ***************************************************************************/
2825 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
2826 struct lsa_QuerySecurity *r)
2828 struct lsa_info *handle=NULL;
2829 struct security_descriptor *psd = NULL;
2833 /* find the connection policy handle. */
2834 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2835 return NT_STATUS_INVALID_HANDLE;
2837 switch (handle->type) {
2838 case LSA_HANDLE_POLICY_TYPE:
2839 case LSA_HANDLE_ACCOUNT_TYPE:
2840 case LSA_HANDLE_TRUST_TYPE:
2842 sd_size = ndr_size_security_descriptor(psd, 0);
2843 status = NT_STATUS_OK;
2846 status = NT_STATUS_INVALID_HANDLE;
2850 if (!NT_STATUS_IS_OK(status)) {
2854 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2855 if (!*r->out.sdbuf) {
2856 return NT_STATUS_NO_MEMORY;
2862 /***************************************************************************
2863 _lsa_AddAccountRights
2864 ***************************************************************************/
2866 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
2867 struct lsa_AddAccountRights *r)
2869 struct lsa_info *info = NULL;
2871 uint32_t acc_granted = 0;
2872 struct security_descriptor *psd = NULL;
2877 /* find the connection policy handle. */
2878 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2879 return NT_STATUS_INVALID_HANDLE;
2881 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2882 return NT_STATUS_INVALID_HANDLE;
2885 /* get the generic lsa account SD for this SID until we store it */
2886 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2887 &lsa_account_mapping,
2888 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2889 if (!NT_STATUS_IS_OK(status)) {
2894 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2895 * on the policy handle. If it does, ask for
2896 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2897 * on the account sid. We don't check here so just use the latter. JRA.
2900 status = access_check_object(psd, p->server_info->security_token,
2901 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2902 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2903 &acc_granted, "_lsa_AddAccountRights" );
2904 if (!NT_STATUS_IS_OK(status)) {
2908 /* according to an NT4 PDC, you can add privileges to SIDs even without
2909 call_lsa_create_account() first. And you can use any arbitrary SID. */
2911 sid_copy( &sid, r->in.sid );
2913 for ( i=0; i < r->in.rights->count; i++ ) {
2915 const char *privname = r->in.rights->names[i].string;
2917 /* only try to add non-null strings */
2922 if ( !grant_privilege_by_name( &sid, privname ) ) {
2923 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2925 return NT_STATUS_NO_SUCH_PRIVILEGE;
2929 return NT_STATUS_OK;
2932 /***************************************************************************
2933 _lsa_RemoveAccountRights
2934 ***************************************************************************/
2936 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
2937 struct lsa_RemoveAccountRights *r)
2939 struct lsa_info *info = NULL;
2941 struct security_descriptor *psd = NULL;
2944 const char *privname = NULL;
2945 uint32_t acc_granted = 0;
2948 /* find the connection policy handle. */
2949 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2950 return NT_STATUS_INVALID_HANDLE;
2952 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2953 return NT_STATUS_INVALID_HANDLE;
2956 /* get the generic lsa account SD for this SID until we store it */
2957 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2958 &lsa_account_mapping,
2959 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2960 if (!NT_STATUS_IS_OK(status)) {
2965 * From the MS DOCs. We need
2966 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2967 * and DELETE on the account sid.
2970 status = access_check_object(psd, p->server_info->security_token,
2971 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2972 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2973 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
2974 &acc_granted, "_lsa_RemoveAccountRights");
2975 if (!NT_STATUS_IS_OK(status)) {
2979 sid_copy( &sid, r->in.sid );
2981 if ( r->in.remove_all ) {
2982 if ( !revoke_all_privileges( &sid ) )
2983 return NT_STATUS_ACCESS_DENIED;
2985 return NT_STATUS_OK;
2988 for ( i=0; i < r->in.rights->count; i++ ) {
2990 privname = r->in.rights->names[i].string;
2992 /* only try to add non-null strings */
2997 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2998 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3000 return NT_STATUS_NO_SUCH_PRIVILEGE;
3004 return NT_STATUS_OK;
3007 /*******************************************************************
3008 ********************************************************************/
3010 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3011 struct lsa_RightSet *r,
3012 PRIVILEGE_SET *privileges)
3015 const char *privname;
3016 const char **privname_array = NULL;
3019 for (i=0; i<privileges->count; i++) {
3020 if (privileges->set[i].luid.high) {
3023 privname = sec_privilege_name(privileges->set[i].luid.low);
3025 if (!add_string_to_array(mem_ctx, privname,
3026 &privname_array, &num_priv)) {
3027 return NT_STATUS_NO_MEMORY;
3034 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
3037 return NT_STATUS_NO_MEMORY;
3040 for (i=0; i<num_priv; i++) {
3041 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3044 r->count = num_priv;
3047 return NT_STATUS_OK;
3050 /***************************************************************************
3051 _lsa_EnumAccountRights
3052 ***************************************************************************/
3054 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3055 struct lsa_EnumAccountRights *r)
3058 struct lsa_info *info = NULL;
3059 PRIVILEGE_SET *privileges;
3061 /* find the connection policy handle. */
3063 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3064 return NT_STATUS_INVALID_HANDLE;
3066 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3067 return NT_STATUS_INVALID_HANDLE;
3070 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3071 return NT_STATUS_ACCESS_DENIED;
3074 /* according to an NT4 PDC, you can add privileges to SIDs even without
3075 call_lsa_create_account() first. And you can use any arbitrary SID. */
3077 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3078 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3079 * the lsa database */
3081 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3082 if (!NT_STATUS_IS_OK(status)) {
3086 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3087 sid_string_dbg(r->in.sid), privileges->count));
3089 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3094 /***************************************************************************
3095 _lsa_LookupPrivValue
3096 ***************************************************************************/
3098 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3099 struct lsa_LookupPrivValue *r)
3101 struct lsa_info *info = NULL;
3102 const char *name = NULL;
3104 /* find the connection policy handle. */
3106 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3107 return NT_STATUS_INVALID_HANDLE;
3109 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3110 return NT_STATUS_INVALID_HANDLE;
3113 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3114 return NT_STATUS_ACCESS_DENIED;
3116 name = r->in.name->string;
3118 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3120 r->out.luid->low = sec_privilege_id(name);
3121 r->out.luid->high = 0;
3122 if (r->out.luid->low == SEC_PRIV_INVALID) {
3123 return NT_STATUS_NO_SUCH_PRIVILEGE;
3125 return NT_STATUS_OK;
3128 /***************************************************************************
3129 _lsa_EnumAccountsWithUserRight
3130 ***************************************************************************/
3132 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3133 struct lsa_EnumAccountsWithUserRight *r)
3136 struct lsa_info *info = NULL;
3137 struct dom_sid *sids = NULL;
3140 enum sec_privilege privilege;
3142 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3143 return NT_STATUS_INVALID_HANDLE;
3146 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3147 return NT_STATUS_INVALID_HANDLE;
3150 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3151 return NT_STATUS_ACCESS_DENIED;
3154 if (!r->in.name || !r->in.name->string) {
3155 return NT_STATUS_NO_SUCH_PRIVILEGE;
3158 privilege = sec_privilege_id(r->in.name->string);
3159 if (privilege == SEC_PRIV_INVALID) {
3160 return NT_STATUS_NO_SUCH_PRIVILEGE;
3163 status = privilege_enum_sids(privilege, p->mem_ctx,
3165 if (!NT_STATUS_IS_OK(status)) {
3169 r->out.sids->num_sids = num_sids;
3170 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3171 r->out.sids->num_sids);
3173 for (i=0; i < r->out.sids->num_sids; i++) {
3174 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3176 if (!r->out.sids->sids[i].sid) {
3177 TALLOC_FREE(r->out.sids->sids);
3178 r->out.sids->num_sids = 0;
3179 return NT_STATUS_NO_MEMORY;
3183 return NT_STATUS_OK;
3186 /***************************************************************************
3188 ***************************************************************************/
3190 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3191 struct lsa_Delete *r)
3193 return NT_STATUS_NOT_SUPPORTED;
3197 * From here on the server routines are just dummy ones to make smbd link with
3198 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3199 * pulling the server stubs across one by one.
3202 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3204 p->rng_fault_state = True;
3205 return NT_STATUS_NOT_IMPLEMENTED;
3208 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3209 struct lsa_ChangePassword *r)
3211 p->rng_fault_state = True;
3212 return NT_STATUS_NOT_IMPLEMENTED;
3215 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3217 p->rng_fault_state = True;
3218 return NT_STATUS_NOT_IMPLEMENTED;
3221 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3223 p->rng_fault_state = True;
3224 return NT_STATUS_NOT_IMPLEMENTED;
3227 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3228 struct lsa_GetQuotasForAccount *r)
3230 p->rng_fault_state = True;
3231 return NT_STATUS_NOT_IMPLEMENTED;
3234 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3235 struct lsa_SetQuotasForAccount *r)
3237 p->rng_fault_state = True;
3238 return NT_STATUS_NOT_IMPLEMENTED;
3241 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3242 struct lsa_SetInformationTrustedDomain *r)
3244 p->rng_fault_state = True;
3245 return NT_STATUS_NOT_IMPLEMENTED;
3248 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
3250 p->rng_fault_state = True;
3251 return NT_STATUS_NOT_IMPLEMENTED;
3254 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3255 struct lsa_SetTrustedDomainInfo *r)
3257 p->rng_fault_state = True;
3258 return NT_STATUS_NOT_IMPLEMENTED;
3261 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3262 struct lsa_StorePrivateData *r)
3264 p->rng_fault_state = True;
3265 return NT_STATUS_NOT_IMPLEMENTED;
3268 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3269 struct lsa_RetrievePrivateData *r)
3271 p->rng_fault_state = True;
3272 return NT_STATUS_NOT_IMPLEMENTED;
3275 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3276 struct lsa_SetInfoPolicy2 *r)
3278 p->rng_fault_state = True;
3279 return NT_STATUS_NOT_IMPLEMENTED;
3282 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3283 struct lsa_SetTrustedDomainInfoByName *r)
3285 p->rng_fault_state = True;
3286 return NT_STATUS_NOT_IMPLEMENTED;
3289 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3290 struct lsa_EnumTrustedDomainsEx *r)
3292 struct lsa_info *info;
3294 struct pdb_trusted_domain **domains;
3295 struct lsa_TrustDomainInfoInfoEx *entries;
3299 /* bail out early if pdb backend is not capable of ex trusted domains,
3300 * if we dont do that, the client might not call
3301 * _lsa_EnumTrustedDomains() afterwards - gd */
3303 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3304 p->rng_fault_state = True;
3305 return NT_STATUS_NOT_IMPLEMENTED;
3308 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3309 return NT_STATUS_INVALID_HANDLE;
3311 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3312 return NT_STATUS_INVALID_HANDLE;
3315 /* check if the user has enough rights */
3316 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3317 return NT_STATUS_ACCESS_DENIED;
3320 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3323 if (!NT_STATUS_IS_OK(nt_status)) {
3327 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3330 return NT_STATUS_NO_MEMORY;
3333 for (i=0; i<count; i++) {
3334 init_lsa_StringLarge(&entries[i].netbios_name,
3335 domains[i]->netbios_name);
3336 entries[i].sid = &domains[i]->security_identifier;
3339 if (*r->in.resume_handle >= count) {
3340 *r->out.resume_handle = -1;
3341 TALLOC_FREE(entries);
3342 return NT_STATUS_NO_MORE_ENTRIES;
3345 /* return the rest, limit by max_size. Note that we
3346 use the w2k3 element size value of 60 */
3347 r->out.domains->count = count - *r->in.resume_handle;
3348 r->out.domains->count = MIN(r->out.domains->count,
3349 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3351 r->out.domains->domains = entries + *r->in.resume_handle;
3353 if (r->out.domains->count < count - *r->in.resume_handle) {
3354 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3355 return STATUS_MORE_ENTRIES;
3358 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3359 * always be larger than the previous input resume handle, in
3360 * particular when hitting the last query it is vital to set the
3361 * resume handle correctly to avoid infinite client loops, as
3362 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3363 * status is NT_STATUS_OK - gd */
3365 *r->out.resume_handle = (uint32_t)-1;
3367 return NT_STATUS_OK;
3370 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3371 struct lsa_QueryDomainInformationPolicy *r)
3373 p->rng_fault_state = True;
3374 return NT_STATUS_NOT_IMPLEMENTED;
3377 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3378 struct lsa_SetDomainInformationPolicy *r)
3380 p->rng_fault_state = True;
3381 return NT_STATUS_NOT_IMPLEMENTED;
3384 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3386 p->rng_fault_state = True;
3387 return NT_STATUS_NOT_IMPLEMENTED;
3390 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3392 p->rng_fault_state = True;
3393 return NT_STATUS_NOT_IMPLEMENTED;
3396 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3398 p->rng_fault_state = True;
3399 return NT_STATUS_NOT_IMPLEMENTED;
3402 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3404 p->rng_fault_state = True;
3405 return NT_STATUS_NOT_IMPLEMENTED;
3408 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3409 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3411 p->rng_fault_state = True;
3412 return NT_STATUS_NOT_IMPLEMENTED;
3415 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3416 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3418 p->rng_fault_state = True;
3419 return NT_STATUS_NOT_IMPLEMENTED;
3422 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3424 p->rng_fault_state = True;
3425 return NT_STATUS_NOT_IMPLEMENTED;
3428 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3429 struct lsa_CREDRGETTARGETINFO *r)
3431 p->rng_fault_state = True;
3432 return NT_STATUS_NOT_IMPLEMENTED;
3435 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3436 struct lsa_CREDRPROFILELOADED *r)
3438 p->rng_fault_state = True;
3439 return NT_STATUS_NOT_IMPLEMENTED;
3442 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3443 struct lsa_CREDRGETSESSIONTYPES *r)
3445 p->rng_fault_state = True;
3446 return NT_STATUS_NOT_IMPLEMENTED;
3449 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3450 struct lsa_LSARREGISTERAUDITEVENT *r)
3452 p->rng_fault_state = True;
3453 return NT_STATUS_NOT_IMPLEMENTED;
3456 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3457 struct lsa_LSARGENAUDITEVENT *r)
3459 p->rng_fault_state = True;
3460 return NT_STATUS_NOT_IMPLEMENTED;
3463 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3464 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3466 p->rng_fault_state = True;
3467 return NT_STATUS_NOT_IMPLEMENTED;
3470 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3471 struct lsa_lsaRQueryForestTrustInformation *r)
3473 p->rng_fault_state = True;
3474 return NT_STATUS_NOT_IMPLEMENTED;
3477 #define DNS_CMP_MATCH 0
3478 #define DNS_CMP_FIRST_IS_CHILD 1
3479 #define DNS_CMP_SECOND_IS_CHILD 2
3480 #define DNS_CMP_NO_MATCH 3
3482 /* this function assumes names are well formed DNS names.
3483 * it doesn't validate them */
3484 static int dns_cmp(const char *s1, size_t l1,
3485 const char *s2, size_t l2)
3487 const char *p1, *p2;
3492 if (StrCaseCmp(s1, s2) == 0) {
3493 return DNS_CMP_MATCH;
3495 return DNS_CMP_NO_MATCH;
3503 cret = DNS_CMP_FIRST_IS_CHILD;
3509 cret = DNS_CMP_SECOND_IS_CHILD;
3512 if (p1[t1 - t2 - 1] != '.') {
3513 return DNS_CMP_NO_MATCH;
3516 if (StrCaseCmp(&p1[t1 - t2], p2) == 0) {
3520 return DNS_CMP_NO_MATCH;
3523 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3524 struct lsa_ForestTrustInformation *lfti,
3525 struct ForestTrustInfo *fti)
3527 struct lsa_ForestTrustRecord *lrec;
3528 struct ForestTrustInfoRecord *rec;
3529 struct lsa_StringLarge *tln;
3530 struct lsa_ForestTrustDomainInfo *info;
3534 fti->count = lfti->count;
3535 fti->records = talloc_array(mem_ctx,
3536 struct ForestTrustInfoRecordArmor,
3538 if (!fti->records) {
3539 return NT_STATUS_NO_MEMORY;
3541 for (i = 0; i < fti->count; i++) {
3542 lrec = lfti->entries[i];
3543 rec = &fti->records[i].record;
3545 rec->flags = lrec->flags;
3546 rec->timestamp = lrec->time;
3547 rec->type = lrec->type;
3549 switch (lrec->type) {
3550 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3551 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3552 tln = &lrec->forest_trust_data.top_level_name;
3553 rec->data.name.string =
3554 talloc_strdup(mem_ctx, tln->string);
3555 if (!rec->data.name.string) {
3556 return NT_STATUS_NO_MEMORY;
3558 rec->data.name.size = strlen(rec->data.name.string);
3560 case LSA_FOREST_TRUST_DOMAIN_INFO:
3561 info = &lrec->forest_trust_data.domain_info;
3562 rec->data.info.sid = *info->domain_sid;
3563 rec->data.info.dns_name.string =
3564 talloc_strdup(mem_ctx,
3565 info->dns_domain_name.string);
3566 if (!rec->data.info.dns_name.string) {
3567 return NT_STATUS_NO_MEMORY;
3569 rec->data.info.dns_name.size =
3570 strlen(rec->data.info.dns_name.string);
3571 rec->data.info.netbios_name.string =
3572 talloc_strdup(mem_ctx,
3573 info->netbios_domain_name.string);
3574 if (!rec->data.info.netbios_name.string) {
3575 return NT_STATUS_NO_MEMORY;
3577 rec->data.info.netbios_name.size =
3578 strlen(rec->data.info.netbios_name.string);
3581 return NT_STATUS_INVALID_DOMAIN_STATE;
3585 return NT_STATUS_OK;
3588 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3589 uint32_t index, uint32_t collision_type,
3590 uint32_t conflict_type, const char *tdo_name);
3592 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
3593 const char *tdo_name,
3594 struct ForestTrustInfo *tdo_fti,
3595 struct ForestTrustInfo *new_fti,
3596 struct lsa_ForestTrustCollisionInfo *c_info)
3598 struct ForestTrustInfoRecord *nrec;
3599 struct ForestTrustInfoRecord *trec;
3600 const char *dns_name;
3601 const char *nb_name = NULL;
3602 struct dom_sid *sid = NULL;
3603 const char *tname = NULL;
3608 uint32_t new_fti_idx;
3610 /* use always TDO type, until we understand when Xref can be used */
3611 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
3616 bool ex_rule = false;
3619 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
3621 nrec = &new_fti->records[new_fti_idx].record;
3623 tln_conflict = false;
3624 sid_conflict = false;
3625 nb_conflict = false;
3628 switch (nrec->type) {
3629 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3630 /* exclusions do not conflict by definition */
3633 case FOREST_TRUST_TOP_LEVEL_NAME:
3634 dns_name = nrec->data.name.string;
3635 dns_len = nrec->data.name.size;
3638 case LSA_FOREST_TRUST_DOMAIN_INFO:
3639 dns_name = nrec->data.info.dns_name.string;
3640 dns_len = nrec->data.info.dns_name.size;
3641 nb_name = nrec->data.info.netbios_name.string;
3642 nb_len = nrec->data.info.netbios_name.size;
3643 sid = &nrec->data.info.sid;
3647 if (!dns_name) continue;
3649 /* check if this is already taken and not excluded */
3650 for (i = 0; i < tdo_fti->count; i++) {
3651 trec = &tdo_fti->records[i].record;
3653 switch (trec->type) {
3654 case FOREST_TRUST_TOP_LEVEL_NAME:
3656 tname = trec->data.name.string;
3657 tlen = trec->data.name.size;
3659 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
3661 tname = trec->data.name.string;
3662 tlen = trec->data.name.size;
3664 case FOREST_TRUST_DOMAIN_INFO:
3666 tname = trec->data.info.dns_name.string;
3667 tlen = trec->data.info.dns_name.size;
3669 ret = dns_cmp(dns_name, dns_len, tname, tlen);
3672 /* if it matches exclusion,
3673 * it doesn't conflict */
3679 case DNS_CMP_FIRST_IS_CHILD:
3680 case DNS_CMP_SECOND_IS_CHILD:
3681 tln_conflict = true;
3687 /* explicit exclusion, no dns name conflict here */
3689 tln_conflict = false;
3692 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
3696 /* also test for domain info */
3697 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
3698 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
3699 sid_conflict = true;
3701 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
3702 StrCaseCmp(trec->data.info.netbios_name.string,
3709 nt_status = add_collision(c_info, new_fti_idx,
3711 LSA_TLN_DISABLED_CONFLICT,
3715 nt_status = add_collision(c_info, new_fti_idx,
3717 LSA_SID_DISABLED_CONFLICT,
3721 nt_status = add_collision(c_info, new_fti_idx,
3723 LSA_NB_DISABLED_CONFLICT,
3728 return NT_STATUS_OK;
3731 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3732 uint32_t idx, uint32_t collision_type,
3733 uint32_t conflict_type, const char *tdo_name)
3735 struct lsa_ForestTrustCollisionRecord **es;
3736 uint32_t i = c_info->count;
3738 es = talloc_realloc(c_info, c_info->entries,
3739 struct lsa_ForestTrustCollisionRecord *, i + 1);
3741 return NT_STATUS_NO_MEMORY;
3743 c_info->entries = es;
3744 c_info->count = i + 1;
3746 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
3748 return NT_STATUS_NO_MEMORY;
3752 es[i]->type = collision_type;
3753 es[i]->flags.flags = conflict_type;
3754 es[i]->name.string = talloc_strdup(es[i], tdo_name);
3755 if (!es[i]->name.string) {
3756 return NT_STATUS_NO_MEMORY;
3758 es[i]->name.size = strlen(es[i]->name.string);
3760 return NT_STATUS_OK;
3763 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3764 struct pdb_trusted_domain *td,
3765 struct ForestTrustInfo *info)
3767 enum ndr_err_code ndr_err;
3769 if (td->trust_forest_trust_info.length == 0 ||
3770 td->trust_forest_trust_info.data == NULL) {
3771 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3773 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
3775 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3776 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3777 return NT_STATUS_INVALID_DOMAIN_STATE;
3780 return NT_STATUS_OK;
3783 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
3784 struct ForestTrustInfo *fti)
3786 struct ForestTrustDataDomainInfo *info;
3787 struct ForestTrustInfoRecord *rec;
3791 fti->records = talloc_array(fti,
3792 struct ForestTrustInfoRecordArmor, 2);
3793 if (!fti->records) {
3794 return NT_STATUS_NO_MEMORY;
3798 rec = &fti->records[0].record;
3802 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3804 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
3805 if (!rec->data.name.string) {
3806 return NT_STATUS_NO_MEMORY;
3808 rec->data.name.size = strlen(rec->data.name.string);
3811 rec = &fti->records[1].record;
3815 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3817 info = &rec->data.info;
3819 info->sid = dom_info->sid;
3820 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
3821 if (!info->dns_name.string) {
3822 return NT_STATUS_NO_MEMORY;
3824 info->dns_name.size = strlen(info->dns_name.string);
3825 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
3826 if (!info->netbios_name.string) {
3827 return NT_STATUS_NO_MEMORY;
3829 info->netbios_name.size = strlen(info->netbios_name.string);
3831 return NT_STATUS_OK;
3834 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
3835 struct lsa_lsaRSetForestTrustInformation *r)
3840 struct lsa_info *handle;
3841 uint32_t num_domains;
3842 struct pdb_trusted_domain **domains;
3843 struct ForestTrustInfo *nfti;
3844 struct ForestTrustInfo *fti;
3845 struct lsa_ForestTrustCollisionInfo *c_info;
3846 struct pdb_domain_info *dom_info;
3847 enum ndr_err_code ndr_err;
3850 return NT_STATUS_NOT_SUPPORTED;
3853 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
3854 return NT_STATUS_INVALID_HANDLE;
3857 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
3858 return NT_STATUS_INVALID_HANDLE;
3861 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
3862 return NT_STATUS_ACCESS_DENIED;
3865 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
3866 if (!NT_STATUS_IS_OK(status)) {
3869 if (num_domains == 0) {
3870 return NT_STATUS_NO_SUCH_DOMAIN;
3873 for (i = 0; i < num_domains; i++) {
3874 if (domains[i]->domain_name == NULL) {
3875 return NT_STATUS_INVALID_DOMAIN_STATE;
3877 if (StrCaseCmp(domains[i]->domain_name,
3878 r->in.trusted_domain_name->string) == 0) {
3882 if (i >= num_domains) {
3883 return NT_STATUS_NO_SUCH_DOMAIN;
3886 if (!(domains[i]->trust_attributes &
3887 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
3888 return NT_STATUS_INVALID_PARAMETER;
3891 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
3892 return NT_STATUS_INVALID_PARAMETER;
3895 /* The following section until COPY_END is a copy from
3896 * source4/rpmc_server/lsa/scesrc_lsa.c */
3897 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
3899 return NT_STATUS_NO_MEMORY;
3902 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
3903 if (!NT_STATUS_IS_OK(status)) {
3907 c_info = talloc_zero(r->out.collision_info,
3908 struct lsa_ForestTrustCollisionInfo);
3910 return NT_STATUS_NO_MEMORY;
3913 /* first check own info, then other domains */
3914 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3916 return NT_STATUS_NO_MEMORY;
3919 dom_info = pdb_get_domain_info(p->mem_ctx);
3921 status = own_ft_info(dom_info, fti);
3922 if (!NT_STATUS_IS_OK(status)) {
3926 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
3927 if (!NT_STATUS_IS_OK(status)) {
3931 for (j = 0; j < num_domains; j++) {
3932 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3934 return NT_STATUS_NO_MEMORY;
3937 status = get_ft_info(p->mem_ctx, domains[j], fti);
3938 if (!NT_STATUS_IS_OK(status)) {
3939 if (NT_STATUS_EQUAL(status,
3940 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3946 if (domains[j]->domain_name == NULL) {
3947 return NT_STATUS_INVALID_DOMAIN_STATE;
3950 status = check_ft_info(c_info, domains[j]->domain_name,
3952 if (!NT_STATUS_IS_OK(status)) {
3957 *r->out.collision_info = c_info;
3959 if (r->in.check_only != 0) {
3960 return NT_STATUS_OK;
3965 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
3967 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
3968 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3969 return NT_STATUS_INVALID_PARAMETER;
3972 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
3973 if (!NT_STATUS_IS_OK(status)) {
3977 return NT_STATUS_OK;
3980 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
3981 struct lsa_CREDRRENAME *r)
3983 p->rng_fault_state = True;
3984 return NT_STATUS_NOT_IMPLEMENTED;
3987 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
3988 struct lsa_LSAROPENPOLICYSCE *r)
3990 p->rng_fault_state = True;
3991 return NT_STATUS_NOT_IMPLEMENTED;
3994 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
3995 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3997 p->rng_fault_state = True;
3998 return NT_STATUS_NOT_IMPLEMENTED;
4001 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4002 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4004 p->rng_fault_state = True;
4005 return NT_STATUS_NOT_IMPLEMENTED;
4008 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4009 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4011 p->rng_fault_state = True;
4012 return NT_STATUS_NOT_IMPLEMENTED;