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/ndr_lsa.h"
35 #include "librpc/gen_ndr/ndr_lsa_scompat.h"
37 #include "../librpc/gen_ndr/netlogon.h"
38 #include "rpc_client/init_lsa.h"
39 #include "../libcli/security/security.h"
40 #include "../libcli/security/dom_sid.h"
41 #include "../librpc/gen_ndr/drsblobs.h"
42 #include "../librpc/gen_ndr/ndr_drsblobs.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 "../libcli/lsarpc/util_lsarpc.h"
53 #include "librpc/rpc/dcesrv_core.h"
54 #include "librpc/rpc/dcerpc_helper.h"
55 #include "lib/param/loadparm.h"
56 #include "source3/lib/substitute.h"
58 #include "lib/crypto/gnutls_helpers.h"
59 #include <gnutls/gnutls.h>
60 #include <gnutls/crypto.h>
63 #define DBGC_CLASS DBGC_RPC_SRV
65 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
67 enum lsa_handle_type {
68 LSA_HANDLE_POLICY_TYPE = 1,
69 LSA_HANDLE_ACCOUNT_TYPE = 2,
70 LSA_HANDLE_TRUST_TYPE = 3,
71 LSA_HANDLE_SECRET_TYPE = 4};
77 enum lsa_handle_type type;
78 struct security_descriptor *sd;
81 const struct generic_mapping lsa_account_mapping = {
85 LSA_ACCOUNT_ALL_ACCESS
88 const struct generic_mapping lsa_policy_mapping = {
95 const struct generic_mapping lsa_secret_mapping = {
102 const struct generic_mapping lsa_trusted_domain_mapping = {
103 LSA_TRUSTED_DOMAIN_READ,
104 LSA_TRUSTED_DOMAIN_WRITE,
105 LSA_TRUSTED_DOMAIN_EXECUTE,
106 LSA_TRUSTED_DOMAIN_ALL_ACCESS
109 /***************************************************************************
110 initialize a lsa_DomainInfo structure.
111 ***************************************************************************/
113 static void init_dom_query_3(struct lsa_DomainInfo *r,
117 init_lsa_StringLarge(&r->name, name);
121 /***************************************************************************
122 initialize a lsa_DomainInfo structure.
123 ***************************************************************************/
125 static void init_dom_query_5(struct lsa_DomainInfo *r,
129 init_lsa_StringLarge(&r->name, name);
133 /***************************************************************************
134 lookup_lsa_rids. Must be called as root for lookup_name to work.
135 ***************************************************************************/
137 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
138 struct lsa_RefDomainList *ref,
139 struct lsa_TranslatedSid *prid,
140 uint32_t num_entries,
141 struct lsa_String *name,
143 uint32_t *pmapped_count)
145 uint32_t mapped_count, i;
147 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
152 for (i = 0; i < num_entries; i++) {
156 const char *full_name;
158 enum lsa_SidType type;
160 /* Split name into domain and user component */
162 /* follow w2k8 behavior and return the builtin domain when no
163 * input has been passed in */
165 if (name[i].string) {
166 full_name = name[i].string;
168 full_name = "BUILTIN";
171 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
173 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
175 type = SID_NAME_UNKNOWN;
180 case SID_NAME_DOM_GRP:
181 case SID_NAME_DOMAIN:
183 case SID_NAME_WKN_GRP:
184 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
185 /* Leave these unchanged */
188 /* Don't hand out anything but the list above */
189 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
190 type = SID_NAME_UNKNOWN;
197 if (type != SID_NAME_UNKNOWN) {
198 if (type == SID_NAME_DOMAIN) {
201 sid_split_rid(&sid, &rid);
203 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
207 prid[i].sid_type = type;
209 prid[i].sid_index = dom_idx;
212 *pmapped_count = mapped_count;
216 /***************************************************************************
217 lookup_lsa_sids. Must be called as root for lookup_name to work.
218 ***************************************************************************/
220 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
221 struct lsa_RefDomainList *ref,
222 struct lsa_TranslatedSid3 *trans_sids,
223 uint32_t num_entries,
224 struct lsa_String *name,
226 uint32_t *pmapped_count)
228 uint32_t mapped_count, i;
230 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
235 for (i = 0; i < num_entries; i++) {
239 const char *full_name;
241 enum lsa_SidType type;
245 /* Split name into domain and user component */
247 full_name = name[i].string;
248 if (full_name == NULL) {
249 return NT_STATUS_NO_MEMORY;
252 DEBUG(5, ("lookup_lsa_sids: looking up name %s\n", full_name));
254 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
256 type = SID_NAME_UNKNOWN;
261 case SID_NAME_DOM_GRP:
262 case SID_NAME_DOMAIN:
264 case SID_NAME_WKN_GRP:
265 DEBUG(5, ("lookup_lsa_sids: %s found\n", full_name));
266 /* Leave these unchanged */
269 /* Don't hand out anything but the list above */
270 DEBUG(5, ("lookup_lsa_sids: %s not found\n", full_name));
271 type = SID_NAME_UNKNOWN;
278 if (type != SID_NAME_UNKNOWN) {
279 struct dom_sid domain_sid;
280 sid_copy(&domain_sid, &sid);
281 sid_split_rid(&domain_sid, &rid);
282 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
286 /* Initialize the lsa_TranslatedSid3 return. */
287 trans_sids[i].sid_type = type;
288 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
289 trans_sids[i].sid_index = dom_idx;
292 *pmapped_count = mapped_count;
296 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
297 const struct generic_mapping *map,
298 struct dom_sid *sid, uint32_t sid_access)
300 struct dom_sid adm_sid;
301 struct security_ace ace[5];
304 struct security_acl *psa = NULL;
306 /* READ|EXECUTE access for Everyone */
308 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
309 map->generic_execute | map->generic_read, 0);
311 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
313 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
314 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
315 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
316 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
318 /* Add Full Access for Domain Admins */
319 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
320 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
321 map->generic_all, 0);
323 /* If we have a sid, give it some special access */
326 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
330 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
331 return NT_STATUS_NO_MEMORY;
333 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
334 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
335 psa, sd_size)) == NULL)
336 return NT_STATUS_NO_MEMORY;
341 /***************************************************************************
342 ***************************************************************************/
344 static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
345 struct pipes_struct *p,
346 enum lsa_handle_type type,
347 uint32_t acc_granted,
350 const struct security_descriptor *sd,
351 struct policy_handle *handle)
353 struct lsa_info *info;
355 ZERO_STRUCTP(handle);
357 info = talloc_zero(mem_ctx, struct lsa_info);
359 return NT_STATUS_NO_MEMORY;
363 info->access = acc_granted;
366 sid_copy(&info->sid, sid);
369 info->name = talloc_strdup(info, name);
372 info->sd = security_descriptor_copy(info, sd);
373 if (info->sd == NULL) {
375 return NT_STATUS_NO_MEMORY;
379 if (!create_policy_hnd(p, handle, type, info)) {
381 ZERO_STRUCTP(handle);
382 return NT_STATUS_NO_MEMORY;
388 /***************************************************************************
390 ***************************************************************************/
392 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
393 struct lsa_OpenPolicy2 *r)
395 struct dcesrv_call_state *dce_call = p->dce_call;
396 struct auth_session_info *session_info =
397 dcesrv_call_session_info(dce_call);
398 struct security_descriptor *psd = NULL;
400 uint32_t des_access = r->in.access_mask;
401 uint32_t acc_granted;
404 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
405 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
406 return NT_STATUS_ACCESS_DENIED;
409 /* Work out max allowed. */
410 map_max_allowed_access(session_info->security_token,
411 session_info->unix_token,
414 /* map the generic bits to the lsa policy ones */
415 se_map_generic(&des_access, &lsa_policy_mapping);
417 /* get the generic lsa policy SD until we store it */
418 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
420 if (!NT_STATUS_IS_OK(status)) {
424 status = access_check_object(psd, session_info->security_token,
425 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
426 &acc_granted, "_lsa_OpenPolicy2" );
427 if (!NT_STATUS_IS_OK(status)) {
431 status = create_lsa_policy_handle(p->mem_ctx, p,
432 LSA_HANDLE_POLICY_TYPE,
434 get_global_sam_sid(),
438 if (!NT_STATUS_IS_OK(status)) {
439 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
445 /***************************************************************************
447 ***************************************************************************/
449 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
450 struct lsa_OpenPolicy *r)
452 struct lsa_OpenPolicy2 o;
454 /* _lsa_OpenPolicy2 will check if this is a NCACN_NP connection */
456 o.in.system_name = NULL; /* should be ignored */
457 o.in.attr = r->in.attr;
458 o.in.access_mask = r->in.access_mask;
460 o.out.handle = r->out.handle;
462 return _lsa_OpenPolicy2(p, &o);
465 /***************************************************************************
466 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
468 ***************************************************************************/
470 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
471 struct lsa_EnumTrustDom *r)
473 struct lsa_info *info;
475 struct trustdom_info **domains;
476 struct lsa_DomainInfo *entries;
479 info = find_policy_by_hnd(p,
481 LSA_HANDLE_POLICY_TYPE,
484 if (!NT_STATUS_IS_OK(nt_status)) {
485 return NT_STATUS_INVALID_HANDLE;
488 /* check if the user has enough rights */
489 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
490 return NT_STATUS_ACCESS_DENIED;
493 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
496 if (!NT_STATUS_IS_OK(nt_status)) {
500 entries = talloc_zero_array(p->mem_ctx, struct lsa_DomainInfo, count);
502 return NT_STATUS_NO_MEMORY;
505 for (i=0; i<count; i++) {
506 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
507 entries[i].sid = &domains[i]->sid;
510 if (*r->in.resume_handle >= count) {
511 *r->out.resume_handle = -1;
512 TALLOC_FREE(entries);
513 return NT_STATUS_NO_MORE_ENTRIES;
516 /* return the rest, limit by max_size. Note that we
517 use the w2k3 element size value of 60 */
518 r->out.domains->count = count - *r->in.resume_handle;
519 r->out.domains->count = MIN(r->out.domains->count,
520 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
522 r->out.domains->domains = entries + *r->in.resume_handle;
524 if (r->out.domains->count < count - *r->in.resume_handle) {
525 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
526 return STATUS_MORE_ENTRIES;
529 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
530 * always be larger than the previous input resume handle, in
531 * particular when hitting the last query it is vital to set the
532 * resume handle correctly to avoid infinite client loops, as
533 * seen e.g. with Windows XP SP3 when resume handle is 0 and
534 * status is NT_STATUS_OK - gd */
536 *r->out.resume_handle = (uint32_t)-1;
541 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
542 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
543 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
545 /***************************************************************************
547 ***************************************************************************/
549 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
550 struct lsa_QueryInfoPolicy *r)
552 NTSTATUS status = NT_STATUS_OK;
553 struct lsa_info *handle;
554 struct dom_sid domain_sid;
556 struct dom_sid *sid = NULL;
557 union lsa_PolicyInformation *info = NULL;
558 uint32_t acc_required = 0;
560 handle = find_policy_by_hnd(p,
562 LSA_HANDLE_POLICY_TYPE,
565 if (!NT_STATUS_IS_OK(status)) {
566 return NT_STATUS_INVALID_HANDLE;
569 switch (r->in.level) {
570 case LSA_POLICY_INFO_AUDIT_LOG:
571 case LSA_POLICY_INFO_AUDIT_EVENTS:
572 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
574 case LSA_POLICY_INFO_DOMAIN:
575 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
577 case LSA_POLICY_INFO_PD:
578 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
580 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
581 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
583 case LSA_POLICY_INFO_ROLE:
584 case LSA_POLICY_INFO_REPLICA:
585 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
587 case LSA_POLICY_INFO_QUOTA:
588 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
590 case LSA_POLICY_INFO_MOD:
591 case LSA_POLICY_INFO_AUDIT_FULL_SET:
592 /* according to MS-LSAD 3.1.4.4.3 */
593 return NT_STATUS_INVALID_PARAMETER;
594 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
595 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
597 case LSA_POLICY_INFO_DNS:
598 case LSA_POLICY_INFO_DNS_INT:
599 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
600 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
606 if (!(handle->access & acc_required)) {
607 /* return NT_STATUS_ACCESS_DENIED; */
610 info = talloc_zero(p->mem_ctx, union lsa_PolicyInformation);
612 return NT_STATUS_NO_MEMORY;
615 switch (r->in.level) {
616 /* according to MS-LSAD 3.1.4.4.3 */
617 case LSA_POLICY_INFO_MOD:
618 case LSA_POLICY_INFO_AUDIT_FULL_SET:
619 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
620 return NT_STATUS_INVALID_PARAMETER;
621 case LSA_POLICY_INFO_AUDIT_LOG:
622 info->audit_log.percent_full = 0;
623 info->audit_log.maximum_log_size = 0;
624 info->audit_log.retention_time = 0;
625 info->audit_log.shutdown_in_progress = 0;
626 info->audit_log.time_to_shutdown = 0;
627 info->audit_log.next_audit_record = 0;
628 status = NT_STATUS_OK;
630 case LSA_POLICY_INFO_PD:
631 info->pd.name.string = NULL;
632 status = NT_STATUS_OK;
634 case LSA_POLICY_INFO_REPLICA:
635 info->replica.source.string = NULL;
636 info->replica.account.string = NULL;
637 status = NT_STATUS_OK;
639 case LSA_POLICY_INFO_QUOTA:
640 info->quota.paged_pool = 0;
641 info->quota.non_paged_pool = 0;
642 info->quota.min_wss = 0;
643 info->quota.max_wss = 0;
644 info->quota.pagefile = 0;
645 info->quota.unknown = 0;
646 status = NT_STATUS_OK;
648 case LSA_POLICY_INFO_AUDIT_EVENTS:
651 uint32_t policy_def = LSA_AUDIT_POLICY_ALL;
653 /* check if the user has enough rights */
654 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
655 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
656 return NT_STATUS_ACCESS_DENIED;
659 /* fake info: We audit everything. ;) */
661 info->audit_events.auditing_mode = true;
662 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
663 info->audit_events.settings = talloc_zero_array(p->mem_ctx,
664 enum lsa_PolicyAuditPolicy,
665 info->audit_events.count);
666 if (!info->audit_events.settings) {
667 return NT_STATUS_NO_MEMORY;
670 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
671 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
672 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
673 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
674 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
675 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
676 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
680 case LSA_POLICY_INFO_DOMAIN:
681 /* check if the user has enough rights */
682 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
683 return NT_STATUS_ACCESS_DENIED;
685 /* Request PolicyPrimaryDomainInformation. */
686 switch (lp_server_role()) {
687 case ROLE_DOMAIN_PDC:
688 case ROLE_DOMAIN_BDC:
690 name = get_global_sam_name();
691 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
693 return NT_STATUS_NO_MEMORY;
696 case ROLE_DOMAIN_MEMBER:
697 name = lp_workgroup();
698 /* We need to return the Domain SID here. */
699 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
700 sid = dom_sid_dup(p->mem_ctx, &domain_sid);
702 return NT_STATUS_NO_MEMORY;
705 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
708 case ROLE_STANDALONE:
709 name = lp_workgroup();
713 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
715 init_dom_query_3(&info->domain, name, sid);
717 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
718 /* check if the user has enough rights */
719 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
720 return NT_STATUS_ACCESS_DENIED;
722 /* Request PolicyAccountDomainInformation. */
723 name = get_global_sam_name();
724 sid = get_global_sam_sid();
726 init_dom_query_5(&info->account_domain, name, sid);
728 case LSA_POLICY_INFO_ROLE:
729 /* check if the user has enough rights */
730 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
731 return NT_STATUS_ACCESS_DENIED;
733 switch (lp_server_role()) {
734 case ROLE_DOMAIN_BDC:
736 * only a BDC is a backup controller
737 * of the domain, it controls.
739 info->role.role = LSA_ROLE_BACKUP;
743 * any other role is a primary
744 * of the domain, it controls.
746 info->role.role = LSA_ROLE_PRIMARY;
750 case LSA_POLICY_INFO_DNS:
751 case LSA_POLICY_INFO_DNS_INT: {
752 struct pdb_domain_info *dominfo;
754 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
755 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
756 "without ADS passdb backend\n"));
757 status = NT_STATUS_INVALID_INFO_CLASS;
761 dominfo = pdb_get_domain_info(info);
762 if (dominfo == NULL) {
763 status = NT_STATUS_NO_MEMORY;
767 init_lsa_StringLarge(&info->dns.name,
769 init_lsa_StringLarge(&info->dns.dns_domain,
770 dominfo->dns_domain);
771 init_lsa_StringLarge(&info->dns.dns_forest,
772 dominfo->dns_forest);
773 info->dns.domain_guid = dominfo->guid;
774 info->dns.sid = &dominfo->sid;
778 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
780 status = NT_STATUS_INVALID_INFO_CLASS;
789 /***************************************************************************
790 _lsa_QueryInfoPolicy2
791 ***************************************************************************/
793 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
794 struct lsa_QueryInfoPolicy2 *r2)
796 struct lsa_QueryInfoPolicy r;
798 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
799 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
800 return NT_STATUS_NOT_IMPLEMENTED;
804 r.in.handle = r2->in.handle;
805 r.in.level = r2->in.level;
806 r.out.info = r2->out.info;
808 return _lsa_QueryInfoPolicy(p, &r);
811 /***************************************************************************
812 _lsa_lookup_sids_internal
813 ***************************************************************************/
815 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
817 uint16_t level, /* input */
818 int num_sids, /* input */
819 struct lsa_SidPtr *sid, /* input */
820 struct lsa_RefDomainList **pp_ref, /* input/output */
821 struct lsa_TranslatedName2 **pp_names,/* input/output */
822 uint32_t *pp_mapped_count) /* input/output */
826 const struct dom_sid **sids = NULL;
827 struct lsa_RefDomainList *ref = NULL;
828 uint32_t mapped_count = 0;
829 struct lsa_dom_info *dom_infos = NULL;
830 struct lsa_name_info *name_infos = NULL;
831 struct lsa_TranslatedName2 *names = NULL;
833 *pp_mapped_count = 0;
841 sids = talloc_array(p->mem_ctx, const struct dom_sid *, num_sids);
842 ref = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
844 if (sids == NULL || ref == NULL) {
845 return NT_STATUS_NO_MEMORY;
848 for (i=0; i<num_sids; i++) {
849 sids[i] = sid[i].sid;
852 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
853 &dom_infos, &name_infos);
855 if (!NT_STATUS_IS_OK(status)) {
859 names = talloc_array(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
861 return NT_STATUS_NO_MEMORY;
864 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
866 if (!dom_infos[i].valid) {
870 if (init_lsa_ref_domain_list(mem_ctx, ref,
872 &dom_infos[i].sid) != i) {
873 DEBUG(0, ("Domain %s mentioned twice??\n",
875 return NT_STATUS_INTERNAL_ERROR;
879 for (i=0; i<num_sids; i++) {
880 struct lsa_name_info *name = &name_infos[i];
882 if (name->type == SID_NAME_UNKNOWN) {
884 /* Unknown sids should return the string
885 * representation of the SID. Windows 2003 behaves
886 * rather erratic here, in many cases it returns the
887 * RID as 8 bytes hex, in others it returns the full
888 * SID. We (Jerry/VL) could not figure out which the
889 * hard cases are, so leave it with the SID. */
890 name->name = dom_sid_string(p->mem_ctx, sids[i]);
891 if (name->name == NULL) {
892 return NT_STATUS_NO_MEMORY;
898 names[i].sid_type = name->type;
899 names[i].name.string = name->name;
900 names[i].sid_index = name->dom_idx;
901 names[i].unknown = 0;
904 status = NT_STATUS_NONE_MAPPED;
905 if (mapped_count > 0) {
906 status = (mapped_count < num_sids) ?
907 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
910 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
911 num_sids, mapped_count, nt_errstr(status)));
913 *pp_mapped_count = mapped_count;
920 /***************************************************************************
922 ***************************************************************************/
924 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
925 struct lsa_LookupSids *r)
928 struct lsa_info *handle;
929 int num_sids = r->in.sids->num_sids;
930 uint32_t mapped_count = 0;
931 struct lsa_RefDomainList *domains = NULL;
932 struct lsa_TranslatedName *names_out = NULL;
933 struct lsa_TranslatedName2 *names = NULL;
936 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
937 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
938 return NT_STATUS_ACCESS_DENIED;
941 if ((r->in.level < 1) || (r->in.level > 6)) {
942 return NT_STATUS_INVALID_PARAMETER;
945 handle = find_policy_by_hnd(p,
947 LSA_HANDLE_POLICY_TYPE,
950 if (!NT_STATUS_IS_OK(status)) {
951 return NT_STATUS_INVALID_HANDLE;
954 /* check if the user has enough rights */
955 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
956 return NT_STATUS_ACCESS_DENIED;
959 if (num_sids > MAX_LOOKUP_SIDS) {
960 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
961 MAX_LOOKUP_SIDS, num_sids));
962 return NT_STATUS_NONE_MAPPED;
965 status = _lsa_lookup_sids_internal(p,
974 /* Only return here when there is a real error.
975 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
976 the requested sids could be resolved. Older versions of XP (pre SP3)
977 rely that we return with the string representations of those SIDs in
978 that case. If we don't, XP crashes - Guenther
981 if (NT_STATUS_IS_ERR(status) &&
982 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
986 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
987 names_out = talloc_array(p->mem_ctx, struct lsa_TranslatedName,
990 return NT_STATUS_NO_MEMORY;
993 for (i=0; i<num_sids; i++) {
994 names_out[i].sid_type = names[i].sid_type;
995 names_out[i].name = names[i].name;
996 names_out[i].sid_index = names[i].sid_index;
999 *r->out.domains = domains;
1000 r->out.names->count = num_sids;
1001 r->out.names->names = names_out;
1002 *r->out.count = mapped_count;
1007 static NTSTATUS _lsa_LookupSids_common(struct pipes_struct *p,
1008 struct lsa_LookupSids2 *r)
1010 struct dcesrv_call_state *dce_call = p->dce_call;
1012 struct lsa_info *handle;
1013 int num_sids = r->in.sids->num_sids;
1014 uint32_t mapped_count = 0;
1015 struct lsa_RefDomainList *domains = NULL;
1016 struct lsa_TranslatedName2 *names = NULL;
1017 bool check_policy = true;
1019 switch (dce_call->pkt.u.request.opnum) {
1020 case NDR_LSA_LOOKUPSIDS3:
1021 check_policy = false;
1023 case NDR_LSA_LOOKUPSIDS2:
1025 check_policy = true;
1028 if ((r->in.level < 1) || (r->in.level > 6)) {
1029 return NT_STATUS_INVALID_PARAMETER;
1033 handle = find_policy_by_hnd(p,
1035 LSA_HANDLE_POLICY_TYPE,
1038 if (!NT_STATUS_IS_OK(status)) {
1039 return NT_STATUS_INVALID_HANDLE;
1042 /* check if the user has enough rights */
1043 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1044 return NT_STATUS_ACCESS_DENIED;
1048 if (num_sids > MAX_LOOKUP_SIDS) {
1049 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1050 MAX_LOOKUP_SIDS, num_sids));
1051 return NT_STATUS_NONE_MAPPED;
1054 status = _lsa_lookup_sids_internal(p,
1063 *r->out.domains = domains;
1064 r->out.names->count = num_sids;
1065 r->out.names->names = names;
1066 *r->out.count = mapped_count;
1071 /***************************************************************************
1073 ***************************************************************************/
1075 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1076 struct lsa_LookupSids2 *r)
1078 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1079 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1080 return NT_STATUS_ACCESS_DENIED;
1083 return _lsa_LookupSids_common(p, r);
1086 /***************************************************************************
1088 ***************************************************************************/
1090 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1091 struct lsa_LookupSids3 *r)
1093 struct dcesrv_call_state *dce_call = p->dce_call;
1094 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1095 enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
1096 struct lsa_LookupSids2 q;
1098 if (p->transport != NCACN_IP_TCP) {
1099 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1100 return NT_STATUS_ACCESS_DENIED;
1103 dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
1105 /* No policy handle on this call. Restrict to crypto connections. */
1106 if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
1107 auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1108 DEBUG(1, ("_lsa_LookupSids3: The client %s is not using "
1109 "a secure connection over netlogon\n",
1110 get_remote_machine_name() ));
1111 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1112 return NT_STATUS_ACCESS_DENIED;
1116 q.in.sids = r->in.sids;
1117 q.in.level = r->in.level;
1118 q.in.lookup_options = r->in.lookup_options;
1119 q.in.client_revision = r->in.client_revision;
1120 q.in.names = r->in.names;
1121 q.in.count = r->in.count;
1123 q.out.domains = r->out.domains;
1124 q.out.names = r->out.names;
1125 q.out.count = r->out.count;
1127 return _lsa_LookupSids_common(p, &q);
1130 /***************************************************************************
1131 ***************************************************************************/
1133 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1138 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1139 flags = LOOKUP_NAME_ALL;
1141 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1142 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1144 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1145 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1147 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1148 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1149 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1150 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1152 flags = LOOKUP_NAME_NONE;
1159 /***************************************************************************
1161 ***************************************************************************/
1163 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1164 struct lsa_LookupNames *r)
1166 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1167 struct lsa_info *handle;
1168 struct lsa_String *names = r->in.names;
1169 uint32_t num_entries = r->in.num_names;
1170 struct lsa_RefDomainList *domains = NULL;
1171 struct lsa_TranslatedSid *rids = NULL;
1172 uint32_t mapped_count = 0;
1175 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1176 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1177 return NT_STATUS_ACCESS_DENIED;
1180 if (num_entries > MAX_LOOKUP_SIDS) {
1181 num_entries = MAX_LOOKUP_SIDS;
1182 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1186 flags = lsa_lookup_level_to_flags(r->in.level);
1188 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1190 return NT_STATUS_NO_MEMORY;
1194 rids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid,
1197 return NT_STATUS_NO_MEMORY;
1203 handle = find_policy_by_hnd(p,
1205 LSA_HANDLE_POLICY_TYPE,
1208 if (!NT_STATUS_IS_OK(status)) {
1209 status = NT_STATUS_INVALID_HANDLE;
1213 /* check if the user has enough rights */
1214 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1215 status = NT_STATUS_ACCESS_DENIED;
1219 /* set up the LSA Lookup RIDs response */
1220 become_root(); /* lookup_name can require root privs */
1221 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1222 names, flags, &mapped_count);
1227 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1228 if (mapped_count == 0) {
1229 status = NT_STATUS_NONE_MAPPED;
1230 } else if (mapped_count != num_entries) {
1231 status = STATUS_SOME_UNMAPPED;
1235 *r->out.count = mapped_count;
1236 *r->out.domains = domains;
1237 r->out.sids->sids = rids;
1238 r->out.sids->count = num_entries;
1243 /***************************************************************************
1245 ***************************************************************************/
1247 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1248 struct lsa_LookupNames2 *r)
1251 struct lsa_LookupNames q;
1252 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1253 struct lsa_TransSidArray *sid_array = NULL;
1256 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1257 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1258 return NT_STATUS_ACCESS_DENIED;
1261 sid_array = talloc_zero(p->mem_ctx, struct lsa_TransSidArray);
1263 return NT_STATUS_NO_MEMORY;
1266 q.in.handle = r->in.handle;
1267 q.in.num_names = r->in.num_names;
1268 q.in.names = r->in.names;
1269 q.in.level = r->in.level;
1270 q.in.sids = sid_array;
1271 q.in.count = r->in.count;
1272 /* we do not know what this is for */
1273 /* = r->in.unknown1; */
1274 /* = r->in.unknown2; */
1276 q.out.domains = r->out.domains;
1277 q.out.sids = sid_array;
1278 q.out.count = r->out.count;
1280 status = _lsa_LookupNames(p, &q);
1282 sid_array2->count = sid_array->count;
1283 sid_array2->sids = talloc_array(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1284 if (!sid_array2->sids) {
1285 return NT_STATUS_NO_MEMORY;
1288 for (i=0; i<sid_array->count; i++) {
1289 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1290 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1291 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1292 sid_array2->sids[i].unknown = 0;
1295 r->out.sids = sid_array2;
1300 static NTSTATUS _lsa_LookupNames_common(struct pipes_struct *p,
1301 struct lsa_LookupNames3 *r)
1303 struct dcesrv_call_state *dce_call = p->dce_call;
1305 struct lsa_info *handle;
1306 struct lsa_String *names = r->in.names;
1307 uint32_t num_entries = r->in.num_names;
1308 struct lsa_RefDomainList *domains = NULL;
1309 struct lsa_TranslatedSid3 *trans_sids = NULL;
1310 uint32_t mapped_count = 0;
1312 bool check_policy = true;
1314 switch (dce_call->pkt.u.request.opnum) {
1315 case NDR_LSA_LOOKUPNAMES4:
1316 check_policy = false;
1318 case NDR_LSA_LOOKUPNAMES3:
1320 check_policy = true;
1323 if (num_entries > MAX_LOOKUP_SIDS) {
1324 num_entries = MAX_LOOKUP_SIDS;
1325 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1328 flags = lsa_lookup_level_to_flags(r->in.level);
1330 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1332 return NT_STATUS_NO_MEMORY;
1336 trans_sids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid3,
1339 return NT_STATUS_NO_MEMORY;
1347 handle = find_policy_by_hnd(p,
1349 LSA_HANDLE_POLICY_TYPE,
1352 if (!NT_STATUS_IS_OK(status)) {
1353 status = NT_STATUS_INVALID_HANDLE;
1357 /* check if the user has enough rights */
1358 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1359 status = NT_STATUS_ACCESS_DENIED;
1364 /* set up the LSA Lookup SIDs response */
1365 become_root(); /* lookup_name can require root privs */
1366 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1367 names, flags, &mapped_count);
1372 if (NT_STATUS_IS_OK(status)) {
1373 if (mapped_count == 0) {
1374 status = NT_STATUS_NONE_MAPPED;
1375 } else if (mapped_count != num_entries) {
1376 status = STATUS_SOME_UNMAPPED;
1380 *r->out.count = mapped_count;
1381 *r->out.domains = domains;
1382 r->out.sids->sids = trans_sids;
1383 r->out.sids->count = num_entries;
1388 /***************************************************************************
1390 ***************************************************************************/
1392 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1393 struct lsa_LookupNames3 *r)
1395 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1396 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1397 return NT_STATUS_ACCESS_DENIED;
1400 return _lsa_LookupNames_common(p, r);
1403 /***************************************************************************
1405 ***************************************************************************/
1407 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1408 struct lsa_LookupNames4 *r)
1410 struct dcesrv_call_state *dce_call = p->dce_call;
1411 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1412 enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
1413 struct lsa_LookupNames3 q;
1415 if (p->transport != NCACN_IP_TCP) {
1416 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1417 return NT_STATUS_ACCESS_DENIED;
1420 dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
1422 /* No policy handle on this call. Restrict to crypto connections. */
1423 if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
1424 auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1425 DEBUG(1, ("_lsa_LookupNames4: The client %s is not using "
1426 "a secure connection over netlogon\n",
1427 get_remote_machine_name()));
1428 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1429 return NT_STATUS_ACCESS_DENIED;
1433 q.in.num_names = r->in.num_names;
1434 q.in.names = r->in.names;
1435 q.in.level = r->in.level;
1436 q.in.lookup_options = r->in.lookup_options;
1437 q.in.client_revision = r->in.client_revision;
1438 q.in.sids = r->in.sids;
1439 q.in.count = r->in.count;
1441 q.out.domains = r->out.domains;
1442 q.out.sids = r->out.sids;
1443 q.out.count = r->out.count;
1445 return _lsa_LookupNames_common(p, &q);
1448 /***************************************************************************
1449 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1450 ***************************************************************************/
1452 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1456 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1457 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1458 return NT_STATUS_ACCESS_DENIED;
1461 (void)find_policy_by_hnd(p,
1466 if (!NT_STATUS_IS_OK(status)) {
1467 return NT_STATUS_INVALID_HANDLE;
1470 close_policy_hnd(p, r->in.handle);
1471 ZERO_STRUCTP(r->out.handle);
1472 return NT_STATUS_OK;
1475 /***************************************************************************
1476 ***************************************************************************/
1478 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1479 const struct dom_sid *sid,
1480 struct trustdom_info **info)
1483 uint32_t num_domains = 0;
1484 struct trustdom_info **domains = NULL;
1487 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1488 if (!NT_STATUS_IS_OK(status)) {
1492 for (i=0; i < num_domains; i++) {
1493 if (dom_sid_equal(&domains[i]->sid, sid)) {
1498 if (i == num_domains) {
1499 return NT_STATUS_INVALID_PARAMETER;
1504 return NT_STATUS_OK;
1507 /***************************************************************************
1508 ***************************************************************************/
1510 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1511 const char *netbios_domain_name,
1512 struct trustdom_info **info_p)
1515 struct trustdom_info *info;
1516 struct pdb_trusted_domain *td;
1518 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1519 if (!NT_STATUS_IS_OK(status)) {
1523 info = talloc(mem_ctx, struct trustdom_info);
1525 return NT_STATUS_NO_MEMORY;
1528 info->name = talloc_strdup(info, netbios_domain_name);
1529 NT_STATUS_HAVE_NO_MEMORY(info->name);
1531 sid_copy(&info->sid, &td->security_identifier);
1535 return NT_STATUS_OK;
1538 /***************************************************************************
1540 ***************************************************************************/
1542 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p,
1543 struct lsa_OpenSecret *r)
1545 struct dcesrv_call_state *dce_call = p->dce_call;
1546 struct auth_session_info *session_info =
1547 dcesrv_call_session_info(dce_call);
1548 struct security_descriptor *psd;
1550 uint32_t acc_granted;
1552 (void)find_policy_by_hnd(p,
1554 LSA_HANDLE_POLICY_TYPE,
1557 if (!NT_STATUS_IS_OK(status)) {
1558 return NT_STATUS_INVALID_HANDLE;
1561 if (!r->in.name.string) {
1562 return NT_STATUS_INVALID_PARAMETER;
1565 /* Work out max allowed. */
1566 map_max_allowed_access(session_info->security_token,
1567 session_info->unix_token,
1568 &r->in.access_mask);
1570 /* map the generic bits to the lsa policy ones */
1571 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
1573 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
1579 if (!NT_STATUS_IS_OK(status)) {
1583 status = access_check_object(psd, session_info->security_token,
1584 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1586 &acc_granted, "_lsa_OpenSecret");
1587 if (!NT_STATUS_IS_OK(status)) {
1591 status = create_lsa_policy_handle(p->mem_ctx, p,
1592 LSA_HANDLE_SECRET_TYPE,
1598 if (!NT_STATUS_IS_OK(status)) {
1599 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1602 return NT_STATUS_OK;
1605 /***************************************************************************
1606 _lsa_OpenTrustedDomain_base
1607 ***************************************************************************/
1609 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1610 uint32_t access_mask,
1611 struct trustdom_info *info,
1612 struct policy_handle *handle)
1614 struct dcesrv_call_state *dce_call = p->dce_call;
1615 struct auth_session_info *session_info =
1616 dcesrv_call_session_info(dce_call);
1617 struct security_descriptor *psd = NULL;
1619 uint32_t acc_granted;
1622 /* des_access is for the account here, not the policy
1623 * handle - so don't check against policy handle. */
1625 /* Work out max allowed. */
1626 map_max_allowed_access(session_info->security_token,
1627 session_info->unix_token,
1630 /* map the generic bits to the lsa account ones */
1631 se_map_generic(&access_mask, &lsa_trusted_domain_mapping);
1633 /* get the generic lsa account SD until we store it */
1634 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1635 &lsa_trusted_domain_mapping,
1637 if (!NT_STATUS_IS_OK(status)) {
1641 status = access_check_object(psd, session_info->security_token,
1642 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1643 access_mask, &acc_granted,
1644 "_lsa_OpenTrustedDomain");
1645 if (!NT_STATUS_IS_OK(status)) {
1649 status = create_lsa_policy_handle(p->mem_ctx, p,
1650 LSA_HANDLE_TRUST_TYPE,
1656 if (!NT_STATUS_IS_OK(status)) {
1657 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1660 return NT_STATUS_OK;
1663 /***************************************************************************
1664 _lsa_OpenTrustedDomain
1665 ***************************************************************************/
1667 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1668 struct lsa_OpenTrustedDomain *r)
1670 struct trustdom_info *info = NULL;
1673 (void)find_policy_by_hnd(p,
1675 LSA_HANDLE_POLICY_TYPE,
1678 if (!NT_STATUS_IS_OK(status)) {
1679 return NT_STATUS_INVALID_HANDLE;
1682 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1685 if (!NT_STATUS_IS_OK(status)) {
1689 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1690 r->out.trustdom_handle);
1693 /***************************************************************************
1694 _lsa_OpenTrustedDomainByName
1695 ***************************************************************************/
1697 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1698 struct lsa_OpenTrustedDomainByName *r)
1700 struct trustdom_info *info = NULL;
1703 (void)find_policy_by_hnd(p,
1705 LSA_HANDLE_POLICY_TYPE,
1708 if (!NT_STATUS_IS_OK(status)) {
1709 return NT_STATUS_INVALID_HANDLE;
1712 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1715 if (!NT_STATUS_IS_OK(status)) {
1719 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1720 r->out.trustdom_handle);
1723 static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
1724 TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
1725 struct trustDomainPasswords *auth_struct)
1727 struct dcesrv_call_state *dce_call = p->dce_call;
1728 struct auth_session_info *session_info =
1729 dcesrv_call_session_info(dce_call);
1730 enum ndr_err_code ndr_err;
1731 DATA_BLOB lsession_key;
1732 gnutls_cipher_hd_t cipher_hnd = NULL;
1733 gnutls_datum_t my_session_key;
1738 encrypted = dcerpc_is_transport_encrypted(session_info);
1739 if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
1741 return NT_STATUS_ACCESS_DENIED;
1744 status = session_extract_session_key(
1745 session_info, &lsession_key, KEY_USE_16BYTES);
1746 if (!NT_STATUS_IS_OK(status)) {
1747 return NT_STATUS_INVALID_PARAMETER;
1750 my_session_key = (gnutls_datum_t) {
1751 .data = lsession_key.data,
1752 .size = lsession_key.length,
1755 GNUTLS_FIPS140_SET_LAX_MODE();
1756 rc = gnutls_cipher_init(&cipher_hnd,
1757 GNUTLS_CIPHER_ARCFOUR_128,
1761 GNUTLS_FIPS140_SET_STRICT_MODE();
1762 status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
1766 rc = gnutls_cipher_decrypt(cipher_hnd,
1769 gnutls_cipher_deinit(cipher_hnd);
1770 GNUTLS_FIPS140_SET_STRICT_MODE();
1772 status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
1776 ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
1778 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
1779 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1780 status = NT_STATUS_INVALID_PARAMETER;
1784 status = NT_STATUS_OK;
1789 static NTSTATUS get_trustauth_inout_blob(TALLOC_CTX *mem_ctx,
1790 struct trustAuthInOutBlob *iopw,
1791 DATA_BLOB *trustauth_blob)
1793 enum ndr_err_code ndr_err;
1795 if (iopw->current.count != iopw->count) {
1796 return NT_STATUS_INVALID_PARAMETER;
1799 if (iopw->previous.count > iopw->current.count) {
1800 return NT_STATUS_INVALID_PARAMETER;
1803 if (iopw->previous.count == 0) {
1805 * If the previous credentials are not present
1806 * we need to make a copy.
1808 iopw->previous = iopw->current;
1811 if (iopw->previous.count < iopw->current.count) {
1812 struct AuthenticationInformationArray *c = &iopw->current;
1813 struct AuthenticationInformationArray *p = &iopw->previous;
1816 * The previous array needs to have the same size
1817 * as the current one.
1819 * We may have to fill with TRUST_AUTH_TYPE_NONE
1822 p->array = talloc_realloc(mem_ctx, p->array,
1823 struct AuthenticationInformation,
1825 if (p->array == NULL) {
1826 return NT_STATUS_NO_MEMORY;
1829 while (p->count < c->count) {
1830 struct AuthenticationInformation *a =
1831 &p->array[p->count++];
1833 *a = (struct AuthenticationInformation) {
1834 .LastUpdateTime = p->array[0].LastUpdateTime,
1835 .AuthType = TRUST_AUTH_TYPE_NONE,
1840 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
1842 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
1843 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1844 return NT_STATUS_INVALID_PARAMETER;
1847 return NT_STATUS_OK;
1850 /***************************************************************************
1851 _lsa_CreateTrustedDomainEx2
1852 ***************************************************************************/
1854 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1855 struct lsa_CreateTrustedDomainEx2 *r)
1857 struct dcesrv_call_state *dce_call = p->dce_call;
1858 struct auth_session_info *session_info =
1859 dcesrv_call_session_info(dce_call);
1860 struct lsa_info *policy;
1862 uint32_t acc_granted;
1863 struct security_descriptor *psd;
1865 struct pdb_trusted_domain td;
1866 struct trustDomainPasswords auth_struct;
1867 DATA_BLOB auth_blob;
1870 return NT_STATUS_NOT_SUPPORTED;
1873 policy = find_policy_by_hnd(p,
1874 r->in.policy_handle,
1875 LSA_HANDLE_POLICY_TYPE,
1878 if (!NT_STATUS_IS_OK(status)) {
1879 return NT_STATUS_INVALID_HANDLE;
1882 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1883 return NT_STATUS_ACCESS_DENIED;
1886 if (session_info->unix_token->uid != sec_initial_uid() &&
1887 !nt_token_check_domain_rid(
1888 session_info->security_token, DOMAIN_RID_ADMINS)) {
1889 return NT_STATUS_ACCESS_DENIED;
1892 /* Work out max allowed. */
1893 map_max_allowed_access(session_info->security_token,
1894 session_info->unix_token,
1895 &r->in.access_mask);
1897 /* map the generic bits to the lsa policy ones */
1898 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1900 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1901 &lsa_trusted_domain_mapping,
1903 if (!NT_STATUS_IS_OK(status)) {
1907 status = access_check_object(psd, session_info->security_token,
1908 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1909 r->in.access_mask, &acc_granted,
1910 "_lsa_CreateTrustedDomainEx2");
1911 if (!NT_STATUS_IS_OK(status)) {
1917 td.domain_name = talloc_strdup(p->mem_ctx,
1918 r->in.info->domain_name.string);
1919 if (td.domain_name == NULL) {
1920 return NT_STATUS_NO_MEMORY;
1922 td.netbios_name = talloc_strdup(p->mem_ctx,
1923 r->in.info->netbios_name.string);
1924 if (td.netbios_name == NULL) {
1925 return NT_STATUS_NO_MEMORY;
1927 sid_copy(&td.security_identifier, r->in.info->sid);
1928 td.trust_direction = r->in.info->trust_direction;
1929 td.trust_type = r->in.info->trust_type;
1930 td.trust_attributes = r->in.info->trust_attributes;
1932 if (r->in.auth_info_internal->auth_blob.size != 0) {
1933 auth_blob.length = r->in.auth_info_internal->auth_blob.size;
1934 auth_blob.data = r->in.auth_info_internal->auth_blob.data;
1936 status = get_trustdom_auth_blob(p, p->mem_ctx, &auth_blob, &auth_struct);
1937 if (!NT_STATUS_IS_OK(status)) {
1938 return NT_STATUS_UNSUCCESSFUL;
1941 status = get_trustauth_inout_blob(p->mem_ctx, &auth_struct.incoming, &td.trust_auth_incoming);
1942 if (!NT_STATUS_IS_OK(status)) {
1943 return NT_STATUS_UNSUCCESSFUL;
1946 status = get_trustauth_inout_blob(p->mem_ctx, &auth_struct.outgoing, &td.trust_auth_outgoing);
1947 if (!NT_STATUS_IS_OK(status)) {
1948 return NT_STATUS_UNSUCCESSFUL;
1951 td.trust_auth_incoming.data = NULL;
1952 td.trust_auth_incoming.length = 0;
1953 td.trust_auth_outgoing.data = NULL;
1954 td.trust_auth_outgoing.length = 0;
1957 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1958 if (!NT_STATUS_IS_OK(status)) {
1962 status = create_lsa_policy_handle(p->mem_ctx, p,
1963 LSA_HANDLE_TRUST_TYPE,
1966 r->in.info->netbios_name.string,
1968 r->out.trustdom_handle);
1969 if (!NT_STATUS_IS_OK(status)) {
1970 pdb_del_trusted_domain(r->in.info->netbios_name.string);
1971 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1974 return NT_STATUS_OK;
1977 /***************************************************************************
1978 _lsa_CreateTrustedDomainEx
1979 ***************************************************************************/
1981 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1982 struct lsa_CreateTrustedDomainEx *r)
1984 struct lsa_CreateTrustedDomainEx2 q;
1985 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1987 ZERO_STRUCT(auth_info);
1989 q.in.policy_handle = r->in.policy_handle;
1990 q.in.info = r->in.info;
1991 q.in.auth_info_internal = &auth_info;
1992 q.in.access_mask = r->in.access_mask;
1993 q.out.trustdom_handle = r->out.trustdom_handle;
1995 return _lsa_CreateTrustedDomainEx2(p, &q);
1998 /***************************************************************************
1999 _lsa_CreateTrustedDomain
2000 ***************************************************************************/
2002 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
2003 struct lsa_CreateTrustedDomain *r)
2005 struct lsa_CreateTrustedDomainEx2 c;
2006 struct lsa_TrustDomainInfoInfoEx info;
2007 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
2009 ZERO_STRUCT(auth_info);
2011 info.domain_name = r->in.info->name;
2012 info.netbios_name = r->in.info->name;
2013 info.sid = r->in.info->sid;
2014 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
2015 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
2016 info.trust_attributes = 0;
2018 c.in.policy_handle = r->in.policy_handle;
2020 c.in.auth_info_internal = &auth_info;
2021 c.in.access_mask = r->in.access_mask;
2022 c.out.trustdom_handle = r->out.trustdom_handle;
2024 return _lsa_CreateTrustedDomainEx2(p, &c);
2027 /***************************************************************************
2028 _lsa_DeleteTrustedDomain
2029 ***************************************************************************/
2031 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
2032 struct lsa_DeleteTrustedDomain *r)
2035 struct lsa_info *handle;
2036 struct pdb_trusted_domain *td;
2038 /* find the connection policy handle. */
2039 handle = find_policy_by_hnd(p,
2041 LSA_HANDLE_POLICY_TYPE,
2044 if (!NT_STATUS_IS_OK(status)) {
2045 return NT_STATUS_INVALID_HANDLE;
2048 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
2049 return NT_STATUS_ACCESS_DENIED;
2052 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
2053 if (!NT_STATUS_IS_OK(status)) {
2057 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
2058 struct dom_sid_buf buf;
2059 DEBUG(10, ("Missing netbios name for trusted domain %s.\n",
2060 dom_sid_str_buf(r->in.dom_sid, &buf)));
2061 return NT_STATUS_UNSUCCESSFUL;
2064 status = pdb_del_trusted_domain(td->netbios_name);
2065 if (!NT_STATUS_IS_OK(status)) {
2069 return NT_STATUS_OK;
2072 /***************************************************************************
2073 _lsa_CloseTrustedDomainEx
2074 ***************************************************************************/
2076 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
2077 struct lsa_CloseTrustedDomainEx *r)
2079 return NT_STATUS_NOT_IMPLEMENTED;
2082 /***************************************************************************
2083 _lsa_QueryTrustedDomainInfo
2084 ***************************************************************************/
2086 static NTSTATUS pdb_trusted_domain_2_info_ex(TALLOC_CTX *mem_ctx,
2087 struct pdb_trusted_domain *td,
2088 struct lsa_TrustDomainInfoInfoEx *info_ex)
2090 if (td->domain_name == NULL ||
2091 td->netbios_name == NULL ||
2092 is_null_sid(&td->security_identifier)) {
2093 return NT_STATUS_INVALID_PARAMETER;
2096 info_ex->domain_name.string = talloc_strdup(mem_ctx, td->domain_name);
2097 info_ex->netbios_name.string = talloc_strdup(mem_ctx, td->netbios_name);
2098 info_ex->sid = dom_sid_dup(mem_ctx, &td->security_identifier);
2099 if (info_ex->domain_name.string == NULL ||
2100 info_ex->netbios_name.string == NULL ||
2101 info_ex->sid == NULL) {
2102 return NT_STATUS_NO_MEMORY;
2105 info_ex->trust_direction = td->trust_direction;
2106 info_ex->trust_type = td->trust_type;
2107 info_ex->trust_attributes = td->trust_attributes;
2109 return NT_STATUS_OK;
2112 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
2113 struct lsa_QueryTrustedDomainInfo *r)
2116 struct lsa_info *handle;
2117 union lsa_TrustedDomainInfo *info;
2118 struct pdb_trusted_domain *td;
2119 uint32_t acc_required;
2121 /* find the connection policy handle. */
2122 handle = find_policy_by_hnd(p,
2123 r->in.trustdom_handle,
2124 LSA_HANDLE_TRUST_TYPE,
2127 if (!NT_STATUS_IS_OK(status)) {
2128 return NT_STATUS_INVALID_HANDLE;
2131 switch (r->in.level) {
2132 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2133 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2135 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2136 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
2138 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2139 acc_required = LSA_TRUSTED_QUERY_POSIX;
2141 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2142 acc_required = LSA_TRUSTED_QUERY_AUTH;
2144 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2145 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2147 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2148 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2150 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2151 acc_required = LSA_TRUSTED_QUERY_AUTH;
2153 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2154 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2155 LSA_TRUSTED_QUERY_POSIX |
2156 LSA_TRUSTED_QUERY_AUTH;
2158 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2159 acc_required = LSA_TRUSTED_QUERY_AUTH;
2161 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2162 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2163 LSA_TRUSTED_QUERY_POSIX |
2164 LSA_TRUSTED_QUERY_AUTH;
2166 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2167 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2169 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2170 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2171 LSA_TRUSTED_QUERY_POSIX |
2172 LSA_TRUSTED_QUERY_AUTH;
2174 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2175 acc_required = LSA_TRUSTED_QUERY_POSIX;
2178 return NT_STATUS_INVALID_PARAMETER;
2181 if (!(handle->access & acc_required)) {
2182 return NT_STATUS_ACCESS_DENIED;
2185 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2186 if (!NT_STATUS_IS_OK(status)) {
2190 info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
2192 return NT_STATUS_NO_MEMORY;
2195 switch (r->in.level) {
2196 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2197 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2199 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2200 return NT_STATUS_INVALID_PARAMETER;
2201 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2202 info->posix_offset.posix_offset = *td->trust_posix_offset;
2204 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2205 return NT_STATUS_INVALID_INFO_CLASS;
2206 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2207 return NT_STATUS_INVALID_PARAMETER;
2208 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2209 status = pdb_trusted_domain_2_info_ex(info, td, &info->info_ex);
2210 if (!NT_STATUS_IS_OK(status)) {
2214 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2215 return NT_STATUS_INVALID_INFO_CLASS;
2216 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2217 status = pdb_trusted_domain_2_info_ex(info, td,
2218 &info->full_info.info_ex);
2219 if (!NT_STATUS_IS_OK(status)) {
2222 info->full_info.posix_offset.posix_offset = *td->trust_posix_offset;
2223 status = auth_blob_2_auth_info(p->mem_ctx,
2224 td->trust_auth_incoming,
2225 td->trust_auth_outgoing,
2226 &info->full_info.auth_info);
2227 if (!NT_STATUS_IS_OK(status)) {
2231 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2232 return NT_STATUS_INVALID_INFO_CLASS;
2233 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2234 return NT_STATUS_INVALID_INFO_CLASS;
2235 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2236 return NT_STATUS_INVALID_PARAMETER;
2237 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2238 info->full_info2_internal.posix_offset.posix_offset = *td->trust_posix_offset;
2239 status = auth_blob_2_auth_info(p->mem_ctx,
2240 td->trust_auth_incoming,
2241 td->trust_auth_outgoing,
2242 &info->full_info2_internal.auth_info);
2243 if (!NT_STATUS_IS_OK(status)) {
2247 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2248 info->enc_types.enc_types = *td->supported_enc_type;
2251 return NT_STATUS_INVALID_PARAMETER;
2254 *r->out.info = info;
2256 return NT_STATUS_OK;
2259 /***************************************************************************
2260 _lsa_QueryTrustedDomainInfoBySid
2261 ***************************************************************************/
2263 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2264 struct lsa_QueryTrustedDomainInfoBySid *r)
2267 struct policy_handle trustdom_handle;
2268 struct lsa_OpenTrustedDomain o;
2269 struct lsa_QueryTrustedDomainInfo q;
2272 o.in.handle = r->in.handle;
2273 o.in.sid = r->in.dom_sid;
2274 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2275 o.out.trustdom_handle = &trustdom_handle;
2277 status = _lsa_OpenTrustedDomain(p, &o);
2278 if (!NT_STATUS_IS_OK(status)) {
2282 q.in.trustdom_handle = &trustdom_handle;
2283 q.in.level = r->in.level;
2284 q.out.info = r->out.info;
2286 status = _lsa_QueryTrustedDomainInfo(p, &q);
2287 if (!NT_STATUS_IS_OK(status)) {
2291 c.in.handle = &trustdom_handle;
2292 c.out.handle = &trustdom_handle;
2294 return _lsa_Close(p, &c);
2297 /***************************************************************************
2298 _lsa_QueryTrustedDomainInfoByName
2299 ***************************************************************************/
2301 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2302 struct lsa_QueryTrustedDomainInfoByName *r)
2305 struct policy_handle trustdom_handle;
2306 struct lsa_OpenTrustedDomainByName o;
2307 struct lsa_QueryTrustedDomainInfo q;
2310 o.in.handle = r->in.handle;
2311 o.in.name.string = r->in.trusted_domain->string;
2312 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2313 o.out.trustdom_handle = &trustdom_handle;
2315 status = _lsa_OpenTrustedDomainByName(p, &o);
2316 if (!NT_STATUS_IS_OK(status)) {
2317 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2318 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2323 q.in.trustdom_handle = &trustdom_handle;
2324 q.in.level = r->in.level;
2325 q.out.info = r->out.info;
2327 status = _lsa_QueryTrustedDomainInfo(p, &q);
2328 if (!NT_STATUS_IS_OK(status)) {
2332 c.in.handle = &trustdom_handle;
2333 c.out.handle = &trustdom_handle;
2335 return _lsa_Close(p, &c);
2338 /***************************************************************************
2340 ***************************************************************************/
2342 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p,
2343 struct lsa_CreateSecret *r)
2345 struct dcesrv_call_state *dce_call = p->dce_call;
2346 struct auth_session_info *session_info =
2347 dcesrv_call_session_info(dce_call);
2349 struct lsa_info *handle;
2350 uint32_t acc_granted;
2351 struct security_descriptor *psd;
2354 /* find the connection policy handle. */
2355 handle = find_policy_by_hnd(p,
2357 LSA_HANDLE_POLICY_TYPE,
2360 if (!NT_STATUS_IS_OK(status)) {
2361 return NT_STATUS_INVALID_HANDLE;
2364 /* check if the user has enough rights */
2366 if (!(handle->access & LSA_POLICY_CREATE_SECRET)) {
2367 return NT_STATUS_ACCESS_DENIED;
2370 /* Work out max allowed. */
2371 map_max_allowed_access(session_info->security_token,
2372 session_info->unix_token,
2373 &r->in.access_mask);
2375 /* map the generic bits to the lsa policy ones */
2376 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
2378 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2379 &lsa_secret_mapping,
2381 if (!NT_STATUS_IS_OK(status)) {
2385 status = access_check_object(psd, session_info->security_token,
2386 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2388 &acc_granted, "_lsa_CreateSecret");
2389 if (!NT_STATUS_IS_OK(status)) {
2393 if (!r->in.name.string) {
2394 return NT_STATUS_INVALID_PARAMETER;
2397 if (strlen(r->in.name.string) > 128) {
2398 return NT_STATUS_NAME_TOO_LONG;
2401 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
2402 NULL, NULL, NULL, NULL, NULL);
2403 if (NT_STATUS_IS_OK(status)) {
2404 return NT_STATUS_OBJECT_NAME_COLLISION;
2407 status = pdb_set_secret(r->in.name.string, NULL, NULL, psd);
2408 if (!NT_STATUS_IS_OK(status)) {
2412 status = create_lsa_policy_handle(p->mem_ctx, p,
2413 LSA_HANDLE_SECRET_TYPE,
2419 if (!NT_STATUS_IS_OK(status)) {
2420 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2423 return NT_STATUS_OK;
2426 /***************************************************************************
2428 ***************************************************************************/
2430 NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
2431 struct lsa_SetSecret *r)
2433 struct dcesrv_call_state *dce_call = p->dce_call;
2434 struct auth_session_info *session_info =
2435 dcesrv_call_session_info(dce_call);
2437 struct lsa_info *info = NULL;
2438 DATA_BLOB blob_new, blob_old;
2439 DATA_BLOB cleartext_blob_new = data_blob_null;
2440 DATA_BLOB cleartext_blob_old = data_blob_null;
2441 DATA_BLOB *cleartext_blob_new_p = NULL;
2442 DATA_BLOB *cleartext_blob_old_p = NULL;
2443 DATA_BLOB session_key;
2445 info = find_policy_by_hnd(p,
2447 LSA_HANDLE_SECRET_TYPE,
2450 if (!NT_STATUS_IS_OK(status)) {
2451 return NT_STATUS_INVALID_HANDLE;
2454 if (!(info->access & LSA_SECRET_SET_VALUE)) {
2455 return NT_STATUS_ACCESS_DENIED;
2458 status = session_extract_session_key(
2459 session_info, &session_key, KEY_USE_16BYTES);
2460 if(!NT_STATUS_IS_OK(status)) {
2464 if (r->in.new_val) {
2465 blob_new = data_blob_const(r->in.new_val->data,
2466 r->in.new_val->length);
2468 status = sess_decrypt_blob(p->mem_ctx, &blob_new,
2470 &cleartext_blob_new);
2471 if (!NT_STATUS_IS_OK(status)) {
2475 cleartext_blob_new_p = &cleartext_blob_new;
2478 if (r->in.old_val) {
2479 blob_old = data_blob_const(r->in.old_val->data,
2480 r->in.old_val->length);
2482 status = sess_decrypt_blob(p->mem_ctx, &blob_old,
2484 &cleartext_blob_old);
2485 if (!NT_STATUS_IS_OK(status)) {
2489 cleartext_blob_old_p = &cleartext_blob_old;
2492 status = pdb_set_secret(info->name, cleartext_blob_new_p, cleartext_blob_old_p, NULL);
2493 if (!NT_STATUS_IS_OK(status)) {
2497 #ifdef DEBUG_PASSWORD
2498 DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
2499 dump_data(10, cleartext_blob_new.data, cleartext_blob_new.length);
2500 DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
2501 dump_data(10, cleartext_blob_old.data, cleartext_blob_old.length);
2504 return NT_STATUS_OK;
2507 /***************************************************************************
2509 ***************************************************************************/
2511 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
2512 struct lsa_QuerySecret *r)
2514 struct dcesrv_call_state *dce_call = p->dce_call;
2515 struct auth_session_info *session_info =
2516 dcesrv_call_session_info(dce_call);
2517 struct lsa_info *info = NULL;
2518 DATA_BLOB blob_new, blob_old;
2519 DATA_BLOB blob_new_crypt, blob_old_crypt;
2520 DATA_BLOB session_key;
2521 NTTIME nttime_new, nttime_old;
2524 info = find_policy_by_hnd(p,
2526 LSA_HANDLE_SECRET_TYPE,
2529 if (!NT_STATUS_IS_OK(status)) {
2530 return NT_STATUS_INVALID_HANDLE;
2533 if (!(info->access & LSA_SECRET_QUERY_VALUE)) {
2534 return NT_STATUS_ACCESS_DENIED;
2537 status = pdb_get_secret(p->mem_ctx, info->name,
2538 &blob_new, &nttime_new,
2539 &blob_old, &nttime_old,
2541 if (!NT_STATUS_IS_OK(status)) {
2545 status = session_extract_session_key(
2546 session_info, &session_key, KEY_USE_16BYTES);
2547 if(!NT_STATUS_IS_OK(status)) {
2551 if (r->in.new_val) {
2552 if (blob_new.length) {
2553 if (!r->out.new_val->buf) {
2554 r->out.new_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2556 if (!r->out.new_val->buf) {
2557 return NT_STATUS_NO_MEMORY;
2560 blob_new_crypt = sess_encrypt_blob(p->mem_ctx, &blob_new,
2562 if (!blob_new_crypt.length) {
2563 return NT_STATUS_NO_MEMORY;
2566 r->out.new_val->buf->data = blob_new_crypt.data;
2567 r->out.new_val->buf->length = blob_new_crypt.length;
2568 r->out.new_val->buf->size = blob_new_crypt.length;
2572 if (r->in.old_val) {
2573 if (blob_old.length) {
2574 if (!r->out.old_val->buf) {
2575 r->out.old_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2577 if (!r->out.old_val->buf) {
2578 return NT_STATUS_NO_MEMORY;
2581 blob_old_crypt = sess_encrypt_blob(p->mem_ctx, &blob_old,
2583 if (!blob_old_crypt.length) {
2584 return NT_STATUS_NO_MEMORY;
2587 r->out.old_val->buf->data = blob_old_crypt.data;
2588 r->out.old_val->buf->length = blob_old_crypt.length;
2589 r->out.old_val->buf->size = blob_old_crypt.length;
2593 if (r->out.new_mtime) {
2594 *r->out.new_mtime = nttime_new;
2597 if (r->out.old_mtime) {
2598 *r->out.old_mtime = nttime_old;
2601 return NT_STATUS_OK;
2604 /***************************************************************************
2606 ***************************************************************************/
2608 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2609 struct lsa_DeleteObject *r)
2612 struct lsa_info *info = NULL;
2614 info = find_policy_by_hnd(p,
2619 if (!NT_STATUS_IS_OK(status)) {
2620 return NT_STATUS_INVALID_HANDLE;
2623 if (!(info->access & SEC_STD_DELETE)) {
2624 return NT_STATUS_ACCESS_DENIED;
2627 switch (info->type) {
2628 case LSA_HANDLE_ACCOUNT_TYPE:
2629 status = privilege_delete_account(&info->sid);
2630 if (!NT_STATUS_IS_OK(status)) {
2631 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2632 nt_errstr(status)));
2636 case LSA_HANDLE_TRUST_TYPE:
2637 if (!pdb_del_trusteddom_pw(info->name)) {
2638 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2640 status = NT_STATUS_OK;
2642 case LSA_HANDLE_SECRET_TYPE:
2643 status = pdb_delete_secret(info->name);
2644 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2645 return NT_STATUS_INVALID_HANDLE;
2649 return NT_STATUS_INVALID_HANDLE;
2652 close_policy_hnd(p, r->in.handle);
2653 ZERO_STRUCTP(r->out.handle);
2658 /***************************************************************************
2660 ***************************************************************************/
2662 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2663 struct lsa_EnumPrivs *r)
2665 struct lsa_info *handle;
2667 uint32_t enum_context = *r->in.resume_handle;
2668 int num_privs = num_privileges_in_short_list();
2669 struct lsa_PrivEntry *entries = NULL;
2672 /* remember that the enum_context starts at 0 and not 1 */
2674 if ( enum_context >= num_privs )
2675 return NT_STATUS_NO_MORE_ENTRIES;
2677 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2678 enum_context, num_privs));
2680 handle = find_policy_by_hnd(p,
2682 LSA_HANDLE_POLICY_TYPE,
2685 if (!NT_STATUS_IS_OK(status)) {
2686 return NT_STATUS_INVALID_HANDLE;
2689 /* check if the user has enough rights
2690 I don't know if it's the right one. not documented. */
2692 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2693 return NT_STATUS_ACCESS_DENIED;
2696 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2698 return NT_STATUS_NO_MEMORY;
2704 for (i = 0; i < num_privs; i++) {
2705 if( i < enum_context) {
2707 init_lsa_StringLarge(&entries[i].name, NULL);
2709 entries[i].luid.low = 0;
2710 entries[i].luid.high = 0;
2713 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2715 entries[i].luid.low = sec_privilege_from_index(i);
2716 entries[i].luid.high = 0;
2720 enum_context = num_privs;
2722 *r->out.resume_handle = enum_context;
2723 r->out.privs->count = num_privs;
2724 r->out.privs->privs = entries;
2726 return NT_STATUS_OK;
2729 /***************************************************************************
2730 _lsa_LookupPrivDisplayName
2731 ***************************************************************************/
2733 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2734 struct lsa_LookupPrivDisplayName *r)
2736 struct lsa_info *handle;
2737 const char *description;
2738 struct lsa_StringLarge *lsa_name;
2741 handle = find_policy_by_hnd(p,
2743 LSA_HANDLE_POLICY_TYPE,
2746 if (!NT_STATUS_IS_OK(status)) {
2747 return NT_STATUS_INVALID_HANDLE;
2750 /* check if the user has enough rights */
2753 * I don't know if it's the right one. not documented.
2755 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2756 return NT_STATUS_ACCESS_DENIED;
2758 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2760 description = get_privilege_dispname(r->in.name->string);
2762 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2763 return NT_STATUS_NO_SUCH_PRIVILEGE;
2766 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2768 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2770 return NT_STATUS_NO_MEMORY;
2773 init_lsa_StringLarge(lsa_name, description);
2775 *r->out.returned_language_id = r->in.language_id;
2776 *r->out.disp_name = lsa_name;
2778 return NT_STATUS_OK;
2781 /***************************************************************************
2783 ***************************************************************************/
2785 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2786 struct lsa_EnumAccounts *r)
2788 struct lsa_info *handle;
2789 struct dom_sid *sid_list;
2790 int i, j, num_entries;
2792 struct lsa_SidPtr *sids = NULL;
2794 handle = find_policy_by_hnd(p,
2796 LSA_HANDLE_POLICY_TYPE,
2799 if (!NT_STATUS_IS_OK(status)) {
2800 return NT_STATUS_INVALID_HANDLE;
2803 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2804 return NT_STATUS_ACCESS_DENIED;
2809 /* The only way we can currently find out all the SIDs that have been
2810 privileged is to scan all privileges */
2812 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2813 if (!NT_STATUS_IS_OK(status)) {
2817 if (*r->in.resume_handle >= num_entries) {
2818 return NT_STATUS_NO_MORE_ENTRIES;
2821 if (num_entries - *r->in.resume_handle) {
2822 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2823 num_entries - *r->in.resume_handle);
2825 talloc_free(sid_list);
2826 return NT_STATUS_NO_MEMORY;
2829 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2830 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2832 talloc_free(sid_list);
2833 return NT_STATUS_NO_MEMORY;
2838 talloc_free(sid_list);
2840 *r->out.resume_handle = num_entries;
2841 r->out.sids->num_sids = num_entries;
2842 r->out.sids->sids = sids;
2844 return NT_STATUS_OK;
2847 /***************************************************************************
2849 ***************************************************************************/
2851 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2852 struct lsa_GetUserName *r)
2854 struct dcesrv_call_state *dce_call = p->dce_call;
2855 struct auth_session_info *session_info =
2856 dcesrv_call_session_info(dce_call);
2857 const char *username, *domname;
2858 struct lsa_String *account_name = NULL;
2859 struct lsa_String *authority_name = NULL;
2861 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
2862 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
2863 return NT_STATUS_ACCESS_DENIED;
2866 if (r->in.account_name &&
2867 *r->in.account_name) {
2868 return NT_STATUS_INVALID_PARAMETER;
2871 if (r->in.authority_name &&
2872 *r->in.authority_name) {
2873 return NT_STATUS_INVALID_PARAMETER;
2876 if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
2878 * I'm 99% sure this is not the right place to do this,
2879 * global_sid_Anonymous should probably be put into the token
2880 * instead of the guest id -- vl
2882 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2883 &domname, &username, NULL)) {
2884 return NT_STATUS_NO_MEMORY;
2887 username = session_info->unix_info->sanitized_username;
2888 domname = session_info->info->domain_name;
2891 account_name = talloc(p->mem_ctx, struct lsa_String);
2892 if (!account_name) {
2893 return NT_STATUS_NO_MEMORY;
2895 init_lsa_String(account_name, username);
2897 if (r->out.authority_name) {
2898 authority_name = talloc(p->mem_ctx, struct lsa_String);
2899 if (!authority_name) {
2900 return NT_STATUS_NO_MEMORY;
2902 init_lsa_String(authority_name, domname);
2905 *r->out.account_name = account_name;
2906 if (r->out.authority_name) {
2907 *r->out.authority_name = authority_name;
2910 return NT_STATUS_OK;
2913 /***************************************************************************
2915 ***************************************************************************/
2917 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2918 struct lsa_CreateAccount *r)
2920 struct dcesrv_call_state *dce_call = p->dce_call;
2921 struct auth_session_info *session_info =
2922 dcesrv_call_session_info(dce_call);
2924 struct lsa_info *handle;
2925 uint32_t acc_granted;
2926 struct security_descriptor *psd;
2928 uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
2929 ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
2930 LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2933 /* find the connection policy handle. */
2934 handle = find_policy_by_hnd(p,
2936 LSA_HANDLE_POLICY_TYPE,
2939 if (!NT_STATUS_IS_OK(status)) {
2940 return NT_STATUS_INVALID_HANDLE;
2943 /* check if the user has enough rights */
2945 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2946 return NT_STATUS_ACCESS_DENIED;
2949 /* Work out max allowed. */
2950 map_max_allowed_access(session_info->security_token,
2951 session_info->unix_token,
2952 &r->in.access_mask);
2954 /* map the generic bits to the lsa policy ones */
2955 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2957 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2958 &lsa_account_mapping,
2959 r->in.sid, owner_access);
2960 if (!NT_STATUS_IS_OK(status)) {
2964 status = access_check_object(psd, session_info->security_token,
2965 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2966 &acc_granted, "_lsa_CreateAccount");
2967 if (!NT_STATUS_IS_OK(status)) {
2971 if ( is_privileged_sid( r->in.sid ) )
2972 return NT_STATUS_OBJECT_NAME_COLLISION;
2974 status = create_lsa_policy_handle(p->mem_ctx, p,
2975 LSA_HANDLE_ACCOUNT_TYPE,
2980 r->out.acct_handle);
2981 if (!NT_STATUS_IS_OK(status)) {
2982 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2985 return privilege_create_account(r->in.sid);
2988 /***************************************************************************
2990 ***************************************************************************/
2992 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2993 struct lsa_OpenAccount *r)
2995 struct dcesrv_call_state *dce_call = p->dce_call;
2996 struct auth_session_info *session_info =
2997 dcesrv_call_session_info(dce_call);
2998 struct security_descriptor *psd = NULL;
3000 uint32_t des_access = r->in.access_mask;
3001 uint32_t acc_granted;
3002 uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
3003 ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
3004 LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3008 /* find the connection policy handle. */
3009 (void)find_policy_by_hnd(p,
3011 LSA_HANDLE_POLICY_TYPE,
3014 if (!NT_STATUS_IS_OK(status)) {
3015 return NT_STATUS_INVALID_HANDLE;
3018 /* des_access is for the account here, not the policy
3019 * handle - so don't check against policy handle. */
3021 /* Work out max allowed. */
3022 map_max_allowed_access(session_info->security_token,
3023 session_info->unix_token,
3026 /* map the generic bits to the lsa account ones */
3027 se_map_generic(&des_access, &lsa_account_mapping);
3029 /* get the generic lsa account SD until we store it */
3030 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3031 &lsa_account_mapping,
3032 r->in.sid, owner_access);
3033 if (!NT_STATUS_IS_OK(status)) {
3037 status = access_check_object(psd, session_info->security_token,
3038 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
3039 &acc_granted, "_lsa_OpenAccount" );
3040 if (!NT_STATUS_IS_OK(status)) {
3044 /* TODO: Fis the parsing routine before reenabling this check! */
3046 if (!lookup_sid(&handle->sid, dom_name, name, &type))
3047 return NT_STATUS_ACCESS_DENIED;
3050 status = create_lsa_policy_handle(p->mem_ctx, p,
3051 LSA_HANDLE_ACCOUNT_TYPE,
3056 r->out.acct_handle);
3057 if (!NT_STATUS_IS_OK(status)) {
3058 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3061 return NT_STATUS_OK;
3064 /***************************************************************************
3065 _lsa_EnumPrivsAccount
3066 For a given SID, enumerate all the privilege this account has.
3067 ***************************************************************************/
3069 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
3070 struct lsa_EnumPrivsAccount *r)
3072 NTSTATUS status = NT_STATUS_OK;
3073 struct lsa_info *info=NULL;
3074 PRIVILEGE_SET *privileges;
3075 struct lsa_PrivilegeSet *priv_set = NULL;
3076 struct dom_sid_buf buf;
3078 /* find the connection policy handle. */
3079 info = find_policy_by_hnd(p,
3081 LSA_HANDLE_ACCOUNT_TYPE,
3084 if (!NT_STATUS_IS_OK(status)) {
3085 return NT_STATUS_INVALID_HANDLE;
3088 if (!(info->access & LSA_ACCOUNT_VIEW))
3089 return NT_STATUS_ACCESS_DENIED;
3091 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
3092 if (!NT_STATUS_IS_OK(status)) {
3096 *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
3098 return NT_STATUS_NO_MEMORY;
3101 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
3102 dom_sid_str_buf(&info->sid, &buf),
3103 privileges->count));
3105 priv_set->count = privileges->count;
3106 priv_set->unknown = 0;
3107 priv_set->set = talloc_move(priv_set, &privileges->set);
3112 /***************************************************************************
3113 _lsa_GetSystemAccessAccount
3114 ***************************************************************************/
3116 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
3117 struct lsa_GetSystemAccessAccount *r)
3120 struct lsa_info *info = NULL;
3121 struct lsa_EnumPrivsAccount e;
3122 struct lsa_PrivilegeSet *privset;
3124 /* find the connection policy handle. */
3126 info = find_policy_by_hnd(p,
3128 LSA_HANDLE_ACCOUNT_TYPE,
3131 if (!NT_STATUS_IS_OK(status)) {
3132 return NT_STATUS_INVALID_HANDLE;
3135 if (!(info->access & LSA_ACCOUNT_VIEW))
3136 return NT_STATUS_ACCESS_DENIED;
3138 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
3140 return NT_STATUS_NO_MEMORY;
3143 e.in.handle = r->in.handle;
3144 e.out.privs = &privset;
3146 status = _lsa_EnumPrivsAccount(p, &e);
3147 if (!NT_STATUS_IS_OK(status)) {
3148 DEBUG(10,("_lsa_GetSystemAccessAccount: "
3149 "failed to call _lsa_EnumPrivsAccount(): %s\n",
3150 nt_errstr(status)));
3154 /* Samba4 would iterate over the privset to merge the policy mode bits,
3155 * not sure samba3 can do the same here, so just return what we did in
3159 0x01 -> Log on locally
3160 0x02 -> Access this computer from network
3161 0x04 -> Log on as a batch job
3162 0x10 -> Log on as a service
3164 they can be ORed together
3167 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
3168 LSA_POLICY_MODE_NETWORK;
3170 return NT_STATUS_OK;
3173 /***************************************************************************
3174 update the systemaccount information
3175 ***************************************************************************/
3177 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
3178 struct lsa_SetSystemAccessAccount *r)
3180 struct lsa_info *info=NULL;
3184 /* find the connection policy handle. */
3185 info = find_policy_by_hnd(p,
3187 LSA_HANDLE_ACCOUNT_TYPE,
3190 if (!NT_STATUS_IS_OK(status)) {
3191 return NT_STATUS_INVALID_HANDLE;
3194 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
3195 return NT_STATUS_ACCESS_DENIED;
3198 map = talloc_zero(p->mem_ctx, GROUP_MAP);
3200 return NT_STATUS_NO_MEMORY;
3203 if (!pdb_getgrsid(map, info->sid)) {
3205 return NT_STATUS_NO_SUCH_GROUP;
3208 status = pdb_update_group_mapping_entry(map);
3213 /***************************************************************************
3214 _lsa_AddPrivilegesToAccount
3215 For a given SID, add some privileges.
3216 ***************************************************************************/
3218 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
3219 struct lsa_AddPrivilegesToAccount *r)
3221 struct lsa_info *info = NULL;
3222 struct lsa_PrivilegeSet *set = NULL;
3225 /* find the connection policy handle. */
3226 info = find_policy_by_hnd(p,
3228 LSA_HANDLE_ACCOUNT_TYPE,
3231 if (!NT_STATUS_IS_OK(status)) {
3232 return NT_STATUS_INVALID_HANDLE;
3235 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3236 return NT_STATUS_ACCESS_DENIED;
3241 if ( !grant_privilege_set( &info->sid, set ) ) {
3242 struct dom_sid_buf buf;
3243 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
3244 dom_sid_str_buf(&info->sid, &buf)));
3245 return NT_STATUS_NO_SUCH_PRIVILEGE;
3248 return NT_STATUS_OK;
3251 /***************************************************************************
3252 _lsa_RemovePrivilegesFromAccount
3253 For a given SID, remove some privileges.
3254 ***************************************************************************/
3256 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
3257 struct lsa_RemovePrivilegesFromAccount *r)
3259 struct lsa_info *info = NULL;
3260 struct lsa_PrivilegeSet *set = NULL;
3263 /* find the connection policy handle. */
3264 info = find_policy_by_hnd(p,
3266 LSA_HANDLE_ACCOUNT_TYPE,
3269 if (!NT_STATUS_IS_OK(status)) {
3270 return NT_STATUS_INVALID_HANDLE;
3273 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3274 return NT_STATUS_ACCESS_DENIED;
3279 if ( !revoke_privilege_set( &info->sid, set) ) {
3280 struct dom_sid_buf buf;
3281 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
3282 dom_sid_str_buf(&info->sid, &buf)));
3283 return NT_STATUS_NO_SUCH_PRIVILEGE;
3286 return NT_STATUS_OK;
3289 /***************************************************************************
3291 ***************************************************************************/
3293 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
3294 struct lsa_LookupPrivName *r)
3296 struct lsa_info *info = NULL;
3298 struct lsa_StringLarge *lsa_name;
3301 /* find the connection policy handle. */
3302 info = find_policy_by_hnd(p,
3304 LSA_HANDLE_POLICY_TYPE,
3307 if (!NT_STATUS_IS_OK(status)) {
3308 return NT_STATUS_INVALID_HANDLE;
3311 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
3312 return NT_STATUS_ACCESS_DENIED;
3315 if (r->in.luid->high != 0) {
3316 return NT_STATUS_NO_SUCH_PRIVILEGE;
3319 name = sec_privilege_name(r->in.luid->low);
3321 return NT_STATUS_NO_SUCH_PRIVILEGE;
3324 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
3326 return NT_STATUS_NO_MEMORY;
3329 lsa_name->string = talloc_strdup(lsa_name, name);
3330 if (!lsa_name->string) {
3331 TALLOC_FREE(lsa_name);
3332 return NT_STATUS_NO_MEMORY;
3335 *r->out.name = lsa_name;
3337 return NT_STATUS_OK;
3340 /***************************************************************************
3342 ***************************************************************************/
3344 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
3345 struct lsa_QuerySecurity *r)
3347 struct lsa_info *handle=NULL;
3348 struct security_descriptor *psd = NULL;
3352 /* find the connection policy handle. */
3353 handle = find_policy_by_hnd(p,
3358 if (!NT_STATUS_IS_OK(status)) {
3359 return NT_STATUS_INVALID_HANDLE;
3362 switch (handle->type) {
3363 case LSA_HANDLE_POLICY_TYPE:
3364 case LSA_HANDLE_ACCOUNT_TYPE:
3365 case LSA_HANDLE_TRUST_TYPE:
3366 case LSA_HANDLE_SECRET_TYPE:
3368 sd_size = ndr_size_security_descriptor(psd, 0);
3369 status = NT_STATUS_OK;
3372 status = NT_STATUS_INVALID_HANDLE;
3376 if (!NT_STATUS_IS_OK(status)) {
3380 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
3381 if (!*r->out.sdbuf) {
3382 return NT_STATUS_NO_MEMORY;
3388 /***************************************************************************
3389 _lsa_AddAccountRights
3390 ***************************************************************************/
3392 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
3393 struct lsa_AddAccountRights *r)
3395 struct dcesrv_call_state *dce_call = p->dce_call;
3396 struct auth_session_info *session_info =
3397 dcesrv_call_session_info(dce_call);
3399 uint32_t acc_granted = 0;
3400 struct security_descriptor *psd = NULL;
3405 /* find the connection policy handle. */
3406 (void)find_policy_by_hnd(p,
3408 LSA_HANDLE_POLICY_TYPE,
3411 if (!NT_STATUS_IS_OK(status)) {
3412 return NT_STATUS_INVALID_HANDLE;
3415 /* get the generic lsa account SD for this SID until we store it */
3416 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3417 &lsa_account_mapping,
3419 if (!NT_STATUS_IS_OK(status)) {
3424 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3425 * on the policy handle. If it does, ask for
3426 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3427 * on the account sid. We don't check here so just use the latter. JRA.
3430 status = access_check_object(psd, session_info->security_token,
3431 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3432 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3433 &acc_granted, "_lsa_AddAccountRights" );
3434 if (!NT_STATUS_IS_OK(status)) {
3438 /* according to an NT4 PDC, you can add privileges to SIDs even without
3439 call_lsa_create_account() first. And you can use any arbitrary SID. */
3441 sid_copy( &sid, r->in.sid );
3443 for ( i=0; i < r->in.rights->count; i++ ) {
3445 const char *privname = r->in.rights->names[i].string;
3447 /* only try to add non-null strings */
3452 if ( !grant_privilege_by_name( &sid, privname ) ) {
3453 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3455 return NT_STATUS_NO_SUCH_PRIVILEGE;
3459 return NT_STATUS_OK;
3462 /***************************************************************************
3463 _lsa_RemoveAccountRights
3464 ***************************************************************************/
3466 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
3467 struct lsa_RemoveAccountRights *r)
3469 struct dcesrv_call_state *dce_call = p->dce_call;
3470 struct auth_session_info *session_info =
3471 dcesrv_call_session_info(dce_call);
3473 struct security_descriptor *psd = NULL;
3476 const char *privname = NULL;
3477 uint32_t acc_granted = 0;
3480 /* find the connection policy handle. */
3481 (void)find_policy_by_hnd(p,
3483 LSA_HANDLE_POLICY_TYPE,
3486 if (!NT_STATUS_IS_OK(status)) {
3487 return NT_STATUS_INVALID_HANDLE;
3490 /* get the generic lsa account SD for this SID until we store it */
3491 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3492 &lsa_account_mapping,
3494 if (!NT_STATUS_IS_OK(status)) {
3499 * From the MS DOCs. We need
3500 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3501 * and DELETE on the account sid.
3504 status = access_check_object(psd, session_info->security_token,
3505 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3506 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3507 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
3508 &acc_granted, "_lsa_RemoveAccountRights");
3509 if (!NT_STATUS_IS_OK(status)) {
3513 sid_copy( &sid, r->in.sid );
3515 if ( r->in.remove_all ) {
3516 if ( !revoke_all_privileges( &sid ) )
3517 return NT_STATUS_ACCESS_DENIED;
3519 return NT_STATUS_OK;
3522 for ( i=0; i < r->in.rights->count; i++ ) {
3524 privname = r->in.rights->names[i].string;
3526 /* only try to add non-null strings */
3531 if ( !revoke_privilege_by_name( &sid, privname ) ) {
3532 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3534 return NT_STATUS_NO_SUCH_PRIVILEGE;
3538 return NT_STATUS_OK;
3541 /*******************************************************************
3542 ********************************************************************/
3544 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3545 struct lsa_RightSet *r,
3546 PRIVILEGE_SET *privileges)
3549 const char *privname;
3550 const char **privname_array = NULL;
3551 size_t num_priv = 0;
3553 for (i=0; i<privileges->count; i++) {
3554 if (privileges->set[i].luid.high) {
3557 privname = sec_privilege_name(privileges->set[i].luid.low);
3559 if (!add_string_to_array(mem_ctx, privname,
3560 &privname_array, &num_priv)) {
3561 return NT_STATUS_NO_MEMORY;
3568 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3571 return NT_STATUS_NO_MEMORY;
3574 for (i=0; i<num_priv; i++) {
3575 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3578 r->count = num_priv;
3581 return NT_STATUS_OK;
3584 /***************************************************************************
3585 _lsa_EnumAccountRights
3586 ***************************************************************************/
3588 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3589 struct lsa_EnumAccountRights *r)
3592 struct lsa_info *info = NULL;
3593 PRIVILEGE_SET *privileges;
3594 struct dom_sid_buf buf;
3596 /* find the connection policy handle. */
3598 info = find_policy_by_hnd(p,
3600 LSA_HANDLE_POLICY_TYPE,
3603 if (!NT_STATUS_IS_OK(status)) {
3604 return NT_STATUS_INVALID_HANDLE;
3607 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3608 return NT_STATUS_ACCESS_DENIED;
3611 /* according to an NT4 PDC, you can add privileges to SIDs even without
3612 call_lsa_create_account() first. And you can use any arbitrary SID. */
3614 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3615 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3616 * the lsa database */
3618 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3619 if (!NT_STATUS_IS_OK(status)) {
3623 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3624 dom_sid_str_buf(r->in.sid, &buf),
3625 privileges->count));
3627 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3632 /***************************************************************************
3633 _lsa_LookupPrivValue
3634 ***************************************************************************/
3636 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3637 struct lsa_LookupPrivValue *r)
3639 struct lsa_info *info = NULL;
3640 const char *name = NULL;
3643 /* find the connection policy handle. */
3645 info = find_policy_by_hnd(p,
3647 LSA_HANDLE_POLICY_TYPE,
3650 if (!NT_STATUS_IS_OK(status)) {
3651 return NT_STATUS_INVALID_HANDLE;
3654 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3655 return NT_STATUS_ACCESS_DENIED;
3657 name = r->in.name->string;
3659 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3661 r->out.luid->low = sec_privilege_id(name);
3662 r->out.luid->high = 0;
3663 if (r->out.luid->low == SEC_PRIV_INVALID) {
3664 return NT_STATUS_NO_SUCH_PRIVILEGE;
3666 return NT_STATUS_OK;
3669 /***************************************************************************
3670 _lsa_EnumAccountsWithUserRight
3671 ***************************************************************************/
3673 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3674 struct lsa_EnumAccountsWithUserRight *r)
3677 struct lsa_info *info = NULL;
3678 struct dom_sid *sids = NULL;
3681 enum sec_privilege privilege;
3683 info = find_policy_by_hnd(p,
3685 LSA_HANDLE_POLICY_TYPE,
3688 if (!NT_STATUS_IS_OK(status)) {
3689 return NT_STATUS_INVALID_HANDLE;
3692 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3693 return NT_STATUS_ACCESS_DENIED;
3696 if (!r->in.name || !r->in.name->string) {
3697 return NT_STATUS_NO_SUCH_PRIVILEGE;
3700 privilege = sec_privilege_id(r->in.name->string);
3701 if (privilege == SEC_PRIV_INVALID) {
3702 return NT_STATUS_NO_SUCH_PRIVILEGE;
3705 status = privilege_enum_sids(privilege, p->mem_ctx,
3707 if (!NT_STATUS_IS_OK(status)) {
3711 r->out.sids->num_sids = num_sids;
3712 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3713 r->out.sids->num_sids);
3715 for (i=0; i < r->out.sids->num_sids; i++) {
3716 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3718 if (!r->out.sids->sids[i].sid) {
3719 TALLOC_FREE(r->out.sids->sids);
3720 r->out.sids->num_sids = 0;
3721 return NT_STATUS_NO_MEMORY;
3725 return NT_STATUS_OK;
3728 /***************************************************************************
3730 ***************************************************************************/
3732 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3733 struct lsa_Delete *r)
3735 return NT_STATUS_NOT_SUPPORTED;
3738 static NTSTATUS info_ex_2_pdb_trusted_domain(
3739 struct lsa_TrustDomainInfoInfoEx *info_ex,
3740 struct pdb_trusted_domain *td)
3742 if (info_ex->domain_name.string == NULL ||
3743 info_ex->netbios_name.string == NULL ||
3744 info_ex->sid == NULL) {
3745 return NT_STATUS_INVALID_PARAMETER;
3748 td->domain_name = talloc_strdup(td, info_ex->domain_name.string);
3749 td->netbios_name = talloc_strdup(td, info_ex->netbios_name.string);
3750 sid_copy(&td->security_identifier, info_ex->sid);
3751 if (td->domain_name == NULL ||
3752 td->netbios_name == NULL ||
3753 is_null_sid(&td->security_identifier)) {
3754 return NT_STATUS_NO_MEMORY;
3756 td->trust_direction = info_ex->trust_direction;
3757 td->trust_type = info_ex->trust_type;
3758 td->trust_attributes = info_ex->trust_attributes;
3760 return NT_STATUS_OK;
3763 static NTSTATUS setInfoTrustedDomain_base(struct pipes_struct *p,
3764 TALLOC_CTX *mem_ctx,
3765 struct lsa_info *policy,
3766 enum lsa_TrustDomInfoEnum level,
3767 union lsa_TrustedDomainInfo *info)
3769 struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
3770 DATA_BLOB auth_blob;
3771 struct trustDomainPasswords auth_struct;
3774 struct pdb_trusted_domain *td;
3775 struct pdb_trusted_domain *orig_td;
3777 td = talloc_zero(mem_ctx, struct pdb_trusted_domain);
3779 return NT_STATUS_NO_MEMORY;
3783 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
3784 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3785 return NT_STATUS_ACCESS_DENIED;
3787 td->trust_posix_offset = &info->posix_offset.posix_offset;
3789 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
3790 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3791 return NT_STATUS_ACCESS_DENIED;
3793 nt_status = info_ex_2_pdb_trusted_domain(&info->info_ex, td);
3794 if (!NT_STATUS_IS_OK(nt_status)) {
3798 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
3799 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3800 return NT_STATUS_ACCESS_DENIED;
3802 nt_status = auth_info_2_auth_blob(td, &info->auth_info,
3803 &td->trust_auth_incoming,
3804 &td->trust_auth_outgoing);
3805 if (!NT_STATUS_IS_OK(nt_status)) {
3809 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
3810 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3811 return NT_STATUS_ACCESS_DENIED;
3813 td->trust_posix_offset = &info->full_info.posix_offset.posix_offset;
3814 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info.info_ex,
3816 if (!NT_STATUS_IS_OK(nt_status)) {
3819 nt_status = auth_info_2_auth_blob(td,
3820 &info->full_info.auth_info,
3821 &td->trust_auth_incoming,
3822 &td->trust_auth_outgoing);
3823 if (!NT_STATUS_IS_OK(nt_status)) {
3827 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
3828 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3829 return NT_STATUS_ACCESS_DENIED;
3831 auth_info_int = &info->auth_info_internal;
3833 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
3834 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3835 return NT_STATUS_ACCESS_DENIED;
3837 td->trust_posix_offset = &info->full_info_internal.posix_offset.posix_offset;
3838 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info_internal.info_ex,
3840 if (!NT_STATUS_IS_OK(nt_status)) {
3843 auth_info_int = &info->full_info_internal.auth_info;
3845 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
3846 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3847 return NT_STATUS_ACCESS_DENIED;
3849 td->supported_enc_type = &info->enc_types.enc_types;
3852 return NT_STATUS_INVALID_PARAMETER;
3855 /* decode auth_info_int if set */
3856 if (auth_info_int) {
3858 /* now decrypt blob */
3859 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
3860 auth_info_int->auth_blob.size);
3862 nt_status = get_trustdom_auth_blob(p, mem_ctx,
3863 &auth_blob, &auth_struct);
3864 if (!NT_STATUS_IS_OK(nt_status)) {
3868 memset(&auth_struct, 0, sizeof(auth_struct));
3871 /* TODO: verify only one object matches the dns/netbios/sid triplet and that
3872 * this is the one we already have */
3874 /* TODO: check if the trust direction is changed and we need to add or remove
3877 /* TODO: check if trust type shall be changed and return an error in this case
3879 nt_status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &policy->sid,
3881 if (!NT_STATUS_IS_OK(nt_status)) {
3886 /* TODO: should we fetch previous values from the existing entry
3887 * and append them ? */
3888 if (auth_struct.incoming.count) {
3889 nt_status = get_trustauth_inout_blob(mem_ctx,
3890 &auth_struct.incoming,
3891 &td->trust_auth_incoming);
3892 if (!NT_STATUS_IS_OK(nt_status)) {
3896 ZERO_STRUCT(td->trust_auth_incoming);
3899 if (auth_struct.outgoing.count) {
3900 nt_status = get_trustauth_inout_blob(mem_ctx,
3901 &auth_struct.outgoing,
3902 &td->trust_auth_outgoing);
3903 if (!NT_STATUS_IS_OK(nt_status)) {
3907 ZERO_STRUCT(td->trust_auth_outgoing);
3910 nt_status = pdb_set_trusted_domain(orig_td->domain_name, td);
3911 if (!NT_STATUS_IS_OK(nt_status)) {
3915 return NT_STATUS_OK;
3918 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3919 struct lsa_SetTrustedDomainInfo *r)
3922 struct policy_handle trustdom_handle;
3923 struct lsa_OpenTrustedDomain o;
3924 struct lsa_SetInformationTrustedDomain s;
3927 o.in.handle = r->in.handle;
3928 o.in.sid = r->in.dom_sid;
3929 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3930 o.out.trustdom_handle = &trustdom_handle;
3932 status = _lsa_OpenTrustedDomain(p, &o);
3933 if (!NT_STATUS_IS_OK(status)) {
3937 s.in.trustdom_handle = &trustdom_handle;
3938 s.in.level = r->in.level;
3939 s.in.info = r->in.info;
3941 status = _lsa_SetInformationTrustedDomain(p, &s);
3942 if (!NT_STATUS_IS_OK(status)) {
3946 c.in.handle = &trustdom_handle;
3947 c.out.handle = &trustdom_handle;
3949 return _lsa_Close(p, &c);
3952 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3953 struct lsa_SetTrustedDomainInfoByName *r)
3956 struct policy_handle trustdom_handle;
3957 struct lsa_OpenTrustedDomainByName o;
3958 struct lsa_SetInformationTrustedDomain s;
3961 o.in.handle = r->in.handle;
3962 o.in.name.string = r->in.trusted_domain->string;
3963 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3964 o.out.trustdom_handle = &trustdom_handle;
3966 status = _lsa_OpenTrustedDomainByName(p, &o);
3967 if (!NT_STATUS_IS_OK(status)) {
3968 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
3969 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3974 s.in.trustdom_handle = &trustdom_handle;
3975 s.in.level = r->in.level;
3976 s.in.info = r->in.info;
3978 status = _lsa_SetInformationTrustedDomain(p, &s);
3979 if (!NT_STATUS_IS_OK(status)) {
3983 c.in.handle = &trustdom_handle;
3984 c.out.handle = &trustdom_handle;
3986 return _lsa_Close(p, &c);
3989 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3990 struct lsa_SetInformationTrustedDomain *r)
3992 struct lsa_info *policy;
3995 policy = find_policy_by_hnd(p,
3996 r->in.trustdom_handle,
3997 LSA_HANDLE_TRUST_TYPE,
4000 if (!NT_STATUS_IS_OK(status)) {
4001 return NT_STATUS_INVALID_HANDLE;
4004 return setInfoTrustedDomain_base(p, p->mem_ctx, policy,
4005 r->in.level, r->in.info);
4010 * From here on the server routines are just dummy ones to make smbd link with
4011 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
4012 * pulling the server stubs across one by one.
4015 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
4017 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4018 return NT_STATUS_NOT_IMPLEMENTED;
4021 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
4022 struct lsa_ChangePassword *r)
4024 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4025 return NT_STATUS_NOT_IMPLEMENTED;
4028 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
4030 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4031 return NT_STATUS_NOT_IMPLEMENTED;
4034 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
4036 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4037 return NT_STATUS_NOT_IMPLEMENTED;
4040 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
4041 struct lsa_GetQuotasForAccount *r)
4043 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4044 return NT_STATUS_NOT_IMPLEMENTED;
4047 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
4048 struct lsa_SetQuotasForAccount *r)
4050 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4051 return NT_STATUS_NOT_IMPLEMENTED;
4054 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
4055 struct lsa_StorePrivateData *r)
4057 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4058 return NT_STATUS_NOT_IMPLEMENTED;
4061 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
4062 struct lsa_RetrievePrivateData *r)
4064 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4065 return NT_STATUS_NOT_IMPLEMENTED;
4068 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
4069 struct lsa_SetInfoPolicy2 *r)
4071 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4072 return NT_STATUS_NOT_IMPLEMENTED;
4075 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
4076 struct lsa_EnumTrustedDomainsEx *r)
4078 struct lsa_info *info;
4080 struct pdb_trusted_domain **domains;
4081 struct lsa_TrustDomainInfoInfoEx *entries;
4085 /* bail out early if pdb backend is not capable of ex trusted domains,
4086 * if we don't do that, the client might not call
4087 * _lsa_EnumTrustedDomains() afterwards - gd */
4089 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
4090 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4091 return NT_STATUS_NOT_IMPLEMENTED;
4094 info = find_policy_by_hnd(p,
4096 LSA_HANDLE_POLICY_TYPE,
4099 if (!NT_STATUS_IS_OK(nt_status)) {
4100 return NT_STATUS_INVALID_HANDLE;
4103 /* check if the user has enough rights */
4104 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
4105 return NT_STATUS_ACCESS_DENIED;
4108 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
4111 if (!NT_STATUS_IS_OK(nt_status)) {
4115 entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
4118 return NT_STATUS_NO_MEMORY;
4121 for (i=0; i<count; i++) {
4122 init_lsa_StringLarge(&entries[i].domain_name,
4123 domains[i]->domain_name);
4124 init_lsa_StringLarge(&entries[i].netbios_name,
4125 domains[i]->netbios_name);
4126 entries[i].sid = &domains[i]->security_identifier;
4127 entries[i].trust_direction = domains[i]->trust_direction;
4128 entries[i].trust_type = domains[i]->trust_type;
4129 entries[i].trust_attributes = domains[i]->trust_attributes;
4132 if (*r->in.resume_handle >= count) {
4133 *r->out.resume_handle = -1;
4134 TALLOC_FREE(entries);
4135 return NT_STATUS_NO_MORE_ENTRIES;
4138 /* return the rest, limit by max_size. Note that we
4139 use the w2k3 element size value of 60 */
4140 r->out.domains->count = count - *r->in.resume_handle;
4141 r->out.domains->count = MIN(r->out.domains->count,
4142 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
4144 r->out.domains->domains = entries + *r->in.resume_handle;
4146 if (r->out.domains->count < count - *r->in.resume_handle) {
4147 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
4148 return STATUS_MORE_ENTRIES;
4151 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
4152 * always be larger than the previous input resume handle, in
4153 * particular when hitting the last query it is vital to set the
4154 * resume handle correctly to avoid infinite client loops, as
4155 * seen e.g. with Windows XP SP3 when resume handle is 0 and
4156 * status is NT_STATUS_OK - gd */
4158 *r->out.resume_handle = (uint32_t)-1;
4160 return NT_STATUS_OK;
4163 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
4164 struct lsa_QueryDomainInformationPolicy *r)
4166 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4167 return NT_STATUS_NOT_IMPLEMENTED;
4170 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
4171 struct lsa_SetDomainInformationPolicy *r)
4173 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4174 return NT_STATUS_NOT_IMPLEMENTED;
4177 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
4179 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4180 return NT_STATUS_NOT_IMPLEMENTED;
4183 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
4185 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4186 return NT_STATUS_NOT_IMPLEMENTED;
4189 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
4191 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4192 return NT_STATUS_NOT_IMPLEMENTED;
4195 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
4197 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4198 return NT_STATUS_NOT_IMPLEMENTED;
4201 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
4202 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
4204 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4205 return NT_STATUS_NOT_IMPLEMENTED;
4208 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
4209 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
4211 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4212 return NT_STATUS_NOT_IMPLEMENTED;
4215 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
4217 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4218 return NT_STATUS_NOT_IMPLEMENTED;
4221 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
4222 struct lsa_CREDRGETTARGETINFO *r)
4224 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4225 return NT_STATUS_NOT_IMPLEMENTED;
4228 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
4229 struct lsa_CREDRPROFILELOADED *r)
4231 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4232 return NT_STATUS_NOT_IMPLEMENTED;
4235 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
4236 struct lsa_CREDRGETSESSIONTYPES *r)
4238 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4239 return NT_STATUS_NOT_IMPLEMENTED;
4242 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
4243 struct lsa_LSARREGISTERAUDITEVENT *r)
4245 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4246 return NT_STATUS_NOT_IMPLEMENTED;
4249 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
4250 struct lsa_LSARGENAUDITEVENT *r)
4252 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4253 return NT_STATUS_NOT_IMPLEMENTED;
4256 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
4257 struct lsa_LSARUNREGISTERAUDITEVENT *r)
4259 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4260 return NT_STATUS_NOT_IMPLEMENTED;
4263 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
4264 struct lsa_lsaRQueryForestTrustInformation *r)
4266 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4267 return NT_STATUS_NOT_IMPLEMENTED;
4270 #define DNS_CMP_MATCH 0
4271 #define DNS_CMP_FIRST_IS_CHILD 1
4272 #define DNS_CMP_SECOND_IS_CHILD 2
4273 #define DNS_CMP_NO_MATCH 3
4275 /* this function assumes names are well formed DNS names.
4276 * it doesn't validate them */
4277 static int dns_cmp(const char *s1, size_t l1,
4278 const char *s2, size_t l2)
4280 const char *p1, *p2;
4285 if (strcasecmp_m(s1, s2) == 0) {
4286 return DNS_CMP_MATCH;
4288 return DNS_CMP_NO_MATCH;
4296 cret = DNS_CMP_FIRST_IS_CHILD;
4302 cret = DNS_CMP_SECOND_IS_CHILD;
4305 if (p1[t1 - t2 - 1] != '.') {
4306 return DNS_CMP_NO_MATCH;
4309 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
4313 return DNS_CMP_NO_MATCH;
4316 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
4317 struct lsa_ForestTrustInformation *lfti,
4318 struct ForestTrustInfo *fti)
4320 struct lsa_ForestTrustRecord *lrec;
4321 struct ForestTrustInfoRecord *rec;
4322 struct lsa_StringLarge *tln;
4323 struct lsa_ForestTrustDomainInfo *info;
4327 fti->count = lfti->count;
4328 fti->records = talloc_array(mem_ctx,
4329 struct ForestTrustInfoRecordArmor,
4331 if (!fti->records) {
4332 return NT_STATUS_NO_MEMORY;
4334 for (i = 0; i < fti->count; i++) {
4335 lrec = lfti->entries[i];
4336 rec = &fti->records[i].record;
4338 rec->flags = lrec->flags;
4339 rec->timestamp = lrec->time;
4340 rec->type = (enum ForestTrustInfoRecordType)lrec->type;
4342 switch (lrec->type) {
4343 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
4344 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4345 tln = &lrec->forest_trust_data.top_level_name;
4346 rec->data.name.string =
4347 talloc_strdup(mem_ctx, tln->string);
4348 if (!rec->data.name.string) {
4349 return NT_STATUS_NO_MEMORY;
4351 rec->data.name.size = strlen(rec->data.name.string);
4353 case LSA_FOREST_TRUST_DOMAIN_INFO:
4354 info = &lrec->forest_trust_data.domain_info;
4355 rec->data.info.sid = *info->domain_sid;
4356 rec->data.info.dns_name.string =
4357 talloc_strdup(mem_ctx,
4358 info->dns_domain_name.string);
4359 if (!rec->data.info.dns_name.string) {
4360 return NT_STATUS_NO_MEMORY;
4362 rec->data.info.dns_name.size =
4363 strlen(rec->data.info.dns_name.string);
4364 rec->data.info.netbios_name.string =
4365 talloc_strdup(mem_ctx,
4366 info->netbios_domain_name.string);
4367 if (!rec->data.info.netbios_name.string) {
4368 return NT_STATUS_NO_MEMORY;
4370 rec->data.info.netbios_name.size =
4371 strlen(rec->data.info.netbios_name.string);
4374 return NT_STATUS_INVALID_DOMAIN_STATE;
4378 return NT_STATUS_OK;
4381 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4382 uint32_t index, uint32_t collision_type,
4383 uint32_t conflict_type, const char *tdo_name);
4385 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
4386 const char *tdo_name,
4387 struct ForestTrustInfo *tdo_fti,
4388 struct ForestTrustInfo *new_fti,
4389 struct lsa_ForestTrustCollisionInfo *c_info)
4391 struct ForestTrustInfoRecord *nrec;
4392 struct ForestTrustInfoRecord *trec;
4393 const char *dns_name;
4394 const char *nb_name = NULL;
4395 struct dom_sid *sid = NULL;
4396 const char *tname = NULL;
4399 uint32_t new_fti_idx;
4401 /* use always TDO type, until we understand when Xref can be used */
4402 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;