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. */
34 #include "../librpc/gen_ndr/srv_lsa.h"
36 #include "../librpc/gen_ndr/netlogon.h"
37 #include "rpc_client/init_lsa.h"
38 #include "../libcli/security/security.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../librpc/gen_ndr/drsblobs.h"
41 #include "../librpc/gen_ndr/ndr_drsblobs.h"
42 #include "../lib/crypto/arcfour.h"
43 #include "../libcli/security/dom_sid.h"
44 #include "../librpc/gen_ndr/ndr_security.h"
47 #include "lib/privileges.h"
48 #include "rpc_server/srv_access_check.h"
49 #include "../librpc/gen_ndr/ndr_wkssvc.h"
50 #include "../libcli/auth/libcli_auth.h"
51 #include "rpc_client/util_lsarpc.h"
54 #define DBGC_CLASS DBGC_RPC_SRV
56 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
58 enum lsa_handle_type {
59 LSA_HANDLE_POLICY_TYPE = 1,
60 LSA_HANDLE_ACCOUNT_TYPE = 2,
61 LSA_HANDLE_TRUST_TYPE = 3,
62 LSA_HANDLE_SECRET_TYPE = 4};
68 enum lsa_handle_type type;
69 struct security_descriptor *sd;
72 const struct generic_mapping lsa_account_mapping = {
76 LSA_ACCOUNT_ALL_ACCESS
79 const struct generic_mapping lsa_policy_mapping = {
86 const struct generic_mapping lsa_secret_mapping = {
93 const struct generic_mapping lsa_trusted_domain_mapping = {
94 LSA_TRUSTED_DOMAIN_READ,
95 LSA_TRUSTED_DOMAIN_WRITE,
96 LSA_TRUSTED_DOMAIN_EXECUTE,
97 LSA_TRUSTED_DOMAIN_ALL_ACCESS
100 /***************************************************************************
101 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
102 ***************************************************************************/
104 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
105 struct lsa_RefDomainList *ref,
106 const char *dom_name,
107 struct dom_sid *dom_sid)
111 if (dom_name != NULL) {
112 for (num = 0; num < ref->count; num++) {
113 if (dom_sid_equal(dom_sid, ref->domains[num].sid)) {
121 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
122 /* index not found, already at maximum domain limit */
126 ref->count = num + 1;
127 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
129 ref->domains = talloc_realloc(mem_ctx, ref->domains,
130 struct lsa_DomainInfo, ref->count);
135 ZERO_STRUCT(ref->domains[num]);
137 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
138 ref->domains[num].sid = dom_sid_dup(mem_ctx, dom_sid);
139 if (!ref->domains[num].sid) {
147 /***************************************************************************
148 initialize a lsa_DomainInfo structure.
149 ***************************************************************************/
151 static void init_dom_query_3(struct lsa_DomainInfo *r,
155 init_lsa_StringLarge(&r->name, name);
159 /***************************************************************************
160 initialize a lsa_DomainInfo structure.
161 ***************************************************************************/
163 static void init_dom_query_5(struct lsa_DomainInfo *r,
167 init_lsa_StringLarge(&r->name, name);
171 /***************************************************************************
172 lookup_lsa_rids. Must be called as root for lookup_name to work.
173 ***************************************************************************/
175 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
176 struct lsa_RefDomainList *ref,
177 struct lsa_TranslatedSid *prid,
178 uint32_t num_entries,
179 struct lsa_String *name,
181 uint32_t *pmapped_count)
183 uint32 mapped_count, i;
185 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
190 for (i = 0; i < num_entries; i++) {
194 const char *full_name;
196 enum lsa_SidType type;
198 /* Split name into domain and user component */
200 /* follow w2k8 behavior and return the builtin domain when no
201 * input has been passed in */
203 if (name[i].string) {
204 full_name = name[i].string;
206 full_name = "BUILTIN";
209 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
211 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
213 type = SID_NAME_UNKNOWN;
218 case SID_NAME_DOM_GRP:
219 case SID_NAME_DOMAIN:
221 case SID_NAME_WKN_GRP:
222 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
223 /* Leave these unchanged */
226 /* Don't hand out anything but the list above */
227 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
228 type = SID_NAME_UNKNOWN;
235 if (type != SID_NAME_UNKNOWN) {
236 if (type == SID_NAME_DOMAIN) {
239 sid_split_rid(&sid, &rid);
241 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
245 prid[i].sid_type = type;
247 prid[i].sid_index = dom_idx;
250 *pmapped_count = mapped_count;
254 /***************************************************************************
255 lookup_lsa_sids. Must be called as root for lookup_name to work.
256 ***************************************************************************/
258 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
259 struct lsa_RefDomainList *ref,
260 struct lsa_TranslatedSid3 *trans_sids,
261 uint32_t num_entries,
262 struct lsa_String *name,
264 uint32 *pmapped_count)
266 uint32 mapped_count, i;
268 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
273 for (i = 0; i < num_entries; i++) {
277 const char *full_name;
279 enum lsa_SidType type;
283 /* Split name into domain and user component */
285 full_name = name[i].string;
286 if (full_name == NULL) {
287 return NT_STATUS_NO_MEMORY;
290 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
292 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
294 type = SID_NAME_UNKNOWN;
299 case SID_NAME_DOM_GRP:
300 case SID_NAME_DOMAIN:
302 case SID_NAME_WKN_GRP:
303 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
304 /* Leave these unchanged */
307 /* Don't hand out anything but the list above */
308 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
309 type = SID_NAME_UNKNOWN;
316 if (type != SID_NAME_UNKNOWN) {
317 struct dom_sid domain_sid;
318 sid_copy(&domain_sid, &sid);
319 sid_split_rid(&domain_sid, &rid);
320 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
324 /* Initialize the lsa_TranslatedSid3 return. */
325 trans_sids[i].sid_type = type;
326 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
327 trans_sids[i].sid_index = dom_idx;
330 *pmapped_count = mapped_count;
334 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
335 const struct generic_mapping *map,
336 struct dom_sid *sid, uint32_t sid_access)
338 struct dom_sid adm_sid;
339 struct security_ace ace[5];
342 struct security_acl *psa = NULL;
344 /* READ|EXECUTE access for Everyone */
346 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
347 map->generic_execute | map->generic_read, 0);
349 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
351 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
352 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
353 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
354 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
356 /* Add Full Access for Domain Admins */
357 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
358 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
359 map->generic_all, 0);
361 /* If we have a sid, give it some special access */
364 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
368 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
369 return NT_STATUS_NO_MEMORY;
371 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
372 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
373 psa, sd_size)) == NULL)
374 return NT_STATUS_NO_MEMORY;
379 /***************************************************************************
380 ***************************************************************************/
382 static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
383 struct pipes_struct *p,
384 enum lsa_handle_type type,
385 uint32_t acc_granted,
388 const struct security_descriptor *sd,
389 struct policy_handle *handle)
391 struct lsa_info *info;
393 ZERO_STRUCTP(handle);
395 info = talloc_zero(mem_ctx, struct lsa_info);
397 return NT_STATUS_NO_MEMORY;
401 info->access = acc_granted;
404 sid_copy(&info->sid, sid);
407 info->name = talloc_strdup(info, name);
410 info->sd = dup_sec_desc(info, sd);
413 return NT_STATUS_NO_MEMORY;
417 if (!create_policy_hnd(p, handle, info)) {
419 ZERO_STRUCTP(handle);
420 return NT_STATUS_NO_MEMORY;
426 /***************************************************************************
428 ***************************************************************************/
430 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
431 struct lsa_OpenPolicy2 *r)
433 struct security_descriptor *psd = NULL;
435 uint32 des_access = r->in.access_mask;
439 /* Work out max allowed. */
440 map_max_allowed_access(p->session_info->security_token,
441 p->session_info->unix_token,
444 /* map the generic bits to the lsa policy ones */
445 se_map_generic(&des_access, &lsa_policy_mapping);
447 /* get the generic lsa policy SD until we store it */
448 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
450 if (!NT_STATUS_IS_OK(status)) {
454 status = access_check_object(psd, p->session_info->security_token,
455 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
456 &acc_granted, "_lsa_OpenPolicy2" );
457 if (!NT_STATUS_IS_OK(status)) {
461 status = create_lsa_policy_handle(p->mem_ctx, p,
462 LSA_HANDLE_POLICY_TYPE,
464 get_global_sam_sid(),
468 if (!NT_STATUS_IS_OK(status)) {
469 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
475 /***************************************************************************
477 ***************************************************************************/
479 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
480 struct lsa_OpenPolicy *r)
482 struct lsa_OpenPolicy2 o;
484 o.in.system_name = NULL; /* should be ignored */
485 o.in.attr = r->in.attr;
486 o.in.access_mask = r->in.access_mask;
488 o.out.handle = r->out.handle;
490 return _lsa_OpenPolicy2(p, &o);
493 /***************************************************************************
494 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
496 ***************************************************************************/
498 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
499 struct lsa_EnumTrustDom *r)
501 struct lsa_info *info;
503 struct trustdom_info **domains;
504 struct lsa_DomainInfo *entries;
508 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
509 return NT_STATUS_INVALID_HANDLE;
511 if (info->type != LSA_HANDLE_POLICY_TYPE) {
512 return NT_STATUS_INVALID_HANDLE;
515 /* check if the user has enough rights */
516 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
517 return NT_STATUS_ACCESS_DENIED;
520 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
523 if (!NT_STATUS_IS_OK(nt_status)) {
527 entries = talloc_zero_array(p->mem_ctx, struct lsa_DomainInfo, count);
529 return NT_STATUS_NO_MEMORY;
532 for (i=0; i<count; i++) {
533 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
534 entries[i].sid = &domains[i]->sid;
537 if (*r->in.resume_handle >= count) {
538 *r->out.resume_handle = -1;
539 TALLOC_FREE(entries);
540 return NT_STATUS_NO_MORE_ENTRIES;
543 /* return the rest, limit by max_size. Note that we
544 use the w2k3 element size value of 60 */
545 r->out.domains->count = count - *r->in.resume_handle;
546 r->out.domains->count = MIN(r->out.domains->count,
547 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
549 r->out.domains->domains = entries + *r->in.resume_handle;
551 if (r->out.domains->count < count - *r->in.resume_handle) {
552 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
553 return STATUS_MORE_ENTRIES;
556 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
557 * always be larger than the previous input resume handle, in
558 * particular when hitting the last query it is vital to set the
559 * resume handle correctly to avoid infinite client loops, as
560 * seen e.g. with Windows XP SP3 when resume handle is 0 and
561 * status is NT_STATUS_OK - gd */
563 *r->out.resume_handle = (uint32_t)-1;
568 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
569 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
570 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
572 /***************************************************************************
574 ***************************************************************************/
576 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
577 struct lsa_QueryInfoPolicy *r)
579 NTSTATUS status = NT_STATUS_OK;
580 struct lsa_info *handle;
581 struct dom_sid domain_sid;
583 struct dom_sid *sid = NULL;
584 union lsa_PolicyInformation *info = NULL;
585 uint32_t acc_required = 0;
587 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
588 return NT_STATUS_INVALID_HANDLE;
590 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
591 return NT_STATUS_INVALID_HANDLE;
594 switch (r->in.level) {
595 case LSA_POLICY_INFO_AUDIT_LOG:
596 case LSA_POLICY_INFO_AUDIT_EVENTS:
597 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
599 case LSA_POLICY_INFO_DOMAIN:
600 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
602 case LSA_POLICY_INFO_PD:
603 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
605 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
606 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
608 case LSA_POLICY_INFO_ROLE:
609 case LSA_POLICY_INFO_REPLICA:
610 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
612 case LSA_POLICY_INFO_QUOTA:
613 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
615 case LSA_POLICY_INFO_MOD:
616 case LSA_POLICY_INFO_AUDIT_FULL_SET:
617 /* according to MS-LSAD 3.1.4.4.3 */
618 return NT_STATUS_INVALID_PARAMETER;
619 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
620 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
622 case LSA_POLICY_INFO_DNS:
623 case LSA_POLICY_INFO_DNS_INT:
624 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
625 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
631 if (!(handle->access & acc_required)) {
632 /* return NT_STATUS_ACCESS_DENIED; */
635 info = talloc_zero(p->mem_ctx, union lsa_PolicyInformation);
637 return NT_STATUS_NO_MEMORY;
640 switch (r->in.level) {
641 /* according to MS-LSAD 3.1.4.4.3 */
642 case LSA_POLICY_INFO_MOD:
643 case LSA_POLICY_INFO_AUDIT_FULL_SET:
644 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
645 return NT_STATUS_INVALID_PARAMETER;
646 case LSA_POLICY_INFO_AUDIT_LOG:
647 info->audit_log.percent_full = 0;
648 info->audit_log.maximum_log_size = 0;
649 info->audit_log.retention_time = 0;
650 info->audit_log.shutdown_in_progress = 0;
651 info->audit_log.time_to_shutdown = 0;
652 info->audit_log.next_audit_record = 0;
653 status = NT_STATUS_OK;
655 case LSA_POLICY_INFO_PD:
656 info->pd.name.string = NULL;
657 status = NT_STATUS_OK;
659 case LSA_POLICY_INFO_REPLICA:
660 info->replica.source.string = NULL;
661 info->replica.account.string = NULL;
662 status = NT_STATUS_OK;
664 case LSA_POLICY_INFO_QUOTA:
665 info->quota.paged_pool = 0;
666 info->quota.non_paged_pool = 0;
667 info->quota.min_wss = 0;
668 info->quota.max_wss = 0;
669 info->quota.pagefile = 0;
670 info->quota.unknown = 0;
671 status = NT_STATUS_OK;
673 case LSA_POLICY_INFO_AUDIT_EVENTS:
676 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
678 /* check if the user has enough rights */
679 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
680 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
681 return NT_STATUS_ACCESS_DENIED;
684 /* fake info: We audit everything. ;) */
686 info->audit_events.auditing_mode = true;
687 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
688 info->audit_events.settings = talloc_zero_array(p->mem_ctx,
689 enum lsa_PolicyAuditPolicy,
690 info->audit_events.count);
691 if (!info->audit_events.settings) {
692 return NT_STATUS_NO_MEMORY;
695 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
696 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
697 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
698 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
699 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
700 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
701 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
705 case LSA_POLICY_INFO_DOMAIN:
706 /* check if the user has enough rights */
707 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
708 return NT_STATUS_ACCESS_DENIED;
710 /* Request PolicyPrimaryDomainInformation. */
711 switch (lp_server_role()) {
712 case ROLE_DOMAIN_PDC:
713 case ROLE_DOMAIN_BDC:
714 name = get_global_sam_name();
715 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
717 return NT_STATUS_NO_MEMORY;
720 case ROLE_DOMAIN_MEMBER:
721 name = lp_workgroup();
722 /* We need to return the Domain SID here. */
723 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
724 sid = dom_sid_dup(p->mem_ctx, &domain_sid);
726 return NT_STATUS_NO_MEMORY;
729 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
732 case ROLE_STANDALONE:
733 name = lp_workgroup();
737 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
739 init_dom_query_3(&info->domain, name, sid);
741 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
742 /* check if the user has enough rights */
743 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
744 return NT_STATUS_ACCESS_DENIED;
746 /* Request PolicyAccountDomainInformation. */
747 name = get_global_sam_name();
748 sid = get_global_sam_sid();
750 init_dom_query_5(&info->account_domain, name, sid);
752 case LSA_POLICY_INFO_ROLE:
753 /* check if the user has enough rights */
754 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
755 return NT_STATUS_ACCESS_DENIED;
757 switch (lp_server_role()) {
758 case ROLE_DOMAIN_BDC:
760 * only a BDC is a backup controller
761 * of the domain, it controls.
763 info->role.role = LSA_ROLE_BACKUP;
767 * any other role is a primary
768 * of the domain, it controls.
770 info->role.role = LSA_ROLE_PRIMARY;
774 case LSA_POLICY_INFO_DNS:
775 case LSA_POLICY_INFO_DNS_INT: {
776 struct pdb_domain_info *dominfo;
778 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
779 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
780 "without ADS passdb backend\n"));
781 status = NT_STATUS_INVALID_INFO_CLASS;
785 dominfo = pdb_get_domain_info(info);
786 if (dominfo == NULL) {
787 status = NT_STATUS_NO_MEMORY;
791 init_lsa_StringLarge(&info->dns.name,
793 init_lsa_StringLarge(&info->dns.dns_domain,
794 dominfo->dns_domain);
795 init_lsa_StringLarge(&info->dns.dns_forest,
796 dominfo->dns_forest);
797 info->dns.domain_guid = dominfo->guid;
798 info->dns.sid = &dominfo->sid;
802 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
804 status = NT_STATUS_INVALID_INFO_CLASS;
813 /***************************************************************************
814 _lsa_QueryInfoPolicy2
815 ***************************************************************************/
817 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
818 struct lsa_QueryInfoPolicy2 *r2)
820 struct lsa_QueryInfoPolicy r;
822 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
823 p->rng_fault_state = True;
824 return NT_STATUS_NOT_IMPLEMENTED;
828 r.in.handle = r2->in.handle;
829 r.in.level = r2->in.level;
830 r.out.info = r2->out.info;
832 return _lsa_QueryInfoPolicy(p, &r);
835 /***************************************************************************
836 _lsa_lookup_sids_internal
837 ***************************************************************************/
839 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
841 uint16_t level, /* input */
842 int num_sids, /* input */
843 struct lsa_SidPtr *sid, /* input */
844 struct lsa_RefDomainList **pp_ref, /* input/output */
845 struct lsa_TranslatedName2 **pp_names,/* input/output */
846 uint32_t *pp_mapped_count) /* input/output */
850 const struct dom_sid **sids = NULL;
851 struct lsa_RefDomainList *ref = NULL;
852 uint32 mapped_count = 0;
853 struct lsa_dom_info *dom_infos = NULL;
854 struct lsa_name_info *name_infos = NULL;
855 struct lsa_TranslatedName2 *names = NULL;
857 *pp_mapped_count = 0;
865 sids = talloc_array(p->mem_ctx, const struct dom_sid *, num_sids);
866 ref = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
868 if (sids == NULL || ref == NULL) {
869 return NT_STATUS_NO_MEMORY;
872 for (i=0; i<num_sids; i++) {
873 sids[i] = sid[i].sid;
876 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
877 &dom_infos, &name_infos);
879 if (!NT_STATUS_IS_OK(status)) {
883 names = talloc_array(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
885 return NT_STATUS_NO_MEMORY;
888 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
890 if (!dom_infos[i].valid) {
894 if (init_lsa_ref_domain_list(mem_ctx, ref,
896 &dom_infos[i].sid) != i) {
897 DEBUG(0, ("Domain %s mentioned twice??\n",
899 return NT_STATUS_INTERNAL_ERROR;
903 for (i=0; i<num_sids; i++) {
904 struct lsa_name_info *name = &name_infos[i];
906 if (name->type == SID_NAME_UNKNOWN) {
908 /* Unknown sids should return the string
909 * representation of the SID. Windows 2003 behaves
910 * rather erratic here, in many cases it returns the
911 * RID as 8 bytes hex, in others it returns the full
912 * SID. We (Jerry/VL) could not figure out which the
913 * hard cases are, so leave it with the SID. */
914 name->name = dom_sid_string(p->mem_ctx, sids[i]);
915 if (name->name == NULL) {
916 return NT_STATUS_NO_MEMORY;
922 names[i].sid_type = name->type;
923 names[i].name.string = name->name;
924 names[i].sid_index = name->dom_idx;
925 names[i].unknown = 0;
928 status = NT_STATUS_NONE_MAPPED;
929 if (mapped_count > 0) {
930 status = (mapped_count < num_sids) ?
931 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
934 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
935 num_sids, mapped_count, nt_errstr(status)));
937 *pp_mapped_count = mapped_count;
944 /***************************************************************************
946 ***************************************************************************/
948 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
949 struct lsa_LookupSids *r)
952 struct lsa_info *handle;
953 int num_sids = r->in.sids->num_sids;
954 uint32 mapped_count = 0;
955 struct lsa_RefDomainList *domains = NULL;
956 struct lsa_TranslatedName *names_out = NULL;
957 struct lsa_TranslatedName2 *names = NULL;
960 if ((r->in.level < 1) || (r->in.level > 6)) {
961 return NT_STATUS_INVALID_PARAMETER;
964 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
965 return NT_STATUS_INVALID_HANDLE;
968 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
969 return NT_STATUS_INVALID_HANDLE;
972 /* check if the user has enough rights */
973 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
974 return NT_STATUS_ACCESS_DENIED;
977 if (num_sids > MAX_LOOKUP_SIDS) {
978 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
979 MAX_LOOKUP_SIDS, num_sids));
980 return NT_STATUS_NONE_MAPPED;
983 status = _lsa_lookup_sids_internal(p,
992 /* Only return here when there is a real error.
993 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
994 the requested sids could be resolved. Older versions of XP (pre SP3)
995 rely that we return with the string representations of those SIDs in
996 that case. If we don't, XP crashes - Guenther
999 if (NT_STATUS_IS_ERR(status) &&
1000 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1004 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
1005 names_out = talloc_array(p->mem_ctx, struct lsa_TranslatedName,
1008 return NT_STATUS_NO_MEMORY;
1011 for (i=0; i<num_sids; i++) {
1012 names_out[i].sid_type = names[i].sid_type;
1013 names_out[i].name = names[i].name;
1014 names_out[i].sid_index = names[i].sid_index;
1017 *r->out.domains = domains;
1018 r->out.names->count = num_sids;
1019 r->out.names->names = names_out;
1020 *r->out.count = mapped_count;
1025 /***************************************************************************
1027 ***************************************************************************/
1029 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1030 struct lsa_LookupSids2 *r)
1033 struct lsa_info *handle;
1034 int num_sids = r->in.sids->num_sids;
1035 uint32 mapped_count = 0;
1036 struct lsa_RefDomainList *domains = NULL;
1037 struct lsa_TranslatedName2 *names = NULL;
1038 bool check_policy = true;
1041 case NDR_LSA_LOOKUPSIDS3:
1042 check_policy = false;
1044 case NDR_LSA_LOOKUPSIDS2:
1046 check_policy = true;
1049 if ((r->in.level < 1) || (r->in.level > 6)) {
1050 return NT_STATUS_INVALID_PARAMETER;
1054 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1055 return NT_STATUS_INVALID_HANDLE;
1058 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1059 return NT_STATUS_INVALID_HANDLE;
1062 /* check if the user has enough rights */
1063 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1064 return NT_STATUS_ACCESS_DENIED;
1068 if (num_sids > MAX_LOOKUP_SIDS) {
1069 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1070 MAX_LOOKUP_SIDS, num_sids));
1071 return NT_STATUS_NONE_MAPPED;
1074 status = _lsa_lookup_sids_internal(p,
1083 *r->out.domains = domains;
1084 r->out.names->count = num_sids;
1085 r->out.names->names = names;
1086 *r->out.count = mapped_count;
1091 /***************************************************************************
1093 ***************************************************************************/
1095 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1096 struct lsa_LookupSids3 *r)
1098 struct lsa_LookupSids2 q;
1100 /* No policy handle on this call. Restrict to crypto connections. */
1101 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1102 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1103 get_remote_machine_name() ));
1104 return NT_STATUS_INVALID_PARAMETER;
1108 q.in.sids = r->in.sids;
1109 q.in.level = r->in.level;
1110 q.in.lookup_options = r->in.lookup_options;
1111 q.in.client_revision = r->in.client_revision;
1112 q.in.names = r->in.names;
1113 q.in.count = r->in.count;
1115 q.out.domains = r->out.domains;
1116 q.out.names = r->out.names;
1117 q.out.count = r->out.count;
1119 return _lsa_LookupSids2(p, &q);
1122 /***************************************************************************
1123 ***************************************************************************/
1125 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1130 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1131 flags = LOOKUP_NAME_ALL;
1133 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1134 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1136 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1137 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1139 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1140 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1141 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1142 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1144 flags = LOOKUP_NAME_NONE;
1151 /***************************************************************************
1153 ***************************************************************************/
1155 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1156 struct lsa_LookupNames *r)
1158 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1159 struct lsa_info *handle;
1160 struct lsa_String *names = r->in.names;
1161 uint32 num_entries = r->in.num_names;
1162 struct lsa_RefDomainList *domains = NULL;
1163 struct lsa_TranslatedSid *rids = NULL;
1164 uint32 mapped_count = 0;
1167 if (num_entries > MAX_LOOKUP_SIDS) {
1168 num_entries = MAX_LOOKUP_SIDS;
1169 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1173 flags = lsa_lookup_level_to_flags(r->in.level);
1175 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1177 return NT_STATUS_NO_MEMORY;
1181 rids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid,
1184 return NT_STATUS_NO_MEMORY;
1190 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1191 status = NT_STATUS_INVALID_HANDLE;
1195 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1196 return NT_STATUS_INVALID_HANDLE;
1199 /* check if the user has enough rights */
1200 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1201 status = NT_STATUS_ACCESS_DENIED;
1205 /* set up the LSA Lookup RIDs response */
1206 become_root(); /* lookup_name can require root privs */
1207 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1208 names, flags, &mapped_count);
1213 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1214 if (mapped_count == 0) {
1215 status = NT_STATUS_NONE_MAPPED;
1216 } else if (mapped_count != num_entries) {
1217 status = STATUS_SOME_UNMAPPED;
1221 *r->out.count = mapped_count;
1222 *r->out.domains = domains;
1223 r->out.sids->sids = rids;
1224 r->out.sids->count = num_entries;
1229 /***************************************************************************
1231 ***************************************************************************/
1233 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1234 struct lsa_LookupNames2 *r)
1237 struct lsa_LookupNames q;
1238 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1239 struct lsa_TransSidArray *sid_array = NULL;
1242 sid_array = talloc_zero(p->mem_ctx, struct lsa_TransSidArray);
1244 return NT_STATUS_NO_MEMORY;
1247 q.in.handle = r->in.handle;
1248 q.in.num_names = r->in.num_names;
1249 q.in.names = r->in.names;
1250 q.in.level = r->in.level;
1251 q.in.sids = sid_array;
1252 q.in.count = r->in.count;
1253 /* we do not know what this is for */
1254 /* = r->in.unknown1; */
1255 /* = r->in.unknown2; */
1257 q.out.domains = r->out.domains;
1258 q.out.sids = sid_array;
1259 q.out.count = r->out.count;
1261 status = _lsa_LookupNames(p, &q);
1263 sid_array2->count = sid_array->count;
1264 sid_array2->sids = talloc_array(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1265 if (!sid_array2->sids) {
1266 return NT_STATUS_NO_MEMORY;
1269 for (i=0; i<sid_array->count; i++) {
1270 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1271 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1272 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1273 sid_array2->sids[i].unknown = 0;
1276 r->out.sids = sid_array2;
1281 /***************************************************************************
1283 ***************************************************************************/
1285 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1286 struct lsa_LookupNames3 *r)
1289 struct lsa_info *handle;
1290 struct lsa_String *names = r->in.names;
1291 uint32 num_entries = r->in.num_names;
1292 struct lsa_RefDomainList *domains = NULL;
1293 struct lsa_TranslatedSid3 *trans_sids = NULL;
1294 uint32 mapped_count = 0;
1296 bool check_policy = true;
1299 case NDR_LSA_LOOKUPNAMES4:
1300 check_policy = false;
1302 case NDR_LSA_LOOKUPNAMES3:
1304 check_policy = true;
1307 if (num_entries > MAX_LOOKUP_SIDS) {
1308 num_entries = MAX_LOOKUP_SIDS;
1309 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1312 /* Probably the lookup_level is some sort of bitmask. */
1313 if (r->in.level == 1) {
1314 flags = LOOKUP_NAME_ALL;
1317 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1319 return NT_STATUS_NO_MEMORY;
1323 trans_sids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid3,
1326 return NT_STATUS_NO_MEMORY;
1334 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1335 status = NT_STATUS_INVALID_HANDLE;
1339 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1340 return NT_STATUS_INVALID_HANDLE;
1343 /* check if the user has enough rights */
1344 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1345 status = NT_STATUS_ACCESS_DENIED;
1350 /* set up the LSA Lookup SIDs response */
1351 become_root(); /* lookup_name can require root privs */
1352 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1353 names, flags, &mapped_count);
1358 if (NT_STATUS_IS_OK(status)) {
1359 if (mapped_count == 0) {
1360 status = NT_STATUS_NONE_MAPPED;
1361 } else if (mapped_count != num_entries) {
1362 status = STATUS_SOME_UNMAPPED;
1366 *r->out.count = mapped_count;
1367 *r->out.domains = domains;
1368 r->out.sids->sids = trans_sids;
1369 r->out.sids->count = num_entries;
1374 /***************************************************************************
1376 ***************************************************************************/
1378 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1379 struct lsa_LookupNames4 *r)
1381 struct lsa_LookupNames3 q;
1383 /* No policy handle on this call. Restrict to crypto connections. */
1384 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1385 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1386 get_remote_machine_name() ));
1387 return NT_STATUS_INVALID_PARAMETER;
1391 q.in.num_names = r->in.num_names;
1392 q.in.names = r->in.names;
1393 q.in.level = r->in.level;
1394 q.in.lookup_options = r->in.lookup_options;
1395 q.in.client_revision = r->in.client_revision;
1396 q.in.sids = r->in.sids;
1397 q.in.count = r->in.count;
1399 q.out.domains = r->out.domains;
1400 q.out.sids = r->out.sids;
1401 q.out.count = r->out.count;
1403 return _lsa_LookupNames3(p, &q);
1406 /***************************************************************************
1407 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1408 ***************************************************************************/
1410 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1412 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1413 return NT_STATUS_INVALID_HANDLE;
1416 close_policy_hnd(p, r->in.handle);
1417 ZERO_STRUCTP(r->out.handle);
1418 return NT_STATUS_OK;
1421 /***************************************************************************
1422 ***************************************************************************/
1424 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1425 const struct dom_sid *sid,
1426 struct trustdom_info **info)
1429 uint32_t num_domains = 0;
1430 struct trustdom_info **domains = NULL;
1433 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1434 if (!NT_STATUS_IS_OK(status)) {
1438 for (i=0; i < num_domains; i++) {
1439 if (dom_sid_equal(&domains[i]->sid, sid)) {
1444 if (i == num_domains) {
1445 return NT_STATUS_INVALID_PARAMETER;
1450 return NT_STATUS_OK;
1453 /***************************************************************************
1454 ***************************************************************************/
1456 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1457 const char *netbios_domain_name,
1458 struct trustdom_info **info_p)
1461 struct trustdom_info *info;
1462 struct pdb_trusted_domain *td;
1464 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1465 if (!NT_STATUS_IS_OK(status)) {
1469 info = talloc(mem_ctx, struct trustdom_info);
1471 return NT_STATUS_NO_MEMORY;
1474 info->name = talloc_strdup(info, netbios_domain_name);
1475 NT_STATUS_HAVE_NO_MEMORY(info->name);
1477 sid_copy(&info->sid, &td->security_identifier);
1481 return NT_STATUS_OK;
1484 /***************************************************************************
1486 ***************************************************************************/
1488 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p,
1489 struct lsa_OpenSecret *r)
1491 struct lsa_info *handle;
1492 struct security_descriptor *psd;
1494 uint32_t acc_granted;
1496 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1497 return NT_STATUS_INVALID_HANDLE;
1500 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1501 return NT_STATUS_INVALID_HANDLE;
1504 if (!r->in.name.string) {
1505 return NT_STATUS_INVALID_PARAMETER;
1508 /* Work out max allowed. */
1509 map_max_allowed_access(p->session_info->security_token,
1510 p->session_info->unix_token,
1511 &r->in.access_mask);
1513 /* map the generic bits to the lsa policy ones */
1514 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
1516 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
1522 if (!NT_STATUS_IS_OK(status)) {
1526 status = access_check_object(psd, p->session_info->security_token,
1527 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1529 &acc_granted, "_lsa_OpenSecret");
1530 if (!NT_STATUS_IS_OK(status)) {
1534 status = create_lsa_policy_handle(p->mem_ctx, p,
1535 LSA_HANDLE_SECRET_TYPE,
1541 if (!NT_STATUS_IS_OK(status)) {
1542 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1545 return NT_STATUS_OK;
1548 /***************************************************************************
1549 _lsa_OpenTrustedDomain_base
1550 ***************************************************************************/
1552 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1553 uint32_t access_mask,
1554 struct trustdom_info *info,
1555 struct policy_handle *handle)
1557 struct security_descriptor *psd = NULL;
1559 uint32_t acc_granted;
1562 /* des_access is for the account here, not the policy
1563 * handle - so don't check against policy handle. */
1565 /* Work out max allowed. */
1566 map_max_allowed_access(p->session_info->security_token,
1567 p->session_info->unix_token,
1570 /* map the generic bits to the lsa account ones */
1571 se_map_generic(&access_mask, &lsa_trusted_domain_mapping);
1573 /* get the generic lsa account SD until we store it */
1574 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1575 &lsa_trusted_domain_mapping,
1577 if (!NT_STATUS_IS_OK(status)) {
1581 status = access_check_object(psd, p->session_info->security_token,
1582 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1583 access_mask, &acc_granted,
1584 "_lsa_OpenTrustedDomain");
1585 if (!NT_STATUS_IS_OK(status)) {
1589 status = create_lsa_policy_handle(p->mem_ctx, p,
1590 LSA_HANDLE_TRUST_TYPE,
1596 if (!NT_STATUS_IS_OK(status)) {
1597 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1600 return NT_STATUS_OK;
1603 /***************************************************************************
1604 _lsa_OpenTrustedDomain
1605 ***************************************************************************/
1607 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1608 struct lsa_OpenTrustedDomain *r)
1610 struct lsa_info *handle = NULL;
1611 struct trustdom_info *info = NULL;
1614 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1615 return NT_STATUS_INVALID_HANDLE;
1618 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1619 return NT_STATUS_INVALID_HANDLE;
1622 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1625 if (!NT_STATUS_IS_OK(status)) {
1629 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1630 r->out.trustdom_handle);
1633 /***************************************************************************
1634 _lsa_OpenTrustedDomainByName
1635 ***************************************************************************/
1637 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1638 struct lsa_OpenTrustedDomainByName *r)
1640 struct lsa_info *handle = NULL;
1641 struct trustdom_info *info = NULL;
1644 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1645 return NT_STATUS_INVALID_HANDLE;
1648 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1649 return NT_STATUS_INVALID_HANDLE;
1652 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1655 if (!NT_STATUS_IS_OK(status)) {
1659 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1660 r->out.trustdom_handle);
1663 /***************************************************************************
1664 _lsa_CreateTrustedDomainEx2
1665 ***************************************************************************/
1667 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1668 struct lsa_CreateTrustedDomainEx2 *r)
1670 struct lsa_info *policy;
1672 uint32_t acc_granted;
1673 struct security_descriptor *psd;
1675 struct pdb_trusted_domain td;
1676 struct trustDomainPasswords auth_struct;
1677 enum ndr_err_code ndr_err;
1678 DATA_BLOB auth_blob;
1681 return NT_STATUS_NOT_SUPPORTED;
1684 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1685 return NT_STATUS_INVALID_HANDLE;
1688 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1689 return NT_STATUS_ACCESS_DENIED;
1692 if (p->session_info->unix_token->uid != sec_initial_uid() &&
1693 !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1694 return NT_STATUS_ACCESS_DENIED;
1697 /* Work out max allowed. */
1698 map_max_allowed_access(p->session_info->security_token,
1699 p->session_info->unix_token,
1700 &r->in.access_mask);
1702 /* map the generic bits to the lsa policy ones */
1703 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1705 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1706 &lsa_trusted_domain_mapping,
1708 if (!NT_STATUS_IS_OK(status)) {
1712 status = access_check_object(psd, p->session_info->security_token,
1713 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1714 r->in.access_mask, &acc_granted,
1715 "_lsa_CreateTrustedDomainEx2");
1716 if (!NT_STATUS_IS_OK(status)) {
1722 td.domain_name = talloc_strdup(p->mem_ctx,
1723 r->in.info->domain_name.string);
1724 if (td.domain_name == NULL) {
1725 return NT_STATUS_NO_MEMORY;
1727 td.netbios_name = talloc_strdup(p->mem_ctx,
1728 r->in.info->netbios_name.string);
1729 if (td.netbios_name == NULL) {
1730 return NT_STATUS_NO_MEMORY;
1732 sid_copy(&td.security_identifier, r->in.info->sid);
1733 td.trust_direction = r->in.info->trust_direction;
1734 td.trust_type = r->in.info->trust_type;
1735 td.trust_attributes = r->in.info->trust_attributes;
1737 if (r->in.auth_info_internal->auth_blob.size != 0) {
1738 auth_blob.length = r->in.auth_info_internal->auth_blob.size;
1739 auth_blob.data = r->in.auth_info_internal->auth_blob.data;
1741 arcfour_crypt_blob(auth_blob.data, auth_blob.length,
1742 &p->session_info->session_key);
1744 ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
1746 (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
1747 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1748 return NT_STATUS_UNSUCCESSFUL;
1751 ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
1752 &auth_struct.incoming,
1753 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1754 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1755 return NT_STATUS_UNSUCCESSFUL;
1758 ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
1759 &auth_struct.outgoing,
1760 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1761 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1762 return NT_STATUS_UNSUCCESSFUL;
1765 td.trust_auth_incoming.data = NULL;
1766 td.trust_auth_incoming.length = 0;
1767 td.trust_auth_outgoing.data = NULL;
1768 td.trust_auth_outgoing.length = 0;
1771 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1772 if (!NT_STATUS_IS_OK(status)) {
1776 status = create_lsa_policy_handle(p->mem_ctx, p,
1777 LSA_HANDLE_TRUST_TYPE,
1780 r->in.info->netbios_name.string,
1782 r->out.trustdom_handle);
1783 if (!NT_STATUS_IS_OK(status)) {
1784 pdb_del_trusted_domain(r->in.info->netbios_name.string);
1785 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1788 return NT_STATUS_OK;
1791 /***************************************************************************
1792 _lsa_CreateTrustedDomainEx
1793 ***************************************************************************/
1795 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1796 struct lsa_CreateTrustedDomainEx *r)
1798 struct lsa_CreateTrustedDomainEx2 q;
1799 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1801 ZERO_STRUCT(auth_info);
1803 q.in.policy_handle = r->in.policy_handle;
1804 q.in.info = r->in.info;
1805 q.in.auth_info_internal = &auth_info;
1806 q.in.access_mask = r->in.access_mask;
1807 q.out.trustdom_handle = r->out.trustdom_handle;
1809 return _lsa_CreateTrustedDomainEx2(p, &q);
1812 /***************************************************************************
1813 _lsa_CreateTrustedDomain
1814 ***************************************************************************/
1816 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1817 struct lsa_CreateTrustedDomain *r)
1819 struct lsa_CreateTrustedDomainEx2 c;
1820 struct lsa_TrustDomainInfoInfoEx info;
1821 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1823 ZERO_STRUCT(auth_info);
1825 info.domain_name = r->in.info->name;
1826 info.netbios_name = r->in.info->name;
1827 info.sid = r->in.info->sid;
1828 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1829 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1830 info.trust_attributes = 0;
1832 c.in.policy_handle = r->in.policy_handle;
1834 c.in.auth_info_internal = &auth_info;
1835 c.in.access_mask = r->in.access_mask;
1836 c.out.trustdom_handle = r->out.trustdom_handle;
1838 return _lsa_CreateTrustedDomainEx2(p, &c);
1841 /***************************************************************************
1842 _lsa_DeleteTrustedDomain
1843 ***************************************************************************/
1845 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1846 struct lsa_DeleteTrustedDomain *r)
1849 struct lsa_info *handle;
1850 struct pdb_trusted_domain *td;
1852 /* find the connection policy handle. */
1853 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1854 return NT_STATUS_INVALID_HANDLE;
1857 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1858 return NT_STATUS_INVALID_HANDLE;
1861 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1862 return NT_STATUS_ACCESS_DENIED;
1865 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1866 if (!NT_STATUS_IS_OK(status)) {
1870 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1871 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1872 sid_string_tos(r->in.dom_sid)));
1873 return NT_STATUS_UNSUCCESSFUL;
1876 status = pdb_del_trusted_domain(td->netbios_name);
1877 if (!NT_STATUS_IS_OK(status)) {
1881 return NT_STATUS_OK;
1884 /***************************************************************************
1885 _lsa_CloseTrustedDomainEx
1886 ***************************************************************************/
1888 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1889 struct lsa_CloseTrustedDomainEx *r)
1891 return NT_STATUS_NOT_IMPLEMENTED;
1894 /***************************************************************************
1895 _lsa_QueryTrustedDomainInfo
1896 ***************************************************************************/
1898 static NTSTATUS pdb_trusted_domain_2_info_ex(TALLOC_CTX *mem_ctx,
1899 struct pdb_trusted_domain *td,
1900 struct lsa_TrustDomainInfoInfoEx *info_ex)
1902 if (td->domain_name == NULL ||
1903 td->netbios_name == NULL ||
1904 is_null_sid(&td->security_identifier)) {
1905 return NT_STATUS_INVALID_PARAMETER;
1908 info_ex->domain_name.string = talloc_strdup(mem_ctx, td->domain_name);
1909 info_ex->netbios_name.string = talloc_strdup(mem_ctx, td->netbios_name);
1910 info_ex->sid = dom_sid_dup(mem_ctx, &td->security_identifier);
1911 if (info_ex->domain_name.string == NULL ||
1912 info_ex->netbios_name.string == NULL ||
1913 info_ex->sid == NULL) {
1914 return NT_STATUS_NO_MEMORY;
1917 info_ex->trust_direction = td->trust_direction;
1918 info_ex->trust_type = td->trust_type;
1919 info_ex->trust_attributes = td->trust_attributes;
1921 return NT_STATUS_OK;
1924 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
1925 struct lsa_QueryTrustedDomainInfo *r)
1928 struct lsa_info *handle;
1929 union lsa_TrustedDomainInfo *info;
1930 struct pdb_trusted_domain *td;
1931 uint32_t acc_required;
1933 /* find the connection policy handle. */
1934 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
1935 return NT_STATUS_INVALID_HANDLE;
1938 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
1939 return NT_STATUS_INVALID_HANDLE;
1942 switch (r->in.level) {
1943 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1944 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1946 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1947 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
1949 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1950 acc_required = LSA_TRUSTED_QUERY_POSIX;
1952 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
1953 acc_required = LSA_TRUSTED_QUERY_AUTH;
1955 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1956 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1958 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1959 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1961 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1962 acc_required = LSA_TRUSTED_QUERY_AUTH;
1964 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1965 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1966 LSA_TRUSTED_QUERY_POSIX |
1967 LSA_TRUSTED_QUERY_AUTH;
1969 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1970 acc_required = LSA_TRUSTED_QUERY_AUTH;
1972 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1973 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1974 LSA_TRUSTED_QUERY_POSIX |
1975 LSA_TRUSTED_QUERY_AUTH;
1977 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1978 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1980 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1981 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1982 LSA_TRUSTED_QUERY_POSIX |
1983 LSA_TRUSTED_QUERY_AUTH;
1985 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1986 acc_required = LSA_TRUSTED_QUERY_POSIX;
1989 return NT_STATUS_INVALID_PARAMETER;
1992 if (!(handle->access & acc_required)) {
1993 return NT_STATUS_ACCESS_DENIED;
1996 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
1997 if (!NT_STATUS_IS_OK(status)) {
2001 info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
2003 return NT_STATUS_NO_MEMORY;
2006 switch (r->in.level) {
2007 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2008 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2010 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2011 return NT_STATUS_INVALID_PARAMETER;
2012 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2013 info->posix_offset.posix_offset = *td->trust_posix_offset;
2015 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2016 return NT_STATUS_INVALID_INFO_CLASS;
2017 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2018 return NT_STATUS_INVALID_PARAMETER;
2019 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2020 status = pdb_trusted_domain_2_info_ex(info, td, &info->info_ex);
2021 if (!NT_STATUS_IS_OK(status)) {
2025 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2026 return NT_STATUS_INVALID_INFO_CLASS;
2027 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2028 status = pdb_trusted_domain_2_info_ex(info, td,
2029 &info->full_info.info_ex);
2030 if (!NT_STATUS_IS_OK(status)) {
2033 info->full_info.posix_offset.posix_offset = *td->trust_posix_offset;
2034 status = auth_blob_2_auth_info(p->mem_ctx,
2035 td->trust_auth_incoming,
2036 td->trust_auth_outgoing,
2037 &info->full_info.auth_info);
2038 if (!NT_STATUS_IS_OK(status)) {
2042 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2043 return NT_STATUS_INVALID_INFO_CLASS;
2044 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2045 return NT_STATUS_INVALID_INFO_CLASS;
2046 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2047 return NT_STATUS_INVALID_PARAMETER;
2048 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2049 info->full_info2_internal.posix_offset.posix_offset = *td->trust_posix_offset;
2050 status = auth_blob_2_auth_info(p->mem_ctx,
2051 td->trust_auth_incoming,
2052 td->trust_auth_outgoing,
2053 &info->full_info2_internal.auth_info);
2054 if (!NT_STATUS_IS_OK(status)) {
2058 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2059 info->enc_types.enc_types = *td->supported_enc_type;
2062 return NT_STATUS_INVALID_PARAMETER;
2065 *r->out.info = info;
2067 return NT_STATUS_OK;
2070 /***************************************************************************
2071 _lsa_QueryTrustedDomainInfoBySid
2072 ***************************************************************************/
2074 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2075 struct lsa_QueryTrustedDomainInfoBySid *r)
2078 struct policy_handle trustdom_handle;
2079 struct lsa_OpenTrustedDomain o;
2080 struct lsa_QueryTrustedDomainInfo q;
2083 o.in.handle = r->in.handle;
2084 o.in.sid = r->in.dom_sid;
2085 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2086 o.out.trustdom_handle = &trustdom_handle;
2088 status = _lsa_OpenTrustedDomain(p, &o);
2089 if (!NT_STATUS_IS_OK(status)) {
2093 q.in.trustdom_handle = &trustdom_handle;
2094 q.in.level = r->in.level;
2095 q.out.info = r->out.info;
2097 status = _lsa_QueryTrustedDomainInfo(p, &q);
2098 if (!NT_STATUS_IS_OK(status)) {
2102 c.in.handle = &trustdom_handle;
2103 c.out.handle = &trustdom_handle;
2105 return _lsa_Close(p, &c);
2108 /***************************************************************************
2109 _lsa_QueryTrustedDomainInfoByName
2110 ***************************************************************************/
2112 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2113 struct lsa_QueryTrustedDomainInfoByName *r)
2116 struct policy_handle trustdom_handle;
2117 struct lsa_OpenTrustedDomainByName o;
2118 struct lsa_QueryTrustedDomainInfo q;
2121 o.in.handle = r->in.handle;
2122 o.in.name.string = r->in.trusted_domain->string;
2123 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2124 o.out.trustdom_handle = &trustdom_handle;
2126 status = _lsa_OpenTrustedDomainByName(p, &o);
2127 if (!NT_STATUS_IS_OK(status)) {
2128 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2129 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2134 q.in.trustdom_handle = &trustdom_handle;
2135 q.in.level = r->in.level;
2136 q.out.info = r->out.info;
2138 status = _lsa_QueryTrustedDomainInfo(p, &q);
2139 if (!NT_STATUS_IS_OK(status)) {
2143 c.in.handle = &trustdom_handle;
2144 c.out.handle = &trustdom_handle;
2146 return _lsa_Close(p, &c);
2149 /***************************************************************************
2151 ***************************************************************************/
2153 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p,
2154 struct lsa_CreateSecret *r)
2157 struct lsa_info *handle;
2158 uint32_t acc_granted;
2159 struct security_descriptor *psd;
2162 /* find the connection policy handle. */
2163 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
2164 return NT_STATUS_INVALID_HANDLE;
2167 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2168 return NT_STATUS_INVALID_HANDLE;
2171 /* check if the user has enough rights */
2173 if (!(handle->access & LSA_POLICY_CREATE_SECRET)) {
2174 return NT_STATUS_ACCESS_DENIED;
2177 /* Work out max allowed. */
2178 map_max_allowed_access(p->session_info->security_token,
2179 p->session_info->unix_token,
2180 &r->in.access_mask);
2182 /* map the generic bits to the lsa policy ones */
2183 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
2185 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2186 &lsa_secret_mapping,
2188 if (!NT_STATUS_IS_OK(status)) {
2192 status = access_check_object(psd, p->session_info->security_token,
2193 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2195 &acc_granted, "_lsa_CreateSecret");
2196 if (!NT_STATUS_IS_OK(status)) {
2200 if (!r->in.name.string) {
2201 return NT_STATUS_INVALID_PARAMETER;
2204 if (strlen(r->in.name.string) > 128) {
2205 return NT_STATUS_NAME_TOO_LONG;
2208 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
2209 NULL, NULL, NULL, NULL, NULL);
2210 if (NT_STATUS_IS_OK(status)) {
2211 return NT_STATUS_OBJECT_NAME_COLLISION;
2214 status = pdb_set_secret(r->in.name.string, NULL, NULL, psd);
2215 if (!NT_STATUS_IS_OK(status)) {
2219 status = create_lsa_policy_handle(p->mem_ctx, p,
2220 LSA_HANDLE_SECRET_TYPE,
2226 if (!NT_STATUS_IS_OK(status)) {
2227 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2230 return NT_STATUS_OK;
2233 /***************************************************************************
2235 ***************************************************************************/
2237 NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
2238 struct lsa_SetSecret *r)
2241 struct lsa_info *info = NULL;
2242 DATA_BLOB blob_new, blob_old;
2243 DATA_BLOB cleartext_blob_new = data_blob_null;
2244 DATA_BLOB cleartext_blob_old = data_blob_null;
2245 DATA_BLOB *cleartext_blob_new_p = NULL;
2246 DATA_BLOB *cleartext_blob_old_p = NULL;
2248 if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
2249 return NT_STATUS_INVALID_HANDLE;
2252 if (info->type != LSA_HANDLE_SECRET_TYPE) {
2253 return NT_STATUS_INVALID_HANDLE;
2256 if (!(info->access & LSA_SECRET_SET_VALUE)) {
2257 return NT_STATUS_ACCESS_DENIED;
2260 if (r->in.new_val) {
2261 blob_new = data_blob_const(r->in.new_val->data,
2262 r->in.new_val->length);
2264 status = sess_decrypt_blob(p->mem_ctx, &blob_new,
2265 &p->session_info->session_key,
2266 &cleartext_blob_new);
2267 if (!NT_STATUS_IS_OK(status)) {
2271 cleartext_blob_new_p = &cleartext_blob_new;
2274 if (r->in.old_val) {
2275 blob_old = data_blob_const(r->in.old_val->data,
2276 r->in.old_val->length);
2278 status = sess_decrypt_blob(p->mem_ctx, &blob_old,
2279 &p->session_info->session_key,
2280 &cleartext_blob_old);
2281 if (!NT_STATUS_IS_OK(status)) {
2285 cleartext_blob_old_p = &cleartext_blob_old;
2288 status = pdb_set_secret(info->name, cleartext_blob_new_p, cleartext_blob_old_p, NULL);
2289 if (!NT_STATUS_IS_OK(status)) {
2293 #ifdef DEBUG_PASSWORD
2294 DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
2295 dump_data(10, cleartext_blob_new.data, cleartext_blob_new.length);
2296 DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
2297 dump_data(10, cleartext_blob_old.data, cleartext_blob_old.length);
2300 return NT_STATUS_OK;
2303 /***************************************************************************
2305 ***************************************************************************/
2307 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
2308 struct lsa_QuerySecret *r)
2310 struct lsa_info *info = NULL;
2311 DATA_BLOB blob_new, blob_old;
2312 DATA_BLOB blob_new_crypt, blob_old_crypt;
2313 NTTIME nttime_new, nttime_old;
2316 if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
2317 return NT_STATUS_INVALID_HANDLE;
2320 if (info->type != LSA_HANDLE_SECRET_TYPE) {
2321 return NT_STATUS_INVALID_HANDLE;
2324 if (!(info->access & LSA_SECRET_QUERY_VALUE)) {
2325 return NT_STATUS_ACCESS_DENIED;
2328 status = pdb_get_secret(p->mem_ctx, info->name,
2329 &blob_new, &nttime_new,
2330 &blob_old, &nttime_old,
2332 if (!NT_STATUS_IS_OK(status)) {
2336 if (r->in.new_val) {
2337 if (blob_new.length) {
2338 if (!r->out.new_val->buf) {
2339 r->out.new_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2341 if (!r->out.new_val->buf) {
2342 return NT_STATUS_NO_MEMORY;
2345 blob_new_crypt = sess_encrypt_blob(p->mem_ctx, &blob_new,
2346 &p->session_info->session_key);
2347 if (!blob_new_crypt.length) {
2348 return NT_STATUS_NO_MEMORY;
2351 r->out.new_val->buf->data = blob_new_crypt.data;
2352 r->out.new_val->buf->length = blob_new_crypt.length;
2353 r->out.new_val->buf->size = blob_new_crypt.length;
2357 if (r->in.old_val) {
2358 if (blob_old.length) {
2359 if (!r->out.old_val->buf) {
2360 r->out.old_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2362 if (!r->out.old_val->buf) {
2363 return NT_STATUS_NO_MEMORY;
2366 blob_old_crypt = sess_encrypt_blob(p->mem_ctx, &blob_old,
2367 &p->session_info->session_key);
2368 if (!blob_old_crypt.length) {
2369 return NT_STATUS_NO_MEMORY;
2372 r->out.old_val->buf->data = blob_old_crypt.data;
2373 r->out.old_val->buf->length = blob_old_crypt.length;
2374 r->out.old_val->buf->size = blob_old_crypt.length;
2378 if (r->out.new_mtime) {
2379 *r->out.new_mtime = nttime_new;
2382 if (r->out.old_mtime) {
2383 *r->out.old_mtime = nttime_old;
2386 return NT_STATUS_OK;
2389 /***************************************************************************
2391 ***************************************************************************/
2393 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2394 struct lsa_DeleteObject *r)
2397 struct lsa_info *info = NULL;
2399 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2400 return NT_STATUS_INVALID_HANDLE;
2403 if (!(info->access & SEC_STD_DELETE)) {
2404 return NT_STATUS_ACCESS_DENIED;
2407 switch (info->type) {
2408 case LSA_HANDLE_ACCOUNT_TYPE:
2409 status = privilege_delete_account(&info->sid);
2410 if (!NT_STATUS_IS_OK(status)) {
2411 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2412 nt_errstr(status)));
2416 case LSA_HANDLE_TRUST_TYPE:
2417 if (!pdb_del_trusteddom_pw(info->name)) {
2418 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2420 status = NT_STATUS_OK;
2422 case LSA_HANDLE_SECRET_TYPE:
2423 status = pdb_delete_secret(info->name);
2424 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2425 return NT_STATUS_INVALID_HANDLE;
2429 return NT_STATUS_INVALID_HANDLE;
2432 close_policy_hnd(p, r->in.handle);
2433 ZERO_STRUCTP(r->out.handle);
2438 /***************************************************************************
2440 ***************************************************************************/
2442 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2443 struct lsa_EnumPrivs *r)
2445 struct lsa_info *handle;
2447 uint32 enum_context = *r->in.resume_handle;
2448 int num_privs = num_privileges_in_short_list();
2449 struct lsa_PrivEntry *entries = NULL;
2451 /* remember that the enum_context starts at 0 and not 1 */
2453 if ( enum_context >= num_privs )
2454 return NT_STATUS_NO_MORE_ENTRIES;
2456 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2457 enum_context, num_privs));
2459 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2460 return NT_STATUS_INVALID_HANDLE;
2462 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2463 return NT_STATUS_INVALID_HANDLE;
2466 /* check if the user has enough rights
2467 I don't know if it's the right one. not documented. */
2469 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2470 return NT_STATUS_ACCESS_DENIED;
2473 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2475 return NT_STATUS_NO_MEMORY;
2481 for (i = 0; i < num_privs; i++) {
2482 if( i < enum_context) {
2484 init_lsa_StringLarge(&entries[i].name, NULL);
2486 entries[i].luid.low = 0;
2487 entries[i].luid.high = 0;
2490 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2492 entries[i].luid.low = sec_privilege_from_index(i);
2493 entries[i].luid.high = 0;
2497 enum_context = num_privs;
2499 *r->out.resume_handle = enum_context;
2500 r->out.privs->count = num_privs;
2501 r->out.privs->privs = entries;
2503 return NT_STATUS_OK;
2506 /***************************************************************************
2507 _lsa_LookupPrivDisplayName
2508 ***************************************************************************/
2510 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2511 struct lsa_LookupPrivDisplayName *r)
2513 struct lsa_info *handle;
2514 const char *description;
2515 struct lsa_StringLarge *lsa_name;
2517 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2518 return NT_STATUS_INVALID_HANDLE;
2520 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2521 return NT_STATUS_INVALID_HANDLE;
2524 /* check if the user has enough rights */
2527 * I don't know if it's the right one. not documented.
2529 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2530 return NT_STATUS_ACCESS_DENIED;
2532 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2534 description = get_privilege_dispname(r->in.name->string);
2536 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2537 return NT_STATUS_NO_SUCH_PRIVILEGE;
2540 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2542 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2544 return NT_STATUS_NO_MEMORY;
2547 init_lsa_StringLarge(lsa_name, description);
2549 *r->out.returned_language_id = r->in.language_id;
2550 *r->out.disp_name = lsa_name;
2552 return NT_STATUS_OK;
2555 /***************************************************************************
2557 ***************************************************************************/
2559 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2560 struct lsa_EnumAccounts *r)
2562 struct lsa_info *handle;
2563 struct dom_sid *sid_list;
2564 int i, j, num_entries;
2566 struct lsa_SidPtr *sids = NULL;
2568 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2569 return NT_STATUS_INVALID_HANDLE;
2571 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2572 return NT_STATUS_INVALID_HANDLE;
2575 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2576 return NT_STATUS_ACCESS_DENIED;
2581 /* The only way we can currently find out all the SIDs that have been
2582 privileged is to scan all privileges */
2584 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2585 if (!NT_STATUS_IS_OK(status)) {
2589 if (*r->in.resume_handle >= num_entries) {
2590 return NT_STATUS_NO_MORE_ENTRIES;
2593 if (num_entries - *r->in.resume_handle) {
2594 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2595 num_entries - *r->in.resume_handle);
2597 talloc_free(sid_list);
2598 return NT_STATUS_NO_MEMORY;
2601 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2602 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2604 talloc_free(sid_list);
2605 return NT_STATUS_NO_MEMORY;
2610 talloc_free(sid_list);
2612 *r->out.resume_handle = num_entries;
2613 r->out.sids->num_sids = num_entries;
2614 r->out.sids->sids = sids;
2616 return NT_STATUS_OK;
2619 /***************************************************************************
2621 ***************************************************************************/
2623 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2624 struct lsa_GetUserName *r)
2626 const char *username, *domname;
2627 struct lsa_String *account_name = NULL;
2628 struct lsa_String *authority_name = NULL;
2630 if (r->in.account_name &&
2631 *r->in.account_name) {
2632 return NT_STATUS_INVALID_PARAMETER;
2635 if (r->in.authority_name &&
2636 *r->in.authority_name) {
2637 return NT_STATUS_INVALID_PARAMETER;
2640 if (security_session_user_level(p->session_info, NULL) < SECURITY_USER) {
2642 * I'm 99% sure this is not the right place to do this,
2643 * global_sid_Anonymous should probably be put into the token
2644 * instead of the guest id -- vl
2646 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2647 &domname, &username, NULL)) {
2648 return NT_STATUS_NO_MEMORY;
2651 username = p->session_info->unix_info->sanitized_username;
2652 domname = p->session_info->info->domain_name;
2655 account_name = talloc(p->mem_ctx, struct lsa_String);
2656 if (!account_name) {
2657 return NT_STATUS_NO_MEMORY;
2659 init_lsa_String(account_name, username);
2661 if (r->out.authority_name) {
2662 authority_name = talloc(p->mem_ctx, struct lsa_String);
2663 if (!authority_name) {
2664 return NT_STATUS_NO_MEMORY;
2666 init_lsa_String(authority_name, domname);
2669 *r->out.account_name = account_name;
2670 if (r->out.authority_name) {
2671 *r->out.authority_name = authority_name;
2674 return NT_STATUS_OK;
2677 /***************************************************************************
2679 ***************************************************************************/
2681 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2682 struct lsa_CreateAccount *r)
2685 struct lsa_info *handle;
2686 uint32_t acc_granted;
2687 struct security_descriptor *psd;
2690 /* find the connection policy handle. */
2691 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2692 return NT_STATUS_INVALID_HANDLE;
2694 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2695 return NT_STATUS_INVALID_HANDLE;
2698 /* check if the user has enough rights */
2700 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2701 return NT_STATUS_ACCESS_DENIED;
2704 /* Work out max allowed. */
2705 map_max_allowed_access(p->session_info->security_token,
2706 p->session_info->unix_token,
2707 &r->in.access_mask);
2709 /* map the generic bits to the lsa policy ones */
2710 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2712 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2713 &lsa_account_mapping,
2714 r->in.sid, LSA_POLICY_ALL_ACCESS);
2715 if (!NT_STATUS_IS_OK(status)) {
2719 status = access_check_object(psd, p->session_info->security_token,
2720 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2721 &acc_granted, "_lsa_CreateAccount");
2722 if (!NT_STATUS_IS_OK(status)) {
2726 if ( is_privileged_sid( r->in.sid ) )
2727 return NT_STATUS_OBJECT_NAME_COLLISION;
2729 status = create_lsa_policy_handle(p->mem_ctx, p,
2730 LSA_HANDLE_ACCOUNT_TYPE,
2735 r->out.acct_handle);
2736 if (!NT_STATUS_IS_OK(status)) {
2737 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2740 return privilege_create_account(r->in.sid);
2743 /***************************************************************************
2745 ***************************************************************************/
2747 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2748 struct lsa_OpenAccount *r)
2750 struct lsa_info *handle;
2751 struct security_descriptor *psd = NULL;
2753 uint32_t des_access = r->in.access_mask;
2754 uint32_t acc_granted;
2757 /* find the connection policy handle. */
2758 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2759 return NT_STATUS_INVALID_HANDLE;
2761 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2762 return NT_STATUS_INVALID_HANDLE;
2765 /* des_access is for the account here, not the policy
2766 * handle - so don't check against policy handle. */
2768 /* Work out max allowed. */
2769 map_max_allowed_access(p->session_info->security_token,
2770 p->session_info->unix_token,
2773 /* map the generic bits to the lsa account ones */
2774 se_map_generic(&des_access, &lsa_account_mapping);
2776 /* get the generic lsa account SD until we store it */
2777 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2778 &lsa_account_mapping,
2779 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2780 if (!NT_STATUS_IS_OK(status)) {
2784 status = access_check_object(psd, p->session_info->security_token,
2785 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2786 &acc_granted, "_lsa_OpenAccount" );
2787 if (!NT_STATUS_IS_OK(status)) {
2791 /* TODO: Fis the parsing routine before reenabling this check! */
2793 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2794 return NT_STATUS_ACCESS_DENIED;
2797 status = create_lsa_policy_handle(p->mem_ctx, p,
2798 LSA_HANDLE_ACCOUNT_TYPE,
2803 r->out.acct_handle);
2804 if (!NT_STATUS_IS_OK(status)) {
2805 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2808 return NT_STATUS_OK;
2811 /***************************************************************************
2812 _lsa_EnumPrivsAccount
2813 For a given SID, enumerate all the privilege this account has.
2814 ***************************************************************************/
2816 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2817 struct lsa_EnumPrivsAccount *r)
2819 NTSTATUS status = NT_STATUS_OK;
2820 struct lsa_info *info=NULL;
2821 PRIVILEGE_SET *privileges;
2822 struct lsa_PrivilegeSet *priv_set = NULL;
2824 /* find the connection policy handle. */
2825 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2826 return NT_STATUS_INVALID_HANDLE;
2828 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2829 return NT_STATUS_INVALID_HANDLE;
2832 if (!(info->access & LSA_ACCOUNT_VIEW))
2833 return NT_STATUS_ACCESS_DENIED;
2835 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2836 if (!NT_STATUS_IS_OK(status)) {
2840 *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2842 return NT_STATUS_NO_MEMORY;
2845 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2846 sid_string_dbg(&info->sid),
2847 privileges->count));
2849 priv_set->count = privileges->count;
2850 priv_set->unknown = 0;
2851 priv_set->set = talloc_move(priv_set, &privileges->set);
2856 /***************************************************************************
2857 _lsa_GetSystemAccessAccount
2858 ***************************************************************************/
2860 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2861 struct lsa_GetSystemAccessAccount *r)
2864 struct lsa_info *info = NULL;
2865 struct lsa_EnumPrivsAccount e;
2866 struct lsa_PrivilegeSet *privset;
2868 /* find the connection policy handle. */
2870 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2871 return NT_STATUS_INVALID_HANDLE;
2873 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2874 return NT_STATUS_INVALID_HANDLE;
2877 if (!(info->access & LSA_ACCOUNT_VIEW))
2878 return NT_STATUS_ACCESS_DENIED;
2880 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2882 return NT_STATUS_NO_MEMORY;
2885 e.in.handle = r->in.handle;
2886 e.out.privs = &privset;
2888 status = _lsa_EnumPrivsAccount(p, &e);
2889 if (!NT_STATUS_IS_OK(status)) {
2890 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2891 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2892 nt_errstr(status)));
2896 /* Samba4 would iterate over the privset to merge the policy mode bits,
2897 * not sure samba3 can do the same here, so just return what we did in
2901 0x01 -> Log on locally
2902 0x02 -> Access this computer from network
2903 0x04 -> Log on as a batch job
2904 0x10 -> Log on as a service
2906 they can be ORed together
2909 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2910 LSA_POLICY_MODE_NETWORK;
2912 return NT_STATUS_OK;
2915 /***************************************************************************
2916 update the systemaccount information
2917 ***************************************************************************/
2919 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2920 struct lsa_SetSystemAccessAccount *r)
2922 struct lsa_info *info=NULL;
2926 /* find the connection policy handle. */
2927 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2928 return NT_STATUS_INVALID_HANDLE;
2930 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2931 return NT_STATUS_INVALID_HANDLE;
2934 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2935 return NT_STATUS_ACCESS_DENIED;
2938 map = talloc_zero(p->mem_ctx, GROUP_MAP);
2940 return NT_STATUS_NO_MEMORY;
2943 if (!pdb_getgrsid(map, info->sid)) {
2945 return NT_STATUS_NO_SUCH_GROUP;
2948 status = pdb_update_group_mapping_entry(map);
2953 /***************************************************************************
2954 _lsa_AddPrivilegesToAccount
2955 For a given SID, add some privileges.
2956 ***************************************************************************/
2958 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
2959 struct lsa_AddPrivilegesToAccount *r)
2961 struct lsa_info *info = NULL;
2962 struct lsa_PrivilegeSet *set = NULL;
2964 /* find the connection policy handle. */
2965 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2966 return NT_STATUS_INVALID_HANDLE;
2968 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2969 return NT_STATUS_INVALID_HANDLE;
2972 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2973 return NT_STATUS_ACCESS_DENIED;
2978 if ( !grant_privilege_set( &info->sid, set ) ) {
2979 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2980 sid_string_dbg(&info->sid) ));
2981 return NT_STATUS_NO_SUCH_PRIVILEGE;
2984 return NT_STATUS_OK;
2987 /***************************************************************************
2988 _lsa_RemovePrivilegesFromAccount
2989 For a given SID, remove some privileges.
2990 ***************************************************************************/
2992 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2993 struct lsa_RemovePrivilegesFromAccount *r)
2995 struct lsa_info *info = NULL;
2996 struct lsa_PrivilegeSet *set = NULL;
2998 /* find the connection policy handle. */
2999 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3000 return NT_STATUS_INVALID_HANDLE;
3002 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3003 return NT_STATUS_INVALID_HANDLE;
3006 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3007 return NT_STATUS_ACCESS_DENIED;
3012 if ( !revoke_privilege_set( &info->sid, set) ) {
3013 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
3014 sid_string_dbg(&info->sid) ));
3015 return NT_STATUS_NO_SUCH_PRIVILEGE;
3018 return NT_STATUS_OK;
3021 /***************************************************************************
3023 ***************************************************************************/
3025 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
3026 struct lsa_LookupPrivName *r)
3028 struct lsa_info *info = NULL;
3030 struct lsa_StringLarge *lsa_name;
3032 /* find the connection policy handle. */
3033 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3034 return NT_STATUS_INVALID_HANDLE;
3037 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3038 return NT_STATUS_INVALID_HANDLE;
3041 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
3042 return NT_STATUS_ACCESS_DENIED;
3045 if (r->in.luid->high != 0) {
3046 return NT_STATUS_NO_SUCH_PRIVILEGE;
3049 name = sec_privilege_name(r->in.luid->low);
3051 return NT_STATUS_NO_SUCH_PRIVILEGE;
3054 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
3056 return NT_STATUS_NO_MEMORY;
3059 lsa_name->string = talloc_strdup(lsa_name, name);
3060 if (!lsa_name->string) {
3061 TALLOC_FREE(lsa_name);
3062 return NT_STATUS_NO_MEMORY;
3065 *r->out.name = lsa_name;
3067 return NT_STATUS_OK;
3070 /***************************************************************************
3072 ***************************************************************************/
3074 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
3075 struct lsa_QuerySecurity *r)
3077 struct lsa_info *handle=NULL;
3078 struct security_descriptor *psd = NULL;
3082 /* find the connection policy handle. */
3083 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
3084 return NT_STATUS_INVALID_HANDLE;
3086 switch (handle->type) {
3087 case LSA_HANDLE_POLICY_TYPE:
3088 case LSA_HANDLE_ACCOUNT_TYPE:
3089 case LSA_HANDLE_TRUST_TYPE:
3090 case LSA_HANDLE_SECRET_TYPE:
3092 sd_size = ndr_size_security_descriptor(psd, 0);
3093 status = NT_STATUS_OK;
3096 status = NT_STATUS_INVALID_HANDLE;
3100 if (!NT_STATUS_IS_OK(status)) {
3104 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
3105 if (!*r->out.sdbuf) {
3106 return NT_STATUS_NO_MEMORY;
3112 /***************************************************************************
3113 _lsa_AddAccountRights
3114 ***************************************************************************/
3116 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
3117 struct lsa_AddAccountRights *r)
3119 struct lsa_info *info = NULL;
3121 uint32_t acc_granted = 0;
3122 struct security_descriptor *psd = NULL;
3127 /* find the connection policy handle. */
3128 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3129 return NT_STATUS_INVALID_HANDLE;
3131 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3132 return NT_STATUS_INVALID_HANDLE;
3135 /* get the generic lsa account SD for this SID until we store it */
3136 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3137 &lsa_account_mapping,
3138 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
3139 if (!NT_STATUS_IS_OK(status)) {
3144 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3145 * on the policy handle. If it does, ask for
3146 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3147 * on the account sid. We don't check here so just use the latter. JRA.
3150 status = access_check_object(psd, p->session_info->security_token,
3151 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3152 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3153 &acc_granted, "_lsa_AddAccountRights" );
3154 if (!NT_STATUS_IS_OK(status)) {
3158 /* according to an NT4 PDC, you can add privileges to SIDs even without
3159 call_lsa_create_account() first. And you can use any arbitrary SID. */
3161 sid_copy( &sid, r->in.sid );
3163 for ( i=0; i < r->in.rights->count; i++ ) {
3165 const char *privname = r->in.rights->names[i].string;
3167 /* only try to add non-null strings */
3172 if ( !grant_privilege_by_name( &sid, privname ) ) {
3173 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3175 return NT_STATUS_NO_SUCH_PRIVILEGE;
3179 return NT_STATUS_OK;
3182 /***************************************************************************
3183 _lsa_RemoveAccountRights
3184 ***************************************************************************/
3186 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
3187 struct lsa_RemoveAccountRights *r)
3189 struct lsa_info *info = NULL;
3191 struct security_descriptor *psd = NULL;
3194 const char *privname = NULL;
3195 uint32_t acc_granted = 0;
3198 /* find the connection policy handle. */
3199 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3200 return NT_STATUS_INVALID_HANDLE;
3202 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3203 return NT_STATUS_INVALID_HANDLE;
3206 /* get the generic lsa account SD for this SID until we store it */
3207 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3208 &lsa_account_mapping,
3209 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
3210 if (!NT_STATUS_IS_OK(status)) {
3215 * From the MS DOCs. We need
3216 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3217 * and DELETE on the account sid.
3220 status = access_check_object(psd, p->session_info->security_token,
3221 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3222 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3223 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
3224 &acc_granted, "_lsa_RemoveAccountRights");
3225 if (!NT_STATUS_IS_OK(status)) {
3229 sid_copy( &sid, r->in.sid );
3231 if ( r->in.remove_all ) {
3232 if ( !revoke_all_privileges( &sid ) )
3233 return NT_STATUS_ACCESS_DENIED;
3235 return NT_STATUS_OK;
3238 for ( i=0; i < r->in.rights->count; i++ ) {
3240 privname = r->in.rights->names[i].string;
3242 /* only try to add non-null strings */
3247 if ( !revoke_privilege_by_name( &sid, privname ) ) {
3248 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3250 return NT_STATUS_NO_SUCH_PRIVILEGE;
3254 return NT_STATUS_OK;
3257 /*******************************************************************
3258 ********************************************************************/
3260 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3261 struct lsa_RightSet *r,
3262 PRIVILEGE_SET *privileges)
3265 const char *privname;
3266 const char **privname_array = NULL;
3269 for (i=0; i<privileges->count; i++) {
3270 if (privileges->set[i].luid.high) {
3273 privname = sec_privilege_name(privileges->set[i].luid.low);
3275 if (!add_string_to_array(mem_ctx, privname,
3276 &privname_array, &num_priv)) {
3277 return NT_STATUS_NO_MEMORY;
3284 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3287 return NT_STATUS_NO_MEMORY;
3290 for (i=0; i<num_priv; i++) {
3291 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3294 r->count = num_priv;
3297 return NT_STATUS_OK;
3300 /***************************************************************************
3301 _lsa_EnumAccountRights
3302 ***************************************************************************/
3304 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3305 struct lsa_EnumAccountRights *r)
3308 struct lsa_info *info = NULL;
3309 PRIVILEGE_SET *privileges;
3311 /* find the connection policy handle. */
3313 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3314 return NT_STATUS_INVALID_HANDLE;
3316 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3317 return NT_STATUS_INVALID_HANDLE;
3320 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3321 return NT_STATUS_ACCESS_DENIED;
3324 /* according to an NT4 PDC, you can add privileges to SIDs even without
3325 call_lsa_create_account() first. And you can use any arbitrary SID. */
3327 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3328 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3329 * the lsa database */
3331 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3332 if (!NT_STATUS_IS_OK(status)) {
3336 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3337 sid_string_dbg(r->in.sid), privileges->count));
3339 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3344 /***************************************************************************
3345 _lsa_LookupPrivValue
3346 ***************************************************************************/
3348 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3349 struct lsa_LookupPrivValue *r)
3351 struct lsa_info *info = NULL;
3352 const char *name = NULL;
3354 /* find the connection policy handle. */
3356 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3357 return NT_STATUS_INVALID_HANDLE;
3359 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3360 return NT_STATUS_INVALID_HANDLE;
3363 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3364 return NT_STATUS_ACCESS_DENIED;
3366 name = r->in.name->string;
3368 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3370 r->out.luid->low = sec_privilege_id(name);
3371 r->out.luid->high = 0;
3372 if (r->out.luid->low == SEC_PRIV_INVALID) {
3373 return NT_STATUS_NO_SUCH_PRIVILEGE;
3375 return NT_STATUS_OK;
3378 /***************************************************************************
3379 _lsa_EnumAccountsWithUserRight
3380 ***************************************************************************/
3382 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3383 struct lsa_EnumAccountsWithUserRight *r)
3386 struct lsa_info *info = NULL;
3387 struct dom_sid *sids = NULL;
3390 enum sec_privilege privilege;
3392 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3393 return NT_STATUS_INVALID_HANDLE;
3396 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3397 return NT_STATUS_INVALID_HANDLE;
3400 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3401 return NT_STATUS_ACCESS_DENIED;
3404 if (!r->in.name || !r->in.name->string) {
3405 return NT_STATUS_NO_SUCH_PRIVILEGE;
3408 privilege = sec_privilege_id(r->in.name->string);
3409 if (privilege == SEC_PRIV_INVALID) {
3410 return NT_STATUS_NO_SUCH_PRIVILEGE;
3413 status = privilege_enum_sids(privilege, p->mem_ctx,
3415 if (!NT_STATUS_IS_OK(status)) {
3419 r->out.sids->num_sids = num_sids;
3420 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3421 r->out.sids->num_sids);
3423 for (i=0; i < r->out.sids->num_sids; i++) {
3424 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3426 if (!r->out.sids->sids[i].sid) {
3427 TALLOC_FREE(r->out.sids->sids);
3428 r->out.sids->num_sids = 0;
3429 return NT_STATUS_NO_MEMORY;
3433 return NT_STATUS_OK;
3436 /***************************************************************************
3438 ***************************************************************************/
3440 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3441 struct lsa_Delete *r)
3443 return NT_STATUS_NOT_SUPPORTED;
3446 static NTSTATUS info_ex_2_pdb_trusted_domain(
3447 struct lsa_TrustDomainInfoInfoEx *info_ex,
3448 struct pdb_trusted_domain *td)
3450 if (info_ex->domain_name.string == NULL ||
3451 info_ex->netbios_name.string == NULL ||
3452 info_ex->sid == NULL) {
3453 return NT_STATUS_INVALID_PARAMETER;
3456 td->domain_name = talloc_strdup(td, info_ex->domain_name.string);
3457 td->netbios_name = talloc_strdup(td, info_ex->netbios_name.string);
3458 sid_copy(&td->security_identifier, info_ex->sid);
3459 if (td->domain_name == NULL ||
3460 td->netbios_name == NULL ||
3461 is_null_sid(&td->security_identifier)) {
3462 return NT_STATUS_NO_MEMORY;
3464 td->trust_direction = info_ex->trust_direction;
3465 td->trust_type = info_ex->trust_type;
3466 td->trust_attributes = info_ex->trust_attributes;
3468 return NT_STATUS_OK;
3471 static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
3472 TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
3473 struct trustDomainPasswords *auth_struct)
3475 enum ndr_err_code ndr_err;
3477 arcfour_crypt_blob(auth_blob->data, auth_blob->length,
3478 &p->session_info->session_key);
3479 ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
3481 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
3482 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3483 return NT_STATUS_INVALID_PARAMETER;
3486 return NT_STATUS_OK;
3489 static NTSTATUS get_trustauth_inout_blob(TALLOC_CTX *mem_ctx,
3490 struct trustAuthInOutBlob *iopw,
3491 DATA_BLOB *trustauth_blob)
3493 enum ndr_err_code ndr_err;
3495 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
3497 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
3498 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3499 return NT_STATUS_INVALID_PARAMETER;
3502 return NT_STATUS_OK;
3505 static NTSTATUS setInfoTrustedDomain_base(struct pipes_struct *p,
3506 TALLOC_CTX *mem_ctx,
3507 struct lsa_info *policy,
3508 enum lsa_TrustDomInfoEnum level,
3509 union lsa_TrustedDomainInfo *info)
3511 struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
3512 DATA_BLOB auth_blob;
3513 struct trustDomainPasswords auth_struct;
3516 struct pdb_trusted_domain *td;
3517 struct pdb_trusted_domain *orig_td;
3519 td = talloc_zero(mem_ctx, struct pdb_trusted_domain);
3521 return NT_STATUS_NO_MEMORY;
3525 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
3526 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3527 return NT_STATUS_ACCESS_DENIED;
3529 td->trust_posix_offset = &info->posix_offset.posix_offset;
3531 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
3532 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3533 return NT_STATUS_ACCESS_DENIED;
3535 nt_status = info_ex_2_pdb_trusted_domain(&info->info_ex, td);
3536 if (!NT_STATUS_IS_OK(nt_status)) {
3540 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
3541 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3542 return NT_STATUS_ACCESS_DENIED;
3544 nt_status = auth_info_2_auth_blob(td, &info->auth_info,
3545 &td->trust_auth_incoming,
3546 &td->trust_auth_outgoing);
3547 if (!NT_STATUS_IS_OK(nt_status)) {
3551 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
3552 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3553 return NT_STATUS_ACCESS_DENIED;
3555 td->trust_posix_offset = &info->full_info.posix_offset.posix_offset;
3556 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info.info_ex,
3558 if (!NT_STATUS_IS_OK(nt_status)) {
3561 nt_status = auth_info_2_auth_blob(td,
3562 &info->full_info.auth_info,
3563 &td->trust_auth_incoming,
3564 &td->trust_auth_outgoing);
3565 if (!NT_STATUS_IS_OK(nt_status)) {
3569 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
3570 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3571 return NT_STATUS_ACCESS_DENIED;
3573 auth_info_int = &info->auth_info_internal;
3575 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
3576 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3577 return NT_STATUS_ACCESS_DENIED;
3579 td->trust_posix_offset = &info->full_info_internal.posix_offset.posix_offset;
3580 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info_internal.info_ex,
3582 if (!NT_STATUS_IS_OK(nt_status)) {
3585 auth_info_int = &info->full_info_internal.auth_info;
3587 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
3588 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3589 return NT_STATUS_ACCESS_DENIED;
3591 td->supported_enc_type = &info->enc_types.enc_types;
3594 return NT_STATUS_INVALID_PARAMETER;
3597 /* decode auth_info_int if set */
3598 if (auth_info_int) {
3600 /* now decrypt blob */
3601 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
3602 auth_info_int->auth_blob.size);
3604 nt_status = get_trustdom_auth_blob(p, mem_ctx,
3605 &auth_blob, &auth_struct);
3606 if (!NT_STATUS_IS_OK(nt_status)) {
3610 memset(&auth_struct, 0, sizeof(auth_struct));
3613 /* TODO: verify only one object matches the dns/netbios/sid triplet and that
3614 * this is the one we already have */
3616 /* TODO: check if the trust direction is changed and we need to add or remove
3619 /* TODO: check if trust type shall be changed and return an error in this case
3621 nt_status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &policy->sid,
3623 if (!NT_STATUS_IS_OK(nt_status)) {
3628 /* TODO: should we fetch previous values from the existing entry
3629 * and append them ? */
3630 if (auth_struct.incoming.count) {
3631 nt_status = get_trustauth_inout_blob(mem_ctx,
3632 &auth_struct.incoming,
3633 &td->trust_auth_incoming);
3634 if (!NT_STATUS_IS_OK(nt_status)) {
3638 ZERO_STRUCT(td->trust_auth_incoming);
3641 if (auth_struct.outgoing.count) {
3642 nt_status = get_trustauth_inout_blob(mem_ctx,
3643 &auth_struct.outgoing,
3644 &td->trust_auth_outgoing);
3645 if (!NT_STATUS_IS_OK(nt_status)) {
3649 ZERO_STRUCT(td->trust_auth_outgoing);
3652 nt_status = pdb_set_trusted_domain(orig_td->domain_name, td);
3653 if (!NT_STATUS_IS_OK(nt_status)) {
3657 return NT_STATUS_OK;
3660 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3661 struct lsa_SetTrustedDomainInfo *r)
3664 struct policy_handle trustdom_handle;
3665 struct lsa_OpenTrustedDomain o;
3666 struct lsa_SetInformationTrustedDomain s;
3669 o.in.handle = r->in.handle;
3670 o.in.sid = r->in.dom_sid;
3671 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3672 o.out.trustdom_handle = &trustdom_handle;
3674 status = _lsa_OpenTrustedDomain(p, &o);
3675 if (!NT_STATUS_IS_OK(status)) {
3679 s.in.trustdom_handle = &trustdom_handle;
3680 s.in.level = r->in.level;
3681 s.in.info = r->in.info;
3683 status = _lsa_SetInformationTrustedDomain(p, &s);
3684 if (!NT_STATUS_IS_OK(status)) {
3688 c.in.handle = &trustdom_handle;
3689 c.out.handle = &trustdom_handle;
3691 return _lsa_Close(p, &c);
3694 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3695 struct lsa_SetTrustedDomainInfoByName *r)
3698 struct policy_handle trustdom_handle;
3699 struct lsa_OpenTrustedDomainByName o;
3700 struct lsa_SetInformationTrustedDomain s;
3703 o.in.handle = r->in.handle;
3704 o.in.name.string = r->in.trusted_domain->string;
3705 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3706 o.out.trustdom_handle = &trustdom_handle;
3708 status = _lsa_OpenTrustedDomainByName(p, &o);
3709 if (!NT_STATUS_IS_OK(status)) {
3710 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
3711 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3716 s.in.trustdom_handle = &trustdom_handle;
3717 s.in.level = r->in.level;
3718 s.in.info = r->in.info;
3720 status = _lsa_SetInformationTrustedDomain(p, &s);
3721 if (!NT_STATUS_IS_OK(status)) {
3725 c.in.handle = &trustdom_handle;
3726 c.out.handle = &trustdom_handle;
3728 return _lsa_Close(p, &c);
3731 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3732 struct lsa_SetInformationTrustedDomain *r)
3734 struct lsa_info *policy;
3736 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&policy)) {
3737 return NT_STATUS_INVALID_HANDLE;
3740 if (policy->type != LSA_HANDLE_TRUST_TYPE) {
3741 return NT_STATUS_INVALID_HANDLE;
3744 return setInfoTrustedDomain_base(p, p->mem_ctx, policy,
3745 r->in.level, r->in.info);
3750 * From here on the server routines are just dummy ones to make smbd link with
3751 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3752 * pulling the server stubs across one by one.
3755 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3757 p->rng_fault_state = True;
3758 return NT_STATUS_NOT_IMPLEMENTED;
3761 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3762 struct lsa_ChangePassword *r)
3764 p->rng_fault_state = True;
3765 return NT_STATUS_NOT_IMPLEMENTED;
3768 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3770 p->rng_fault_state = True;
3771 return NT_STATUS_NOT_IMPLEMENTED;
3774 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3776 p->rng_fault_state = True;
3777 return NT_STATUS_NOT_IMPLEMENTED;
3780 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3781 struct lsa_GetQuotasForAccount *r)
3783 p->rng_fault_state = True;
3784 return NT_STATUS_NOT_IMPLEMENTED;
3787 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3788 struct lsa_SetQuotasForAccount *r)
3790 p->rng_fault_state = True;
3791 return NT_STATUS_NOT_IMPLEMENTED;
3794 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3795 struct lsa_StorePrivateData *r)
3797 p->rng_fault_state = True;
3798 return NT_STATUS_NOT_IMPLEMENTED;
3801 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3802 struct lsa_RetrievePrivateData *r)
3804 p->rng_fault_state = True;
3805 return NT_STATUS_NOT_IMPLEMENTED;
3808 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3809 struct lsa_SetInfoPolicy2 *r)
3811 p->rng_fault_state = True;
3812 return NT_STATUS_NOT_IMPLEMENTED;
3815 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3816 struct lsa_EnumTrustedDomainsEx *r)
3818 struct lsa_info *info;
3820 struct pdb_trusted_domain **domains;
3821 struct lsa_TrustDomainInfoInfoEx *entries;
3825 /* bail out early if pdb backend is not capable of ex trusted domains,
3826 * if we dont do that, the client might not call
3827 * _lsa_EnumTrustedDomains() afterwards - gd */
3829 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3830 p->rng_fault_state = True;
3831 return NT_STATUS_NOT_IMPLEMENTED;
3834 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3835 return NT_STATUS_INVALID_HANDLE;
3837 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3838 return NT_STATUS_INVALID_HANDLE;
3841 /* check if the user has enough rights */
3842 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3843 return NT_STATUS_ACCESS_DENIED;
3846 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3849 if (!NT_STATUS_IS_OK(nt_status)) {
3853 entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3856 return NT_STATUS_NO_MEMORY;
3859 for (i=0; i<count; i++) {
3860 init_lsa_StringLarge(&entries[i].netbios_name,
3861 domains[i]->netbios_name);
3862 entries[i].sid = &domains[i]->security_identifier;
3865 if (*r->in.resume_handle >= count) {
3866 *r->out.resume_handle = -1;
3867 TALLOC_FREE(entries);
3868 return NT_STATUS_NO_MORE_ENTRIES;
3871 /* return the rest, limit by max_size. Note that we
3872 use the w2k3 element size value of 60 */
3873 r->out.domains->count = count - *r->in.resume_handle;
3874 r->out.domains->count = MIN(r->out.domains->count,
3875 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3877 r->out.domains->domains = entries + *r->in.resume_handle;
3879 if (r->out.domains->count < count - *r->in.resume_handle) {
3880 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3881 return STATUS_MORE_ENTRIES;
3884 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3885 * always be larger than the previous input resume handle, in
3886 * particular when hitting the last query it is vital to set the
3887 * resume handle correctly to avoid infinite client loops, as
3888 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3889 * status is NT_STATUS_OK - gd */
3891 *r->out.resume_handle = (uint32_t)-1;
3893 return NT_STATUS_OK;
3896 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3897 struct lsa_QueryDomainInformationPolicy *r)
3899 p->rng_fault_state = True;
3900 return NT_STATUS_NOT_IMPLEMENTED;
3903 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3904 struct lsa_SetDomainInformationPolicy *r)
3906 p->rng_fault_state = True;
3907 return NT_STATUS_NOT_IMPLEMENTED;
3910 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3912 p->rng_fault_state = True;
3913 return NT_STATUS_NOT_IMPLEMENTED;
3916 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3918 p->rng_fault_state = True;
3919 return NT_STATUS_NOT_IMPLEMENTED;
3922 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3924 p->rng_fault_state = True;
3925 return NT_STATUS_NOT_IMPLEMENTED;
3928 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3930 p->rng_fault_state = True;
3931 return NT_STATUS_NOT_IMPLEMENTED;
3934 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3935 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3937 p->rng_fault_state = True;
3938 return NT_STATUS_NOT_IMPLEMENTED;
3941 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3942 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3944 p->rng_fault_state = True;
3945 return NT_STATUS_NOT_IMPLEMENTED;
3948 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3950 p->rng_fault_state = True;
3951 return NT_STATUS_NOT_IMPLEMENTED;
3954 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3955 struct lsa_CREDRGETTARGETINFO *r)
3957 p->rng_fault_state = True;
3958 return NT_STATUS_NOT_IMPLEMENTED;
3961 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3962 struct lsa_CREDRPROFILELOADED *r)
3964 p->rng_fault_state = True;
3965 return NT_STATUS_NOT_IMPLEMENTED;
3968 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3969 struct lsa_CREDRGETSESSIONTYPES *r)
3971 p->rng_fault_state = True;
3972 return NT_STATUS_NOT_IMPLEMENTED;
3975 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3976 struct lsa_LSARREGISTERAUDITEVENT *r)
3978 p->rng_fault_state = True;
3979 return NT_STATUS_NOT_IMPLEMENTED;
3982 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3983 struct lsa_LSARGENAUDITEVENT *r)
3985 p->rng_fault_state = True;
3986 return NT_STATUS_NOT_IMPLEMENTED;
3989 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3990 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3992 p->rng_fault_state = True;
3993 return NT_STATUS_NOT_IMPLEMENTED;
3996 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3997 struct lsa_lsaRQueryForestTrustInformation *r)
3999 p->rng_fault_state = True;
4000 return NT_STATUS_NOT_IMPLEMENTED;
4003 #define DNS_CMP_MATCH 0
4004 #define DNS_CMP_FIRST_IS_CHILD 1
4005 #define DNS_CMP_SECOND_IS_CHILD 2
4006 #define DNS_CMP_NO_MATCH 3
4008 /* this function assumes names are well formed DNS names.
4009 * it doesn't validate them */
4010 static int dns_cmp(const char *s1, size_t l1,
4011 const char *s2, size_t l2)
4013 const char *p1, *p2;
4018 if (strcasecmp_m(s1, s2) == 0) {
4019 return DNS_CMP_MATCH;
4021 return DNS_CMP_NO_MATCH;
4029 cret = DNS_CMP_FIRST_IS_CHILD;
4035 cret = DNS_CMP_SECOND_IS_CHILD;
4038 if (p1[t1 - t2 - 1] != '.') {
4039 return DNS_CMP_NO_MATCH;
4042 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
4046 return DNS_CMP_NO_MATCH;
4049 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
4050 struct lsa_ForestTrustInformation *lfti,
4051 struct ForestTrustInfo *fti)
4053 struct lsa_ForestTrustRecord *lrec;
4054 struct ForestTrustInfoRecord *rec;
4055 struct lsa_StringLarge *tln;
4056 struct lsa_ForestTrustDomainInfo *info;
4060 fti->count = lfti->count;
4061 fti->records = talloc_array(mem_ctx,
4062 struct ForestTrustInfoRecordArmor,
4064 if (!fti->records) {
4065 return NT_STATUS_NO_MEMORY;
4067 for (i = 0; i < fti->count; i++) {
4068 lrec = lfti->entries[i];
4069 rec = &fti->records[i].record;
4071 rec->flags = lrec->flags;
4072 rec->timestamp = lrec->time;
4073 rec->type = lrec->type;
4075 switch (lrec->type) {
4076 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
4077 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4078 tln = &lrec->forest_trust_data.top_level_name;
4079 rec->data.name.string =
4080 talloc_strdup(mem_ctx, tln->string);
4081 if (!rec->data.name.string) {
4082 return NT_STATUS_NO_MEMORY;
4084 rec->data.name.size = strlen(rec->data.name.string);
4086 case LSA_FOREST_TRUST_DOMAIN_INFO:
4087 info = &lrec->forest_trust_data.domain_info;
4088 rec->data.info.sid = *info->domain_sid;
4089 rec->data.info.dns_name.string =
4090 talloc_strdup(mem_ctx,
4091 info->dns_domain_name.string);
4092 if (!rec->data.info.dns_name.string) {
4093 return NT_STATUS_NO_MEMORY;
4095 rec->data.info.dns_name.size =
4096 strlen(rec->data.info.dns_name.string);
4097 rec->data.info.netbios_name.string =
4098 talloc_strdup(mem_ctx,
4099 info->netbios_domain_name.string);
4100 if (!rec->data.info.netbios_name.string) {
4101 return NT_STATUS_NO_MEMORY;
4103 rec->data.info.netbios_name.size =
4104 strlen(rec->data.info.netbios_name.string);
4107 return NT_STATUS_INVALID_DOMAIN_STATE;
4111 return NT_STATUS_OK;
4114 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4115 uint32_t index, uint32_t collision_type,
4116 uint32_t conflict_type, const char *tdo_name);
4118 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
4119 const char *tdo_name,
4120 struct ForestTrustInfo *tdo_fti,
4121 struct ForestTrustInfo *new_fti,
4122 struct lsa_ForestTrustCollisionInfo *c_info)
4124 struct ForestTrustInfoRecord *nrec;
4125 struct ForestTrustInfoRecord *trec;
4126 const char *dns_name;
4127 const char *nb_name = NULL;
4128 struct dom_sid *sid = NULL;
4129 const char *tname = NULL;
4134 uint32_t new_fti_idx;
4136 /* use always TDO type, until we understand when Xref can be used */
4137 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
4142 bool ex_rule = false;
4145 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
4147 nrec = &new_fti->records[new_fti_idx].record;
4149 tln_conflict = false;
4150 sid_conflict = false;
4151 nb_conflict = false;
4154 switch (nrec->type) {
4155 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4156 /* exclusions do not conflict by definition */
4159 case FOREST_TRUST_TOP_LEVEL_NAME:
4160 dns_name = nrec->data.name.string;
4161 dns_len = nrec->data.name.size;
4164 case LSA_FOREST_TRUST_DOMAIN_INFO:
4165 dns_name = nrec->data.info.dns_name.string;
4166 dns_len = nrec->data.info.dns_name.size;
4167 nb_name = nrec->data.info.netbios_name.string;
4168 nb_len = nrec->data.info.netbios_name.size;
4169 sid = &nrec->data.info.sid;
4173 if (!dns_name) continue;
4175 /* check if this is already taken and not excluded */
4176 for (i = 0; i < tdo_fti->count; i++) {
4177 trec = &tdo_fti->records[i].record;
4179 switch (trec->type) {
4180 case FOREST_TRUST_TOP_LEVEL_NAME:
4182 tname = trec->data.name.string;
4183 tlen = trec->data.name.size;
4185 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
4187 tname = trec->data.name.string;
4188 tlen = trec->data.name.size;
4190 case FOREST_TRUST_DOMAIN_INFO:
4192 tname = trec->data.info.dns_name.string;
4193 tlen = trec->data.info.dns_name.size;
4196 return NT_STATUS_INVALID_PARAMETER;
4198 ret = dns_cmp(dns_name, dns_len, tname, tlen);
4201 /* if it matches exclusion,
4202 * it doesn't conflict */
4208 case DNS_CMP_FIRST_IS_CHILD:
4209 case DNS_CMP_SECOND_IS_CHILD:
4210 tln_conflict = true;
4216 /* explicit exclusion, no dns name conflict here */
4218 tln_conflict = false;
4221 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
4225 /* also test for domain info */
4226 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
4227 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
4228 sid_conflict = true;
4230 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
4231 strcasecmp_m(trec->data.info.netbios_name.string,
4238 nt_status = add_collision(c_info, new_fti_idx,
4240 LSA_TLN_DISABLED_CONFLICT,
4244 nt_status = add_collision(c_info, new_fti_idx,
4246 LSA_SID_DISABLED_CONFLICT,
4250 nt_status = add_collision(c_info, new_fti_idx,
4252 LSA_NB_DISABLED_CONFLICT,
4257 return NT_STATUS_OK;
4260 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4261 uint32_t idx, uint32_t collision_type,
4262 uint32_t conflict_type, const char *tdo_name)
4264 struct lsa_ForestTrustCollisionRecord **es;
4265 uint32_t i = c_info->count;
4267 es = talloc_realloc(c_info, c_info->entries,
4268 struct lsa_ForestTrustCollisionRecord *, i + 1);
4270 return NT_STATUS_NO_MEMORY;
4272 c_info->entries = es;
4273 c_info->count = i + 1;
4275 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4277 return NT_STATUS_NO_MEMORY;
4281 es[i]->type = collision_type;
4282 es[i]->flags.flags = conflict_type;
4283 es[i]->name.string = talloc_strdup(es[i], tdo_name);
4284 if (!es[i]->name.string) {
4285 return NT_STATUS_NO_MEMORY;
4287 es[i]->name.size = strlen(es[i]->name.string);
4289 return NT_STATUS_OK;
4292 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
4293 struct pdb_trusted_domain *td,
4294 struct ForestTrustInfo *info)
4296 enum ndr_err_code ndr_err;
4298 if (td->trust_forest_trust_info.length == 0 ||
4299 td->trust_forest_trust_info.data == NULL) {
4300 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4302 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
4304 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
4305 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4306 return NT_STATUS_INVALID_DOMAIN_STATE;
4309 return NT_STATUS_OK;
4312 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
4313 struct ForestTrustInfo *fti)
4315 struct ForestTrustDataDomainInfo *info;
4316 struct ForestTrustInfoRecord *rec;
4320 fti->records = talloc_array(fti,
4321 struct ForestTrustInfoRecordArmor, 2);
4322 if (!fti->records) {
4323 return NT_STATUS_NO_MEMORY;
4327 rec = &fti->records[0].record;
4331 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
4333 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
4334 if (!rec->data.name.string) {
4335 return NT_STATUS_NO_MEMORY;
4337 rec->data.name.size = strlen(rec->data.name.string);
4340 rec = &fti->records[1].record;
4344 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
4346 info = &rec->data.info;
4348 info->sid = dom_info->sid;
4349 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
4350 if (!info->dns_name.string) {
4351 return NT_STATUS_NO_MEMORY;
4353 info->dns_name.size = strlen(info->dns_name.string);
4354 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
4355 if (!info->netbios_name.string) {
4356 return NT_STATUS_NO_MEMORY;
4358 info->netbios_name.size = strlen(info->netbios_name.string);
4360 return NT_STATUS_OK;
4363 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
4364 struct lsa_lsaRSetForestTrustInformation *r)
4369 struct lsa_info *handle;
4370 uint32_t num_domains;
4371 struct pdb_trusted_domain **domains;
4372 struct ForestTrustInfo *nfti;
4373 struct ForestTrustInfo *fti;
4374 struct lsa_ForestTrustCollisionInfo *c_info;
4375 struct pdb_domain_info *dom_info;
4376 enum ndr_err_code ndr_err;
4379 return NT_STATUS_NOT_SUPPORTED;
4382 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
4383 return NT_STATUS_INVALID_HANDLE;
4386 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
4387 return NT_STATUS_INVALID_HANDLE;
4390 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
4391 return NT_STATUS_ACCESS_DENIED;
4394 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
4395 if (!NT_STATUS_IS_OK(status)) {
4398 if (num_domains == 0) {
4399 return NT_STATUS_NO_SUCH_DOMAIN;
4402 for (i = 0; i < num_domains; i++) {
4403 if (domains[i]->domain_name == NULL) {
4404 return NT_STATUS_INVALID_DOMAIN_STATE;
4406 if (strcasecmp_m(domains[i]->domain_name,
4407 r->in.trusted_domain_name->string) == 0) {
4411 if (i >= num_domains) {
4412 return NT_STATUS_NO_SUCH_DOMAIN;
4415 if (!(domains[i]->trust_attributes &
4416 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4417 return NT_STATUS_INVALID_PARAMETER;
4420 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4421 return NT_STATUS_INVALID_PARAMETER;
4424 /* The following section until COPY_END is a copy from
4425 * source4/rpmc_server/lsa/scesrc_lsa.c */
4426 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
4428 return NT_STATUS_NO_MEMORY;
4431 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4432 if (!NT_STATUS_IS_OK(status)) {
4436 c_info = talloc_zero(r->out.collision_info,
4437 struct lsa_ForestTrustCollisionInfo);
4439 return NT_STATUS_NO_MEMORY;
4442 /* first check own info, then other domains */
4443 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4445 return NT_STATUS_NO_MEMORY;
4448 dom_info = pdb_get_domain_info(p->mem_ctx);
4450 status = own_ft_info(dom_info, fti);
4451 if (!NT_STATUS_IS_OK(status)) {
4455 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
4456 if (!NT_STATUS_IS_OK(status)) {
4460 for (j = 0; j < num_domains; j++) {
4461 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4463 return NT_STATUS_NO_MEMORY;
4466 status = get_ft_info(p->mem_ctx, domains[j], fti);
4467 if (!NT_STATUS_IS_OK(status)) {
4468 if (NT_STATUS_EQUAL(status,
4469 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4475 if (domains[j]->domain_name == NULL) {
4476 return NT_STATUS_INVALID_DOMAIN_STATE;
4479 status = check_ft_info(c_info, domains[j]->domain_name,
4481 if (!NT_STATUS_IS_OK(status)) {
4486 *r->out.collision_info = c_info;
4488 if (r->in.check_only != 0) {
4489 return NT_STATUS_OK;
4494 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
4496 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4497 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4498 return NT_STATUS_INVALID_PARAMETER;
4501 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
4502 if (!NT_STATUS_IS_OK(status)) {
4506 return NT_STATUS_OK;
4509 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
4510 struct lsa_CREDRRENAME *r)
4512 p->rng_fault_state = True;
4513 return NT_STATUS_NOT_IMPLEMENTED;
4516 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
4517 struct lsa_LSAROPENPOLICYSCE *r)
4519 p->rng_fault_state = True;
4520 return NT_STATUS_NOT_IMPLEMENTED;
4523 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4524 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4526 p->rng_fault_state = True;
4527 return NT_STATUS_NOT_IMPLEMENTED;
4530 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4531 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4533 p->rng_fault_state = True;
4534 return NT_STATUS_NOT_IMPLEMENTED;
4537 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4538 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4540 p->rng_fault_state = True;
4541 return NT_STATUS_NOT_IMPLEMENTED;