2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Jeremy Allison 2001, 2006.
8 * Copyright (C) Rafal Szczesniak 2002,
9 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
10 * Copyright (C) Simo Sorce 2003.
11 * Copyright (C) Gerald (Jerry) Carter 2005.
12 * Copyright (C) Volker Lendecke 2005.
13 * Copyright (C) Guenther Deschner 2008.
14 * Copyright (C) Andrew Bartlett 2010.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
30 /* This is the implementation of the lsa server code. */
34 #include "../librpc/gen_ndr/srv_lsa.h"
36 #include "../librpc/gen_ndr/netlogon.h"
37 #include "rpc_client/init_lsa.h"
38 #include "../libcli/security/security.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../librpc/gen_ndr/drsblobs.h"
41 #include "../librpc/gen_ndr/ndr_drsblobs.h"
42 #include "../lib/crypto/arcfour.h"
43 #include "../libcli/security/dom_sid.h"
44 #include "../librpc/gen_ndr/ndr_security.h"
47 #include "lib/privileges.h"
48 #include "rpc_server/srv_access_check.h"
49 #include "../librpc/gen_ndr/ndr_wkssvc.h"
50 #include "../libcli/auth/proto.h"
53 #define DBGC_CLASS DBGC_RPC_SRV
55 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
57 enum lsa_handle_type {
58 LSA_HANDLE_POLICY_TYPE = 1,
59 LSA_HANDLE_ACCOUNT_TYPE = 2,
60 LSA_HANDLE_TRUST_TYPE = 3,
61 LSA_HANDLE_SECRET_TYPE = 4};
67 enum lsa_handle_type type;
68 struct security_descriptor *sd;
71 const struct generic_mapping lsa_account_mapping = {
75 LSA_ACCOUNT_ALL_ACCESS
78 const struct generic_mapping lsa_policy_mapping = {
85 const struct generic_mapping lsa_secret_mapping = {
92 const struct generic_mapping lsa_trusted_domain_mapping = {
93 LSA_TRUSTED_DOMAIN_READ,
94 LSA_TRUSTED_DOMAIN_WRITE,
95 LSA_TRUSTED_DOMAIN_EXECUTE,
96 LSA_TRUSTED_DOMAIN_ALL_ACCESS
99 /***************************************************************************
100 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
101 ***************************************************************************/
103 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
104 struct lsa_RefDomainList *ref,
105 const char *dom_name,
106 struct dom_sid *dom_sid)
110 if (dom_name != NULL) {
111 for (num = 0; num < ref->count; num++) {
112 if (dom_sid_equal(dom_sid, ref->domains[num].sid)) {
120 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
121 /* index not found, already at maximum domain limit */
125 ref->count = num + 1;
126 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
128 ref->domains = talloc_realloc(mem_ctx, ref->domains,
129 struct lsa_DomainInfo, ref->count);
134 ZERO_STRUCT(ref->domains[num]);
136 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
137 ref->domains[num].sid = dom_sid_dup(mem_ctx, dom_sid);
138 if (!ref->domains[num].sid) {
146 /***************************************************************************
147 initialize a lsa_DomainInfo structure.
148 ***************************************************************************/
150 static void init_dom_query_3(struct lsa_DomainInfo *r,
154 init_lsa_StringLarge(&r->name, name);
158 /***************************************************************************
159 initialize a lsa_DomainInfo structure.
160 ***************************************************************************/
162 static void init_dom_query_5(struct lsa_DomainInfo *r,
166 init_lsa_StringLarge(&r->name, name);
170 /***************************************************************************
171 lookup_lsa_rids. Must be called as root for lookup_name to work.
172 ***************************************************************************/
174 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
175 struct lsa_RefDomainList *ref,
176 struct lsa_TranslatedSid *prid,
177 uint32_t num_entries,
178 struct lsa_String *name,
180 uint32_t *pmapped_count)
182 uint32 mapped_count, i;
184 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
189 for (i = 0; i < num_entries; i++) {
193 const char *full_name;
195 enum lsa_SidType type;
197 /* Split name into domain and user component */
199 /* follow w2k8 behavior and return the builtin domain when no
200 * input has been passed in */
202 if (name[i].string) {
203 full_name = name[i].string;
205 full_name = "BUILTIN";
208 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
210 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
212 type = SID_NAME_UNKNOWN;
217 case SID_NAME_DOM_GRP:
218 case SID_NAME_DOMAIN:
220 case SID_NAME_WKN_GRP:
221 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
222 /* Leave these unchanged */
225 /* Don't hand out anything but the list above */
226 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
227 type = SID_NAME_UNKNOWN;
234 if (type != SID_NAME_UNKNOWN) {
235 if (type == SID_NAME_DOMAIN) {
238 sid_split_rid(&sid, &rid);
240 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
244 prid[i].sid_type = type;
246 prid[i].sid_index = dom_idx;
249 *pmapped_count = mapped_count;
253 /***************************************************************************
254 lookup_lsa_sids. Must be called as root for lookup_name to work.
255 ***************************************************************************/
257 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
258 struct lsa_RefDomainList *ref,
259 struct lsa_TranslatedSid3 *trans_sids,
260 uint32_t num_entries,
261 struct lsa_String *name,
263 uint32 *pmapped_count)
265 uint32 mapped_count, i;
267 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
272 for (i = 0; i < num_entries; i++) {
276 const char *full_name;
278 enum lsa_SidType type;
282 /* Split name into domain and user component */
284 full_name = name[i].string;
285 if (full_name == NULL) {
286 return NT_STATUS_NO_MEMORY;
289 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
291 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
293 type = SID_NAME_UNKNOWN;
298 case SID_NAME_DOM_GRP:
299 case SID_NAME_DOMAIN:
301 case SID_NAME_WKN_GRP:
302 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
303 /* Leave these unchanged */
306 /* Don't hand out anything but the list above */
307 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
308 type = SID_NAME_UNKNOWN;
315 if (type != SID_NAME_UNKNOWN) {
316 struct dom_sid domain_sid;
317 sid_copy(&domain_sid, &sid);
318 sid_split_rid(&domain_sid, &rid);
319 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
323 /* Initialize the lsa_TranslatedSid3 return. */
324 trans_sids[i].sid_type = type;
325 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
326 trans_sids[i].sid_index = dom_idx;
329 *pmapped_count = mapped_count;
333 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
334 const struct generic_mapping *map,
335 struct dom_sid *sid, uint32_t sid_access)
337 struct dom_sid adm_sid;
338 struct security_ace ace[5];
341 struct security_acl *psa = NULL;
343 /* READ|EXECUTE access for Everyone */
345 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
346 map->generic_execute | map->generic_read, 0);
348 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
350 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
351 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
352 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
353 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
355 /* Add Full Access for Domain Admins */
356 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
357 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
358 map->generic_all, 0);
360 /* If we have a sid, give it some special access */
363 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
367 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
368 return NT_STATUS_NO_MEMORY;
370 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
371 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
372 psa, sd_size)) == NULL)
373 return NT_STATUS_NO_MEMORY;
378 /***************************************************************************
379 ***************************************************************************/
381 static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
382 struct pipes_struct *p,
383 enum lsa_handle_type type,
384 uint32_t acc_granted,
387 const struct security_descriptor *sd,
388 struct policy_handle *handle)
390 struct lsa_info *info;
392 ZERO_STRUCTP(handle);
394 info = talloc_zero(mem_ctx, struct lsa_info);
396 return NT_STATUS_NO_MEMORY;
400 info->access = acc_granted;
403 sid_copy(&info->sid, sid);
406 info->name = talloc_strdup(info, name);
409 info->sd = dup_sec_desc(info, sd);
412 return NT_STATUS_NO_MEMORY;
416 if (!create_policy_hnd(p, handle, info)) {
418 ZERO_STRUCTP(handle);
419 return NT_STATUS_NO_MEMORY;
425 /***************************************************************************
427 ***************************************************************************/
429 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
430 struct lsa_OpenPolicy2 *r)
432 struct security_descriptor *psd = NULL;
434 uint32 des_access = r->in.access_mask;
438 /* Work out max allowed. */
439 map_max_allowed_access(p->session_info->security_token,
440 p->session_info->unix_token,
443 /* map the generic bits to the lsa policy ones */
444 se_map_generic(&des_access, &lsa_policy_mapping);
446 /* get the generic lsa policy SD until we store it */
447 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
449 if (!NT_STATUS_IS_OK(status)) {
453 status = access_check_object(psd, p->session_info->security_token,
454 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
455 &acc_granted, "_lsa_OpenPolicy2" );
456 if (!NT_STATUS_IS_OK(status)) {
460 status = create_lsa_policy_handle(p->mem_ctx, p,
461 LSA_HANDLE_POLICY_TYPE,
463 get_global_sam_sid(),
467 if (!NT_STATUS_IS_OK(status)) {
468 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
474 /***************************************************************************
476 ***************************************************************************/
478 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
479 struct lsa_OpenPolicy *r)
481 struct lsa_OpenPolicy2 o;
483 o.in.system_name = NULL; /* should be ignored */
484 o.in.attr = r->in.attr;
485 o.in.access_mask = r->in.access_mask;
487 o.out.handle = r->out.handle;
489 return _lsa_OpenPolicy2(p, &o);
492 /***************************************************************************
493 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
495 ***************************************************************************/
497 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
498 struct lsa_EnumTrustDom *r)
500 struct lsa_info *info;
502 struct trustdom_info **domains;
503 struct lsa_DomainInfo *entries;
507 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
508 return NT_STATUS_INVALID_HANDLE;
510 if (info->type != LSA_HANDLE_POLICY_TYPE) {
511 return NT_STATUS_INVALID_HANDLE;
514 /* check if the user has enough rights */
515 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
516 return NT_STATUS_ACCESS_DENIED;
519 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
522 if (!NT_STATUS_IS_OK(nt_status)) {
526 entries = talloc_zero_array(p->mem_ctx, struct lsa_DomainInfo, count);
528 return NT_STATUS_NO_MEMORY;
531 for (i=0; i<count; i++) {
532 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
533 entries[i].sid = &domains[i]->sid;
536 if (*r->in.resume_handle >= count) {
537 *r->out.resume_handle = -1;
538 TALLOC_FREE(entries);
539 return NT_STATUS_NO_MORE_ENTRIES;
542 /* return the rest, limit by max_size. Note that we
543 use the w2k3 element size value of 60 */
544 r->out.domains->count = count - *r->in.resume_handle;
545 r->out.domains->count = MIN(r->out.domains->count,
546 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
548 r->out.domains->domains = entries + *r->in.resume_handle;
550 if (r->out.domains->count < count - *r->in.resume_handle) {
551 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
552 return STATUS_MORE_ENTRIES;
555 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
556 * always be larger than the previous input resume handle, in
557 * particular when hitting the last query it is vital to set the
558 * resume handle correctly to avoid infinite client loops, as
559 * seen e.g. with Windows XP SP3 when resume handle is 0 and
560 * status is NT_STATUS_OK - gd */
562 *r->out.resume_handle = (uint32_t)-1;
567 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
568 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
569 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
571 /***************************************************************************
573 ***************************************************************************/
575 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
576 struct lsa_QueryInfoPolicy *r)
578 NTSTATUS status = NT_STATUS_OK;
579 struct lsa_info *handle;
580 struct dom_sid domain_sid;
582 struct dom_sid *sid = NULL;
583 union lsa_PolicyInformation *info = NULL;
584 uint32_t acc_required = 0;
586 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
587 return NT_STATUS_INVALID_HANDLE;
589 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
590 return NT_STATUS_INVALID_HANDLE;
593 switch (r->in.level) {
594 case LSA_POLICY_INFO_AUDIT_LOG:
595 case LSA_POLICY_INFO_AUDIT_EVENTS:
596 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
598 case LSA_POLICY_INFO_DOMAIN:
599 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
601 case LSA_POLICY_INFO_PD:
602 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
604 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
605 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
607 case LSA_POLICY_INFO_ROLE:
608 case LSA_POLICY_INFO_REPLICA:
609 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
611 case LSA_POLICY_INFO_QUOTA:
612 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
614 case LSA_POLICY_INFO_MOD:
615 case LSA_POLICY_INFO_AUDIT_FULL_SET:
616 /* according to MS-LSAD 3.1.4.4.3 */
617 return NT_STATUS_INVALID_PARAMETER;
618 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
619 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
621 case LSA_POLICY_INFO_DNS:
622 case LSA_POLICY_INFO_DNS_INT:
623 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
624 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
630 if (!(handle->access & acc_required)) {
631 /* return NT_STATUS_ACCESS_DENIED; */
634 info = talloc_zero(p->mem_ctx, union lsa_PolicyInformation);
636 return NT_STATUS_NO_MEMORY;
639 switch (r->in.level) {
640 /* according to MS-LSAD 3.1.4.4.3 */
641 case LSA_POLICY_INFO_MOD:
642 case LSA_POLICY_INFO_AUDIT_FULL_SET:
643 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
644 return NT_STATUS_INVALID_PARAMETER;
645 case LSA_POLICY_INFO_AUDIT_LOG:
646 info->audit_log.percent_full = 0;
647 info->audit_log.maximum_log_size = 0;
648 info->audit_log.retention_time = 0;
649 info->audit_log.shutdown_in_progress = 0;
650 info->audit_log.time_to_shutdown = 0;
651 info->audit_log.next_audit_record = 0;
652 status = NT_STATUS_OK;
654 case LSA_POLICY_INFO_PD:
655 info->pd.name.string = NULL;
656 status = NT_STATUS_OK;
658 case LSA_POLICY_INFO_REPLICA:
659 info->replica.source.string = NULL;
660 info->replica.account.string = NULL;
661 status = NT_STATUS_OK;
663 case LSA_POLICY_INFO_QUOTA:
664 info->quota.paged_pool = 0;
665 info->quota.non_paged_pool = 0;
666 info->quota.min_wss = 0;
667 info->quota.max_wss = 0;
668 info->quota.pagefile = 0;
669 info->quota.unknown = 0;
670 status = NT_STATUS_OK;
672 case LSA_POLICY_INFO_AUDIT_EVENTS:
675 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
677 /* check if the user has enough rights */
678 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
679 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
680 return NT_STATUS_ACCESS_DENIED;
683 /* fake info: We audit everything. ;) */
685 info->audit_events.auditing_mode = true;
686 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
687 info->audit_events.settings = talloc_zero_array(p->mem_ctx,
688 enum lsa_PolicyAuditPolicy,
689 info->audit_events.count);
690 if (!info->audit_events.settings) {
691 return NT_STATUS_NO_MEMORY;
694 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
695 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
696 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
697 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
698 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
699 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
700 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
704 case LSA_POLICY_INFO_DOMAIN:
705 /* check if the user has enough rights */
706 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
707 return NT_STATUS_ACCESS_DENIED;
709 /* Request PolicyPrimaryDomainInformation. */
710 switch (lp_server_role()) {
711 case ROLE_DOMAIN_PDC:
712 case ROLE_DOMAIN_BDC:
713 name = get_global_sam_name();
714 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
716 return NT_STATUS_NO_MEMORY;
719 case ROLE_DOMAIN_MEMBER:
720 name = lp_workgroup();
721 /* We need to return the Domain SID here. */
722 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
723 sid = dom_sid_dup(p->mem_ctx, &domain_sid);
725 return NT_STATUS_NO_MEMORY;
728 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
731 case ROLE_STANDALONE:
732 name = lp_workgroup();
736 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
738 init_dom_query_3(&info->domain, name, sid);
740 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
741 /* check if the user has enough rights */
742 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
743 return NT_STATUS_ACCESS_DENIED;
745 /* Request PolicyAccountDomainInformation. */
746 name = get_global_sam_name();
747 sid = get_global_sam_sid();
749 init_dom_query_5(&info->account_domain, name, sid);
751 case LSA_POLICY_INFO_ROLE:
752 /* check if the user has enough rights */
753 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
754 return NT_STATUS_ACCESS_DENIED;
756 switch (lp_server_role()) {
757 case ROLE_DOMAIN_BDC:
759 * only a BDC is a backup controller
760 * of the domain, it controls.
762 info->role.role = LSA_ROLE_BACKUP;
766 * any other role is a primary
767 * of the domain, it controls.
769 info->role.role = LSA_ROLE_PRIMARY;
773 case LSA_POLICY_INFO_DNS:
774 case LSA_POLICY_INFO_DNS_INT: {
775 struct pdb_domain_info *dominfo;
777 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
778 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
779 "without ADS passdb backend\n"));
780 status = NT_STATUS_INVALID_INFO_CLASS;
784 dominfo = pdb_get_domain_info(info);
785 if (dominfo == NULL) {
786 status = NT_STATUS_NO_MEMORY;
790 init_lsa_StringLarge(&info->dns.name,
792 init_lsa_StringLarge(&info->dns.dns_domain,
793 dominfo->dns_domain);
794 init_lsa_StringLarge(&info->dns.dns_forest,
795 dominfo->dns_forest);
796 info->dns.domain_guid = dominfo->guid;
797 info->dns.sid = &dominfo->sid;
801 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
803 status = NT_STATUS_INVALID_INFO_CLASS;
812 /***************************************************************************
813 _lsa_QueryInfoPolicy2
814 ***************************************************************************/
816 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
817 struct lsa_QueryInfoPolicy2 *r2)
819 struct lsa_QueryInfoPolicy r;
821 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
822 p->rng_fault_state = True;
823 return NT_STATUS_NOT_IMPLEMENTED;
827 r.in.handle = r2->in.handle;
828 r.in.level = r2->in.level;
829 r.out.info = r2->out.info;
831 return _lsa_QueryInfoPolicy(p, &r);
834 /***************************************************************************
835 _lsa_lookup_sids_internal
836 ***************************************************************************/
838 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
840 uint16_t level, /* input */
841 int num_sids, /* input */
842 struct lsa_SidPtr *sid, /* input */
843 struct lsa_RefDomainList **pp_ref, /* input/output */
844 struct lsa_TranslatedName2 **pp_names,/* input/output */
845 uint32_t *pp_mapped_count) /* input/output */
849 const struct dom_sid **sids = NULL;
850 struct lsa_RefDomainList *ref = NULL;
851 uint32 mapped_count = 0;
852 struct lsa_dom_info *dom_infos = NULL;
853 struct lsa_name_info *name_infos = NULL;
854 struct lsa_TranslatedName2 *names = NULL;
856 *pp_mapped_count = 0;
864 sids = talloc_array(p->mem_ctx, const struct dom_sid *, num_sids);
865 ref = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
867 if (sids == NULL || ref == NULL) {
868 return NT_STATUS_NO_MEMORY;
871 for (i=0; i<num_sids; i++) {
872 sids[i] = sid[i].sid;
875 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
876 &dom_infos, &name_infos);
878 if (!NT_STATUS_IS_OK(status)) {
882 names = talloc_array(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
884 return NT_STATUS_NO_MEMORY;
887 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
889 if (!dom_infos[i].valid) {
893 if (init_lsa_ref_domain_list(mem_ctx, ref,
895 &dom_infos[i].sid) != i) {
896 DEBUG(0, ("Domain %s mentioned twice??\n",
898 return NT_STATUS_INTERNAL_ERROR;
902 for (i=0; i<num_sids; i++) {
903 struct lsa_name_info *name = &name_infos[i];
905 if (name->type == SID_NAME_UNKNOWN) {
907 /* Unknown sids should return the string
908 * representation of the SID. Windows 2003 behaves
909 * rather erratic here, in many cases it returns the
910 * RID as 8 bytes hex, in others it returns the full
911 * SID. We (Jerry/VL) could not figure out which the
912 * hard cases are, so leave it with the SID. */
913 name->name = dom_sid_string(p->mem_ctx, sids[i]);
914 if (name->name == NULL) {
915 return NT_STATUS_NO_MEMORY;
921 names[i].sid_type = name->type;
922 names[i].name.string = name->name;
923 names[i].sid_index = name->dom_idx;
924 names[i].unknown = 0;
927 status = NT_STATUS_NONE_MAPPED;
928 if (mapped_count > 0) {
929 status = (mapped_count < num_sids) ?
930 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
933 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
934 num_sids, mapped_count, nt_errstr(status)));
936 *pp_mapped_count = mapped_count;
943 /***************************************************************************
945 ***************************************************************************/
947 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
948 struct lsa_LookupSids *r)
951 struct lsa_info *handle;
952 int num_sids = r->in.sids->num_sids;
953 uint32 mapped_count = 0;
954 struct lsa_RefDomainList *domains = NULL;
955 struct lsa_TranslatedName *names_out = NULL;
956 struct lsa_TranslatedName2 *names = NULL;
959 if ((r->in.level < 1) || (r->in.level > 6)) {
960 return NT_STATUS_INVALID_PARAMETER;
963 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
964 return NT_STATUS_INVALID_HANDLE;
967 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
968 return NT_STATUS_INVALID_HANDLE;
971 /* check if the user has enough rights */
972 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
973 return NT_STATUS_ACCESS_DENIED;
976 if (num_sids > MAX_LOOKUP_SIDS) {
977 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
978 MAX_LOOKUP_SIDS, num_sids));
979 return NT_STATUS_NONE_MAPPED;
982 status = _lsa_lookup_sids_internal(p,
991 /* Only return here when there is a real error.
992 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
993 the requested sids could be resolved. Older versions of XP (pre SP3)
994 rely that we return with the string representations of those SIDs in
995 that case. If we don't, XP crashes - Guenther
998 if (NT_STATUS_IS_ERR(status) &&
999 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1003 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
1004 names_out = talloc_array(p->mem_ctx, struct lsa_TranslatedName,
1007 return NT_STATUS_NO_MEMORY;
1010 for (i=0; i<num_sids; i++) {
1011 names_out[i].sid_type = names[i].sid_type;
1012 names_out[i].name = names[i].name;
1013 names_out[i].sid_index = names[i].sid_index;
1016 *r->out.domains = domains;
1017 r->out.names->count = num_sids;
1018 r->out.names->names = names_out;
1019 *r->out.count = mapped_count;
1024 /***************************************************************************
1026 ***************************************************************************/
1028 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1029 struct lsa_LookupSids2 *r)
1032 struct lsa_info *handle;
1033 int num_sids = r->in.sids->num_sids;
1034 uint32 mapped_count = 0;
1035 struct lsa_RefDomainList *domains = NULL;
1036 struct lsa_TranslatedName2 *names = NULL;
1037 bool check_policy = true;
1040 case NDR_LSA_LOOKUPSIDS3:
1041 check_policy = false;
1043 case NDR_LSA_LOOKUPSIDS2:
1045 check_policy = true;
1048 if ((r->in.level < 1) || (r->in.level > 6)) {
1049 return NT_STATUS_INVALID_PARAMETER;
1053 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1054 return NT_STATUS_INVALID_HANDLE;
1057 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1058 return NT_STATUS_INVALID_HANDLE;
1061 /* check if the user has enough rights */
1062 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1063 return NT_STATUS_ACCESS_DENIED;
1067 if (num_sids > MAX_LOOKUP_SIDS) {
1068 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1069 MAX_LOOKUP_SIDS, num_sids));
1070 return NT_STATUS_NONE_MAPPED;
1073 status = _lsa_lookup_sids_internal(p,
1082 *r->out.domains = domains;
1083 r->out.names->count = num_sids;
1084 r->out.names->names = names;
1085 *r->out.count = mapped_count;
1090 /***************************************************************************
1092 ***************************************************************************/
1094 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1095 struct lsa_LookupSids3 *r)
1097 struct lsa_LookupSids2 q;
1099 /* No policy handle on this call. Restrict to crypto connections. */
1100 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1101 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1102 get_remote_machine_name() ));
1103 return NT_STATUS_INVALID_PARAMETER;
1107 q.in.sids = r->in.sids;
1108 q.in.level = r->in.level;
1109 q.in.lookup_options = r->in.lookup_options;
1110 q.in.client_revision = r->in.client_revision;
1111 q.in.names = r->in.names;
1112 q.in.count = r->in.count;
1114 q.out.domains = r->out.domains;
1115 q.out.names = r->out.names;
1116 q.out.count = r->out.count;
1118 return _lsa_LookupSids2(p, &q);
1121 /***************************************************************************
1122 ***************************************************************************/
1124 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1129 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1130 flags = LOOKUP_NAME_ALL;
1132 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1133 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1135 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1136 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1138 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1139 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1140 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1141 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1143 flags = LOOKUP_NAME_NONE;
1150 /***************************************************************************
1152 ***************************************************************************/
1154 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1155 struct lsa_LookupNames *r)
1157 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1158 struct lsa_info *handle;
1159 struct lsa_String *names = r->in.names;
1160 uint32 num_entries = r->in.num_names;
1161 struct lsa_RefDomainList *domains = NULL;
1162 struct lsa_TranslatedSid *rids = NULL;
1163 uint32 mapped_count = 0;
1166 if (num_entries > MAX_LOOKUP_SIDS) {
1167 num_entries = MAX_LOOKUP_SIDS;
1168 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1172 flags = lsa_lookup_level_to_flags(r->in.level);
1174 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1176 return NT_STATUS_NO_MEMORY;
1180 rids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid,
1183 return NT_STATUS_NO_MEMORY;
1189 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1190 status = NT_STATUS_INVALID_HANDLE;
1194 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1195 return NT_STATUS_INVALID_HANDLE;
1198 /* check if the user has enough rights */
1199 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1200 status = NT_STATUS_ACCESS_DENIED;
1204 /* set up the LSA Lookup RIDs response */
1205 become_root(); /* lookup_name can require root privs */
1206 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1207 names, flags, &mapped_count);
1212 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1213 if (mapped_count == 0) {
1214 status = NT_STATUS_NONE_MAPPED;
1215 } else if (mapped_count != num_entries) {
1216 status = STATUS_SOME_UNMAPPED;
1220 *r->out.count = mapped_count;
1221 *r->out.domains = domains;
1222 r->out.sids->sids = rids;
1223 r->out.sids->count = num_entries;
1228 /***************************************************************************
1230 ***************************************************************************/
1232 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1233 struct lsa_LookupNames2 *r)
1236 struct lsa_LookupNames q;
1237 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1238 struct lsa_TransSidArray *sid_array = NULL;
1241 sid_array = talloc_zero(p->mem_ctx, struct lsa_TransSidArray);
1243 return NT_STATUS_NO_MEMORY;
1246 q.in.handle = r->in.handle;
1247 q.in.num_names = r->in.num_names;
1248 q.in.names = r->in.names;
1249 q.in.level = r->in.level;
1250 q.in.sids = sid_array;
1251 q.in.count = r->in.count;
1252 /* we do not know what this is for */
1253 /* = r->in.unknown1; */
1254 /* = r->in.unknown2; */
1256 q.out.domains = r->out.domains;
1257 q.out.sids = sid_array;
1258 q.out.count = r->out.count;
1260 status = _lsa_LookupNames(p, &q);
1262 sid_array2->count = sid_array->count;
1263 sid_array2->sids = talloc_array(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1264 if (!sid_array2->sids) {
1265 return NT_STATUS_NO_MEMORY;
1268 for (i=0; i<sid_array->count; i++) {
1269 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1270 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1271 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1272 sid_array2->sids[i].unknown = 0;
1275 r->out.sids = sid_array2;
1280 /***************************************************************************
1282 ***************************************************************************/
1284 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1285 struct lsa_LookupNames3 *r)
1288 struct lsa_info *handle;
1289 struct lsa_String *names = r->in.names;
1290 uint32 num_entries = r->in.num_names;
1291 struct lsa_RefDomainList *domains = NULL;
1292 struct lsa_TranslatedSid3 *trans_sids = NULL;
1293 uint32 mapped_count = 0;
1295 bool check_policy = true;
1298 case NDR_LSA_LOOKUPNAMES4:
1299 check_policy = false;
1301 case NDR_LSA_LOOKUPNAMES3:
1303 check_policy = true;
1306 if (num_entries > MAX_LOOKUP_SIDS) {
1307 num_entries = MAX_LOOKUP_SIDS;
1308 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1311 /* Probably the lookup_level is some sort of bitmask. */
1312 if (r->in.level == 1) {
1313 flags = LOOKUP_NAME_ALL;
1316 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1318 return NT_STATUS_NO_MEMORY;
1322 trans_sids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid3,
1325 return NT_STATUS_NO_MEMORY;
1333 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1334 status = NT_STATUS_INVALID_HANDLE;
1338 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1339 return NT_STATUS_INVALID_HANDLE;
1342 /* check if the user has enough rights */
1343 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1344 status = NT_STATUS_ACCESS_DENIED;
1349 /* set up the LSA Lookup SIDs response */
1350 become_root(); /* lookup_name can require root privs */
1351 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1352 names, flags, &mapped_count);
1357 if (NT_STATUS_IS_OK(status)) {
1358 if (mapped_count == 0) {
1359 status = NT_STATUS_NONE_MAPPED;
1360 } else if (mapped_count != num_entries) {
1361 status = STATUS_SOME_UNMAPPED;
1365 *r->out.count = mapped_count;
1366 *r->out.domains = domains;
1367 r->out.sids->sids = trans_sids;
1368 r->out.sids->count = num_entries;
1373 /***************************************************************************
1375 ***************************************************************************/
1377 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1378 struct lsa_LookupNames4 *r)
1380 struct lsa_LookupNames3 q;
1382 /* No policy handle on this call. Restrict to crypto connections. */
1383 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1384 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1385 get_remote_machine_name() ));
1386 return NT_STATUS_INVALID_PARAMETER;
1390 q.in.num_names = r->in.num_names;
1391 q.in.names = r->in.names;
1392 q.in.level = r->in.level;
1393 q.in.lookup_options = r->in.lookup_options;
1394 q.in.client_revision = r->in.client_revision;
1395 q.in.sids = r->in.sids;
1396 q.in.count = r->in.count;
1398 q.out.domains = r->out.domains;
1399 q.out.sids = r->out.sids;
1400 q.out.count = r->out.count;
1402 return _lsa_LookupNames3(p, &q);
1405 /***************************************************************************
1406 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1407 ***************************************************************************/
1409 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1411 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1412 return NT_STATUS_INVALID_HANDLE;
1415 close_policy_hnd(p, r->in.handle);
1416 ZERO_STRUCTP(r->out.handle);
1417 return NT_STATUS_OK;
1420 /***************************************************************************
1421 ***************************************************************************/
1423 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1424 const struct dom_sid *sid,
1425 struct trustdom_info **info)
1428 uint32_t num_domains = 0;
1429 struct trustdom_info **domains = NULL;
1432 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1433 if (!NT_STATUS_IS_OK(status)) {
1437 for (i=0; i < num_domains; i++) {
1438 if (dom_sid_equal(&domains[i]->sid, sid)) {
1443 if (i == num_domains) {
1444 return NT_STATUS_INVALID_PARAMETER;
1449 return NT_STATUS_OK;
1452 /***************************************************************************
1453 ***************************************************************************/
1455 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1456 const char *netbios_domain_name,
1457 struct trustdom_info **info_p)
1460 struct trustdom_info *info;
1461 struct pdb_trusted_domain *td;
1463 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1464 if (!NT_STATUS_IS_OK(status)) {
1468 info = talloc(mem_ctx, struct trustdom_info);
1470 return NT_STATUS_NO_MEMORY;
1473 info->name = talloc_strdup(info, netbios_domain_name);
1474 NT_STATUS_HAVE_NO_MEMORY(info->name);
1476 sid_copy(&info->sid, &td->security_identifier);
1480 return NT_STATUS_OK;
1483 /***************************************************************************
1485 ***************************************************************************/
1487 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p,
1488 struct lsa_OpenSecret *r)
1490 struct lsa_info *handle;
1491 struct security_descriptor *psd;
1493 uint32_t acc_granted;
1495 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1496 return NT_STATUS_INVALID_HANDLE;
1499 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1500 return NT_STATUS_INVALID_HANDLE;
1503 if (!r->in.name.string) {
1504 return NT_STATUS_INVALID_PARAMETER;
1507 /* Work out max allowed. */
1508 map_max_allowed_access(p->session_info->security_token,
1509 p->session_info->unix_token,
1510 &r->in.access_mask);
1512 /* map the generic bits to the lsa policy ones */
1513 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
1515 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
1521 if (!NT_STATUS_IS_OK(status)) {
1525 status = access_check_object(psd, p->session_info->security_token,
1526 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1528 &acc_granted, "_lsa_OpenSecret");
1529 if (!NT_STATUS_IS_OK(status)) {
1533 status = create_lsa_policy_handle(p->mem_ctx, p,
1534 LSA_HANDLE_SECRET_TYPE,
1540 if (!NT_STATUS_IS_OK(status)) {
1541 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1544 return NT_STATUS_OK;
1547 /***************************************************************************
1548 _lsa_OpenTrustedDomain_base
1549 ***************************************************************************/
1551 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1552 uint32_t access_mask,
1553 struct trustdom_info *info,
1554 struct policy_handle *handle)
1556 struct security_descriptor *psd = NULL;
1558 uint32_t acc_granted;
1561 /* des_access is for the account here, not the policy
1562 * handle - so don't check against policy handle. */
1564 /* Work out max allowed. */
1565 map_max_allowed_access(p->session_info->security_token,
1566 p->session_info->unix_token,
1569 /* map the generic bits to the lsa account ones */
1570 se_map_generic(&access_mask, &lsa_account_mapping);
1572 /* get the generic lsa account SD until we store it */
1573 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1574 &lsa_trusted_domain_mapping,
1576 if (!NT_STATUS_IS_OK(status)) {
1580 status = access_check_object(psd, p->session_info->security_token,
1581 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1582 access_mask, &acc_granted,
1583 "_lsa_OpenTrustedDomain");
1584 if (!NT_STATUS_IS_OK(status)) {
1588 status = create_lsa_policy_handle(p->mem_ctx, p,
1589 LSA_HANDLE_TRUST_TYPE,
1595 if (!NT_STATUS_IS_OK(status)) {
1596 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1599 return NT_STATUS_OK;
1602 /***************************************************************************
1603 _lsa_OpenTrustedDomain
1604 ***************************************************************************/
1606 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1607 struct lsa_OpenTrustedDomain *r)
1609 struct lsa_info *handle = NULL;
1610 struct trustdom_info *info = NULL;
1613 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1614 return NT_STATUS_INVALID_HANDLE;
1617 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1618 return NT_STATUS_INVALID_HANDLE;
1621 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1624 if (!NT_STATUS_IS_OK(status)) {
1628 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1629 r->out.trustdom_handle);
1632 /***************************************************************************
1633 _lsa_OpenTrustedDomainByName
1634 ***************************************************************************/
1636 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1637 struct lsa_OpenTrustedDomainByName *r)
1639 struct lsa_info *handle = NULL;
1640 struct trustdom_info *info = NULL;
1643 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1644 return NT_STATUS_INVALID_HANDLE;
1647 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1648 return NT_STATUS_INVALID_HANDLE;
1651 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1654 if (!NT_STATUS_IS_OK(status)) {
1658 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1659 r->out.trustdom_handle);
1662 static NTSTATUS add_trusted_domain_user(TALLOC_CTX *mem_ctx,
1663 const char *netbios_name,
1664 const char *domain_name,
1665 const struct trustDomainPasswords *auth_struct)
1668 struct samu *sam_acct;
1671 struct dom_sid user_sid;
1676 sam_acct = samu_new(mem_ctx);
1677 if (sam_acct == NULL) {
1678 return NT_STATUS_NO_MEMORY;
1681 acct_name = talloc_asprintf(mem_ctx, "%s$", netbios_name);
1682 if (acct_name == NULL) {
1683 return NT_STATUS_NO_MEMORY;
1685 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1686 return NT_STATUS_UNSUCCESSFUL;
1689 if (!pdb_set_domain(sam_acct, domain_name, PDB_SET)) {
1690 return NT_STATUS_UNSUCCESSFUL;
1693 if (!pdb_set_acct_ctrl(sam_acct, ACB_DOMTRUST, PDB_SET)) {
1694 return NT_STATUS_UNSUCCESSFUL;
1697 if (!pdb_new_rid(&rid)) {
1698 return NT_STATUS_DS_NO_MORE_RIDS;
1700 sid_compose(&user_sid, get_global_sam_sid(), rid);
1701 if (!pdb_set_user_sid(sam_acct, &user_sid, PDB_SET)) {
1702 return NT_STATUS_UNSUCCESSFUL;
1705 for (i = 0; i < auth_struct->incoming.count; i++) {
1706 switch (auth_struct->incoming.current.array[i].AuthType) {
1707 case TRUST_AUTH_TYPE_CLEAR:
1708 if (!convert_string_talloc(mem_ctx,
1711 auth_struct->incoming.current.array[i].AuthInfo.clear.password,
1712 auth_struct->incoming.current.array[i].AuthInfo.clear.size,
1715 return NT_STATUS_UNSUCCESSFUL;
1717 if (!pdb_set_plaintext_passwd(sam_acct, dummy)) {
1718 return NT_STATUS_UNSUCCESSFUL;
1726 status = pdb_add_sam_account(sam_acct);
1727 if (!NT_STATUS_IS_OK(status)) {
1731 return NT_STATUS_OK;
1734 /***************************************************************************
1735 _lsa_CreateTrustedDomainEx2
1736 ***************************************************************************/
1738 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1739 struct lsa_CreateTrustedDomainEx2 *r)
1741 struct lsa_info *policy;
1743 uint32_t acc_granted;
1744 struct security_descriptor *psd;
1746 struct pdb_trusted_domain td;
1747 struct trustDomainPasswords auth_struct;
1748 enum ndr_err_code ndr_err;
1749 DATA_BLOB auth_blob;
1752 return NT_STATUS_NOT_SUPPORTED;
1755 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1756 return NT_STATUS_INVALID_HANDLE;
1759 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1760 return NT_STATUS_ACCESS_DENIED;
1763 if (p->session_info->unix_token->uid != sec_initial_uid() &&
1764 !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1765 return NT_STATUS_ACCESS_DENIED;
1768 /* Work out max allowed. */
1769 map_max_allowed_access(p->session_info->security_token,
1770 p->session_info->unix_token,
1771 &r->in.access_mask);
1773 /* map the generic bits to the lsa policy ones */
1774 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1776 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1777 &lsa_trusted_domain_mapping,
1779 if (!NT_STATUS_IS_OK(status)) {
1783 status = access_check_object(psd, p->session_info->security_token,
1784 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1785 r->in.access_mask, &acc_granted,
1786 "_lsa_CreateTrustedDomainEx2");
1787 if (!NT_STATUS_IS_OK(status)) {
1793 td.domain_name = talloc_strdup(p->mem_ctx,
1794 r->in.info->domain_name.string);
1795 if (td.domain_name == NULL) {
1796 return NT_STATUS_NO_MEMORY;
1798 td.netbios_name = talloc_strdup(p->mem_ctx,
1799 r->in.info->netbios_name.string);
1800 if (td.netbios_name == NULL) {
1801 return NT_STATUS_NO_MEMORY;
1803 sid_copy(&td.security_identifier, r->in.info->sid);
1804 td.trust_direction = r->in.info->trust_direction;
1805 td.trust_type = r->in.info->trust_type;
1806 td.trust_attributes = r->in.info->trust_attributes;
1808 if (r->in.auth_info_internal->auth_blob.size != 0) {
1809 auth_blob.length = r->in.auth_info_internal->auth_blob.size;
1810 auth_blob.data = r->in.auth_info_internal->auth_blob.data;
1812 arcfour_crypt_blob(auth_blob.data, auth_blob.length,
1813 &p->session_info->session_key);
1815 ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
1817 (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
1818 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1819 return NT_STATUS_UNSUCCESSFUL;
1822 ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
1823 &auth_struct.incoming,
1824 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1825 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1826 return NT_STATUS_UNSUCCESSFUL;
1829 ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
1830 &auth_struct.outgoing,
1831 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1832 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1833 return NT_STATUS_UNSUCCESSFUL;
1836 td.trust_auth_incoming.data = NULL;
1837 td.trust_auth_incoming.length = 0;
1838 td.trust_auth_outgoing.data = NULL;
1839 td.trust_auth_outgoing.length = 0;
1842 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1843 if (!NT_STATUS_IS_OK(status)) {
1847 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1848 status = add_trusted_domain_user(p->mem_ctx,
1849 r->in.info->netbios_name.string,
1850 r->in.info->domain_name.string,
1852 if (!NT_STATUS_IS_OK(status)) {
1857 status = create_lsa_policy_handle(p->mem_ctx, p,
1858 LSA_HANDLE_TRUST_TYPE,
1861 r->in.info->netbios_name.string,
1863 r->out.trustdom_handle);
1864 if (!NT_STATUS_IS_OK(status)) {
1865 pdb_del_trusteddom_pw(r->in.info->netbios_name.string);
1866 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1869 return NT_STATUS_OK;
1872 /***************************************************************************
1873 _lsa_CreateTrustedDomainEx
1874 ***************************************************************************/
1876 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1877 struct lsa_CreateTrustedDomainEx *r)
1879 struct lsa_CreateTrustedDomainEx2 q;
1880 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1882 ZERO_STRUCT(auth_info);
1884 q.in.policy_handle = r->in.policy_handle;
1885 q.in.info = r->in.info;
1886 q.in.auth_info_internal = &auth_info;
1887 q.in.access_mask = r->in.access_mask;
1888 q.out.trustdom_handle = r->out.trustdom_handle;
1890 return _lsa_CreateTrustedDomainEx2(p, &q);
1893 /***************************************************************************
1894 _lsa_CreateTrustedDomain
1895 ***************************************************************************/
1897 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1898 struct lsa_CreateTrustedDomain *r)
1900 struct lsa_CreateTrustedDomainEx2 c;
1901 struct lsa_TrustDomainInfoInfoEx info;
1902 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1904 ZERO_STRUCT(auth_info);
1906 info.domain_name = r->in.info->name;
1907 info.netbios_name = r->in.info->name;
1908 info.sid = r->in.info->sid;
1909 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1910 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1911 info.trust_attributes = 0;
1913 c.in.policy_handle = r->in.policy_handle;
1915 c.in.auth_info_internal = &auth_info;
1916 c.in.access_mask = r->in.access_mask;
1917 c.out.trustdom_handle = r->out.trustdom_handle;
1919 return _lsa_CreateTrustedDomainEx2(p, &c);
1922 /***************************************************************************
1923 _lsa_DeleteTrustedDomain
1924 ***************************************************************************/
1926 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1927 struct lsa_DeleteTrustedDomain *r)
1930 struct lsa_info *handle;
1931 struct pdb_trusted_domain *td;
1932 struct samu *sam_acct;
1935 /* find the connection policy handle. */
1936 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1937 return NT_STATUS_INVALID_HANDLE;
1940 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1941 return NT_STATUS_INVALID_HANDLE;
1944 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1945 return NT_STATUS_ACCESS_DENIED;
1948 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1949 if (!NT_STATUS_IS_OK(status)) {
1953 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1954 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1955 sid_string_tos(r->in.dom_sid)));
1956 return NT_STATUS_UNSUCCESSFUL;
1959 if (td->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1960 sam_acct = samu_new(p->mem_ctx);
1961 if (sam_acct == NULL) {
1962 return NT_STATUS_NO_MEMORY;
1965 acct_name = talloc_asprintf(p->mem_ctx, "%s$", td->netbios_name);
1966 if (acct_name == NULL) {
1967 return NT_STATUS_NO_MEMORY;
1969 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1970 return NT_STATUS_UNSUCCESSFUL;
1972 status = pdb_delete_sam_account(sam_acct);
1973 if (!NT_STATUS_IS_OK(status)) {
1978 status = pdb_del_trusted_domain(td->netbios_name);
1979 if (!NT_STATUS_IS_OK(status)) {
1983 return NT_STATUS_OK;
1986 /***************************************************************************
1987 _lsa_CloseTrustedDomainEx
1988 ***************************************************************************/
1990 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1991 struct lsa_CloseTrustedDomainEx *r)
1993 return NT_STATUS_NOT_IMPLEMENTED;
1996 /***************************************************************************
1997 _lsa_QueryTrustedDomainInfo
1998 ***************************************************************************/
2000 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
2001 struct lsa_QueryTrustedDomainInfo *r)
2004 struct lsa_info *handle;
2005 union lsa_TrustedDomainInfo *info;
2006 struct pdb_trusted_domain *td;
2007 uint32_t acc_required;
2009 /* find the connection policy handle. */
2010 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
2011 return NT_STATUS_INVALID_HANDLE;
2014 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
2015 return NT_STATUS_INVALID_HANDLE;
2018 switch (r->in.level) {
2019 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2020 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2022 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2023 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
2025 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2026 acc_required = LSA_TRUSTED_QUERY_POSIX;
2028 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2029 acc_required = LSA_TRUSTED_QUERY_AUTH;
2031 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2032 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2034 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2035 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2037 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2038 acc_required = LSA_TRUSTED_QUERY_AUTH;
2040 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2041 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2042 LSA_TRUSTED_QUERY_POSIX |
2043 LSA_TRUSTED_QUERY_AUTH;
2045 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2046 acc_required = LSA_TRUSTED_QUERY_AUTH;
2048 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2049 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2050 LSA_TRUSTED_QUERY_POSIX |
2051 LSA_TRUSTED_QUERY_AUTH;
2053 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2054 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2056 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2057 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2058 LSA_TRUSTED_QUERY_POSIX |
2059 LSA_TRUSTED_QUERY_AUTH;
2061 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2062 acc_required = LSA_TRUSTED_QUERY_POSIX;
2065 return NT_STATUS_INVALID_PARAMETER;
2068 if (!(handle->access & acc_required)) {
2069 return NT_STATUS_ACCESS_DENIED;
2072 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2073 if (!NT_STATUS_IS_OK(status)) {
2077 info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
2079 return NT_STATUS_NO_MEMORY;
2082 switch (r->in.level) {
2083 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2084 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2086 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2087 return NT_STATUS_INVALID_PARAMETER;
2088 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2090 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2091 return NT_STATUS_INVALID_INFO_CLASS;
2092 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2093 return NT_STATUS_INVALID_PARAMETER;
2094 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2095 init_lsa_StringLarge(&info->info_ex.domain_name, td->domain_name);
2096 init_lsa_StringLarge(&info->info_ex.netbios_name, td->netbios_name);
2097 info->info_ex.sid = dom_sid_dup(info, &td->security_identifier);
2098 if (!info->info_ex.sid) {
2099 return NT_STATUS_NO_MEMORY;
2101 info->info_ex.trust_direction = td->trust_direction;
2102 info->info_ex.trust_type = td->trust_type;
2103 info->info_ex.trust_attributes = td->trust_attributes;
2105 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2106 return NT_STATUS_INVALID_INFO_CLASS;
2107 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2109 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2110 return NT_STATUS_INVALID_INFO_CLASS;
2111 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2112 return NT_STATUS_INVALID_INFO_CLASS;
2113 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2114 return NT_STATUS_INVALID_PARAMETER;
2115 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2117 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2120 return NT_STATUS_INVALID_PARAMETER;
2123 *r->out.info = info;
2125 return NT_STATUS_OK;
2128 /***************************************************************************
2129 _lsa_QueryTrustedDomainInfoBySid
2130 ***************************************************************************/
2132 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2133 struct lsa_QueryTrustedDomainInfoBySid *r)
2136 struct policy_handle trustdom_handle;
2137 struct lsa_OpenTrustedDomain o;
2138 struct lsa_QueryTrustedDomainInfo q;
2141 o.in.handle = r->in.handle;
2142 o.in.sid = r->in.dom_sid;
2143 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2144 o.out.trustdom_handle = &trustdom_handle;
2146 status = _lsa_OpenTrustedDomain(p, &o);
2147 if (!NT_STATUS_IS_OK(status)) {
2151 q.in.trustdom_handle = &trustdom_handle;
2152 q.in.level = r->in.level;
2153 q.out.info = r->out.info;
2155 status = _lsa_QueryTrustedDomainInfo(p, &q);
2156 if (!NT_STATUS_IS_OK(status)) {
2160 c.in.handle = &trustdom_handle;
2161 c.out.handle = &trustdom_handle;
2163 return _lsa_Close(p, &c);
2166 /***************************************************************************
2167 _lsa_QueryTrustedDomainInfoByName
2168 ***************************************************************************/
2170 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2171 struct lsa_QueryTrustedDomainInfoByName *r)
2174 struct policy_handle trustdom_handle;
2175 struct lsa_OpenTrustedDomainByName o;
2176 struct lsa_QueryTrustedDomainInfo q;
2179 o.in.handle = r->in.handle;
2180 o.in.name.string = r->in.trusted_domain->string;
2181 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2182 o.out.trustdom_handle = &trustdom_handle;
2184 status = _lsa_OpenTrustedDomainByName(p, &o);
2185 if (!NT_STATUS_IS_OK(status)) {
2186 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2187 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2192 q.in.trustdom_handle = &trustdom_handle;
2193 q.in.level = r->in.level;
2194 q.out.info = r->out.info;
2196 status = _lsa_QueryTrustedDomainInfo(p, &q);
2197 if (!NT_STATUS_IS_OK(status)) {
2201 c.in.handle = &trustdom_handle;
2202 c.out.handle = &trustdom_handle;
2204 return _lsa_Close(p, &c);
2207 /***************************************************************************
2209 ***************************************************************************/
2211 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p,
2212 struct lsa_CreateSecret *r)
2215 struct lsa_info *handle;
2216 uint32_t acc_granted;
2217 struct security_descriptor *psd;
2220 /* find the connection policy handle. */
2221 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
2222 return NT_STATUS_INVALID_HANDLE;
2225 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2226 return NT_STATUS_INVALID_HANDLE;
2229 /* check if the user has enough rights */
2231 if (!(handle->access & LSA_POLICY_CREATE_SECRET)) {
2232 return NT_STATUS_ACCESS_DENIED;
2235 /* Work out max allowed. */
2236 map_max_allowed_access(p->session_info->security_token,
2237 p->session_info->unix_token,
2238 &r->in.access_mask);
2240 /* map the generic bits to the lsa policy ones */
2241 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
2243 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2244 &lsa_secret_mapping,
2246 if (!NT_STATUS_IS_OK(status)) {
2250 status = access_check_object(psd, p->session_info->security_token,
2251 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2253 &acc_granted, "_lsa_CreateSecret");
2254 if (!NT_STATUS_IS_OK(status)) {
2258 if (!r->in.name.string) {
2259 return NT_STATUS_INVALID_PARAMETER;
2262 if (strlen(r->in.name.string) > 128) {
2263 return NT_STATUS_NAME_TOO_LONG;
2266 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
2267 NULL, NULL, NULL, NULL, NULL);
2268 if (NT_STATUS_IS_OK(status)) {
2269 return NT_STATUS_OBJECT_NAME_COLLISION;
2272 status = pdb_set_secret(r->in.name.string, NULL, NULL, psd);
2273 if (!NT_STATUS_IS_OK(status)) {
2277 status = create_lsa_policy_handle(p->mem_ctx, p,
2278 LSA_HANDLE_SECRET_TYPE,
2284 if (!NT_STATUS_IS_OK(status)) {
2285 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2288 return NT_STATUS_OK;
2291 /***************************************************************************
2293 ***************************************************************************/
2295 NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
2296 struct lsa_SetSecret *r)
2299 struct lsa_info *info = NULL;
2300 DATA_BLOB blob_new, blob_old;
2301 DATA_BLOB cleartext_blob_new = data_blob_null;
2302 DATA_BLOB cleartext_blob_old = data_blob_null;
2303 DATA_BLOB *cleartext_blob_new_p = NULL;
2304 DATA_BLOB *cleartext_blob_old_p = NULL;
2306 if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
2307 return NT_STATUS_INVALID_HANDLE;
2310 if (info->type != LSA_HANDLE_SECRET_TYPE) {
2311 return NT_STATUS_INVALID_HANDLE;
2314 if (!(info->access & LSA_SECRET_SET_VALUE)) {
2315 return NT_STATUS_ACCESS_DENIED;
2318 if (r->in.new_val) {
2319 blob_new = data_blob_const(r->in.new_val->data,
2320 r->in.new_val->length);
2322 status = sess_decrypt_blob(p->mem_ctx, &blob_new,
2323 &p->session_info->session_key,
2324 &cleartext_blob_new);
2325 if (!NT_STATUS_IS_OK(status)) {
2329 cleartext_blob_new_p = &cleartext_blob_new;
2332 if (r->in.old_val) {
2333 blob_old = data_blob_const(r->in.old_val->data,
2334 r->in.old_val->length);
2336 status = sess_decrypt_blob(p->mem_ctx, &blob_old,
2337 &p->session_info->session_key,
2338 &cleartext_blob_old);
2339 if (!NT_STATUS_IS_OK(status)) {
2343 cleartext_blob_old_p = &cleartext_blob_old;
2346 status = pdb_set_secret(info->name, cleartext_blob_new_p, cleartext_blob_old_p, NULL);
2347 if (!NT_STATUS_IS_OK(status)) {
2351 #ifdef DEBUG_PASSWORD
2352 DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
2353 dump_data(10, cleartext_blob_new.data, cleartext_blob_new.length);
2354 DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
2355 dump_data(10, cleartext_blob_old.data, cleartext_blob_old.length);
2358 return NT_STATUS_OK;
2361 /***************************************************************************
2363 ***************************************************************************/
2365 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
2366 struct lsa_QuerySecret *r)
2368 struct lsa_info *info = NULL;
2369 DATA_BLOB blob_new, blob_old;
2370 DATA_BLOB blob_new_crypt, blob_old_crypt;
2371 NTTIME nttime_new, nttime_old;
2374 if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
2375 return NT_STATUS_INVALID_HANDLE;
2378 if (info->type != LSA_HANDLE_SECRET_TYPE) {
2379 return NT_STATUS_INVALID_HANDLE;
2382 if (!(info->access & LSA_SECRET_QUERY_VALUE)) {
2383 return NT_STATUS_ACCESS_DENIED;
2386 status = pdb_get_secret(p->mem_ctx, info->name,
2387 &blob_new, &nttime_new,
2388 &blob_old, &nttime_old,
2390 if (!NT_STATUS_IS_OK(status)) {
2394 if (r->in.new_val) {
2395 if (blob_new.length) {
2396 if (!r->out.new_val->buf) {
2397 r->out.new_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2399 if (!r->out.new_val->buf) {
2400 return NT_STATUS_NO_MEMORY;
2403 blob_new_crypt = sess_encrypt_blob(p->mem_ctx, &blob_new,
2404 &p->session_info->session_key);
2405 if (!blob_new_crypt.length) {
2406 return NT_STATUS_NO_MEMORY;
2409 r->out.new_val->buf->data = blob_new_crypt.data;
2410 r->out.new_val->buf->length = blob_new_crypt.length;
2411 r->out.new_val->buf->size = blob_new_crypt.length;
2415 if (r->in.old_val) {
2416 if (blob_old.length) {
2417 if (!r->out.old_val->buf) {
2418 r->out.old_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2420 if (!r->out.old_val->buf) {
2421 return NT_STATUS_NO_MEMORY;
2424 blob_old_crypt = sess_encrypt_blob(p->mem_ctx, &blob_old,
2425 &p->session_info->session_key);
2426 if (!blob_old_crypt.length) {
2427 return NT_STATUS_NO_MEMORY;
2430 r->out.old_val->buf->data = blob_old_crypt.data;
2431 r->out.old_val->buf->length = blob_old_crypt.length;
2432 r->out.old_val->buf->size = blob_old_crypt.length;
2436 if (r->out.new_mtime) {
2437 *r->out.new_mtime = nttime_new;
2440 if (r->out.old_mtime) {
2441 *r->out.old_mtime = nttime_old;
2444 return NT_STATUS_OK;
2447 /***************************************************************************
2449 ***************************************************************************/
2451 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2452 struct lsa_DeleteObject *r)
2455 struct lsa_info *info = NULL;
2457 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2458 return NT_STATUS_INVALID_HANDLE;
2461 if (!(info->access & SEC_STD_DELETE)) {
2462 return NT_STATUS_ACCESS_DENIED;
2465 switch (info->type) {
2466 case LSA_HANDLE_ACCOUNT_TYPE:
2467 status = privilege_delete_account(&info->sid);
2468 if (!NT_STATUS_IS_OK(status)) {
2469 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2470 nt_errstr(status)));
2474 case LSA_HANDLE_TRUST_TYPE:
2475 if (!pdb_del_trusteddom_pw(info->name)) {
2476 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2478 status = NT_STATUS_OK;
2480 case LSA_HANDLE_SECRET_TYPE:
2481 status = pdb_delete_secret(info->name);
2482 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2483 return NT_STATUS_INVALID_HANDLE;
2487 return NT_STATUS_INVALID_HANDLE;
2490 close_policy_hnd(p, r->in.handle);
2491 ZERO_STRUCTP(r->out.handle);
2496 /***************************************************************************
2498 ***************************************************************************/
2500 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2501 struct lsa_EnumPrivs *r)
2503 struct lsa_info *handle;
2505 uint32 enum_context = *r->in.resume_handle;
2506 int num_privs = num_privileges_in_short_list();
2507 struct lsa_PrivEntry *entries = NULL;
2509 /* remember that the enum_context starts at 0 and not 1 */
2511 if ( enum_context >= num_privs )
2512 return NT_STATUS_NO_MORE_ENTRIES;
2514 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2515 enum_context, num_privs));
2517 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2518 return NT_STATUS_INVALID_HANDLE;
2520 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2521 return NT_STATUS_INVALID_HANDLE;
2524 /* check if the user has enough rights
2525 I don't know if it's the right one. not documented. */
2527 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2528 return NT_STATUS_ACCESS_DENIED;
2531 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2533 return NT_STATUS_NO_MEMORY;
2539 for (i = 0; i < num_privs; i++) {
2540 if( i < enum_context) {
2542 init_lsa_StringLarge(&entries[i].name, NULL);
2544 entries[i].luid.low = 0;
2545 entries[i].luid.high = 0;
2548 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2550 entries[i].luid.low = sec_privilege_from_index(i);
2551 entries[i].luid.high = 0;
2555 enum_context = num_privs;
2557 *r->out.resume_handle = enum_context;
2558 r->out.privs->count = num_privs;
2559 r->out.privs->privs = entries;
2561 return NT_STATUS_OK;
2564 /***************************************************************************
2565 _lsa_LookupPrivDisplayName
2566 ***************************************************************************/
2568 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2569 struct lsa_LookupPrivDisplayName *r)
2571 struct lsa_info *handle;
2572 const char *description;
2573 struct lsa_StringLarge *lsa_name;
2575 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2576 return NT_STATUS_INVALID_HANDLE;
2578 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2579 return NT_STATUS_INVALID_HANDLE;
2582 /* check if the user has enough rights */
2585 * I don't know if it's the right one. not documented.
2587 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2588 return NT_STATUS_ACCESS_DENIED;
2590 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2592 description = get_privilege_dispname(r->in.name->string);
2594 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2595 return NT_STATUS_NO_SUCH_PRIVILEGE;
2598 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2600 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2602 return NT_STATUS_NO_MEMORY;
2605 init_lsa_StringLarge(lsa_name, description);
2607 *r->out.returned_language_id = r->in.language_id;
2608 *r->out.disp_name = lsa_name;
2610 return NT_STATUS_OK;
2613 /***************************************************************************
2615 ***************************************************************************/
2617 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2618 struct lsa_EnumAccounts *r)
2620 struct lsa_info *handle;
2621 struct dom_sid *sid_list;
2622 int i, j, num_entries;
2624 struct lsa_SidPtr *sids = NULL;
2626 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2627 return NT_STATUS_INVALID_HANDLE;
2629 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2630 return NT_STATUS_INVALID_HANDLE;
2633 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2634 return NT_STATUS_ACCESS_DENIED;
2639 /* The only way we can currently find out all the SIDs that have been
2640 privileged is to scan all privileges */
2642 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2643 if (!NT_STATUS_IS_OK(status)) {
2647 if (*r->in.resume_handle >= num_entries) {
2648 return NT_STATUS_NO_MORE_ENTRIES;
2651 if (num_entries - *r->in.resume_handle) {
2652 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2653 num_entries - *r->in.resume_handle);
2655 talloc_free(sid_list);
2656 return NT_STATUS_NO_MEMORY;
2659 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2660 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2662 talloc_free(sid_list);
2663 return NT_STATUS_NO_MEMORY;
2668 talloc_free(sid_list);
2670 *r->out.resume_handle = num_entries;
2671 r->out.sids->num_sids = num_entries;
2672 r->out.sids->sids = sids;
2674 return NT_STATUS_OK;
2677 /***************************************************************************
2679 ***************************************************************************/
2681 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2682 struct lsa_GetUserName *r)
2684 const char *username, *domname;
2685 struct lsa_String *account_name = NULL;
2686 struct lsa_String *authority_name = NULL;
2688 if (r->in.account_name &&
2689 *r->in.account_name) {
2690 return NT_STATUS_INVALID_PARAMETER;
2693 if (r->in.authority_name &&
2694 *r->in.authority_name) {
2695 return NT_STATUS_INVALID_PARAMETER;
2698 if (security_session_user_level(p->session_info, NULL) < SECURITY_USER) {
2700 * I'm 99% sure this is not the right place to do this,
2701 * global_sid_Anonymous should probably be put into the token
2702 * instead of the guest id -- vl
2704 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2705 &domname, &username, NULL)) {
2706 return NT_STATUS_NO_MEMORY;
2709 username = p->session_info->unix_info->sanitized_username;
2710 domname = p->session_info->info->domain_name;
2713 account_name = talloc(p->mem_ctx, struct lsa_String);
2714 if (!account_name) {
2715 return NT_STATUS_NO_MEMORY;
2717 init_lsa_String(account_name, username);
2719 if (r->out.authority_name) {
2720 authority_name = talloc(p->mem_ctx, struct lsa_String);
2721 if (!authority_name) {
2722 return NT_STATUS_NO_MEMORY;
2724 init_lsa_String(authority_name, domname);
2727 *r->out.account_name = account_name;
2728 if (r->out.authority_name) {
2729 *r->out.authority_name = authority_name;
2732 return NT_STATUS_OK;
2735 /***************************************************************************
2737 ***************************************************************************/
2739 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2740 struct lsa_CreateAccount *r)
2743 struct lsa_info *handle;
2744 uint32_t acc_granted;
2745 struct security_descriptor *psd;
2748 /* find the connection policy handle. */
2749 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2750 return NT_STATUS_INVALID_HANDLE;
2752 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2753 return NT_STATUS_INVALID_HANDLE;
2756 /* check if the user has enough rights */
2758 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2759 return NT_STATUS_ACCESS_DENIED;
2762 /* Work out max allowed. */
2763 map_max_allowed_access(p->session_info->security_token,
2764 p->session_info->unix_token,
2765 &r->in.access_mask);
2767 /* map the generic bits to the lsa policy ones */
2768 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2770 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2771 &lsa_account_mapping,
2772 r->in.sid, LSA_POLICY_ALL_ACCESS);
2773 if (!NT_STATUS_IS_OK(status)) {
2777 status = access_check_object(psd, p->session_info->security_token,
2778 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2779 &acc_granted, "_lsa_CreateAccount");
2780 if (!NT_STATUS_IS_OK(status)) {
2784 if ( is_privileged_sid( r->in.sid ) )
2785 return NT_STATUS_OBJECT_NAME_COLLISION;
2787 status = create_lsa_policy_handle(p->mem_ctx, p,
2788 LSA_HANDLE_ACCOUNT_TYPE,
2793 r->out.acct_handle);
2794 if (!NT_STATUS_IS_OK(status)) {
2795 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2798 return privilege_create_account(r->in.sid);
2801 /***************************************************************************
2803 ***************************************************************************/
2805 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2806 struct lsa_OpenAccount *r)
2808 struct lsa_info *handle;
2809 struct security_descriptor *psd = NULL;
2811 uint32_t des_access = r->in.access_mask;
2812 uint32_t acc_granted;
2815 /* find the connection policy handle. */
2816 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2817 return NT_STATUS_INVALID_HANDLE;
2819 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2820 return NT_STATUS_INVALID_HANDLE;
2823 /* des_access is for the account here, not the policy
2824 * handle - so don't check against policy handle. */
2826 /* Work out max allowed. */
2827 map_max_allowed_access(p->session_info->security_token,
2828 p->session_info->unix_token,
2831 /* map the generic bits to the lsa account ones */
2832 se_map_generic(&des_access, &lsa_account_mapping);
2834 /* get the generic lsa account SD until we store it */
2835 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2836 &lsa_account_mapping,
2837 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2838 if (!NT_STATUS_IS_OK(status)) {
2842 status = access_check_object(psd, p->session_info->security_token,
2843 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2844 &acc_granted, "_lsa_OpenAccount" );
2845 if (!NT_STATUS_IS_OK(status)) {
2849 /* TODO: Fis the parsing routine before reenabling this check! */
2851 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2852 return NT_STATUS_ACCESS_DENIED;
2855 status = create_lsa_policy_handle(p->mem_ctx, p,
2856 LSA_HANDLE_ACCOUNT_TYPE,
2861 r->out.acct_handle);
2862 if (!NT_STATUS_IS_OK(status)) {
2863 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2866 return NT_STATUS_OK;
2869 /***************************************************************************
2870 _lsa_EnumPrivsAccount
2871 For a given SID, enumerate all the privilege this account has.
2872 ***************************************************************************/
2874 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2875 struct lsa_EnumPrivsAccount *r)
2877 NTSTATUS status = NT_STATUS_OK;
2878 struct lsa_info *info=NULL;
2879 PRIVILEGE_SET *privileges;
2880 struct lsa_PrivilegeSet *priv_set = NULL;
2882 /* find the connection policy handle. */
2883 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2884 return NT_STATUS_INVALID_HANDLE;
2886 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2887 return NT_STATUS_INVALID_HANDLE;
2890 if (!(info->access & LSA_ACCOUNT_VIEW))
2891 return NT_STATUS_ACCESS_DENIED;
2893 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2894 if (!NT_STATUS_IS_OK(status)) {
2898 *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2900 return NT_STATUS_NO_MEMORY;
2903 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2904 sid_string_dbg(&info->sid),
2905 privileges->count));
2907 priv_set->count = privileges->count;
2908 priv_set->unknown = 0;
2909 priv_set->set = talloc_move(priv_set, &privileges->set);
2914 /***************************************************************************
2915 _lsa_GetSystemAccessAccount
2916 ***************************************************************************/
2918 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2919 struct lsa_GetSystemAccessAccount *r)
2922 struct lsa_info *info = NULL;
2923 struct lsa_EnumPrivsAccount e;
2924 struct lsa_PrivilegeSet *privset;
2926 /* find the connection policy handle. */
2928 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2929 return NT_STATUS_INVALID_HANDLE;
2931 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2932 return NT_STATUS_INVALID_HANDLE;
2935 if (!(info->access & LSA_ACCOUNT_VIEW))
2936 return NT_STATUS_ACCESS_DENIED;
2938 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2940 return NT_STATUS_NO_MEMORY;
2943 e.in.handle = r->in.handle;
2944 e.out.privs = &privset;
2946 status = _lsa_EnumPrivsAccount(p, &e);
2947 if (!NT_STATUS_IS_OK(status)) {
2948 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2949 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2950 nt_errstr(status)));
2954 /* Samba4 would iterate over the privset to merge the policy mode bits,
2955 * not sure samba3 can do the same here, so just return what we did in
2959 0x01 -> Log on locally
2960 0x02 -> Access this computer from network
2961 0x04 -> Log on as a batch job
2962 0x10 -> Log on as a service
2964 they can be ORed together
2967 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2968 LSA_POLICY_MODE_NETWORK;
2970 return NT_STATUS_OK;
2973 /***************************************************************************
2974 update the systemaccount information
2975 ***************************************************************************/
2977 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2978 struct lsa_SetSystemAccessAccount *r)
2980 struct lsa_info *info=NULL;
2983 /* find the connection policy handle. */
2984 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2985 return NT_STATUS_INVALID_HANDLE;
2987 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2988 return NT_STATUS_INVALID_HANDLE;
2991 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2992 return NT_STATUS_ACCESS_DENIED;
2995 if (!pdb_getgrsid(&map, info->sid))
2996 return NT_STATUS_NO_SUCH_GROUP;
2998 return pdb_update_group_mapping_entry(&map);
3001 /***************************************************************************
3002 _lsa_AddPrivilegesToAccount
3003 For a given SID, add some privileges.
3004 ***************************************************************************/
3006 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
3007 struct lsa_AddPrivilegesToAccount *r)
3009 struct lsa_info *info = NULL;
3010 struct lsa_PrivilegeSet *set = NULL;
3012 /* find the connection policy handle. */
3013 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3014 return NT_STATUS_INVALID_HANDLE;
3016 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3017 return NT_STATUS_INVALID_HANDLE;
3020 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3021 return NT_STATUS_ACCESS_DENIED;
3026 if ( !grant_privilege_set( &info->sid, set ) ) {
3027 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
3028 sid_string_dbg(&info->sid) ));
3029 return NT_STATUS_NO_SUCH_PRIVILEGE;
3032 return NT_STATUS_OK;
3035 /***************************************************************************
3036 _lsa_RemovePrivilegesFromAccount
3037 For a given SID, remove some privileges.
3038 ***************************************************************************/
3040 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
3041 struct lsa_RemovePrivilegesFromAccount *r)
3043 struct lsa_info *info = NULL;
3044 struct lsa_PrivilegeSet *set = NULL;
3046 /* find the connection policy handle. */
3047 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3048 return NT_STATUS_INVALID_HANDLE;
3050 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3051 return NT_STATUS_INVALID_HANDLE;
3054 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3055 return NT_STATUS_ACCESS_DENIED;
3060 if ( !revoke_privilege_set( &info->sid, set) ) {
3061 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
3062 sid_string_dbg(&info->sid) ));
3063 return NT_STATUS_NO_SUCH_PRIVILEGE;
3066 return NT_STATUS_OK;
3069 /***************************************************************************
3071 ***************************************************************************/
3073 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
3074 struct lsa_LookupPrivName *r)
3076 struct lsa_info *info = NULL;
3078 struct lsa_StringLarge *lsa_name;
3080 /* find the connection policy handle. */
3081 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3082 return NT_STATUS_INVALID_HANDLE;
3085 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3086 return NT_STATUS_INVALID_HANDLE;
3089 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
3090 return NT_STATUS_ACCESS_DENIED;
3093 if (r->in.luid->high != 0) {
3094 return NT_STATUS_NO_SUCH_PRIVILEGE;
3097 name = sec_privilege_name(r->in.luid->low);
3099 return NT_STATUS_NO_SUCH_PRIVILEGE;
3102 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
3104 return NT_STATUS_NO_MEMORY;
3107 lsa_name->string = talloc_strdup(lsa_name, name);
3108 if (!lsa_name->string) {
3109 TALLOC_FREE(lsa_name);
3110 return NT_STATUS_NO_MEMORY;
3113 *r->out.name = lsa_name;
3115 return NT_STATUS_OK;
3118 /***************************************************************************
3120 ***************************************************************************/
3122 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
3123 struct lsa_QuerySecurity *r)
3125 struct lsa_info *handle=NULL;
3126 struct security_descriptor *psd = NULL;
3130 /* find the connection policy handle. */
3131 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
3132 return NT_STATUS_INVALID_HANDLE;
3134 switch (handle->type) {
3135 case LSA_HANDLE_POLICY_TYPE:
3136 case LSA_HANDLE_ACCOUNT_TYPE:
3137 case LSA_HANDLE_TRUST_TYPE:
3138 case LSA_HANDLE_SECRET_TYPE:
3140 sd_size = ndr_size_security_descriptor(psd, 0);
3141 status = NT_STATUS_OK;
3144 status = NT_STATUS_INVALID_HANDLE;
3148 if (!NT_STATUS_IS_OK(status)) {
3152 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
3153 if (!*r->out.sdbuf) {
3154 return NT_STATUS_NO_MEMORY;
3160 /***************************************************************************
3161 _lsa_AddAccountRights
3162 ***************************************************************************/
3164 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
3165 struct lsa_AddAccountRights *r)
3167 struct lsa_info *info = NULL;
3169 uint32_t acc_granted = 0;
3170 struct security_descriptor *psd = NULL;
3175 /* find the connection policy handle. */
3176 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3177 return NT_STATUS_INVALID_HANDLE;
3179 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3180 return NT_STATUS_INVALID_HANDLE;
3183 /* get the generic lsa account SD for this SID until we store it */
3184 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3185 &lsa_account_mapping,
3186 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
3187 if (!NT_STATUS_IS_OK(status)) {
3192 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3193 * on the policy handle. If it does, ask for
3194 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3195 * on the account sid. We don't check here so just use the latter. JRA.
3198 status = access_check_object(psd, p->session_info->security_token,
3199 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3200 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3201 &acc_granted, "_lsa_AddAccountRights" );
3202 if (!NT_STATUS_IS_OK(status)) {
3206 /* according to an NT4 PDC, you can add privileges to SIDs even without
3207 call_lsa_create_account() first. And you can use any arbitrary SID. */
3209 sid_copy( &sid, r->in.sid );
3211 for ( i=0; i < r->in.rights->count; i++ ) {
3213 const char *privname = r->in.rights->names[i].string;
3215 /* only try to add non-null strings */
3220 if ( !grant_privilege_by_name( &sid, privname ) ) {
3221 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3223 return NT_STATUS_NO_SUCH_PRIVILEGE;
3227 return NT_STATUS_OK;
3230 /***************************************************************************
3231 _lsa_RemoveAccountRights
3232 ***************************************************************************/
3234 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
3235 struct lsa_RemoveAccountRights *r)
3237 struct lsa_info *info = NULL;
3239 struct security_descriptor *psd = NULL;
3242 const char *privname = NULL;
3243 uint32_t acc_granted = 0;
3246 /* find the connection policy handle. */
3247 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3248 return NT_STATUS_INVALID_HANDLE;
3250 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3251 return NT_STATUS_INVALID_HANDLE;
3254 /* get the generic lsa account SD for this SID until we store it */
3255 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3256 &lsa_account_mapping,
3257 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
3258 if (!NT_STATUS_IS_OK(status)) {
3263 * From the MS DOCs. We need
3264 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3265 * and DELETE on the account sid.
3268 status = access_check_object(psd, p->session_info->security_token,
3269 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3270 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3271 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
3272 &acc_granted, "_lsa_RemoveAccountRights");
3273 if (!NT_STATUS_IS_OK(status)) {
3277 sid_copy( &sid, r->in.sid );
3279 if ( r->in.remove_all ) {
3280 if ( !revoke_all_privileges( &sid ) )
3281 return NT_STATUS_ACCESS_DENIED;
3283 return NT_STATUS_OK;
3286 for ( i=0; i < r->in.rights->count; i++ ) {
3288 privname = r->in.rights->names[i].string;
3290 /* only try to add non-null strings */
3295 if ( !revoke_privilege_by_name( &sid, privname ) ) {
3296 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3298 return NT_STATUS_NO_SUCH_PRIVILEGE;
3302 return NT_STATUS_OK;
3305 /*******************************************************************
3306 ********************************************************************/
3308 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3309 struct lsa_RightSet *r,
3310 PRIVILEGE_SET *privileges)
3313 const char *privname;
3314 const char **privname_array = NULL;
3317 for (i=0; i<privileges->count; i++) {
3318 if (privileges->set[i].luid.high) {
3321 privname = sec_privilege_name(privileges->set[i].luid.low);
3323 if (!add_string_to_array(mem_ctx, privname,
3324 &privname_array, &num_priv)) {
3325 return NT_STATUS_NO_MEMORY;
3332 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3335 return NT_STATUS_NO_MEMORY;
3338 for (i=0; i<num_priv; i++) {
3339 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3342 r->count = num_priv;
3345 return NT_STATUS_OK;
3348 /***************************************************************************
3349 _lsa_EnumAccountRights
3350 ***************************************************************************/
3352 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3353 struct lsa_EnumAccountRights *r)
3356 struct lsa_info *info = NULL;
3357 PRIVILEGE_SET *privileges;
3359 /* find the connection policy handle. */
3361 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3362 return NT_STATUS_INVALID_HANDLE;
3364 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3365 return NT_STATUS_INVALID_HANDLE;
3368 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3369 return NT_STATUS_ACCESS_DENIED;
3372 /* according to an NT4 PDC, you can add privileges to SIDs even without
3373 call_lsa_create_account() first. And you can use any arbitrary SID. */
3375 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3376 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3377 * the lsa database */
3379 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3380 if (!NT_STATUS_IS_OK(status)) {
3384 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3385 sid_string_dbg(r->in.sid), privileges->count));
3387 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3392 /***************************************************************************
3393 _lsa_LookupPrivValue
3394 ***************************************************************************/
3396 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3397 struct lsa_LookupPrivValue *r)
3399 struct lsa_info *info = NULL;
3400 const char *name = NULL;
3402 /* find the connection policy handle. */
3404 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3405 return NT_STATUS_INVALID_HANDLE;
3407 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3408 return NT_STATUS_INVALID_HANDLE;
3411 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3412 return NT_STATUS_ACCESS_DENIED;
3414 name = r->in.name->string;
3416 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3418 r->out.luid->low = sec_privilege_id(name);
3419 r->out.luid->high = 0;
3420 if (r->out.luid->low == SEC_PRIV_INVALID) {
3421 return NT_STATUS_NO_SUCH_PRIVILEGE;
3423 return NT_STATUS_OK;
3426 /***************************************************************************
3427 _lsa_EnumAccountsWithUserRight
3428 ***************************************************************************/
3430 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3431 struct lsa_EnumAccountsWithUserRight *r)
3434 struct lsa_info *info = NULL;
3435 struct dom_sid *sids = NULL;
3438 enum sec_privilege privilege;
3440 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3441 return NT_STATUS_INVALID_HANDLE;
3444 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3445 return NT_STATUS_INVALID_HANDLE;
3448 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3449 return NT_STATUS_ACCESS_DENIED;
3452 if (!r->in.name || !r->in.name->string) {
3453 return NT_STATUS_NO_SUCH_PRIVILEGE;
3456 privilege = sec_privilege_id(r->in.name->string);
3457 if (privilege == SEC_PRIV_INVALID) {
3458 return NT_STATUS_NO_SUCH_PRIVILEGE;
3461 status = privilege_enum_sids(privilege, p->mem_ctx,
3463 if (!NT_STATUS_IS_OK(status)) {
3467 r->out.sids->num_sids = num_sids;
3468 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3469 r->out.sids->num_sids);
3471 for (i=0; i < r->out.sids->num_sids; i++) {
3472 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3474 if (!r->out.sids->sids[i].sid) {
3475 TALLOC_FREE(r->out.sids->sids);
3476 r->out.sids->num_sids = 0;
3477 return NT_STATUS_NO_MEMORY;
3481 return NT_STATUS_OK;
3484 /***************************************************************************
3486 ***************************************************************************/
3488 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3489 struct lsa_Delete *r)
3491 return NT_STATUS_NOT_SUPPORTED;
3495 * From here on the server routines are just dummy ones to make smbd link with
3496 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3497 * pulling the server stubs across one by one.
3500 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3502 p->rng_fault_state = True;
3503 return NT_STATUS_NOT_IMPLEMENTED;
3506 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3507 struct lsa_ChangePassword *r)
3509 p->rng_fault_state = True;
3510 return NT_STATUS_NOT_IMPLEMENTED;
3513 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3515 p->rng_fault_state = True;
3516 return NT_STATUS_NOT_IMPLEMENTED;
3519 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3521 p->rng_fault_state = True;
3522 return NT_STATUS_NOT_IMPLEMENTED;
3525 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3526 struct lsa_GetQuotasForAccount *r)
3528 p->rng_fault_state = True;
3529 return NT_STATUS_NOT_IMPLEMENTED;
3532 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3533 struct lsa_SetQuotasForAccount *r)
3535 p->rng_fault_state = True;
3536 return NT_STATUS_NOT_IMPLEMENTED;
3539 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3540 struct lsa_SetInformationTrustedDomain *r)
3542 p->rng_fault_state = True;
3543 return NT_STATUS_NOT_IMPLEMENTED;
3546 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3547 struct lsa_SetTrustedDomainInfo *r)
3549 p->rng_fault_state = True;
3550 return NT_STATUS_NOT_IMPLEMENTED;
3553 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3554 struct lsa_StorePrivateData *r)
3556 p->rng_fault_state = True;
3557 return NT_STATUS_NOT_IMPLEMENTED;
3560 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3561 struct lsa_RetrievePrivateData *r)
3563 p->rng_fault_state = True;
3564 return NT_STATUS_NOT_IMPLEMENTED;
3567 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3568 struct lsa_SetInfoPolicy2 *r)
3570 p->rng_fault_state = True;
3571 return NT_STATUS_NOT_IMPLEMENTED;
3574 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3575 struct lsa_SetTrustedDomainInfoByName *r)
3577 p->rng_fault_state = True;
3578 return NT_STATUS_NOT_IMPLEMENTED;
3581 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3582 struct lsa_EnumTrustedDomainsEx *r)
3584 struct lsa_info *info;
3586 struct pdb_trusted_domain **domains;
3587 struct lsa_TrustDomainInfoInfoEx *entries;
3591 /* bail out early if pdb backend is not capable of ex trusted domains,
3592 * if we dont do that, the client might not call
3593 * _lsa_EnumTrustedDomains() afterwards - gd */
3595 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3596 p->rng_fault_state = True;
3597 return NT_STATUS_NOT_IMPLEMENTED;
3600 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3601 return NT_STATUS_INVALID_HANDLE;
3603 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3604 return NT_STATUS_INVALID_HANDLE;
3607 /* check if the user has enough rights */
3608 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3609 return NT_STATUS_ACCESS_DENIED;
3612 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3615 if (!NT_STATUS_IS_OK(nt_status)) {
3619 entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3622 return NT_STATUS_NO_MEMORY;
3625 for (i=0; i<count; i++) {
3626 init_lsa_StringLarge(&entries[i].netbios_name,
3627 domains[i]->netbios_name);
3628 entries[i].sid = &domains[i]->security_identifier;
3631 if (*r->in.resume_handle >= count) {
3632 *r->out.resume_handle = -1;
3633 TALLOC_FREE(entries);
3634 return NT_STATUS_NO_MORE_ENTRIES;
3637 /* return the rest, limit by max_size. Note that we
3638 use the w2k3 element size value of 60 */
3639 r->out.domains->count = count - *r->in.resume_handle;
3640 r->out.domains->count = MIN(r->out.domains->count,
3641 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3643 r->out.domains->domains = entries + *r->in.resume_handle;
3645 if (r->out.domains->count < count - *r->in.resume_handle) {
3646 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3647 return STATUS_MORE_ENTRIES;
3650 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3651 * always be larger than the previous input resume handle, in
3652 * particular when hitting the last query it is vital to set the
3653 * resume handle correctly to avoid infinite client loops, as
3654 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3655 * status is NT_STATUS_OK - gd */
3657 *r->out.resume_handle = (uint32_t)-1;
3659 return NT_STATUS_OK;
3662 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3663 struct lsa_QueryDomainInformationPolicy *r)
3665 p->rng_fault_state = True;
3666 return NT_STATUS_NOT_IMPLEMENTED;
3669 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3670 struct lsa_SetDomainInformationPolicy *r)
3672 p->rng_fault_state = True;
3673 return NT_STATUS_NOT_IMPLEMENTED;
3676 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3678 p->rng_fault_state = True;
3679 return NT_STATUS_NOT_IMPLEMENTED;
3682 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3684 p->rng_fault_state = True;
3685 return NT_STATUS_NOT_IMPLEMENTED;
3688 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3690 p->rng_fault_state = True;
3691 return NT_STATUS_NOT_IMPLEMENTED;
3694 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3696 p->rng_fault_state = True;
3697 return NT_STATUS_NOT_IMPLEMENTED;
3700 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3701 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3703 p->rng_fault_state = True;
3704 return NT_STATUS_NOT_IMPLEMENTED;
3707 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3708 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3710 p->rng_fault_state = True;
3711 return NT_STATUS_NOT_IMPLEMENTED;
3714 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3716 p->rng_fault_state = True;
3717 return NT_STATUS_NOT_IMPLEMENTED;
3720 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3721 struct lsa_CREDRGETTARGETINFO *r)
3723 p->rng_fault_state = True;
3724 return NT_STATUS_NOT_IMPLEMENTED;
3727 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3728 struct lsa_CREDRPROFILELOADED *r)
3730 p->rng_fault_state = True;
3731 return NT_STATUS_NOT_IMPLEMENTED;
3734 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3735 struct lsa_CREDRGETSESSIONTYPES *r)
3737 p->rng_fault_state = True;
3738 return NT_STATUS_NOT_IMPLEMENTED;
3741 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3742 struct lsa_LSARREGISTERAUDITEVENT *r)
3744 p->rng_fault_state = True;
3745 return NT_STATUS_NOT_IMPLEMENTED;
3748 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3749 struct lsa_LSARGENAUDITEVENT *r)
3751 p->rng_fault_state = True;
3752 return NT_STATUS_NOT_IMPLEMENTED;
3755 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3756 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3758 p->rng_fault_state = True;
3759 return NT_STATUS_NOT_IMPLEMENTED;
3762 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3763 struct lsa_lsaRQueryForestTrustInformation *r)
3765 p->rng_fault_state = True;
3766 return NT_STATUS_NOT_IMPLEMENTED;
3769 #define DNS_CMP_MATCH 0
3770 #define DNS_CMP_FIRST_IS_CHILD 1
3771 #define DNS_CMP_SECOND_IS_CHILD 2
3772 #define DNS_CMP_NO_MATCH 3
3774 /* this function assumes names are well formed DNS names.
3775 * it doesn't validate them */
3776 static int dns_cmp(const char *s1, size_t l1,
3777 const char *s2, size_t l2)
3779 const char *p1, *p2;
3784 if (strcasecmp_m(s1, s2) == 0) {
3785 return DNS_CMP_MATCH;
3787 return DNS_CMP_NO_MATCH;
3795 cret = DNS_CMP_FIRST_IS_CHILD;
3801 cret = DNS_CMP_SECOND_IS_CHILD;
3804 if (p1[t1 - t2 - 1] != '.') {
3805 return DNS_CMP_NO_MATCH;
3808 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
3812 return DNS_CMP_NO_MATCH;
3815 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3816 struct lsa_ForestTrustInformation *lfti,
3817 struct ForestTrustInfo *fti)
3819 struct lsa_ForestTrustRecord *lrec;
3820 struct ForestTrustInfoRecord *rec;
3821 struct lsa_StringLarge *tln;
3822 struct lsa_ForestTrustDomainInfo *info;
3826 fti->count = lfti->count;
3827 fti->records = talloc_array(mem_ctx,
3828 struct ForestTrustInfoRecordArmor,
3830 if (!fti->records) {
3831 return NT_STATUS_NO_MEMORY;
3833 for (i = 0; i < fti->count; i++) {
3834 lrec = lfti->entries[i];
3835 rec = &fti->records[i].record;
3837 rec->flags = lrec->flags;
3838 rec->timestamp = lrec->time;
3839 rec->type = lrec->type;
3841 switch (lrec->type) {
3842 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3843 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3844 tln = &lrec->forest_trust_data.top_level_name;
3845 rec->data.name.string =
3846 talloc_strdup(mem_ctx, tln->string);
3847 if (!rec->data.name.string) {
3848 return NT_STATUS_NO_MEMORY;
3850 rec->data.name.size = strlen(rec->data.name.string);
3852 case LSA_FOREST_TRUST_DOMAIN_INFO:
3853 info = &lrec->forest_trust_data.domain_info;
3854 rec->data.info.sid = *info->domain_sid;
3855 rec->data.info.dns_name.string =
3856 talloc_strdup(mem_ctx,
3857 info->dns_domain_name.string);
3858 if (!rec->data.info.dns_name.string) {
3859 return NT_STATUS_NO_MEMORY;
3861 rec->data.info.dns_name.size =
3862 strlen(rec->data.info.dns_name.string);
3863 rec->data.info.netbios_name.string =
3864 talloc_strdup(mem_ctx,
3865 info->netbios_domain_name.string);
3866 if (!rec->data.info.netbios_name.string) {
3867 return NT_STATUS_NO_MEMORY;
3869 rec->data.info.netbios_name.size =
3870 strlen(rec->data.info.netbios_name.string);
3873 return NT_STATUS_INVALID_DOMAIN_STATE;
3877 return NT_STATUS_OK;
3880 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3881 uint32_t index, uint32_t collision_type,
3882 uint32_t conflict_type, const char *tdo_name);
3884 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
3885 const char *tdo_name,
3886 struct ForestTrustInfo *tdo_fti,
3887 struct ForestTrustInfo *new_fti,
3888 struct lsa_ForestTrustCollisionInfo *c_info)
3890 struct ForestTrustInfoRecord *nrec;
3891 struct ForestTrustInfoRecord *trec;
3892 const char *dns_name;
3893 const char *nb_name = NULL;
3894 struct dom_sid *sid = NULL;
3895 const char *tname = NULL;
3900 uint32_t new_fti_idx;
3902 /* use always TDO type, until we understand when Xref can be used */
3903 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
3908 bool ex_rule = false;
3911 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
3913 nrec = &new_fti->records[new_fti_idx].record;
3915 tln_conflict = false;
3916 sid_conflict = false;
3917 nb_conflict = false;
3920 switch (nrec->type) {
3921 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3922 /* exclusions do not conflict by definition */
3925 case FOREST_TRUST_TOP_LEVEL_NAME:
3926 dns_name = nrec->data.name.string;
3927 dns_len = nrec->data.name.size;
3930 case LSA_FOREST_TRUST_DOMAIN_INFO:
3931 dns_name = nrec->data.info.dns_name.string;
3932 dns_len = nrec->data.info.dns_name.size;
3933 nb_name = nrec->data.info.netbios_name.string;
3934 nb_len = nrec->data.info.netbios_name.size;
3935 sid = &nrec->data.info.sid;
3939 if (!dns_name) continue;
3941 /* check if this is already taken and not excluded */
3942 for (i = 0; i < tdo_fti->count; i++) {
3943 trec = &tdo_fti->records[i].record;
3945 switch (trec->type) {
3946 case FOREST_TRUST_TOP_LEVEL_NAME:
3948 tname = trec->data.name.string;
3949 tlen = trec->data.name.size;
3951 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
3953 tname = trec->data.name.string;
3954 tlen = trec->data.name.size;
3956 case FOREST_TRUST_DOMAIN_INFO:
3958 tname = trec->data.info.dns_name.string;
3959 tlen = trec->data.info.dns_name.size;
3962 return NT_STATUS_INVALID_PARAMETER;
3964 ret = dns_cmp(dns_name, dns_len, tname, tlen);
3967 /* if it matches exclusion,
3968 * it doesn't conflict */
3974 case DNS_CMP_FIRST_IS_CHILD:
3975 case DNS_CMP_SECOND_IS_CHILD:
3976 tln_conflict = true;
3982 /* explicit exclusion, no dns name conflict here */
3984 tln_conflict = false;
3987 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
3991 /* also test for domain info */
3992 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
3993 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
3994 sid_conflict = true;
3996 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
3997 strcasecmp_m(trec->data.info.netbios_name.string,
4004 nt_status = add_collision(c_info, new_fti_idx,
4006 LSA_TLN_DISABLED_CONFLICT,
4010 nt_status = add_collision(c_info, new_fti_idx,
4012 LSA_SID_DISABLED_CONFLICT,
4016 nt_status = add_collision(c_info, new_fti_idx,
4018 LSA_NB_DISABLED_CONFLICT,
4023 return NT_STATUS_OK;
4026 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4027 uint32_t idx, uint32_t collision_type,
4028 uint32_t conflict_type, const char *tdo_name)
4030 struct lsa_ForestTrustCollisionRecord **es;
4031 uint32_t i = c_info->count;
4033 es = talloc_realloc(c_info, c_info->entries,
4034 struct lsa_ForestTrustCollisionRecord *, i + 1);
4036 return NT_STATUS_NO_MEMORY;
4038 c_info->entries = es;
4039 c_info->count = i + 1;
4041 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4043 return NT_STATUS_NO_MEMORY;
4047 es[i]->type = collision_type;
4048 es[i]->flags.flags = conflict_type;
4049 es[i]->name.string = talloc_strdup(es[i], tdo_name);
4050 if (!es[i]->name.string) {
4051 return NT_STATUS_NO_MEMORY;
4053 es[i]->name.size = strlen(es[i]->name.string);
4055 return NT_STATUS_OK;
4058 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
4059 struct pdb_trusted_domain *td,
4060 struct ForestTrustInfo *info)
4062 enum ndr_err_code ndr_err;
4064 if (td->trust_forest_trust_info.length == 0 ||
4065 td->trust_forest_trust_info.data == NULL) {
4066 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4068 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
4070 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
4071 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4072 return NT_STATUS_INVALID_DOMAIN_STATE;
4075 return NT_STATUS_OK;
4078 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
4079 struct ForestTrustInfo *fti)
4081 struct ForestTrustDataDomainInfo *info;
4082 struct ForestTrustInfoRecord *rec;
4086 fti->records = talloc_array(fti,
4087 struct ForestTrustInfoRecordArmor, 2);
4088 if (!fti->records) {
4089 return NT_STATUS_NO_MEMORY;
4093 rec = &fti->records[0].record;
4097 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
4099 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
4100 if (!rec->data.name.string) {
4101 return NT_STATUS_NO_MEMORY;
4103 rec->data.name.size = strlen(rec->data.name.string);
4106 rec = &fti->records[1].record;
4110 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
4112 info = &rec->data.info;
4114 info->sid = dom_info->sid;
4115 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
4116 if (!info->dns_name.string) {
4117 return NT_STATUS_NO_MEMORY;
4119 info->dns_name.size = strlen(info->dns_name.string);
4120 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
4121 if (!info->netbios_name.string) {
4122 return NT_STATUS_NO_MEMORY;
4124 info->netbios_name.size = strlen(info->netbios_name.string);
4126 return NT_STATUS_OK;
4129 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
4130 struct lsa_lsaRSetForestTrustInformation *r)
4135 struct lsa_info *handle;
4136 uint32_t num_domains;
4137 struct pdb_trusted_domain **domains;
4138 struct ForestTrustInfo *nfti;
4139 struct ForestTrustInfo *fti;
4140 struct lsa_ForestTrustCollisionInfo *c_info;
4141 struct pdb_domain_info *dom_info;
4142 enum ndr_err_code ndr_err;
4145 return NT_STATUS_NOT_SUPPORTED;
4148 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
4149 return NT_STATUS_INVALID_HANDLE;
4152 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
4153 return NT_STATUS_INVALID_HANDLE;
4156 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
4157 return NT_STATUS_ACCESS_DENIED;
4160 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
4161 if (!NT_STATUS_IS_OK(status)) {
4164 if (num_domains == 0) {
4165 return NT_STATUS_NO_SUCH_DOMAIN;
4168 for (i = 0; i < num_domains; i++) {
4169 if (domains[i]->domain_name == NULL) {
4170 return NT_STATUS_INVALID_DOMAIN_STATE;
4172 if (strcasecmp_m(domains[i]->domain_name,
4173 r->in.trusted_domain_name->string) == 0) {
4177 if (i >= num_domains) {
4178 return NT_STATUS_NO_SUCH_DOMAIN;
4181 if (!(domains[i]->trust_attributes &
4182 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4183 return NT_STATUS_INVALID_PARAMETER;
4186 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4187 return NT_STATUS_INVALID_PARAMETER;
4190 /* The following section until COPY_END is a copy from
4191 * source4/rpmc_server/lsa/scesrc_lsa.c */
4192 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
4194 return NT_STATUS_NO_MEMORY;
4197 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4198 if (!NT_STATUS_IS_OK(status)) {
4202 c_info = talloc_zero(r->out.collision_info,
4203 struct lsa_ForestTrustCollisionInfo);
4205 return NT_STATUS_NO_MEMORY;
4208 /* first check own info, then other domains */
4209 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4211 return NT_STATUS_NO_MEMORY;
4214 dom_info = pdb_get_domain_info(p->mem_ctx);
4216 status = own_ft_info(dom_info, fti);
4217 if (!NT_STATUS_IS_OK(status)) {
4221 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
4222 if (!NT_STATUS_IS_OK(status)) {
4226 for (j = 0; j < num_domains; j++) {
4227 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4229 return NT_STATUS_NO_MEMORY;
4232 status = get_ft_info(p->mem_ctx, domains[j], fti);
4233 if (!NT_STATUS_IS_OK(status)) {
4234 if (NT_STATUS_EQUAL(status,
4235 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4241 if (domains[j]->domain_name == NULL) {
4242 return NT_STATUS_INVALID_DOMAIN_STATE;
4245 status = check_ft_info(c_info, domains[j]->domain_name,
4247 if (!NT_STATUS_IS_OK(status)) {
4252 *r->out.collision_info = c_info;
4254 if (r->in.check_only != 0) {
4255 return NT_STATUS_OK;
4260 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
4262 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4263 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4264 return NT_STATUS_INVALID_PARAMETER;
4267 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
4268 if (!NT_STATUS_IS_OK(status)) {
4272 return NT_STATUS_OK;
4275 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
4276 struct lsa_CREDRRENAME *r)
4278 p->rng_fault_state = True;
4279 return NT_STATUS_NOT_IMPLEMENTED;
4282 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
4283 struct lsa_LSAROPENPOLICYSCE *r)
4285 p->rng_fault_state = True;
4286 return NT_STATUS_NOT_IMPLEMENTED;
4289 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4290 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4292 p->rng_fault_state = True;
4293 return NT_STATUS_NOT_IMPLEMENTED;
4296 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4297 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4299 p->rng_fault_state = True;
4300 return NT_STATUS_NOT_IMPLEMENTED;
4303 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4304 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4306 p->rng_fault_state = True;
4307 return NT_STATUS_NOT_IMPLEMENTED;