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->session_info->security_token,
434 &p->session_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->session_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) {
901 /* Unknown sids should return the string
902 * representation of the SID. Windows 2003 behaves
903 * rather erratic here, in many cases it returns the
904 * RID as 8 bytes hex, in others it returns the full
905 * SID. We (Jerry/VL) could not figure out which the
906 * hard cases are, so leave it with the SID. */
907 name->name = dom_sid_string(p->mem_ctx, sids[i]);
908 if (name->name == NULL) {
909 return NT_STATUS_NO_MEMORY;
915 names[i].sid_type = name->type;
916 names[i].name.string = name->name;
917 names[i].sid_index = name->dom_idx;
918 names[i].unknown = 0;
921 status = NT_STATUS_NONE_MAPPED;
922 if (mapped_count > 0) {
923 status = (mapped_count < num_sids) ?
924 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
927 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
928 num_sids, mapped_count, nt_errstr(status)));
930 *pp_mapped_count = mapped_count;
937 /***************************************************************************
939 ***************************************************************************/
941 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
942 struct lsa_LookupSids *r)
945 struct lsa_info *handle;
946 int num_sids = r->in.sids->num_sids;
947 uint32 mapped_count = 0;
948 struct lsa_RefDomainList *domains = NULL;
949 struct lsa_TranslatedName *names_out = NULL;
950 struct lsa_TranslatedName2 *names = NULL;
953 if ((r->in.level < 1) || (r->in.level > 6)) {
954 return NT_STATUS_INVALID_PARAMETER;
957 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
958 return NT_STATUS_INVALID_HANDLE;
961 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
962 return NT_STATUS_INVALID_HANDLE;
965 /* check if the user has enough rights */
966 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
967 return NT_STATUS_ACCESS_DENIED;
970 if (num_sids > MAX_LOOKUP_SIDS) {
971 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
972 MAX_LOOKUP_SIDS, num_sids));
973 return NT_STATUS_NONE_MAPPED;
976 status = _lsa_lookup_sids_internal(p,
985 /* Only return here when there is a real error.
986 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
987 the requested sids could be resolved. Older versions of XP (pre SP3)
988 rely that we return with the string representations of those SIDs in
989 that case. If we don't, XP crashes - Guenther
992 if (NT_STATUS_IS_ERR(status) &&
993 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
997 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
998 names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
1001 return NT_STATUS_NO_MEMORY;
1004 for (i=0; i<num_sids; i++) {
1005 names_out[i].sid_type = names[i].sid_type;
1006 names_out[i].name = names[i].name;
1007 names_out[i].sid_index = names[i].sid_index;
1010 *r->out.domains = domains;
1011 r->out.names->count = num_sids;
1012 r->out.names->names = names_out;
1013 *r->out.count = mapped_count;
1018 /***************************************************************************
1020 ***************************************************************************/
1022 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1023 struct lsa_LookupSids2 *r)
1026 struct lsa_info *handle;
1027 int num_sids = r->in.sids->num_sids;
1028 uint32 mapped_count = 0;
1029 struct lsa_RefDomainList *domains = NULL;
1030 struct lsa_TranslatedName2 *names = NULL;
1031 bool check_policy = true;
1034 case NDR_LSA_LOOKUPSIDS3:
1035 check_policy = false;
1037 case NDR_LSA_LOOKUPSIDS2:
1039 check_policy = true;
1042 if ((r->in.level < 1) || (r->in.level > 6)) {
1043 return NT_STATUS_INVALID_PARAMETER;
1047 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1048 return NT_STATUS_INVALID_HANDLE;
1051 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1052 return NT_STATUS_INVALID_HANDLE;
1055 /* check if the user has enough rights */
1056 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1057 return NT_STATUS_ACCESS_DENIED;
1061 if (num_sids > MAX_LOOKUP_SIDS) {
1062 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1063 MAX_LOOKUP_SIDS, num_sids));
1064 return NT_STATUS_NONE_MAPPED;
1067 status = _lsa_lookup_sids_internal(p,
1076 *r->out.domains = domains;
1077 r->out.names->count = num_sids;
1078 r->out.names->names = names;
1079 *r->out.count = mapped_count;
1084 /***************************************************************************
1086 ***************************************************************************/
1088 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1089 struct lsa_LookupSids3 *r)
1091 struct lsa_LookupSids2 q;
1093 /* No policy handle on this call. Restrict to crypto connections. */
1094 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1095 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1096 get_remote_machine_name() ));
1097 return NT_STATUS_INVALID_PARAMETER;
1101 q.in.sids = r->in.sids;
1102 q.in.level = r->in.level;
1103 q.in.lookup_options = r->in.lookup_options;
1104 q.in.client_revision = r->in.client_revision;
1105 q.in.names = r->in.names;
1106 q.in.count = r->in.count;
1108 q.out.domains = r->out.domains;
1109 q.out.names = r->out.names;
1110 q.out.count = r->out.count;
1112 return _lsa_LookupSids2(p, &q);
1115 /***************************************************************************
1116 ***************************************************************************/
1118 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1123 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1124 flags = LOOKUP_NAME_ALL;
1126 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1127 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1129 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1130 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1132 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1133 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1134 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1135 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1137 flags = LOOKUP_NAME_NONE;
1144 /***************************************************************************
1146 ***************************************************************************/
1148 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1149 struct lsa_LookupNames *r)
1151 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1152 struct lsa_info *handle;
1153 struct lsa_String *names = r->in.names;
1154 uint32 num_entries = r->in.num_names;
1155 struct lsa_RefDomainList *domains = NULL;
1156 struct lsa_TranslatedSid *rids = NULL;
1157 uint32 mapped_count = 0;
1160 if (num_entries > MAX_LOOKUP_SIDS) {
1161 num_entries = MAX_LOOKUP_SIDS;
1162 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1166 flags = lsa_lookup_level_to_flags(r->in.level);
1168 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1170 return NT_STATUS_NO_MEMORY;
1174 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1177 return NT_STATUS_NO_MEMORY;
1183 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1184 status = NT_STATUS_INVALID_HANDLE;
1188 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1189 return NT_STATUS_INVALID_HANDLE;
1192 /* check if the user has enough rights */
1193 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1194 status = NT_STATUS_ACCESS_DENIED;
1198 /* set up the LSA Lookup RIDs response */
1199 become_root(); /* lookup_name can require root privs */
1200 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1201 names, flags, &mapped_count);
1206 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1207 if (mapped_count == 0) {
1208 status = NT_STATUS_NONE_MAPPED;
1209 } else if (mapped_count != num_entries) {
1210 status = STATUS_SOME_UNMAPPED;
1214 *r->out.count = mapped_count;
1215 *r->out.domains = domains;
1216 r->out.sids->sids = rids;
1217 r->out.sids->count = num_entries;
1222 /***************************************************************************
1224 ***************************************************************************/
1226 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1227 struct lsa_LookupNames2 *r)
1230 struct lsa_LookupNames q;
1231 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1232 struct lsa_TransSidArray *sid_array = NULL;
1235 sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1237 return NT_STATUS_NO_MEMORY;
1240 q.in.handle = r->in.handle;
1241 q.in.num_names = r->in.num_names;
1242 q.in.names = r->in.names;
1243 q.in.level = r->in.level;
1244 q.in.sids = sid_array;
1245 q.in.count = r->in.count;
1246 /* we do not know what this is for */
1247 /* = r->in.unknown1; */
1248 /* = r->in.unknown2; */
1250 q.out.domains = r->out.domains;
1251 q.out.sids = sid_array;
1252 q.out.count = r->out.count;
1254 status = _lsa_LookupNames(p, &q);
1256 sid_array2->count = sid_array->count;
1257 sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1258 if (!sid_array2->sids) {
1259 return NT_STATUS_NO_MEMORY;
1262 for (i=0; i<sid_array->count; i++) {
1263 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1264 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1265 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1266 sid_array2->sids[i].unknown = 0;
1269 r->out.sids = sid_array2;
1274 /***************************************************************************
1276 ***************************************************************************/
1278 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1279 struct lsa_LookupNames3 *r)
1282 struct lsa_info *handle;
1283 struct lsa_String *names = r->in.names;
1284 uint32 num_entries = r->in.num_names;
1285 struct lsa_RefDomainList *domains = NULL;
1286 struct lsa_TranslatedSid3 *trans_sids = NULL;
1287 uint32 mapped_count = 0;
1289 bool check_policy = true;
1292 case NDR_LSA_LOOKUPNAMES4:
1293 check_policy = false;
1295 case NDR_LSA_LOOKUPNAMES3:
1297 check_policy = true;
1300 if (num_entries > MAX_LOOKUP_SIDS) {
1301 num_entries = MAX_LOOKUP_SIDS;
1302 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1305 /* Probably the lookup_level is some sort of bitmask. */
1306 if (r->in.level == 1) {
1307 flags = LOOKUP_NAME_ALL;
1310 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1312 return NT_STATUS_NO_MEMORY;
1316 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1319 return NT_STATUS_NO_MEMORY;
1327 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1328 status = NT_STATUS_INVALID_HANDLE;
1332 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1333 return NT_STATUS_INVALID_HANDLE;
1336 /* check if the user has enough rights */
1337 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1338 status = NT_STATUS_ACCESS_DENIED;
1343 /* set up the LSA Lookup SIDs response */
1344 become_root(); /* lookup_name can require root privs */
1345 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1346 names, flags, &mapped_count);
1351 if (NT_STATUS_IS_OK(status)) {
1352 if (mapped_count == 0) {
1353 status = NT_STATUS_NONE_MAPPED;
1354 } else if (mapped_count != num_entries) {
1355 status = STATUS_SOME_UNMAPPED;
1359 *r->out.count = mapped_count;
1360 *r->out.domains = domains;
1361 r->out.sids->sids = trans_sids;
1362 r->out.sids->count = num_entries;
1367 /***************************************************************************
1369 ***************************************************************************/
1371 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1372 struct lsa_LookupNames4 *r)
1374 struct lsa_LookupNames3 q;
1376 /* No policy handle on this call. Restrict to crypto connections. */
1377 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1378 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1379 get_remote_machine_name() ));
1380 return NT_STATUS_INVALID_PARAMETER;
1384 q.in.num_names = r->in.num_names;
1385 q.in.names = r->in.names;
1386 q.in.level = r->in.level;
1387 q.in.lookup_options = r->in.lookup_options;
1388 q.in.client_revision = r->in.client_revision;
1389 q.in.sids = r->in.sids;
1390 q.in.count = r->in.count;
1392 q.out.domains = r->out.domains;
1393 q.out.sids = r->out.sids;
1394 q.out.count = r->out.count;
1396 return _lsa_LookupNames3(p, &q);
1399 /***************************************************************************
1400 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1401 ***************************************************************************/
1403 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1405 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1406 return NT_STATUS_INVALID_HANDLE;
1409 close_policy_hnd(p, r->in.handle);
1410 ZERO_STRUCTP(r->out.handle);
1411 return NT_STATUS_OK;
1414 /***************************************************************************
1415 ***************************************************************************/
1417 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1418 const struct dom_sid *sid,
1419 struct trustdom_info **info)
1422 uint32_t num_domains = 0;
1423 struct trustdom_info **domains = NULL;
1426 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1427 if (!NT_STATUS_IS_OK(status)) {
1431 for (i=0; i < num_domains; i++) {
1432 if (dom_sid_equal(&domains[i]->sid, sid)) {
1437 if (i == num_domains) {
1438 return NT_STATUS_INVALID_PARAMETER;
1443 return NT_STATUS_OK;
1446 /***************************************************************************
1447 ***************************************************************************/
1449 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1450 const char *netbios_domain_name,
1451 struct trustdom_info **info_p)
1454 struct trustdom_info *info;
1455 struct pdb_trusted_domain *td;
1457 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1458 if (!NT_STATUS_IS_OK(status)) {
1462 info = talloc(mem_ctx, struct trustdom_info);
1464 return NT_STATUS_NO_MEMORY;
1467 info->name = talloc_strdup(info, netbios_domain_name);
1468 NT_STATUS_HAVE_NO_MEMORY(info->name);
1470 sid_copy(&info->sid, &td->security_identifier);
1474 return NT_STATUS_OK;
1477 /***************************************************************************
1478 ***************************************************************************/
1480 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p, struct lsa_OpenSecret *r)
1482 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1485 /***************************************************************************
1486 _lsa_OpenTrustedDomain_base
1487 ***************************************************************************/
1489 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1490 uint32_t access_mask,
1491 struct trustdom_info *info,
1492 struct policy_handle *handle)
1494 struct security_descriptor *psd = NULL;
1496 uint32_t acc_granted;
1499 /* des_access is for the account here, not the policy
1500 * handle - so don't check against policy handle. */
1502 /* Work out max allowed. */
1503 map_max_allowed_access(p->session_info->security_token,
1504 &p->session_info->utok,
1507 /* map the generic bits to the lsa account ones */
1508 se_map_generic(&access_mask, &lsa_account_mapping);
1510 /* get the generic lsa account SD until we store it */
1511 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1512 &lsa_trusted_domain_mapping,
1514 if (!NT_STATUS_IS_OK(status)) {
1518 status = access_check_object(psd, p->session_info->security_token,
1519 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1520 access_mask, &acc_granted,
1521 "_lsa_OpenTrustedDomain");
1522 if (!NT_STATUS_IS_OK(status)) {
1526 status = create_lsa_policy_handle(p->mem_ctx, p,
1527 LSA_HANDLE_TRUST_TYPE,
1533 if (!NT_STATUS_IS_OK(status)) {
1534 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1537 return NT_STATUS_OK;
1540 /***************************************************************************
1541 _lsa_OpenTrustedDomain
1542 ***************************************************************************/
1544 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1545 struct lsa_OpenTrustedDomain *r)
1547 struct lsa_info *handle = NULL;
1548 struct trustdom_info *info = NULL;
1551 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1552 return NT_STATUS_INVALID_HANDLE;
1555 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1556 return NT_STATUS_INVALID_HANDLE;
1559 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1562 if (!NT_STATUS_IS_OK(status)) {
1566 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1567 r->out.trustdom_handle);
1570 /***************************************************************************
1571 _lsa_OpenTrustedDomainByName
1572 ***************************************************************************/
1574 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1575 struct lsa_OpenTrustedDomainByName *r)
1577 struct lsa_info *handle = NULL;
1578 struct trustdom_info *info = NULL;
1581 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1582 return NT_STATUS_INVALID_HANDLE;
1585 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1586 return NT_STATUS_INVALID_HANDLE;
1589 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1592 if (!NT_STATUS_IS_OK(status)) {
1596 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1597 r->out.trustdom_handle);
1600 static NTSTATUS add_trusted_domain_user(TALLOC_CTX *mem_ctx,
1601 const char *netbios_name,
1602 const char *domain_name,
1603 struct trustDomainPasswords auth_struct)
1606 struct samu *sam_acct;
1609 struct dom_sid user_sid;
1614 sam_acct = samu_new(mem_ctx);
1615 if (sam_acct == NULL) {
1616 return NT_STATUS_NO_MEMORY;
1619 acct_name = talloc_asprintf(mem_ctx, "%s$", netbios_name);
1620 if (acct_name == NULL) {
1621 return NT_STATUS_NO_MEMORY;
1623 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1624 return NT_STATUS_UNSUCCESSFUL;
1627 if (!pdb_set_domain(sam_acct, domain_name, PDB_SET)) {
1628 return NT_STATUS_UNSUCCESSFUL;
1631 if (!pdb_set_acct_ctrl(sam_acct, ACB_DOMTRUST, PDB_SET)) {
1632 return NT_STATUS_UNSUCCESSFUL;
1635 if (!pdb_new_rid(&rid)) {
1636 return NT_STATUS_DS_NO_MORE_RIDS;
1638 sid_compose(&user_sid, get_global_sam_sid(), rid);
1639 if (!pdb_set_user_sid(sam_acct, &user_sid, PDB_SET)) {
1640 return NT_STATUS_UNSUCCESSFUL;
1643 for (i = 0; i < auth_struct.incoming.count; i++) {
1644 switch (auth_struct.incoming.current.array[i].AuthType) {
1645 case TRUST_AUTH_TYPE_CLEAR:
1646 if (!convert_string_talloc(mem_ctx,
1649 auth_struct.incoming.current.array[i].AuthInfo.clear.password,
1650 auth_struct.incoming.current.array[i].AuthInfo.clear.size,
1654 return NT_STATUS_UNSUCCESSFUL;
1656 if (!pdb_set_plaintext_passwd(sam_acct, dummy)) {
1657 return NT_STATUS_UNSUCCESSFUL;
1665 status = pdb_add_sam_account(sam_acct);
1666 if (!NT_STATUS_IS_OK(status)) {
1670 return NT_STATUS_OK;
1673 /***************************************************************************
1674 _lsa_CreateTrustedDomainEx2
1675 ***************************************************************************/
1677 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1678 struct lsa_CreateTrustedDomainEx2 *r)
1680 struct lsa_info *policy;
1682 uint32_t acc_granted;
1683 struct security_descriptor *psd;
1685 struct pdb_trusted_domain td;
1686 struct trustDomainPasswords auth_struct;
1687 enum ndr_err_code ndr_err;
1688 DATA_BLOB auth_blob;
1691 return NT_STATUS_NOT_SUPPORTED;
1694 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1695 return NT_STATUS_INVALID_HANDLE;
1698 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1699 return NT_STATUS_ACCESS_DENIED;
1702 if (p->session_info->utok.uid != sec_initial_uid() &&
1703 !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1704 return NT_STATUS_ACCESS_DENIED;
1707 /* Work out max allowed. */
1708 map_max_allowed_access(p->session_info->security_token,
1709 &p->session_info->utok,
1710 &r->in.access_mask);
1712 /* map the generic bits to the lsa policy ones */
1713 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1715 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1716 &lsa_trusted_domain_mapping,
1718 if (!NT_STATUS_IS_OK(status)) {
1722 status = access_check_object(psd, p->session_info->security_token,
1723 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1724 r->in.access_mask, &acc_granted,
1725 "_lsa_CreateTrustedDomainEx2");
1726 if (!NT_STATUS_IS_OK(status)) {
1732 td.domain_name = talloc_strdup(p->mem_ctx,
1733 r->in.info->domain_name.string);
1734 if (td.domain_name == NULL) {
1735 return NT_STATUS_NO_MEMORY;
1737 td.netbios_name = talloc_strdup(p->mem_ctx,
1738 r->in.info->netbios_name.string);
1739 if (td.netbios_name == NULL) {
1740 return NT_STATUS_NO_MEMORY;
1742 sid_copy(&td.security_identifier, r->in.info->sid);
1743 td.trust_direction = r->in.info->trust_direction;
1744 td.trust_type = r->in.info->trust_type;
1745 td.trust_attributes = r->in.info->trust_attributes;
1747 if (r->in.auth_info->auth_blob.size != 0) {
1748 auth_blob.length = r->in.auth_info->auth_blob.size;
1749 auth_blob.data = r->in.auth_info->auth_blob.data;
1751 arcfour_crypt_blob(auth_blob.data, auth_blob.length,
1752 &p->session_info->user_session_key);
1754 ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
1756 (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
1757 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1758 return NT_STATUS_UNSUCCESSFUL;
1761 ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
1762 &auth_struct.incoming,
1763 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1764 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1765 return NT_STATUS_UNSUCCESSFUL;
1768 ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
1769 &auth_struct.outgoing,
1770 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1771 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1772 return NT_STATUS_UNSUCCESSFUL;
1775 td.trust_auth_incoming.data = NULL;
1776 td.trust_auth_incoming.length = 0;
1777 td.trust_auth_outgoing.data = NULL;
1778 td.trust_auth_outgoing.length = 0;
1781 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1782 if (!NT_STATUS_IS_OK(status)) {
1786 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1787 status = add_trusted_domain_user(p->mem_ctx,
1788 r->in.info->netbios_name.string,
1789 r->in.info->domain_name.string,
1791 if (!NT_STATUS_IS_OK(status)) {
1796 status = create_lsa_policy_handle(p->mem_ctx, p,
1797 LSA_HANDLE_TRUST_TYPE,
1800 r->in.info->netbios_name.string,
1802 r->out.trustdom_handle);
1803 if (!NT_STATUS_IS_OK(status)) {
1804 pdb_del_trusteddom_pw(r->in.info->netbios_name.string);
1805 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1808 return NT_STATUS_OK;
1811 /***************************************************************************
1812 _lsa_CreateTrustedDomainEx
1813 ***************************************************************************/
1815 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1816 struct lsa_CreateTrustedDomainEx *r)
1818 struct lsa_CreateTrustedDomainEx2 q;
1820 q.in.policy_handle = r->in.policy_handle;
1821 q.in.info = r->in.info;
1822 q.in.auth_info = r->in.auth_info;
1823 q.in.access_mask = r->in.access_mask;
1824 q.out.trustdom_handle = r->out.trustdom_handle;
1826 return _lsa_CreateTrustedDomainEx2(p, &q);
1829 /***************************************************************************
1830 _lsa_CreateTrustedDomain
1831 ***************************************************************************/
1833 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1834 struct lsa_CreateTrustedDomain *r)
1836 struct lsa_CreateTrustedDomainEx2 c;
1837 struct lsa_TrustDomainInfoInfoEx info;
1838 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1840 ZERO_STRUCT(auth_info);
1842 info.domain_name = r->in.info->name;
1843 info.netbios_name = r->in.info->name;
1844 info.sid = r->in.info->sid;
1845 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1846 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1847 info.trust_attributes = 0;
1849 c.in.policy_handle = r->in.policy_handle;
1851 c.in.auth_info = &auth_info;
1852 c.in.access_mask = r->in.access_mask;
1853 c.out.trustdom_handle = r->out.trustdom_handle;
1855 return _lsa_CreateTrustedDomainEx2(p, &c);
1858 /***************************************************************************
1859 _lsa_DeleteTrustedDomain
1860 ***************************************************************************/
1862 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1863 struct lsa_DeleteTrustedDomain *r)
1866 struct lsa_info *handle;
1867 struct pdb_trusted_domain *td;
1868 struct samu *sam_acct;
1871 /* find the connection policy handle. */
1872 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1873 return NT_STATUS_INVALID_HANDLE;
1876 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1877 return NT_STATUS_INVALID_HANDLE;
1880 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1881 return NT_STATUS_ACCESS_DENIED;
1884 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1885 if (!NT_STATUS_IS_OK(status)) {
1889 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1890 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1891 sid_string_tos(r->in.dom_sid)));
1892 return NT_STATUS_UNSUCCESSFUL;
1895 if (td->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1896 sam_acct = samu_new(p->mem_ctx);
1897 if (sam_acct == NULL) {
1898 return NT_STATUS_NO_MEMORY;
1901 acct_name = talloc_asprintf(p->mem_ctx, "%s$", td->netbios_name);
1902 if (acct_name == NULL) {
1903 return NT_STATUS_NO_MEMORY;
1905 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1906 return NT_STATUS_UNSUCCESSFUL;
1908 status = pdb_delete_sam_account(sam_acct);
1909 if (!NT_STATUS_IS_OK(status)) {
1914 status = pdb_del_trusted_domain(td->netbios_name);
1915 if (!NT_STATUS_IS_OK(status)) {
1919 return NT_STATUS_OK;
1922 /***************************************************************************
1923 _lsa_CloseTrustedDomainEx
1924 ***************************************************************************/
1926 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1927 struct lsa_CloseTrustedDomainEx *r)
1929 return NT_STATUS_NOT_IMPLEMENTED;
1932 /***************************************************************************
1933 _lsa_QueryTrustedDomainInfo
1934 ***************************************************************************/
1936 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
1937 struct lsa_QueryTrustedDomainInfo *r)
1940 struct lsa_info *handle;
1941 union lsa_TrustedDomainInfo *info;
1942 struct pdb_trusted_domain *td;
1943 uint32_t acc_required;
1945 /* find the connection policy handle. */
1946 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
1947 return NT_STATUS_INVALID_HANDLE;
1950 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
1951 return NT_STATUS_INVALID_HANDLE;
1954 switch (r->in.level) {
1955 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1956 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1958 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1959 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
1961 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1962 acc_required = LSA_TRUSTED_QUERY_POSIX;
1964 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
1965 acc_required = LSA_TRUSTED_QUERY_AUTH;
1967 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1968 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1970 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1971 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1973 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1974 acc_required = LSA_TRUSTED_QUERY_AUTH;
1976 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1977 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1978 LSA_TRUSTED_QUERY_POSIX |
1979 LSA_TRUSTED_QUERY_AUTH;
1981 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1982 acc_required = LSA_TRUSTED_QUERY_AUTH;
1984 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1985 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1986 LSA_TRUSTED_QUERY_POSIX |
1987 LSA_TRUSTED_QUERY_AUTH;
1989 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1990 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1992 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1993 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1994 LSA_TRUSTED_QUERY_POSIX |
1995 LSA_TRUSTED_QUERY_AUTH;
1997 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1998 acc_required = LSA_TRUSTED_QUERY_POSIX;
2001 return NT_STATUS_INVALID_PARAMETER;
2004 if (!(handle->access & acc_required)) {
2005 return NT_STATUS_ACCESS_DENIED;
2008 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2009 if (!NT_STATUS_IS_OK(status)) {
2013 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_TrustedDomainInfo);
2015 return NT_STATUS_NO_MEMORY;
2018 switch (r->in.level) {
2019 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2020 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2022 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2023 return NT_STATUS_INVALID_PARAMETER;
2024 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2026 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2027 return NT_STATUS_INVALID_INFO_CLASS;
2028 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2029 return NT_STATUS_INVALID_PARAMETER;
2030 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2031 init_lsa_StringLarge(&info->info_ex.domain_name, td->domain_name);
2032 init_lsa_StringLarge(&info->info_ex.netbios_name, td->netbios_name);
2033 info->info_ex.sid = dom_sid_dup(info, &td->security_identifier);
2034 if (!info->info_ex.sid) {
2035 return NT_STATUS_NO_MEMORY;
2037 info->info_ex.trust_direction = td->trust_direction;
2038 info->info_ex.trust_type = td->trust_type;
2039 info->info_ex.trust_attributes = td->trust_attributes;
2041 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2042 return NT_STATUS_INVALID_INFO_CLASS;
2043 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2045 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2046 return NT_STATUS_INVALID_INFO_CLASS;
2047 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2048 return NT_STATUS_INVALID_INFO_CLASS;
2049 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2050 return NT_STATUS_INVALID_PARAMETER;
2051 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2053 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2056 return NT_STATUS_INVALID_PARAMETER;
2059 *r->out.info = info;
2061 return NT_STATUS_OK;
2064 /***************************************************************************
2065 _lsa_QueryTrustedDomainInfoBySid
2066 ***************************************************************************/
2068 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2069 struct lsa_QueryTrustedDomainInfoBySid *r)
2072 struct policy_handle trustdom_handle;
2073 struct lsa_OpenTrustedDomain o;
2074 struct lsa_QueryTrustedDomainInfo q;
2077 o.in.handle = r->in.handle;
2078 o.in.sid = r->in.dom_sid;
2079 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2080 o.out.trustdom_handle = &trustdom_handle;
2082 status = _lsa_OpenTrustedDomain(p, &o);
2083 if (!NT_STATUS_IS_OK(status)) {
2087 q.in.trustdom_handle = &trustdom_handle;
2088 q.in.level = r->in.level;
2089 q.out.info = r->out.info;
2091 status = _lsa_QueryTrustedDomainInfo(p, &q);
2092 if (!NT_STATUS_IS_OK(status)) {
2096 c.in.handle = &trustdom_handle;
2097 c.out.handle = &trustdom_handle;
2099 return _lsa_Close(p, &c);
2102 /***************************************************************************
2103 _lsa_QueryTrustedDomainInfoByName
2104 ***************************************************************************/
2106 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2107 struct lsa_QueryTrustedDomainInfoByName *r)
2110 struct policy_handle trustdom_handle;
2111 struct lsa_OpenTrustedDomainByName o;
2112 struct lsa_QueryTrustedDomainInfo q;
2115 o.in.handle = r->in.handle;
2116 o.in.name.string = r->in.trusted_domain->string;
2117 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2118 o.out.trustdom_handle = &trustdom_handle;
2120 status = _lsa_OpenTrustedDomainByName(p, &o);
2121 if (!NT_STATUS_IS_OK(status)) {
2122 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2123 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2128 q.in.trustdom_handle = &trustdom_handle;
2129 q.in.level = r->in.level;
2130 q.out.info = r->out.info;
2132 status = _lsa_QueryTrustedDomainInfo(p, &q);
2133 if (!NT_STATUS_IS_OK(status)) {
2137 c.in.handle = &trustdom_handle;
2138 c.out.handle = &trustdom_handle;
2140 return _lsa_Close(p, &c);
2143 /***************************************************************************
2144 ***************************************************************************/
2146 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p, struct lsa_CreateSecret *r)
2148 return NT_STATUS_ACCESS_DENIED;
2151 /***************************************************************************
2152 ***************************************************************************/
2154 NTSTATUS _lsa_SetSecret(struct pipes_struct *p, struct lsa_SetSecret *r)
2156 return NT_STATUS_ACCESS_DENIED;
2159 /***************************************************************************
2161 ***************************************************************************/
2163 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2164 struct lsa_DeleteObject *r)
2167 struct lsa_info *info = NULL;
2169 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2170 return NT_STATUS_INVALID_HANDLE;
2173 if (!(info->access & SEC_STD_DELETE)) {
2174 return NT_STATUS_ACCESS_DENIED;
2177 switch (info->type) {
2178 case LSA_HANDLE_ACCOUNT_TYPE:
2179 status = privilege_delete_account(&info->sid);
2180 if (!NT_STATUS_IS_OK(status)) {
2181 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2182 nt_errstr(status)));
2187 return NT_STATUS_INVALID_HANDLE;
2190 close_policy_hnd(p, r->in.handle);
2191 ZERO_STRUCTP(r->out.handle);
2196 /***************************************************************************
2198 ***************************************************************************/
2200 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2201 struct lsa_EnumPrivs *r)
2203 struct lsa_info *handle;
2205 uint32 enum_context = *r->in.resume_handle;
2206 int num_privs = num_privileges_in_short_list();
2207 struct lsa_PrivEntry *entries = NULL;
2209 /* remember that the enum_context starts at 0 and not 1 */
2211 if ( enum_context >= num_privs )
2212 return NT_STATUS_NO_MORE_ENTRIES;
2214 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2215 enum_context, num_privs));
2217 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2218 return NT_STATUS_INVALID_HANDLE;
2220 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2221 return NT_STATUS_INVALID_HANDLE;
2224 /* check if the user has enough rights
2225 I don't know if it's the right one. not documented. */
2227 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2228 return NT_STATUS_ACCESS_DENIED;
2231 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2233 return NT_STATUS_NO_MEMORY;
2239 for (i = 0; i < num_privs; i++) {
2240 if( i < enum_context) {
2242 init_lsa_StringLarge(&entries[i].name, NULL);
2244 entries[i].luid.low = 0;
2245 entries[i].luid.high = 0;
2248 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2250 entries[i].luid.low = sec_privilege_from_index(i);
2251 entries[i].luid.high = 0;
2255 enum_context = num_privs;
2257 *r->out.resume_handle = enum_context;
2258 r->out.privs->count = num_privs;
2259 r->out.privs->privs = entries;
2261 return NT_STATUS_OK;
2264 /***************************************************************************
2265 _lsa_LookupPrivDisplayName
2266 ***************************************************************************/
2268 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2269 struct lsa_LookupPrivDisplayName *r)
2271 struct lsa_info *handle;
2272 const char *description;
2273 struct lsa_StringLarge *lsa_name;
2275 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2276 return NT_STATUS_INVALID_HANDLE;
2278 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2279 return NT_STATUS_INVALID_HANDLE;
2282 /* check if the user has enough rights */
2285 * I don't know if it's the right one. not documented.
2287 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2288 return NT_STATUS_ACCESS_DENIED;
2290 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2292 description = get_privilege_dispname(r->in.name->string);
2294 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2295 return NT_STATUS_NO_SUCH_PRIVILEGE;
2298 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2300 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2302 return NT_STATUS_NO_MEMORY;
2305 init_lsa_StringLarge(lsa_name, description);
2307 *r->out.returned_language_id = r->in.language_id;
2308 *r->out.disp_name = lsa_name;
2310 return NT_STATUS_OK;
2313 /***************************************************************************
2315 ***************************************************************************/
2317 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2318 struct lsa_EnumAccounts *r)
2320 struct lsa_info *handle;
2321 struct dom_sid *sid_list;
2322 int i, j, num_entries;
2324 struct lsa_SidPtr *sids = NULL;
2326 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2327 return NT_STATUS_INVALID_HANDLE;
2329 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2330 return NT_STATUS_INVALID_HANDLE;
2333 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2334 return NT_STATUS_ACCESS_DENIED;
2339 /* The only way we can currently find out all the SIDs that have been
2340 privileged is to scan all privileges */
2342 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2343 if (!NT_STATUS_IS_OK(status)) {
2347 if (*r->in.resume_handle >= num_entries) {
2348 return NT_STATUS_NO_MORE_ENTRIES;
2351 if (num_entries - *r->in.resume_handle) {
2352 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
2353 num_entries - *r->in.resume_handle);
2355 talloc_free(sid_list);
2356 return NT_STATUS_NO_MEMORY;
2359 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2360 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2362 talloc_free(sid_list);
2363 return NT_STATUS_NO_MEMORY;
2368 talloc_free(sid_list);
2370 *r->out.resume_handle = num_entries;
2371 r->out.sids->num_sids = num_entries;
2372 r->out.sids->sids = sids;
2374 return NT_STATUS_OK;
2377 /***************************************************************************
2379 ***************************************************************************/
2381 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2382 struct lsa_GetUserName *r)
2384 const char *username, *domname;
2385 struct lsa_String *account_name = NULL;
2386 struct lsa_String *authority_name = NULL;
2388 if (r->in.account_name &&
2389 *r->in.account_name) {
2390 return NT_STATUS_INVALID_PARAMETER;
2393 if (r->in.authority_name &&
2394 *r->in.authority_name) {
2395 return NT_STATUS_INVALID_PARAMETER;
2398 if (p->session_info->guest) {
2400 * I'm 99% sure this is not the right place to do this,
2401 * global_sid_Anonymous should probably be put into the token
2402 * instead of the guest id -- vl
2404 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2405 &domname, &username, NULL)) {
2406 return NT_STATUS_NO_MEMORY;
2409 username = p->session_info->sanitized_username;
2410 domname = p->session_info->info3->base.domain.string;
2413 account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2414 if (!account_name) {
2415 return NT_STATUS_NO_MEMORY;
2417 init_lsa_String(account_name, username);
2419 if (r->out.authority_name) {
2420 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2421 if (!authority_name) {
2422 return NT_STATUS_NO_MEMORY;
2424 init_lsa_String(authority_name, domname);
2427 *r->out.account_name = account_name;
2428 if (r->out.authority_name) {
2429 *r->out.authority_name = authority_name;
2432 return NT_STATUS_OK;
2435 /***************************************************************************
2437 ***************************************************************************/
2439 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2440 struct lsa_CreateAccount *r)
2443 struct lsa_info *handle;
2444 uint32_t acc_granted;
2445 struct security_descriptor *psd;
2448 /* find the connection policy handle. */
2449 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2450 return NT_STATUS_INVALID_HANDLE;
2452 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2453 return NT_STATUS_INVALID_HANDLE;
2456 /* check if the user has enough rights */
2458 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2459 return NT_STATUS_ACCESS_DENIED;
2462 /* Work out max allowed. */
2463 map_max_allowed_access(p->session_info->security_token,
2464 &p->session_info->utok,
2465 &r->in.access_mask);
2467 /* map the generic bits to the lsa policy ones */
2468 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2470 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2471 &lsa_account_mapping,
2472 r->in.sid, LSA_POLICY_ALL_ACCESS);
2473 if (!NT_STATUS_IS_OK(status)) {
2477 status = access_check_object(psd, p->session_info->security_token,
2478 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2479 &acc_granted, "_lsa_CreateAccount");
2480 if (!NT_STATUS_IS_OK(status)) {
2484 if ( is_privileged_sid( r->in.sid ) )
2485 return NT_STATUS_OBJECT_NAME_COLLISION;
2487 status = create_lsa_policy_handle(p->mem_ctx, p,
2488 LSA_HANDLE_ACCOUNT_TYPE,
2493 r->out.acct_handle);
2494 if (!NT_STATUS_IS_OK(status)) {
2495 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2498 return privilege_create_account(r->in.sid);
2501 /***************************************************************************
2503 ***************************************************************************/
2505 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2506 struct lsa_OpenAccount *r)
2508 struct lsa_info *handle;
2509 struct security_descriptor *psd = NULL;
2511 uint32_t des_access = r->in.access_mask;
2512 uint32_t acc_granted;
2515 /* find the connection policy handle. */
2516 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2517 return NT_STATUS_INVALID_HANDLE;
2519 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2520 return NT_STATUS_INVALID_HANDLE;
2523 /* des_access is for the account here, not the policy
2524 * handle - so don't check against policy handle. */
2526 /* Work out max allowed. */
2527 map_max_allowed_access(p->session_info->security_token,
2528 &p->session_info->utok,
2531 /* map the generic bits to the lsa account ones */
2532 se_map_generic(&des_access, &lsa_account_mapping);
2534 /* get the generic lsa account SD until we store it */
2535 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2536 &lsa_account_mapping,
2537 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2538 if (!NT_STATUS_IS_OK(status)) {
2542 status = access_check_object(psd, p->session_info->security_token,
2543 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2544 &acc_granted, "_lsa_OpenAccount" );
2545 if (!NT_STATUS_IS_OK(status)) {
2549 /* TODO: Fis the parsing routine before reenabling this check! */
2551 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2552 return NT_STATUS_ACCESS_DENIED;
2555 status = create_lsa_policy_handle(p->mem_ctx, p,
2556 LSA_HANDLE_ACCOUNT_TYPE,
2561 r->out.acct_handle);
2562 if (!NT_STATUS_IS_OK(status)) {
2563 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2566 return NT_STATUS_OK;
2569 /***************************************************************************
2570 _lsa_EnumPrivsAccount
2571 For a given SID, enumerate all the privilege this account has.
2572 ***************************************************************************/
2574 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2575 struct lsa_EnumPrivsAccount *r)
2577 NTSTATUS status = NT_STATUS_OK;
2578 struct lsa_info *info=NULL;
2579 PRIVILEGE_SET *privileges;
2580 struct lsa_PrivilegeSet *priv_set = NULL;
2582 /* find the connection policy handle. */
2583 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2584 return NT_STATUS_INVALID_HANDLE;
2586 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2587 return NT_STATUS_INVALID_HANDLE;
2590 if (!(info->access & LSA_ACCOUNT_VIEW))
2591 return NT_STATUS_ACCESS_DENIED;
2593 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2594 if (!NT_STATUS_IS_OK(status)) {
2598 *r->out.privs = priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
2600 return NT_STATUS_NO_MEMORY;
2603 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2604 sid_string_dbg(&info->sid),
2605 privileges->count));
2607 priv_set->count = privileges->count;
2608 priv_set->unknown = 0;
2609 priv_set->set = talloc_move(priv_set, &privileges->set);
2614 /***************************************************************************
2615 _lsa_GetSystemAccessAccount
2616 ***************************************************************************/
2618 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2619 struct lsa_GetSystemAccessAccount *r)
2622 struct lsa_info *info = NULL;
2623 struct lsa_EnumPrivsAccount e;
2624 struct lsa_PrivilegeSet *privset;
2626 /* find the connection policy handle. */
2628 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2629 return NT_STATUS_INVALID_HANDLE;
2631 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2632 return NT_STATUS_INVALID_HANDLE;
2635 if (!(info->access & LSA_ACCOUNT_VIEW))
2636 return NT_STATUS_ACCESS_DENIED;
2638 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2640 return NT_STATUS_NO_MEMORY;
2643 e.in.handle = r->in.handle;
2644 e.out.privs = &privset;
2646 status = _lsa_EnumPrivsAccount(p, &e);
2647 if (!NT_STATUS_IS_OK(status)) {
2648 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2649 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2650 nt_errstr(status)));
2654 /* Samba4 would iterate over the privset to merge the policy mode bits,
2655 * not sure samba3 can do the same here, so just return what we did in
2659 0x01 -> Log on locally
2660 0x02 -> Access this computer from network
2661 0x04 -> Log on as a batch job
2662 0x10 -> Log on as a service
2664 they can be ORed together
2667 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2668 LSA_POLICY_MODE_NETWORK;
2670 return NT_STATUS_OK;
2673 /***************************************************************************
2674 update the systemaccount information
2675 ***************************************************************************/
2677 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2678 struct lsa_SetSystemAccessAccount *r)
2680 struct lsa_info *info=NULL;
2683 /* find the connection policy handle. */
2684 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2685 return NT_STATUS_INVALID_HANDLE;
2687 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2688 return NT_STATUS_INVALID_HANDLE;
2691 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2692 return NT_STATUS_ACCESS_DENIED;
2695 if (!pdb_getgrsid(&map, info->sid))
2696 return NT_STATUS_NO_SUCH_GROUP;
2698 return pdb_update_group_mapping_entry(&map);
2701 /***************************************************************************
2702 _lsa_AddPrivilegesToAccount
2703 For a given SID, add some privileges.
2704 ***************************************************************************/
2706 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
2707 struct lsa_AddPrivilegesToAccount *r)
2709 struct lsa_info *info = NULL;
2710 struct lsa_PrivilegeSet *set = NULL;
2712 /* find the connection policy handle. */
2713 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2714 return NT_STATUS_INVALID_HANDLE;
2716 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2717 return NT_STATUS_INVALID_HANDLE;
2720 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2721 return NT_STATUS_ACCESS_DENIED;
2726 if ( !grant_privilege_set( &info->sid, set ) ) {
2727 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2728 sid_string_dbg(&info->sid) ));
2729 return NT_STATUS_NO_SUCH_PRIVILEGE;
2732 return NT_STATUS_OK;
2735 /***************************************************************************
2736 _lsa_RemovePrivilegesFromAccount
2737 For a given SID, remove some privileges.
2738 ***************************************************************************/
2740 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2741 struct lsa_RemovePrivilegesFromAccount *r)
2743 struct lsa_info *info = NULL;
2744 struct lsa_PrivilegeSet *set = NULL;
2746 /* find the connection policy handle. */
2747 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2748 return NT_STATUS_INVALID_HANDLE;
2750 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2751 return NT_STATUS_INVALID_HANDLE;
2754 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2755 return NT_STATUS_ACCESS_DENIED;
2760 if ( !revoke_privilege_set( &info->sid, set) ) {
2761 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2762 sid_string_dbg(&info->sid) ));
2763 return NT_STATUS_NO_SUCH_PRIVILEGE;
2766 return NT_STATUS_OK;
2769 /***************************************************************************
2771 ***************************************************************************/
2773 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2774 struct lsa_LookupPrivName *r)
2776 struct lsa_info *info = NULL;
2778 struct lsa_StringLarge *lsa_name;
2780 /* find the connection policy handle. */
2781 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2782 return NT_STATUS_INVALID_HANDLE;
2785 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2786 return NT_STATUS_INVALID_HANDLE;
2789 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2790 return NT_STATUS_ACCESS_DENIED;
2793 if (r->in.luid->high != 0) {
2794 return NT_STATUS_NO_SUCH_PRIVILEGE;
2797 name = sec_privilege_name(r->in.luid->low);
2799 return NT_STATUS_NO_SUCH_PRIVILEGE;
2802 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2804 return NT_STATUS_NO_MEMORY;
2807 lsa_name->string = talloc_strdup(lsa_name, name);
2808 if (!lsa_name->string) {
2809 TALLOC_FREE(lsa_name);
2810 return NT_STATUS_NO_MEMORY;
2813 *r->out.name = lsa_name;
2815 return NT_STATUS_OK;
2818 /***************************************************************************
2820 ***************************************************************************/
2822 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
2823 struct lsa_QuerySecurity *r)
2825 struct lsa_info *handle=NULL;
2826 struct security_descriptor *psd = NULL;
2830 /* find the connection policy handle. */
2831 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2832 return NT_STATUS_INVALID_HANDLE;
2834 switch (handle->type) {
2835 case LSA_HANDLE_POLICY_TYPE:
2836 case LSA_HANDLE_ACCOUNT_TYPE:
2837 case LSA_HANDLE_TRUST_TYPE:
2839 sd_size = ndr_size_security_descriptor(psd, 0);
2840 status = NT_STATUS_OK;
2843 status = NT_STATUS_INVALID_HANDLE;
2847 if (!NT_STATUS_IS_OK(status)) {
2851 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2852 if (!*r->out.sdbuf) {
2853 return NT_STATUS_NO_MEMORY;
2859 /***************************************************************************
2860 _lsa_AddAccountRights
2861 ***************************************************************************/
2863 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
2864 struct lsa_AddAccountRights *r)
2866 struct lsa_info *info = NULL;
2868 uint32_t acc_granted = 0;
2869 struct security_descriptor *psd = NULL;
2874 /* find the connection policy handle. */
2875 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2876 return NT_STATUS_INVALID_HANDLE;
2878 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2879 return NT_STATUS_INVALID_HANDLE;
2882 /* get the generic lsa account SD for this SID until we store it */
2883 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2884 &lsa_account_mapping,
2885 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2886 if (!NT_STATUS_IS_OK(status)) {
2891 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2892 * on the policy handle. If it does, ask for
2893 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2894 * on the account sid. We don't check here so just use the latter. JRA.
2897 status = access_check_object(psd, p->session_info->security_token,
2898 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2899 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2900 &acc_granted, "_lsa_AddAccountRights" );
2901 if (!NT_STATUS_IS_OK(status)) {
2905 /* according to an NT4 PDC, you can add privileges to SIDs even without
2906 call_lsa_create_account() first. And you can use any arbitrary SID. */
2908 sid_copy( &sid, r->in.sid );
2910 for ( i=0; i < r->in.rights->count; i++ ) {
2912 const char *privname = r->in.rights->names[i].string;
2914 /* only try to add non-null strings */
2919 if ( !grant_privilege_by_name( &sid, privname ) ) {
2920 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2922 return NT_STATUS_NO_SUCH_PRIVILEGE;
2926 return NT_STATUS_OK;
2929 /***************************************************************************
2930 _lsa_RemoveAccountRights
2931 ***************************************************************************/
2933 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
2934 struct lsa_RemoveAccountRights *r)
2936 struct lsa_info *info = NULL;
2938 struct security_descriptor *psd = NULL;
2941 const char *privname = NULL;
2942 uint32_t acc_granted = 0;
2945 /* find the connection policy handle. */
2946 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2947 return NT_STATUS_INVALID_HANDLE;
2949 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2950 return NT_STATUS_INVALID_HANDLE;
2953 /* get the generic lsa account SD for this SID until we store it */
2954 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2955 &lsa_account_mapping,
2956 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2957 if (!NT_STATUS_IS_OK(status)) {
2962 * From the MS DOCs. We need
2963 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2964 * and DELETE on the account sid.
2967 status = access_check_object(psd, p->session_info->security_token,
2968 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2969 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2970 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
2971 &acc_granted, "_lsa_RemoveAccountRights");
2972 if (!NT_STATUS_IS_OK(status)) {
2976 sid_copy( &sid, r->in.sid );
2978 if ( r->in.remove_all ) {
2979 if ( !revoke_all_privileges( &sid ) )
2980 return NT_STATUS_ACCESS_DENIED;
2982 return NT_STATUS_OK;
2985 for ( i=0; i < r->in.rights->count; i++ ) {
2987 privname = r->in.rights->names[i].string;
2989 /* only try to add non-null strings */
2994 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2995 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2997 return NT_STATUS_NO_SUCH_PRIVILEGE;
3001 return NT_STATUS_OK;
3004 /*******************************************************************
3005 ********************************************************************/
3007 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3008 struct lsa_RightSet *r,
3009 PRIVILEGE_SET *privileges)
3012 const char *privname;
3013 const char **privname_array = NULL;
3016 for (i=0; i<privileges->count; i++) {
3017 if (privileges->set[i].luid.high) {
3020 privname = sec_privilege_name(privileges->set[i].luid.low);
3022 if (!add_string_to_array(mem_ctx, privname,
3023 &privname_array, &num_priv)) {
3024 return NT_STATUS_NO_MEMORY;
3031 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
3034 return NT_STATUS_NO_MEMORY;
3037 for (i=0; i<num_priv; i++) {
3038 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3041 r->count = num_priv;
3044 return NT_STATUS_OK;
3047 /***************************************************************************
3048 _lsa_EnumAccountRights
3049 ***************************************************************************/
3051 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3052 struct lsa_EnumAccountRights *r)
3055 struct lsa_info *info = NULL;
3056 PRIVILEGE_SET *privileges;
3058 /* find the connection policy handle. */
3060 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3061 return NT_STATUS_INVALID_HANDLE;
3063 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3064 return NT_STATUS_INVALID_HANDLE;
3067 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3068 return NT_STATUS_ACCESS_DENIED;
3071 /* according to an NT4 PDC, you can add privileges to SIDs even without
3072 call_lsa_create_account() first. And you can use any arbitrary SID. */
3074 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3075 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3076 * the lsa database */
3078 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3079 if (!NT_STATUS_IS_OK(status)) {
3083 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3084 sid_string_dbg(r->in.sid), privileges->count));
3086 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3091 /***************************************************************************
3092 _lsa_LookupPrivValue
3093 ***************************************************************************/
3095 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3096 struct lsa_LookupPrivValue *r)
3098 struct lsa_info *info = NULL;
3099 const char *name = NULL;
3101 /* find the connection policy handle. */
3103 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3104 return NT_STATUS_INVALID_HANDLE;
3106 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3107 return NT_STATUS_INVALID_HANDLE;
3110 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3111 return NT_STATUS_ACCESS_DENIED;
3113 name = r->in.name->string;
3115 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3117 r->out.luid->low = sec_privilege_id(name);
3118 r->out.luid->high = 0;
3119 if (r->out.luid->low == SEC_PRIV_INVALID) {
3120 return NT_STATUS_NO_SUCH_PRIVILEGE;
3122 return NT_STATUS_OK;
3125 /***************************************************************************
3126 _lsa_EnumAccountsWithUserRight
3127 ***************************************************************************/
3129 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3130 struct lsa_EnumAccountsWithUserRight *r)
3133 struct lsa_info *info = NULL;
3134 struct dom_sid *sids = NULL;
3137 enum sec_privilege privilege;
3139 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3140 return NT_STATUS_INVALID_HANDLE;
3143 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3144 return NT_STATUS_INVALID_HANDLE;
3147 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3148 return NT_STATUS_ACCESS_DENIED;
3151 if (!r->in.name || !r->in.name->string) {
3152 return NT_STATUS_NO_SUCH_PRIVILEGE;
3155 privilege = sec_privilege_id(r->in.name->string);
3156 if (privilege == SEC_PRIV_INVALID) {
3157 return NT_STATUS_NO_SUCH_PRIVILEGE;
3160 status = privilege_enum_sids(privilege, p->mem_ctx,
3162 if (!NT_STATUS_IS_OK(status)) {
3166 r->out.sids->num_sids = num_sids;
3167 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3168 r->out.sids->num_sids);
3170 for (i=0; i < r->out.sids->num_sids; i++) {
3171 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3173 if (!r->out.sids->sids[i].sid) {
3174 TALLOC_FREE(r->out.sids->sids);
3175 r->out.sids->num_sids = 0;
3176 return NT_STATUS_NO_MEMORY;
3180 return NT_STATUS_OK;
3183 /***************************************************************************
3185 ***************************************************************************/
3187 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3188 struct lsa_Delete *r)
3190 return NT_STATUS_NOT_SUPPORTED;
3194 * From here on the server routines are just dummy ones to make smbd link with
3195 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3196 * pulling the server stubs across one by one.
3199 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3201 p->rng_fault_state = True;
3202 return NT_STATUS_NOT_IMPLEMENTED;
3205 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3206 struct lsa_ChangePassword *r)
3208 p->rng_fault_state = True;
3209 return NT_STATUS_NOT_IMPLEMENTED;
3212 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3214 p->rng_fault_state = True;
3215 return NT_STATUS_NOT_IMPLEMENTED;
3218 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3220 p->rng_fault_state = True;
3221 return NT_STATUS_NOT_IMPLEMENTED;
3224 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3225 struct lsa_GetQuotasForAccount *r)
3227 p->rng_fault_state = True;
3228 return NT_STATUS_NOT_IMPLEMENTED;
3231 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3232 struct lsa_SetQuotasForAccount *r)
3234 p->rng_fault_state = True;
3235 return NT_STATUS_NOT_IMPLEMENTED;
3238 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3239 struct lsa_SetInformationTrustedDomain *r)
3241 p->rng_fault_state = True;
3242 return NT_STATUS_NOT_IMPLEMENTED;
3245 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
3247 p->rng_fault_state = True;
3248 return NT_STATUS_NOT_IMPLEMENTED;
3251 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3252 struct lsa_SetTrustedDomainInfo *r)
3254 p->rng_fault_state = True;
3255 return NT_STATUS_NOT_IMPLEMENTED;
3258 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3259 struct lsa_StorePrivateData *r)
3261 p->rng_fault_state = True;
3262 return NT_STATUS_NOT_IMPLEMENTED;
3265 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3266 struct lsa_RetrievePrivateData *r)
3268 p->rng_fault_state = True;
3269 return NT_STATUS_NOT_IMPLEMENTED;
3272 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3273 struct lsa_SetInfoPolicy2 *r)
3275 p->rng_fault_state = True;
3276 return NT_STATUS_NOT_IMPLEMENTED;
3279 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3280 struct lsa_SetTrustedDomainInfoByName *r)
3282 p->rng_fault_state = True;
3283 return NT_STATUS_NOT_IMPLEMENTED;
3286 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3287 struct lsa_EnumTrustedDomainsEx *r)
3289 struct lsa_info *info;
3291 struct pdb_trusted_domain **domains;
3292 struct lsa_TrustDomainInfoInfoEx *entries;
3296 /* bail out early if pdb backend is not capable of ex trusted domains,
3297 * if we dont do that, the client might not call
3298 * _lsa_EnumTrustedDomains() afterwards - gd */
3300 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3301 p->rng_fault_state = True;
3302 return NT_STATUS_NOT_IMPLEMENTED;
3305 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3306 return NT_STATUS_INVALID_HANDLE;
3308 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3309 return NT_STATUS_INVALID_HANDLE;
3312 /* check if the user has enough rights */
3313 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3314 return NT_STATUS_ACCESS_DENIED;
3317 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3320 if (!NT_STATUS_IS_OK(nt_status)) {
3324 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3327 return NT_STATUS_NO_MEMORY;
3330 for (i=0; i<count; i++) {
3331 init_lsa_StringLarge(&entries[i].netbios_name,
3332 domains[i]->netbios_name);
3333 entries[i].sid = &domains[i]->security_identifier;
3336 if (*r->in.resume_handle >= count) {
3337 *r->out.resume_handle = -1;
3338 TALLOC_FREE(entries);
3339 return NT_STATUS_NO_MORE_ENTRIES;
3342 /* return the rest, limit by max_size. Note that we
3343 use the w2k3 element size value of 60 */
3344 r->out.domains->count = count - *r->in.resume_handle;
3345 r->out.domains->count = MIN(r->out.domains->count,
3346 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3348 r->out.domains->domains = entries + *r->in.resume_handle;
3350 if (r->out.domains->count < count - *r->in.resume_handle) {
3351 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3352 return STATUS_MORE_ENTRIES;
3355 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3356 * always be larger than the previous input resume handle, in
3357 * particular when hitting the last query it is vital to set the
3358 * resume handle correctly to avoid infinite client loops, as
3359 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3360 * status is NT_STATUS_OK - gd */
3362 *r->out.resume_handle = (uint32_t)-1;
3364 return NT_STATUS_OK;
3367 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3368 struct lsa_QueryDomainInformationPolicy *r)
3370 p->rng_fault_state = True;
3371 return NT_STATUS_NOT_IMPLEMENTED;
3374 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3375 struct lsa_SetDomainInformationPolicy *r)
3377 p->rng_fault_state = True;
3378 return NT_STATUS_NOT_IMPLEMENTED;
3381 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3383 p->rng_fault_state = True;
3384 return NT_STATUS_NOT_IMPLEMENTED;
3387 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3389 p->rng_fault_state = True;
3390 return NT_STATUS_NOT_IMPLEMENTED;
3393 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3395 p->rng_fault_state = True;
3396 return NT_STATUS_NOT_IMPLEMENTED;
3399 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3401 p->rng_fault_state = True;
3402 return NT_STATUS_NOT_IMPLEMENTED;
3405 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3406 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3408 p->rng_fault_state = True;
3409 return NT_STATUS_NOT_IMPLEMENTED;
3412 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3413 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3415 p->rng_fault_state = True;
3416 return NT_STATUS_NOT_IMPLEMENTED;
3419 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3421 p->rng_fault_state = True;
3422 return NT_STATUS_NOT_IMPLEMENTED;
3425 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3426 struct lsa_CREDRGETTARGETINFO *r)
3428 p->rng_fault_state = True;
3429 return NT_STATUS_NOT_IMPLEMENTED;
3432 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3433 struct lsa_CREDRPROFILELOADED *r)
3435 p->rng_fault_state = True;
3436 return NT_STATUS_NOT_IMPLEMENTED;
3439 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3440 struct lsa_CREDRGETSESSIONTYPES *r)
3442 p->rng_fault_state = True;
3443 return NT_STATUS_NOT_IMPLEMENTED;
3446 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3447 struct lsa_LSARREGISTERAUDITEVENT *r)
3449 p->rng_fault_state = True;
3450 return NT_STATUS_NOT_IMPLEMENTED;
3453 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3454 struct lsa_LSARGENAUDITEVENT *r)
3456 p->rng_fault_state = True;
3457 return NT_STATUS_NOT_IMPLEMENTED;
3460 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3461 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3463 p->rng_fault_state = True;
3464 return NT_STATUS_NOT_IMPLEMENTED;
3467 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3468 struct lsa_lsaRQueryForestTrustInformation *r)
3470 p->rng_fault_state = True;
3471 return NT_STATUS_NOT_IMPLEMENTED;
3474 #define DNS_CMP_MATCH 0
3475 #define DNS_CMP_FIRST_IS_CHILD 1
3476 #define DNS_CMP_SECOND_IS_CHILD 2
3477 #define DNS_CMP_NO_MATCH 3
3479 /* this function assumes names are well formed DNS names.
3480 * it doesn't validate them */
3481 static int dns_cmp(const char *s1, size_t l1,
3482 const char *s2, size_t l2)
3484 const char *p1, *p2;
3489 if (StrCaseCmp(s1, s2) == 0) {
3490 return DNS_CMP_MATCH;
3492 return DNS_CMP_NO_MATCH;
3500 cret = DNS_CMP_FIRST_IS_CHILD;
3506 cret = DNS_CMP_SECOND_IS_CHILD;
3509 if (p1[t1 - t2 - 1] != '.') {
3510 return DNS_CMP_NO_MATCH;
3513 if (StrCaseCmp(&p1[t1 - t2], p2) == 0) {
3517 return DNS_CMP_NO_MATCH;
3520 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3521 struct lsa_ForestTrustInformation *lfti,
3522 struct ForestTrustInfo *fti)
3524 struct lsa_ForestTrustRecord *lrec;
3525 struct ForestTrustInfoRecord *rec;
3526 struct lsa_StringLarge *tln;
3527 struct lsa_ForestTrustDomainInfo *info;
3531 fti->count = lfti->count;
3532 fti->records = talloc_array(mem_ctx,
3533 struct ForestTrustInfoRecordArmor,
3535 if (!fti->records) {
3536 return NT_STATUS_NO_MEMORY;
3538 for (i = 0; i < fti->count; i++) {
3539 lrec = lfti->entries[i];
3540 rec = &fti->records[i].record;
3542 rec->flags = lrec->flags;
3543 rec->timestamp = lrec->time;
3544 rec->type = lrec->type;
3546 switch (lrec->type) {
3547 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3548 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3549 tln = &lrec->forest_trust_data.top_level_name;
3550 rec->data.name.string =
3551 talloc_strdup(mem_ctx, tln->string);
3552 if (!rec->data.name.string) {
3553 return NT_STATUS_NO_MEMORY;
3555 rec->data.name.size = strlen(rec->data.name.string);
3557 case LSA_FOREST_TRUST_DOMAIN_INFO:
3558 info = &lrec->forest_trust_data.domain_info;
3559 rec->data.info.sid = *info->domain_sid;
3560 rec->data.info.dns_name.string =
3561 talloc_strdup(mem_ctx,
3562 info->dns_domain_name.string);
3563 if (!rec->data.info.dns_name.string) {
3564 return NT_STATUS_NO_MEMORY;
3566 rec->data.info.dns_name.size =
3567 strlen(rec->data.info.dns_name.string);
3568 rec->data.info.netbios_name.string =
3569 talloc_strdup(mem_ctx,
3570 info->netbios_domain_name.string);
3571 if (!rec->data.info.netbios_name.string) {
3572 return NT_STATUS_NO_MEMORY;
3574 rec->data.info.netbios_name.size =
3575 strlen(rec->data.info.netbios_name.string);
3578 return NT_STATUS_INVALID_DOMAIN_STATE;
3582 return NT_STATUS_OK;
3585 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3586 uint32_t index, uint32_t collision_type,
3587 uint32_t conflict_type, const char *tdo_name);
3589 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
3590 const char *tdo_name,
3591 struct ForestTrustInfo *tdo_fti,
3592 struct ForestTrustInfo *new_fti,
3593 struct lsa_ForestTrustCollisionInfo *c_info)
3595 struct ForestTrustInfoRecord *nrec;
3596 struct ForestTrustInfoRecord *trec;
3597 const char *dns_name;
3598 const char *nb_name = NULL;
3599 struct dom_sid *sid = NULL;
3600 const char *tname = NULL;
3605 uint32_t new_fti_idx;
3607 /* use always TDO type, until we understand when Xref can be used */
3608 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
3613 bool ex_rule = false;
3616 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
3618 nrec = &new_fti->records[new_fti_idx].record;
3620 tln_conflict = false;
3621 sid_conflict = false;
3622 nb_conflict = false;
3625 switch (nrec->type) {
3626 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3627 /* exclusions do not conflict by definition */
3630 case FOREST_TRUST_TOP_LEVEL_NAME:
3631 dns_name = nrec->data.name.string;
3632 dns_len = nrec->data.name.size;
3635 case LSA_FOREST_TRUST_DOMAIN_INFO:
3636 dns_name = nrec->data.info.dns_name.string;
3637 dns_len = nrec->data.info.dns_name.size;
3638 nb_name = nrec->data.info.netbios_name.string;
3639 nb_len = nrec->data.info.netbios_name.size;
3640 sid = &nrec->data.info.sid;
3644 if (!dns_name) continue;
3646 /* check if this is already taken and not excluded */
3647 for (i = 0; i < tdo_fti->count; i++) {
3648 trec = &tdo_fti->records[i].record;
3650 switch (trec->type) {
3651 case FOREST_TRUST_TOP_LEVEL_NAME:
3653 tname = trec->data.name.string;
3654 tlen = trec->data.name.size;
3656 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
3658 tname = trec->data.name.string;
3659 tlen = trec->data.name.size;
3661 case FOREST_TRUST_DOMAIN_INFO:
3663 tname = trec->data.info.dns_name.string;
3664 tlen = trec->data.info.dns_name.size;
3666 ret = dns_cmp(dns_name, dns_len, tname, tlen);
3669 /* if it matches exclusion,
3670 * it doesn't conflict */
3676 case DNS_CMP_FIRST_IS_CHILD:
3677 case DNS_CMP_SECOND_IS_CHILD:
3678 tln_conflict = true;
3684 /* explicit exclusion, no dns name conflict here */
3686 tln_conflict = false;
3689 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
3693 /* also test for domain info */
3694 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
3695 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
3696 sid_conflict = true;
3698 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
3699 StrCaseCmp(trec->data.info.netbios_name.string,
3706 nt_status = add_collision(c_info, new_fti_idx,
3708 LSA_TLN_DISABLED_CONFLICT,
3712 nt_status = add_collision(c_info, new_fti_idx,
3714 LSA_SID_DISABLED_CONFLICT,
3718 nt_status = add_collision(c_info, new_fti_idx,
3720 LSA_NB_DISABLED_CONFLICT,
3725 return NT_STATUS_OK;
3728 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3729 uint32_t idx, uint32_t collision_type,
3730 uint32_t conflict_type, const char *tdo_name)
3732 struct lsa_ForestTrustCollisionRecord **es;
3733 uint32_t i = c_info->count;
3735 es = talloc_realloc(c_info, c_info->entries,
3736 struct lsa_ForestTrustCollisionRecord *, i + 1);
3738 return NT_STATUS_NO_MEMORY;
3740 c_info->entries = es;
3741 c_info->count = i + 1;
3743 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
3745 return NT_STATUS_NO_MEMORY;
3749 es[i]->type = collision_type;
3750 es[i]->flags.flags = conflict_type;
3751 es[i]->name.string = talloc_strdup(es[i], tdo_name);
3752 if (!es[i]->name.string) {
3753 return NT_STATUS_NO_MEMORY;
3755 es[i]->name.size = strlen(es[i]->name.string);
3757 return NT_STATUS_OK;
3760 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3761 struct pdb_trusted_domain *td,
3762 struct ForestTrustInfo *info)
3764 enum ndr_err_code ndr_err;
3766 if (td->trust_forest_trust_info.length == 0 ||
3767 td->trust_forest_trust_info.data == NULL) {
3768 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3770 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
3772 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3773 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3774 return NT_STATUS_INVALID_DOMAIN_STATE;
3777 return NT_STATUS_OK;
3780 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
3781 struct ForestTrustInfo *fti)
3783 struct ForestTrustDataDomainInfo *info;
3784 struct ForestTrustInfoRecord *rec;
3788 fti->records = talloc_array(fti,
3789 struct ForestTrustInfoRecordArmor, 2);
3790 if (!fti->records) {
3791 return NT_STATUS_NO_MEMORY;
3795 rec = &fti->records[0].record;
3799 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3801 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
3802 if (!rec->data.name.string) {
3803 return NT_STATUS_NO_MEMORY;
3805 rec->data.name.size = strlen(rec->data.name.string);
3808 rec = &fti->records[1].record;
3812 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3814 info = &rec->data.info;
3816 info->sid = dom_info->sid;
3817 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
3818 if (!info->dns_name.string) {
3819 return NT_STATUS_NO_MEMORY;
3821 info->dns_name.size = strlen(info->dns_name.string);
3822 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
3823 if (!info->netbios_name.string) {
3824 return NT_STATUS_NO_MEMORY;
3826 info->netbios_name.size = strlen(info->netbios_name.string);
3828 return NT_STATUS_OK;
3831 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
3832 struct lsa_lsaRSetForestTrustInformation *r)
3837 struct lsa_info *handle;
3838 uint32_t num_domains;
3839 struct pdb_trusted_domain **domains;
3840 struct ForestTrustInfo *nfti;
3841 struct ForestTrustInfo *fti;
3842 struct lsa_ForestTrustCollisionInfo *c_info;
3843 struct pdb_domain_info *dom_info;
3844 enum ndr_err_code ndr_err;
3847 return NT_STATUS_NOT_SUPPORTED;
3850 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
3851 return NT_STATUS_INVALID_HANDLE;
3854 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
3855 return NT_STATUS_INVALID_HANDLE;
3858 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
3859 return NT_STATUS_ACCESS_DENIED;
3862 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
3863 if (!NT_STATUS_IS_OK(status)) {
3866 if (num_domains == 0) {
3867 return NT_STATUS_NO_SUCH_DOMAIN;
3870 for (i = 0; i < num_domains; i++) {
3871 if (domains[i]->domain_name == NULL) {
3872 return NT_STATUS_INVALID_DOMAIN_STATE;
3874 if (StrCaseCmp(domains[i]->domain_name,
3875 r->in.trusted_domain_name->string) == 0) {
3879 if (i >= num_domains) {
3880 return NT_STATUS_NO_SUCH_DOMAIN;
3883 if (!(domains[i]->trust_attributes &
3884 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
3885 return NT_STATUS_INVALID_PARAMETER;
3888 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
3889 return NT_STATUS_INVALID_PARAMETER;
3892 /* The following section until COPY_END is a copy from
3893 * source4/rpmc_server/lsa/scesrc_lsa.c */
3894 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
3896 return NT_STATUS_NO_MEMORY;
3899 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
3900 if (!NT_STATUS_IS_OK(status)) {
3904 c_info = talloc_zero(r->out.collision_info,
3905 struct lsa_ForestTrustCollisionInfo);
3907 return NT_STATUS_NO_MEMORY;
3910 /* first check own info, then other domains */
3911 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3913 return NT_STATUS_NO_MEMORY;
3916 dom_info = pdb_get_domain_info(p->mem_ctx);
3918 status = own_ft_info(dom_info, fti);
3919 if (!NT_STATUS_IS_OK(status)) {
3923 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
3924 if (!NT_STATUS_IS_OK(status)) {
3928 for (j = 0; j < num_domains; j++) {
3929 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3931 return NT_STATUS_NO_MEMORY;
3934 status = get_ft_info(p->mem_ctx, domains[j], fti);
3935 if (!NT_STATUS_IS_OK(status)) {
3936 if (NT_STATUS_EQUAL(status,
3937 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3943 if (domains[j]->domain_name == NULL) {
3944 return NT_STATUS_INVALID_DOMAIN_STATE;
3947 status = check_ft_info(c_info, domains[j]->domain_name,
3949 if (!NT_STATUS_IS_OK(status)) {
3954 *r->out.collision_info = c_info;
3956 if (r->in.check_only != 0) {
3957 return NT_STATUS_OK;
3962 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
3964 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
3965 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3966 return NT_STATUS_INVALID_PARAMETER;
3969 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
3970 if (!NT_STATUS_IS_OK(status)) {
3974 return NT_STATUS_OK;
3977 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
3978 struct lsa_CREDRRENAME *r)
3980 p->rng_fault_state = True;
3981 return NT_STATUS_NOT_IMPLEMENTED;
3984 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
3985 struct lsa_LSAROPENPOLICYSCE *r)
3987 p->rng_fault_state = True;
3988 return NT_STATUS_NOT_IMPLEMENTED;
3991 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
3992 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3994 p->rng_fault_state = True;
3995 return NT_STATUS_NOT_IMPLEMENTED;
3998 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
3999 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4001 p->rng_fault_state = True;
4002 return NT_STATUS_NOT_IMPLEMENTED;
4005 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4006 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4008 p->rng_fault_state = True;
4009 return NT_STATUS_NOT_IMPLEMENTED;