s4:selftest: samba.tests.krb5.netlogon don't need explicit FAST_SUPPORT
[Samba.git] / source3 / rpc_server / lsa / srv_lsa_nt.c
blobbf8ad241a5b1a2f6048726f7c5db801bc7abd89e
1 /*
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. */
32 #include "includes.h"
33 #include "ntdomain.h"
34 #include "librpc/gen_ndr/ndr_lsa.h"
35 #include "librpc/gen_ndr/ndr_lsa_scompat.h"
36 #include "secrets.h"
37 #include "../librpc/gen_ndr/netlogon.h"
38 #include "rpc_client/init_lsa.h"
39 #include "../libcli/security/security.h"
40 #include "../libcli/security/dom_sid.h"
41 #include "../librpc/gen_ndr/drsblobs.h"
42 #include "../librpc/gen_ndr/ndr_drsblobs.h"
43 #include "../libcli/security/dom_sid.h"
44 #include "../librpc/gen_ndr/ndr_security.h"
45 #include "passdb.h"
46 #include "auth.h"
47 #include "lib/privileges.h"
48 #include "rpc_server/srv_access_check.h"
49 #include "../librpc/gen_ndr/ndr_wkssvc.h"
50 #include "../libcli/auth/libcli_auth.h"
51 #include "../libcli/lsarpc/util_lsarpc.h"
52 #include "lsa.h"
53 #include "librpc/rpc/dcesrv_core.h"
54 #include "librpc/rpc/dcerpc_helper.h"
55 #include "lib/param/loadparm.h"
56 #include "source3/lib/substitute.h"
57 #include "librpc/rpc/dcerpc_lsa.h"
59 #include "lib/crypto/gnutls_helpers.h"
60 #include <gnutls/gnutls.h>
61 #include <gnutls/crypto.h>
63 #undef strcasecmp
65 #undef DBGC_CLASS
66 #define DBGC_CLASS DBGC_RPC_SRV
68 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
70 enum lsa_handle_type {
71 LSA_HANDLE_POLICY_TYPE = 1,
72 LSA_HANDLE_ACCOUNT_TYPE = 2,
73 LSA_HANDLE_TRUST_TYPE = 3,
74 LSA_HANDLE_SECRET_TYPE = 4};
76 struct lsa_info {
77 struct dom_sid sid;
78 const char *name;
79 uint32_t access;
80 enum lsa_handle_type type;
81 struct security_descriptor *sd;
84 const struct generic_mapping lsa_account_mapping = {
85 LSA_ACCOUNT_READ,
86 LSA_ACCOUNT_WRITE,
87 LSA_ACCOUNT_EXECUTE,
88 LSA_ACCOUNT_ALL_ACCESS
91 const struct generic_mapping lsa_policy_mapping = {
92 LSA_POLICY_READ,
93 LSA_POLICY_WRITE,
94 LSA_POLICY_EXECUTE,
95 LSA_POLICY_ALL_ACCESS
98 const struct generic_mapping lsa_secret_mapping = {
99 LSA_SECRET_READ,
100 LSA_SECRET_WRITE,
101 LSA_SECRET_EXECUTE,
102 LSA_SECRET_ALL_ACCESS
105 const struct generic_mapping lsa_trusted_domain_mapping = {
106 LSA_TRUSTED_DOMAIN_READ,
107 LSA_TRUSTED_DOMAIN_WRITE,
108 LSA_TRUSTED_DOMAIN_EXECUTE,
109 LSA_TRUSTED_DOMAIN_ALL_ACCESS
112 /***************************************************************************
113 initialize a lsa_DomainInfo structure.
114 ***************************************************************************/
116 static void init_dom_query_3(struct lsa_DomainInfo *r,
117 const char *name,
118 struct dom_sid *sid)
120 init_lsa_StringLarge(&r->name, name);
121 r->sid = sid;
124 /***************************************************************************
125 initialize a lsa_DomainInfo structure.
126 ***************************************************************************/
128 static void init_dom_query_5(struct lsa_DomainInfo *r,
129 const char *name,
130 struct dom_sid *sid)
132 init_lsa_StringLarge(&r->name, name);
133 r->sid = sid;
136 /***************************************************************************
137 lookup_lsa_rids. Must be called as root for lookup_name to work.
138 ***************************************************************************/
140 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
141 struct lsa_RefDomainList *ref,
142 struct lsa_TranslatedSid *prid,
143 uint32_t num_entries,
144 struct lsa_String *name,
145 int flags,
146 uint32_t *pmapped_count)
148 uint32_t mapped_count, i;
150 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
152 mapped_count = 0;
153 *pmapped_count = 0;
155 for (i = 0; i < num_entries; i++) {
156 struct dom_sid sid;
157 uint32_t rid;
158 int dom_idx;
159 const char *full_name;
160 const char *domain;
161 enum lsa_SidType type;
163 /* Split name into domain and user component */
165 /* follow w2k8 behavior and return the builtin domain when no
166 * input has been passed in */
168 if (name[i].string) {
169 full_name = name[i].string;
170 } else {
171 full_name = "BUILTIN";
174 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
176 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
177 &sid, &type)) {
178 type = SID_NAME_UNKNOWN;
181 switch (type) {
182 case SID_NAME_USER:
183 case SID_NAME_DOM_GRP:
184 case SID_NAME_DOMAIN:
185 case SID_NAME_ALIAS:
186 case SID_NAME_WKN_GRP:
187 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
188 /* Leave these unchanged */
189 break;
190 default:
191 /* Don't hand out anything but the list above */
192 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
193 type = SID_NAME_UNKNOWN;
194 break;
197 rid = 0;
198 dom_idx = -1;
200 if (type != SID_NAME_UNKNOWN) {
201 if (type == SID_NAME_DOMAIN) {
202 rid = (uint32_t)-1;
203 } else {
204 sid_split_rid(&sid, &rid);
206 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
207 mapped_count++;
210 prid[i].sid_type = type;
211 prid[i].rid = rid;
212 prid[i].sid_index = dom_idx;
215 *pmapped_count = mapped_count;
216 return NT_STATUS_OK;
219 /***************************************************************************
220 lookup_lsa_sids. Must be called as root for lookup_name to work.
221 ***************************************************************************/
223 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
224 struct lsa_RefDomainList *ref,
225 struct lsa_TranslatedSid3 *trans_sids,
226 uint32_t num_entries,
227 struct lsa_String *name,
228 int flags,
229 uint32_t *pmapped_count)
231 uint32_t mapped_count, i;
233 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
235 mapped_count = 0;
236 *pmapped_count = 0;
238 for (i = 0; i < num_entries; i++) {
239 struct dom_sid sid;
240 uint32_t rid;
241 int dom_idx;
242 const char *full_name;
243 const char *domain;
244 enum lsa_SidType type;
246 ZERO_STRUCT(sid);
248 /* Split name into domain and user component */
250 full_name = name[i].string;
251 if (full_name == NULL) {
252 return NT_STATUS_NO_MEMORY;
255 DEBUG(5, ("lookup_lsa_sids: looking up name %s\n", full_name));
257 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
258 &sid, &type)) {
259 type = SID_NAME_UNKNOWN;
262 switch (type) {
263 case SID_NAME_USER:
264 case SID_NAME_DOM_GRP:
265 case SID_NAME_DOMAIN:
266 case SID_NAME_ALIAS:
267 case SID_NAME_WKN_GRP:
268 DEBUG(5, ("lookup_lsa_sids: %s found\n", full_name));
269 /* Leave these unchanged */
270 break;
271 default:
272 /* Don't hand out anything but the list above */
273 DEBUG(5, ("lookup_lsa_sids: %s not found\n", full_name));
274 type = SID_NAME_UNKNOWN;
275 break;
278 rid = 0;
279 dom_idx = -1;
281 if (type != SID_NAME_UNKNOWN) {
282 struct dom_sid domain_sid;
283 sid_copy(&domain_sid, &sid);
284 sid_split_rid(&domain_sid, &rid);
285 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
286 mapped_count++;
289 /* Initialize the lsa_TranslatedSid3 return. */
290 trans_sids[i].sid_type = type;
291 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
292 trans_sids[i].sid_index = dom_idx;
295 *pmapped_count = mapped_count;
296 return NT_STATUS_OK;
299 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
300 const struct generic_mapping *map,
301 struct dom_sid *sid, uint32_t sid_access)
303 struct dom_sid adm_sid;
304 struct security_ace ace[5] = {};
305 size_t i = 0;
307 struct security_acl *psa = NULL;
309 /* READ|EXECUTE access for Everyone */
311 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
312 map->generic_execute | map->generic_read, 0);
314 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
316 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
317 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
318 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
319 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
321 /* Add Full Access for Domain Admins */
322 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
323 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
324 map->generic_all, 0);
326 /* If we have a sid, give it some special access */
328 if (sid) {
329 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
330 sid_access, 0);
333 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
334 return NT_STATUS_NO_MEMORY;
336 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
337 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
338 psa, sd_size)) == NULL)
339 return NT_STATUS_NO_MEMORY;
341 return NT_STATUS_OK;
344 /***************************************************************************
345 ***************************************************************************/
347 static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
348 struct pipes_struct *p,
349 enum lsa_handle_type type,
350 uint32_t acc_granted,
351 struct dom_sid *sid,
352 const char *name,
353 const struct security_descriptor *sd,
354 struct policy_handle *handle)
356 struct lsa_info *info;
358 ZERO_STRUCTP(handle);
360 info = talloc_zero(mem_ctx, struct lsa_info);
361 if (!info) {
362 return NT_STATUS_NO_MEMORY;
365 info->type = type;
366 info->access = acc_granted;
368 if (sid) {
369 sid_copy(&info->sid, sid);
372 info->name = talloc_strdup(info, name);
374 if (sd != NULL) {
375 info->sd = security_descriptor_copy(info, sd);
376 if (info->sd == NULL) {
377 talloc_free(info);
378 return NT_STATUS_NO_MEMORY;
382 if (!create_policy_hnd(p, handle, type, info)) {
383 talloc_free(info);
384 ZERO_STRUCTP(handle);
385 return NT_STATUS_NO_MEMORY;
388 return NT_STATUS_OK;
391 /***************************************************************************
392 _lsa_OpenPolicy2
393 ***************************************************************************/
395 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
396 struct lsa_OpenPolicy2 *r)
398 struct dcesrv_call_state *dce_call = p->dce_call;
399 struct auth_session_info *session_info =
400 dcesrv_call_session_info(dce_call);
401 struct security_descriptor *psd = NULL;
402 size_t sd_size;
403 uint32_t des_access = r->in.access_mask;
404 uint32_t acc_granted;
405 NTSTATUS status;
407 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
408 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
409 return NT_STATUS_ACCESS_DENIED;
412 /* Work out max allowed. */
413 map_max_allowed_access(session_info->security_token,
414 session_info->unix_token,
415 &des_access);
417 /* map the generic bits to the lsa policy ones */
418 se_map_generic(&des_access, &lsa_policy_mapping);
420 /* get the generic lsa policy SD until we store it */
421 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
422 NULL, 0);
423 if (!NT_STATUS_IS_OK(status)) {
424 return status;
427 status = access_check_object(psd, session_info->security_token,
428 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
429 &acc_granted, "_lsa_OpenPolicy2" );
430 if (!NT_STATUS_IS_OK(status)) {
431 return status;
434 status = create_lsa_policy_handle(p->mem_ctx, p,
435 LSA_HANDLE_POLICY_TYPE,
436 acc_granted,
437 get_global_sam_sid(),
438 NULL,
439 psd,
440 r->out.handle);
441 if (!NT_STATUS_IS_OK(status)) {
442 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
445 return NT_STATUS_OK;
448 /***************************************************************************
449 _lsa_OpenPolicy
450 ***************************************************************************/
452 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
453 struct lsa_OpenPolicy *r)
455 struct lsa_OpenPolicy2 o;
457 /* _lsa_OpenPolicy2 will check if this is a NCACN_NP connection */
459 o.in.system_name = NULL; /* should be ignored */
460 o.in.attr = r->in.attr;
461 o.in.access_mask = r->in.access_mask;
463 o.out.handle = r->out.handle;
465 return _lsa_OpenPolicy2(p, &o);
468 /***************************************************************************
469 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
470 ufff, done :) mimir
471 ***************************************************************************/
473 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
474 struct lsa_EnumTrustDom *r)
476 struct lsa_info *info;
477 uint32_t i, count;
478 struct trustdom_info **domains;
479 struct lsa_DomainInfo *entries;
480 NTSTATUS nt_status;
482 info = find_policy_by_hnd(p,
483 r->in.handle,
484 LSA_HANDLE_POLICY_TYPE,
485 struct lsa_info,
486 &nt_status);
487 if (!NT_STATUS_IS_OK(nt_status)) {
488 return NT_STATUS_INVALID_HANDLE;
491 /* check if the user has enough rights */
492 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
493 return NT_STATUS_ACCESS_DENIED;
495 become_root();
496 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
497 unbecome_root();
499 if (!NT_STATUS_IS_OK(nt_status)) {
500 return nt_status;
503 entries = talloc_zero_array(p->mem_ctx, struct lsa_DomainInfo, count);
504 if (!entries) {
505 return NT_STATUS_NO_MEMORY;
508 for (i=0; i<count; i++) {
509 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
510 entries[i].sid = &domains[i]->sid;
513 if (*r->in.resume_handle >= count) {
514 *r->out.resume_handle = -1;
515 TALLOC_FREE(entries);
516 return NT_STATUS_NO_MORE_ENTRIES;
519 /* return the rest, limit by max_size. Note that we
520 use the w2k3 element size value of 60 */
521 r->out.domains->count = count - *r->in.resume_handle;
522 r->out.domains->count = MIN(r->out.domains->count,
523 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
525 r->out.domains->domains = entries + *r->in.resume_handle;
527 if (r->out.domains->count < count - *r->in.resume_handle) {
528 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
529 return STATUS_MORE_ENTRIES;
532 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
533 * always be larger than the previous input resume handle, in
534 * particular when hitting the last query it is vital to set the
535 * resume handle correctly to avoid infinite client loops, as
536 * seen e.g. with Windows XP SP3 when resume handle is 0 and
537 * status is NT_STATUS_OK - gd */
539 *r->out.resume_handle = (uint32_t)-1;
541 return NT_STATUS_OK;
544 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
545 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
546 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
548 /***************************************************************************
549 _lsa_QueryInfoPolicy
550 ***************************************************************************/
552 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
553 struct lsa_QueryInfoPolicy *r)
555 NTSTATUS status = NT_STATUS_OK;
556 struct lsa_info *handle;
557 struct dom_sid domain_sid;
558 const char *name;
559 struct dom_sid *sid = NULL;
560 union lsa_PolicyInformation *info = NULL;
561 uint32_t acc_required = 0;
563 handle = find_policy_by_hnd(p,
564 r->in.handle,
565 LSA_HANDLE_POLICY_TYPE,
566 struct lsa_info,
567 &status);
568 if (!NT_STATUS_IS_OK(status)) {
569 return NT_STATUS_INVALID_HANDLE;
572 switch (r->in.level) {
573 case LSA_POLICY_INFO_AUDIT_LOG:
574 case LSA_POLICY_INFO_AUDIT_EVENTS:
575 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
576 break;
577 case LSA_POLICY_INFO_DOMAIN:
578 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
579 break;
580 case LSA_POLICY_INFO_PD:
581 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
582 break;
583 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
584 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
585 break;
586 case LSA_POLICY_INFO_ROLE:
587 case LSA_POLICY_INFO_REPLICA:
588 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
589 break;
590 case LSA_POLICY_INFO_QUOTA:
591 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
592 break;
593 case LSA_POLICY_INFO_MOD:
594 case LSA_POLICY_INFO_AUDIT_FULL_SET:
595 /* according to MS-LSAD 3.1.4.4.3 */
596 return NT_STATUS_INVALID_PARAMETER;
597 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
598 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
599 break;
600 case LSA_POLICY_INFO_DNS:
601 case LSA_POLICY_INFO_DNS_INT:
602 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
603 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
604 break;
605 default:
606 break;
609 if (!(handle->access & acc_required)) {
610 /* return NT_STATUS_ACCESS_DENIED; */
613 info = talloc_zero(p->mem_ctx, union lsa_PolicyInformation);
614 if (!info) {
615 return NT_STATUS_NO_MEMORY;
618 switch (r->in.level) {
619 /* according to MS-LSAD 3.1.4.4.3 */
620 case LSA_POLICY_INFO_MOD:
621 case LSA_POLICY_INFO_AUDIT_FULL_SET:
622 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
623 return NT_STATUS_INVALID_PARAMETER;
624 case LSA_POLICY_INFO_AUDIT_LOG:
625 info->audit_log.percent_full = 0;
626 info->audit_log.maximum_log_size = 0;
627 info->audit_log.retention_time = 0;
628 info->audit_log.shutdown_in_progress = 0;
629 info->audit_log.time_to_shutdown = 0;
630 info->audit_log.next_audit_record = 0;
631 status = NT_STATUS_OK;
632 break;
633 case LSA_POLICY_INFO_PD:
634 info->pd.name.string = NULL;
635 status = NT_STATUS_OK;
636 break;
637 case LSA_POLICY_INFO_REPLICA:
638 info->replica.source.string = NULL;
639 info->replica.account.string = NULL;
640 status = NT_STATUS_OK;
641 break;
642 case LSA_POLICY_INFO_QUOTA:
643 info->quota.paged_pool = 0;
644 info->quota.non_paged_pool = 0;
645 info->quota.min_wss = 0;
646 info->quota.max_wss = 0;
647 info->quota.pagefile = 0;
648 info->quota.unknown = 0;
649 status = NT_STATUS_OK;
650 break;
651 case LSA_POLICY_INFO_AUDIT_EVENTS:
654 uint32_t policy_def = LSA_AUDIT_POLICY_ALL;
656 /* check if the user has enough rights */
657 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
658 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
659 return NT_STATUS_ACCESS_DENIED;
662 /* fake info: We audit everything. ;) */
664 info->audit_events.auditing_mode = true;
665 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
666 info->audit_events.settings = talloc_zero_array(p->mem_ctx,
667 enum lsa_PolicyAuditPolicy,
668 info->audit_events.count);
669 if (!info->audit_events.settings) {
670 return NT_STATUS_NO_MEMORY;
673 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
674 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
675 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
676 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
677 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
678 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
679 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
681 break;
683 case LSA_POLICY_INFO_DOMAIN:
684 /* check if the user has enough rights */
685 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
686 return NT_STATUS_ACCESS_DENIED;
688 /* Request PolicyPrimaryDomainInformation. */
689 switch (lp_server_role()) {
690 case ROLE_DOMAIN_PDC:
691 case ROLE_DOMAIN_BDC:
692 case ROLE_IPA_DC:
693 name = get_global_sam_name();
694 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
695 if (!sid) {
696 return NT_STATUS_NO_MEMORY;
698 break;
699 case ROLE_DOMAIN_MEMBER:
700 name = lp_workgroup();
701 /* We need to return the Domain SID here. */
702 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
703 sid = dom_sid_dup(p->mem_ctx, &domain_sid);
704 if (!sid) {
705 return NT_STATUS_NO_MEMORY;
707 } else {
708 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
710 break;
711 case ROLE_STANDALONE:
712 name = lp_workgroup();
713 sid = NULL;
714 break;
715 default:
716 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
718 init_dom_query_3(&info->domain, name, sid);
719 break;
720 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
721 /* check if the user has enough rights */
722 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
723 return NT_STATUS_ACCESS_DENIED;
725 /* Request PolicyAccountDomainInformation. */
726 name = get_global_sam_name();
727 sid = get_global_sam_sid();
729 init_dom_query_5(&info->account_domain, name, sid);
730 break;
731 case LSA_POLICY_INFO_ROLE:
732 /* check if the user has enough rights */
733 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
734 return NT_STATUS_ACCESS_DENIED;
736 switch (lp_server_role()) {
737 case ROLE_DOMAIN_BDC:
739 * only a BDC is a backup controller
740 * of the domain, it controls.
742 info->role.role = LSA_ROLE_BACKUP;
743 break;
744 default:
746 * any other role is a primary
747 * of the domain, it controls.
749 info->role.role = LSA_ROLE_PRIMARY;
750 break;
752 break;
753 case LSA_POLICY_INFO_DNS:
754 case LSA_POLICY_INFO_DNS_INT: {
755 struct pdb_domain_info *dominfo;
757 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
758 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
759 "without ADS passdb backend\n"));
760 status = NT_STATUS_INVALID_INFO_CLASS;
761 break;
764 dominfo = pdb_get_domain_info(info);
765 if (dominfo == NULL) {
766 status = NT_STATUS_NO_MEMORY;
767 break;
770 init_lsa_StringLarge(&info->dns.name,
771 dominfo->name);
772 init_lsa_StringLarge(&info->dns.dns_domain,
773 dominfo->dns_domain);
774 init_lsa_StringLarge(&info->dns.dns_forest,
775 dominfo->dns_forest);
776 info->dns.domain_guid = dominfo->guid;
777 info->dns.sid = &dominfo->sid;
778 break;
780 default:
781 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
782 r->in.level));
783 status = NT_STATUS_INVALID_INFO_CLASS;
784 break;
787 *r->out.info = info;
789 return status;
792 /***************************************************************************
793 _lsa_QueryInfoPolicy2
794 ***************************************************************************/
796 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
797 struct lsa_QueryInfoPolicy2 *r2)
799 struct lsa_QueryInfoPolicy r;
801 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
802 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
803 return NT_STATUS_NOT_IMPLEMENTED;
806 ZERO_STRUCT(r);
807 r.in.handle = r2->in.handle;
808 r.in.level = r2->in.level;
809 r.out.info = r2->out.info;
811 return _lsa_QueryInfoPolicy(p, &r);
814 /***************************************************************************
815 _lsa_lookup_sids_internal
816 ***************************************************************************/
818 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
819 TALLOC_CTX *mem_ctx,
820 uint16_t level, /* input */
821 int num_sids, /* input */
822 struct lsa_SidPtr *sid, /* input */
823 struct lsa_RefDomainList **pp_ref, /* input/output */
824 struct lsa_TranslatedName2 **pp_names,/* input/output */
825 uint32_t *pp_mapped_count) /* input/output */
827 NTSTATUS status;
828 int i;
829 const struct dom_sid **sids = NULL;
830 struct lsa_RefDomainList *ref = NULL;
831 uint32_t mapped_count = 0;
832 struct lsa_dom_info *dom_infos = NULL;
833 struct lsa_name_info *name_infos = NULL;
834 struct lsa_TranslatedName2 *names = NULL;
836 *pp_mapped_count = 0;
837 *pp_names = NULL;
838 *pp_ref = NULL;
840 if (num_sids == 0) {
841 return NT_STATUS_OK;
844 sids = talloc_array(p->mem_ctx, const struct dom_sid *, num_sids);
845 ref = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
847 if (sids == NULL || ref == NULL) {
848 return NT_STATUS_NO_MEMORY;
851 for (i=0; i<num_sids; i++) {
852 sids[i] = sid[i].sid;
855 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
856 &dom_infos, &name_infos);
858 if (!NT_STATUS_IS_OK(status)) {
859 return status;
862 names = talloc_array(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
863 if (names == NULL) {
864 return NT_STATUS_NO_MEMORY;
867 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
869 if (!dom_infos[i].valid) {
870 break;
873 if (init_lsa_ref_domain_list(mem_ctx, ref,
874 dom_infos[i].name,
875 &dom_infos[i].sid) != i) {
876 DEBUG(0, ("Domain %s mentioned twice??\n",
877 dom_infos[i].name));
878 return NT_STATUS_INTERNAL_ERROR;
882 for (i=0; i<num_sids; i++) {
883 struct lsa_name_info *name = &name_infos[i];
885 if (name->type == SID_NAME_UNKNOWN) {
886 name->dom_idx = -1;
887 /* Unknown sids should return the string
888 * representation of the SID. Windows 2003 behaves
889 * rather erratic here, in many cases it returns the
890 * RID as 8 bytes hex, in others it returns the full
891 * SID. We (Jerry/VL) could not figure out which the
892 * hard cases are, so leave it with the SID. */
893 name->name = dom_sid_string(p->mem_ctx, sids[i]);
894 if (name->name == NULL) {
895 return NT_STATUS_NO_MEMORY;
897 } else {
898 mapped_count += 1;
901 names[i].sid_type = name->type;
902 names[i].name.string = name->name;
903 names[i].sid_index = name->dom_idx;
904 names[i].unknown = 0;
907 status = NT_STATUS_NONE_MAPPED;
908 if (mapped_count > 0) {
909 status = (mapped_count < num_sids) ?
910 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
913 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
914 num_sids, mapped_count, nt_errstr(status)));
916 *pp_mapped_count = mapped_count;
917 *pp_names = names;
918 *pp_ref = ref;
920 return status;
923 /***************************************************************************
924 _lsa_LookupSids
925 ***************************************************************************/
927 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
928 struct lsa_LookupSids *r)
930 NTSTATUS status;
931 struct lsa_info *handle;
932 int num_sids = r->in.sids->num_sids;
933 uint32_t mapped_count = 0;
934 struct lsa_RefDomainList *domains = NULL;
935 struct lsa_TranslatedName *names_out = NULL;
936 struct lsa_TranslatedName2 *names = NULL;
937 int i;
939 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
940 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
941 return NT_STATUS_ACCESS_DENIED;
944 if ((r->in.level < 1) || (r->in.level > 6)) {
945 return NT_STATUS_INVALID_PARAMETER;
948 handle = find_policy_by_hnd(p,
949 r->in.handle,
950 LSA_HANDLE_POLICY_TYPE,
951 struct lsa_info,
952 &status);
953 if (!NT_STATUS_IS_OK(status)) {
954 return NT_STATUS_INVALID_HANDLE;
957 /* check if the user has enough rights */
958 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
959 return NT_STATUS_ACCESS_DENIED;
962 if (num_sids > MAX_LOOKUP_SIDS) {
963 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
964 MAX_LOOKUP_SIDS, num_sids));
965 return NT_STATUS_NONE_MAPPED;
968 status = _lsa_lookup_sids_internal(p,
969 p->mem_ctx,
970 r->in.level,
971 num_sids,
972 r->in.sids->sids,
973 &domains,
974 &names,
975 &mapped_count);
977 /* Only return here when there is a real error.
978 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
979 the requested sids could be resolved. Older versions of XP (pre SP3)
980 rely that we return with the string representations of those SIDs in
981 that case. If we don't, XP crashes - Guenther
984 if (NT_STATUS_IS_ERR(status) &&
985 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
986 return status;
989 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
990 names_out = talloc_array(p->mem_ctx, struct lsa_TranslatedName,
991 num_sids);
992 if (!names_out) {
993 return NT_STATUS_NO_MEMORY;
996 for (i=0; i<num_sids; i++) {
997 names_out[i].sid_type = names[i].sid_type;
998 names_out[i].name = names[i].name;
999 names_out[i].sid_index = names[i].sid_index;
1002 *r->out.domains = domains;
1003 r->out.names->count = num_sids;
1004 r->out.names->names = names_out;
1005 *r->out.count = mapped_count;
1007 return status;
1010 static NTSTATUS _lsa_LookupSids_common(struct pipes_struct *p,
1011 struct lsa_LookupSids2 *r)
1013 struct dcesrv_call_state *dce_call = p->dce_call;
1014 NTSTATUS status;
1015 struct lsa_info *handle;
1016 int num_sids = r->in.sids->num_sids;
1017 uint32_t mapped_count = 0;
1018 struct lsa_RefDomainList *domains = NULL;
1019 struct lsa_TranslatedName2 *names = NULL;
1020 bool check_policy = true;
1022 switch (dce_call->pkt.u.request.opnum) {
1023 case NDR_LSA_LOOKUPSIDS3:
1024 check_policy = false;
1025 break;
1026 case NDR_LSA_LOOKUPSIDS2:
1027 default:
1028 check_policy = true;
1031 if ((r->in.level < 1) || (r->in.level > 6)) {
1032 return NT_STATUS_INVALID_PARAMETER;
1035 if (check_policy) {
1036 handle = find_policy_by_hnd(p,
1037 r->in.handle,
1038 LSA_HANDLE_POLICY_TYPE,
1039 struct lsa_info,
1040 &status);
1041 if (!NT_STATUS_IS_OK(status)) {
1042 return NT_STATUS_INVALID_HANDLE;
1045 /* check if the user has enough rights */
1046 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1047 return NT_STATUS_ACCESS_DENIED;
1051 if (num_sids > MAX_LOOKUP_SIDS) {
1052 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1053 MAX_LOOKUP_SIDS, num_sids));
1054 return NT_STATUS_NONE_MAPPED;
1057 status = _lsa_lookup_sids_internal(p,
1058 p->mem_ctx,
1059 r->in.level,
1060 num_sids,
1061 r->in.sids->sids,
1062 &domains,
1063 &names,
1064 &mapped_count);
1066 *r->out.domains = domains;
1067 r->out.names->count = num_sids;
1068 r->out.names->names = names;
1069 *r->out.count = mapped_count;
1071 return status;
1074 /***************************************************************************
1075 _lsa_LookupSids2
1076 ***************************************************************************/
1078 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1079 struct lsa_LookupSids2 *r)
1081 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1082 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1083 return NT_STATUS_ACCESS_DENIED;
1086 return _lsa_LookupSids_common(p, r);
1089 /***************************************************************************
1090 _lsa_LookupSids3
1091 ***************************************************************************/
1093 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1094 struct lsa_LookupSids3 *r)
1096 struct dcesrv_call_state *dce_call = p->dce_call;
1097 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1098 enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
1099 struct lsa_LookupSids2 q;
1101 if (p->transport != NCACN_IP_TCP) {
1102 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1103 return NT_STATUS_ACCESS_DENIED;
1106 dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
1108 /* No policy handle on this call. Restrict to crypto connections. */
1109 if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
1110 auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1111 DEBUG(1, ("_lsa_LookupSids3: The client %s is not using "
1112 "a secure connection over netlogon\n",
1113 get_remote_machine_name() ));
1114 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1115 return NT_STATUS_ACCESS_DENIED;
1118 q.in.handle = NULL;
1119 q.in.sids = r->in.sids;
1120 q.in.level = r->in.level;
1121 q.in.lookup_options = r->in.lookup_options;
1122 q.in.client_revision = r->in.client_revision;
1123 q.in.names = r->in.names;
1124 q.in.count = r->in.count;
1126 q.out.domains = r->out.domains;
1127 q.out.names = r->out.names;
1128 q.out.count = r->out.count;
1130 return _lsa_LookupSids_common(p, &q);
1133 /***************************************************************************
1134 ***************************************************************************/
1136 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1138 int flags;
1140 switch (level) {
1141 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1142 flags = LOOKUP_NAME_ALL;
1143 break;
1144 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1145 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1146 break;
1147 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1148 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1149 break;
1150 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1151 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1152 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1153 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1154 default:
1155 flags = LOOKUP_NAME_NONE;
1156 break;
1159 return flags;
1162 /***************************************************************************
1163 _lsa_LookupNames
1164 ***************************************************************************/
1166 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1167 struct lsa_LookupNames *r)
1169 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1170 struct lsa_info *handle;
1171 struct lsa_String *names = r->in.names;
1172 uint32_t num_entries = r->in.num_names;
1173 struct lsa_RefDomainList *domains = NULL;
1174 struct lsa_TranslatedSid *rids = NULL;
1175 uint32_t mapped_count = 0;
1176 int flags = 0;
1178 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1179 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1180 return NT_STATUS_ACCESS_DENIED;
1183 if (num_entries > MAX_LOOKUP_SIDS) {
1184 num_entries = MAX_LOOKUP_SIDS;
1185 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1186 num_entries));
1189 flags = lsa_lookup_level_to_flags(r->in.level);
1191 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1192 if (!domains) {
1193 return NT_STATUS_NO_MEMORY;
1196 if (num_entries) {
1197 rids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid,
1198 num_entries);
1199 if (!rids) {
1200 return NT_STATUS_NO_MEMORY;
1202 } else {
1203 rids = NULL;
1206 handle = find_policy_by_hnd(p,
1207 r->in.handle,
1208 LSA_HANDLE_POLICY_TYPE,
1209 struct lsa_info,
1210 &status);
1211 if (!NT_STATUS_IS_OK(status)) {
1212 status = NT_STATUS_INVALID_HANDLE;
1213 goto done;
1216 /* check if the user has enough rights */
1217 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1218 status = NT_STATUS_ACCESS_DENIED;
1219 goto done;
1222 /* set up the LSA Lookup RIDs response */
1223 become_root(); /* lookup_name can require root privs */
1224 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1225 names, flags, &mapped_count);
1226 unbecome_root();
1228 done:
1230 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1231 if (mapped_count == 0) {
1232 status = NT_STATUS_NONE_MAPPED;
1233 } else if (mapped_count != num_entries) {
1234 status = STATUS_SOME_UNMAPPED;
1238 *r->out.count = mapped_count;
1239 *r->out.domains = domains;
1240 r->out.sids->sids = rids;
1241 r->out.sids->count = num_entries;
1243 return status;
1246 /***************************************************************************
1247 _lsa_LookupNames2
1248 ***************************************************************************/
1250 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1251 struct lsa_LookupNames2 *r)
1253 NTSTATUS status;
1254 struct lsa_LookupNames q;
1255 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1256 struct lsa_TransSidArray *sid_array = NULL;
1257 uint32_t i;
1259 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1260 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1261 return NT_STATUS_ACCESS_DENIED;
1264 sid_array = talloc_zero(p->mem_ctx, struct lsa_TransSidArray);
1265 if (!sid_array) {
1266 return NT_STATUS_NO_MEMORY;
1269 q.in.handle = r->in.handle;
1270 q.in.num_names = r->in.num_names;
1271 q.in.names = r->in.names;
1272 q.in.level = r->in.level;
1273 q.in.sids = sid_array;
1274 q.in.count = r->in.count;
1275 /* we do not know what this is for */
1276 /* = r->in.unknown1; */
1277 /* = r->in.unknown2; */
1279 q.out.domains = r->out.domains;
1280 q.out.sids = sid_array;
1281 q.out.count = r->out.count;
1283 status = _lsa_LookupNames(p, &q);
1285 sid_array2->count = sid_array->count;
1286 sid_array2->sids = talloc_array(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1287 if (!sid_array2->sids) {
1288 return NT_STATUS_NO_MEMORY;
1291 for (i=0; i<sid_array->count; i++) {
1292 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1293 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1294 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1295 sid_array2->sids[i].unknown = 0;
1298 r->out.sids = sid_array2;
1300 return status;
1303 static NTSTATUS _lsa_LookupNames_common(struct pipes_struct *p,
1304 struct lsa_LookupNames3 *r)
1306 struct dcesrv_call_state *dce_call = p->dce_call;
1307 NTSTATUS status;
1308 struct lsa_info *handle;
1309 struct lsa_String *names = r->in.names;
1310 uint32_t num_entries = r->in.num_names;
1311 struct lsa_RefDomainList *domains = NULL;
1312 struct lsa_TranslatedSid3 *trans_sids = NULL;
1313 uint32_t mapped_count = 0;
1314 int flags = 0;
1315 bool check_policy = true;
1317 switch (dce_call->pkt.u.request.opnum) {
1318 case NDR_LSA_LOOKUPNAMES4:
1319 check_policy = false;
1320 break;
1321 case NDR_LSA_LOOKUPNAMES3:
1322 default:
1323 check_policy = true;
1326 if (num_entries > MAX_LOOKUP_SIDS) {
1327 num_entries = MAX_LOOKUP_SIDS;
1328 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1331 flags = lsa_lookup_level_to_flags(r->in.level);
1333 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1334 if (!domains) {
1335 return NT_STATUS_NO_MEMORY;
1338 if (num_entries) {
1339 trans_sids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid3,
1340 num_entries);
1341 if (!trans_sids) {
1342 return NT_STATUS_NO_MEMORY;
1344 } else {
1345 trans_sids = NULL;
1348 if (check_policy) {
1350 handle = find_policy_by_hnd(p,
1351 r->in.handle,
1352 LSA_HANDLE_POLICY_TYPE,
1353 struct lsa_info,
1354 &status);
1355 if (!NT_STATUS_IS_OK(status)) {
1356 status = NT_STATUS_INVALID_HANDLE;
1357 goto done;
1360 /* check if the user has enough rights */
1361 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1362 status = NT_STATUS_ACCESS_DENIED;
1363 goto done;
1367 /* set up the LSA Lookup SIDs response */
1368 become_root(); /* lookup_name can require root privs */
1369 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1370 names, flags, &mapped_count);
1371 unbecome_root();
1373 done:
1375 if (NT_STATUS_IS_OK(status)) {
1376 if (mapped_count == 0) {
1377 status = NT_STATUS_NONE_MAPPED;
1378 } else if (mapped_count != num_entries) {
1379 status = STATUS_SOME_UNMAPPED;
1383 *r->out.count = mapped_count;
1384 *r->out.domains = domains;
1385 r->out.sids->sids = trans_sids;
1386 r->out.sids->count = num_entries;
1388 return status;
1391 /***************************************************************************
1392 _lsa_LookupNames3
1393 ***************************************************************************/
1395 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1396 struct lsa_LookupNames3 *r)
1398 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1399 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1400 return NT_STATUS_ACCESS_DENIED;
1403 return _lsa_LookupNames_common(p, r);
1406 /***************************************************************************
1407 _lsa_LookupNames4
1408 ***************************************************************************/
1410 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1411 struct lsa_LookupNames4 *r)
1413 struct dcesrv_call_state *dce_call = p->dce_call;
1414 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1415 enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
1416 struct lsa_LookupNames3 q;
1418 if (p->transport != NCACN_IP_TCP) {
1419 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1420 return NT_STATUS_ACCESS_DENIED;
1423 dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
1425 /* No policy handle on this call. Restrict to crypto connections. */
1426 if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
1427 auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1428 DEBUG(1, ("_lsa_LookupNames4: The client %s is not using "
1429 "a secure connection over netlogon\n",
1430 get_remote_machine_name()));
1431 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1432 return NT_STATUS_ACCESS_DENIED;
1435 q.in.handle = NULL;
1436 q.in.num_names = r->in.num_names;
1437 q.in.names = r->in.names;
1438 q.in.level = r->in.level;
1439 q.in.lookup_options = r->in.lookup_options;
1440 q.in.client_revision = r->in.client_revision;
1441 q.in.sids = r->in.sids;
1442 q.in.count = r->in.count;
1444 q.out.domains = r->out.domains;
1445 q.out.sids = r->out.sids;
1446 q.out.count = r->out.count;
1448 return _lsa_LookupNames_common(p, &q);
1451 /***************************************************************************
1452 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1453 ***************************************************************************/
1455 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1457 NTSTATUS status;
1459 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1460 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1461 return NT_STATUS_ACCESS_DENIED;
1464 (void)find_policy_by_hnd(p,
1465 r->in.handle,
1466 DCESRV_HANDLE_ANY,
1467 struct lsa_info,
1468 &status);
1469 if (!NT_STATUS_IS_OK(status)) {
1470 return NT_STATUS_INVALID_HANDLE;
1473 close_policy_hnd(p, r->in.handle);
1474 ZERO_STRUCTP(r->out.handle);
1475 return NT_STATUS_OK;
1478 /***************************************************************************
1479 ***************************************************************************/
1481 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1482 const struct dom_sid *sid,
1483 struct trustdom_info **info)
1485 NTSTATUS status;
1486 uint32_t num_domains = 0;
1487 struct trustdom_info **domains = NULL;
1488 int i;
1490 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1491 if (!NT_STATUS_IS_OK(status)) {
1492 return status;
1495 for (i=0; i < num_domains; i++) {
1496 if (dom_sid_equal(&domains[i]->sid, sid)) {
1497 break;
1501 if (i == num_domains) {
1502 return NT_STATUS_INVALID_PARAMETER;
1505 *info = domains[i];
1507 return NT_STATUS_OK;
1510 /***************************************************************************
1511 ***************************************************************************/
1513 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1514 const char *netbios_domain_name,
1515 struct trustdom_info **info_p)
1517 NTSTATUS status;
1518 struct trustdom_info *info;
1519 struct pdb_trusted_domain *td;
1521 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1522 if (!NT_STATUS_IS_OK(status)) {
1523 return status;
1526 info = talloc(mem_ctx, struct trustdom_info);
1527 if (!info) {
1528 return NT_STATUS_NO_MEMORY;
1531 info->name = talloc_strdup(info, netbios_domain_name);
1532 NT_STATUS_HAVE_NO_MEMORY(info->name);
1534 sid_copy(&info->sid, &td->security_identifier);
1536 *info_p = info;
1538 return NT_STATUS_OK;
1541 /***************************************************************************
1542 _lsa_OpenSecret
1543 ***************************************************************************/
1545 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p,
1546 struct lsa_OpenSecret *r)
1548 struct dcesrv_call_state *dce_call = p->dce_call;
1549 struct auth_session_info *session_info =
1550 dcesrv_call_session_info(dce_call);
1551 struct security_descriptor *psd;
1552 NTSTATUS status;
1553 uint32_t acc_granted;
1555 (void)find_policy_by_hnd(p,
1556 r->in.handle,
1557 LSA_HANDLE_POLICY_TYPE,
1558 struct lsa_info,
1559 &status);
1560 if (!NT_STATUS_IS_OK(status)) {
1561 return NT_STATUS_INVALID_HANDLE;
1564 if (!r->in.name.string) {
1565 return NT_STATUS_INVALID_PARAMETER;
1568 /* Work out max allowed. */
1569 map_max_allowed_access(session_info->security_token,
1570 session_info->unix_token,
1571 &r->in.access_mask);
1573 /* map the generic bits to the lsa policy ones */
1574 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
1576 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
1577 NULL,
1578 NULL,
1579 NULL,
1580 NULL,
1581 &psd);
1582 if (!NT_STATUS_IS_OK(status)) {
1583 return status;
1586 status = access_check_object(psd, session_info->security_token,
1587 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1588 r->in.access_mask,
1589 &acc_granted, "_lsa_OpenSecret");
1590 if (!NT_STATUS_IS_OK(status)) {
1591 return status;
1594 status = create_lsa_policy_handle(p->mem_ctx, p,
1595 LSA_HANDLE_SECRET_TYPE,
1596 acc_granted,
1597 NULL,
1598 r->in.name.string,
1599 psd,
1600 r->out.sec_handle);
1601 if (!NT_STATUS_IS_OK(status)) {
1602 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1605 return NT_STATUS_OK;
1608 /***************************************************************************
1609 _lsa_OpenTrustedDomain_base
1610 ***************************************************************************/
1612 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1613 uint32_t access_mask,
1614 struct trustdom_info *info,
1615 struct policy_handle *handle)
1617 struct dcesrv_call_state *dce_call = p->dce_call;
1618 struct auth_session_info *session_info =
1619 dcesrv_call_session_info(dce_call);
1620 struct security_descriptor *psd = NULL;
1621 size_t sd_size;
1622 uint32_t acc_granted;
1623 NTSTATUS status;
1625 /* des_access is for the account here, not the policy
1626 * handle - so don't check against policy handle. */
1628 /* Work out max allowed. */
1629 map_max_allowed_access(session_info->security_token,
1630 session_info->unix_token,
1631 &access_mask);
1633 /* map the generic bits to the lsa account ones */
1634 se_map_generic(&access_mask, &lsa_trusted_domain_mapping);
1636 /* get the generic lsa account SD until we store it */
1637 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1638 &lsa_trusted_domain_mapping,
1639 NULL, 0);
1640 if (!NT_STATUS_IS_OK(status)) {
1641 return status;
1644 status = access_check_object(psd, session_info->security_token,
1645 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1646 access_mask, &acc_granted,
1647 "_lsa_OpenTrustedDomain");
1648 if (!NT_STATUS_IS_OK(status)) {
1649 return status;
1652 status = create_lsa_policy_handle(p->mem_ctx, p,
1653 LSA_HANDLE_TRUST_TYPE,
1654 acc_granted,
1655 &info->sid,
1656 info->name,
1657 psd,
1658 handle);
1659 if (!NT_STATUS_IS_OK(status)) {
1660 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1663 return NT_STATUS_OK;
1666 /***************************************************************************
1667 _lsa_OpenTrustedDomain
1668 ***************************************************************************/
1670 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1671 struct lsa_OpenTrustedDomain *r)
1673 struct trustdom_info *info = NULL;
1674 NTSTATUS status;
1676 (void)find_policy_by_hnd(p,
1677 r->in.handle,
1678 LSA_HANDLE_POLICY_TYPE,
1679 struct lsa_info,
1680 &status);
1681 if (!NT_STATUS_IS_OK(status)) {
1682 return NT_STATUS_INVALID_HANDLE;
1685 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1686 r->in.sid,
1687 &info);
1688 if (!NT_STATUS_IS_OK(status)) {
1689 return status;
1692 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1693 r->out.trustdom_handle);
1696 /***************************************************************************
1697 _lsa_OpenTrustedDomainByName
1698 ***************************************************************************/
1700 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1701 struct lsa_OpenTrustedDomainByName *r)
1703 struct trustdom_info *info = NULL;
1704 NTSTATUS status;
1706 (void)find_policy_by_hnd(p,
1707 r->in.handle,
1708 LSA_HANDLE_POLICY_TYPE,
1709 struct lsa_info,
1710 &status);
1711 if (!NT_STATUS_IS_OK(status)) {
1712 return NT_STATUS_INVALID_HANDLE;
1715 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1716 r->in.name.string,
1717 &info);
1718 if (!NT_STATUS_IS_OK(status)) {
1719 return status;
1722 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1723 r->out.trustdom_handle);
1726 static NTSTATUS get_trustdom_auth_blob_aes(
1727 struct dcesrv_call_state *dce_call,
1728 TALLOC_CTX *mem_ctx,
1729 struct lsa_TrustDomainInfoAuthInfoInternalAES *auth_info,
1730 struct trustDomainPasswords *auth_struct)
1732 DATA_BLOB session_key = data_blob_null;
1733 DATA_BLOB salt = data_blob(auth_info->salt, sizeof(auth_info->salt));
1734 DATA_BLOB auth_blob = data_blob(auth_info->cipher.data,
1735 auth_info->cipher.size);
1736 DATA_BLOB ciphertext = data_blob_null;
1737 enum ndr_err_code ndr_err;
1738 NTSTATUS status;
1741 * The data blob starts with 512 bytes of random data and has two 32bit
1742 * size parameters.
1744 if (auth_blob.length < 520) {
1745 return NT_STATUS_INVALID_PARAMETER;
1748 status = dcesrv_transport_session_key(dce_call, &session_key);
1749 if (!NT_STATUS_IS_OK(status)) {
1750 return status;
1753 status = samba_gnutls_aead_aes_256_cbc_hmac_sha512_decrypt(
1754 mem_ctx,
1755 &auth_blob,
1756 &session_key,
1757 &lsa_aes256_enc_key_salt,
1758 &lsa_aes256_mac_key_salt,
1759 &salt,
1760 auth_info->auth_data,
1761 &ciphertext);
1762 if (!NT_STATUS_IS_OK(status)) {
1763 return status;
1766 ndr_err = ndr_pull_struct_blob(
1767 &ciphertext,
1768 mem_ctx,
1769 auth_struct,
1770 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
1771 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1772 return NT_STATUS_INVALID_PARAMETER;
1775 return NT_STATUS_OK;
1778 static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
1779 TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
1780 struct trustDomainPasswords *auth_struct)
1782 struct dcesrv_call_state *dce_call = p->dce_call;
1783 struct auth_session_info *session_info =
1784 dcesrv_call_session_info(dce_call);
1785 enum ndr_err_code ndr_err;
1786 DATA_BLOB lsession_key;
1787 gnutls_cipher_hd_t cipher_hnd = NULL;
1788 gnutls_datum_t my_session_key;
1789 NTSTATUS status;
1790 int rc;
1791 bool encrypted;
1793 encrypted = dcerpc_is_transport_encrypted(session_info);
1794 if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
1795 !encrypted) {
1796 return NT_STATUS_ACCESS_DENIED;
1799 status = session_extract_session_key(
1800 session_info, &lsession_key, KEY_USE_16BYTES);
1801 if (!NT_STATUS_IS_OK(status)) {
1802 return NT_STATUS_INVALID_PARAMETER;
1805 my_session_key = (gnutls_datum_t) {
1806 .data = lsession_key.data,
1807 .size = lsession_key.length,
1810 GNUTLS_FIPS140_SET_LAX_MODE();
1811 rc = gnutls_cipher_init(&cipher_hnd,
1812 GNUTLS_CIPHER_ARCFOUR_128,
1813 &my_session_key,
1814 NULL);
1815 if (rc < 0) {
1816 GNUTLS_FIPS140_SET_STRICT_MODE();
1817 status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
1818 goto out;
1821 rc = gnutls_cipher_decrypt(cipher_hnd,
1822 auth_blob->data,
1823 auth_blob->length);
1824 gnutls_cipher_deinit(cipher_hnd);
1825 GNUTLS_FIPS140_SET_STRICT_MODE();
1826 if (rc < 0) {
1827 status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
1828 goto out;
1831 ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
1832 auth_struct,
1833 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
1834 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1835 status = NT_STATUS_INVALID_PARAMETER;
1836 goto out;
1839 status = NT_STATUS_OK;
1840 out:
1841 return status;
1844 static NTSTATUS get_trustauth_inout_blob(TALLOC_CTX *mem_ctx,
1845 struct trustAuthInOutBlob *iopw,
1846 DATA_BLOB *trustauth_blob)
1848 enum ndr_err_code ndr_err;
1850 if (iopw->current.count != iopw->count) {
1851 return NT_STATUS_INVALID_PARAMETER;
1854 if (iopw->previous.count > iopw->current.count) {
1855 return NT_STATUS_INVALID_PARAMETER;
1858 if (iopw->previous.count == 0) {
1860 * If the previous credentials are not present
1861 * we need to make a copy.
1863 iopw->previous = iopw->current;
1866 if (iopw->previous.count < iopw->current.count) {
1867 struct AuthenticationInformationArray *c = &iopw->current;
1868 struct AuthenticationInformationArray *p = &iopw->previous;
1871 * The previous array needs to have the same size
1872 * as the current one.
1874 * We may have to fill with TRUST_AUTH_TYPE_NONE
1875 * elements.
1877 p->array = talloc_realloc(mem_ctx, p->array,
1878 struct AuthenticationInformation,
1879 c->count);
1880 if (p->array == NULL) {
1881 return NT_STATUS_NO_MEMORY;
1884 while (p->count < c->count) {
1885 struct AuthenticationInformation *a =
1886 &p->array[p->count++];
1888 *a = (struct AuthenticationInformation) {
1889 .LastUpdateTime = p->array[0].LastUpdateTime,
1890 .AuthType = TRUST_AUTH_TYPE_NONE,
1895 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
1896 iopw,
1897 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
1898 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1899 return NT_STATUS_INVALID_PARAMETER;
1902 return NT_STATUS_OK;
1905 static NTSTATUS lsa_CreateTrustedDomain_precheck(
1906 TALLOC_CTX *mem_ctx,
1907 struct lsa_info *policy,
1908 struct auth_session_info *session_info,
1909 struct lsa_TrustDomainInfoInfoEx *info)
1911 const char *netbios_name = NULL;
1912 const char *dns_name = NULL;
1913 bool ok;
1915 netbios_name = info->netbios_name.string;
1916 if (netbios_name == NULL) {
1917 return NT_STATUS_INVALID_PARAMETER;
1920 dns_name = info->domain_name.string;
1921 if (dns_name == NULL) {
1922 return NT_STATUS_INVALID_PARAMETER;
1925 if (info->sid == NULL) {
1926 return NT_STATUS_INVALID_SID;
1929 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1930 return NT_STATUS_ACCESS_DENIED;
1934 * We expect S-1-5-21-A-B-C, but we don't
1935 * allow S-1-5-21-0-0-0 as this is used
1936 * for claims and compound identities.
1938 ok = dom_sid_is_valid_account_domain(info->sid);
1939 if (!ok) {
1940 return NT_STATUS_INVALID_PARAMETER;
1943 if (strcasecmp(netbios_name, "BUILTIN") == 0 ||
1944 strcasecmp(dns_name, "BUILTIN") == 0)
1946 return NT_STATUS_INVALID_PARAMETER;
1949 if (policy->name != NULL &&
1950 (strcasecmp(netbios_name, policy->name) == 0 ||
1951 strcasecmp(dns_name, policy->name) == 0))
1953 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
1956 if (session_info->unix_token->uid != sec_initial_uid() &&
1957 !nt_token_check_domain_rid(session_info->security_token,
1958 DOMAIN_RID_ADMINS))
1960 return NT_STATUS_ACCESS_DENIED;
1963 return NT_STATUS_OK;
1966 static NTSTATUS lsa_CreateTrustedDomain_common(
1967 struct pipes_struct *p,
1968 TALLOC_CTX *mem_ctx,
1969 struct auth_session_info *session_info,
1970 struct lsa_info *policy,
1971 uint32_t access_mask,
1972 struct lsa_TrustDomainInfoInfoEx *info,
1973 struct trustDomainPasswords *auth_struct,
1974 struct policy_handle **ptrustdom_handle)
1976 struct security_descriptor *psd = NULL;
1977 size_t sd_size = 0;
1978 uint32_t acc_granted = 0;
1979 struct pdb_trusted_domain td = {
1980 .trust_type = 0,
1982 NTSTATUS status;
1984 /* Work out max allowed. */
1985 map_max_allowed_access(session_info->security_token,
1986 session_info->unix_token,
1987 &access_mask);
1989 /* map the generic bits to the lsa policy ones */
1990 se_map_generic(&access_mask, &lsa_account_mapping);
1992 status = make_lsa_object_sd(
1993 mem_ctx, &psd, &sd_size, &lsa_trusted_domain_mapping, NULL, 0);
1994 if (!NT_STATUS_IS_OK(status)) {
1995 return status;
1998 status = access_check_object(psd,
1999 session_info->security_token,
2000 SEC_PRIV_INVALID,
2001 SEC_PRIV_INVALID,
2003 access_mask,
2004 &acc_granted,
2005 "lsa_CreateTrustedDomain_common");
2006 if (!NT_STATUS_IS_OK(status)) {
2007 return status;
2010 td.domain_name = talloc_strdup(mem_ctx, info->domain_name.string);
2011 if (td.domain_name == NULL) {
2012 return NT_STATUS_NO_MEMORY;
2014 td.netbios_name = talloc_strdup(mem_ctx, info->netbios_name.string);
2015 if (td.netbios_name == NULL) {
2016 return NT_STATUS_NO_MEMORY;
2018 sid_copy(&td.security_identifier, info->sid);
2019 td.trust_direction = info->trust_direction;
2020 td.trust_type = info->trust_type;
2021 td.trust_attributes = info->trust_attributes;
2023 status = get_trustauth_inout_blob(mem_ctx,
2024 &auth_struct->incoming,
2025 &td.trust_auth_incoming);
2026 if (!NT_STATUS_IS_OK(status)) {
2027 return NT_STATUS_UNSUCCESSFUL;
2030 status = get_trustauth_inout_blob(mem_ctx,
2031 &auth_struct->outgoing,
2032 &td.trust_auth_outgoing);
2033 if (!NT_STATUS_IS_OK(status)) {
2034 return NT_STATUS_UNSUCCESSFUL;
2037 status = pdb_set_trusted_domain(info->domain_name.string, &td);
2038 if (!NT_STATUS_IS_OK(status)) {
2039 DBG_ERR("pdb_set_trusted_domain failed: %s\n",
2040 nt_errstr(status));
2041 return status;
2044 status = create_lsa_policy_handle(mem_ctx, p,
2045 LSA_HANDLE_TRUST_TYPE,
2046 acc_granted,
2047 info->sid,
2048 info->netbios_name.string,
2049 psd,
2050 *ptrustdom_handle);
2051 if (!NT_STATUS_IS_OK(status)) {
2052 pdb_del_trusted_domain(info->netbios_name.string);
2053 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2056 return NT_STATUS_OK;
2059 /***************************************************************************
2060 _lsa_CreateTrustedDomainEx2
2061 ***************************************************************************/
2063 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
2064 struct lsa_CreateTrustedDomainEx2 *r)
2066 struct dcesrv_call_state *dce_call = p->dce_call;
2067 struct auth_session_info *session_info =
2068 dcesrv_call_session_info(dce_call);
2069 struct lsa_info *policy;
2070 NTSTATUS status;
2071 struct trustDomainPasswords auth_struct = {
2072 .incoming_size = 0,
2074 DATA_BLOB auth_blob = data_blob_null;
2076 if (!IS_DC) {
2077 return NT_STATUS_NOT_SUPPORTED;
2080 policy = find_policy_by_hnd(p,
2081 r->in.policy_handle,
2082 LSA_HANDLE_POLICY_TYPE,
2083 struct lsa_info,
2084 &status);
2085 if (!NT_STATUS_IS_OK(status)) {
2086 return NT_STATUS_INVALID_HANDLE;
2089 status = lsa_CreateTrustedDomain_precheck(p->mem_ctx,
2090 policy,
2091 session_info,
2092 r->in.info);
2093 if (!NT_STATUS_IS_OK(status)) {
2094 return status;
2098 if (r->in.auth_info_internal->auth_blob.size == 0) {
2099 return NT_STATUS_INVALID_PARAMETER;
2102 auth_blob = data_blob_const(r->in.auth_info_internal->auth_blob.data,
2103 r->in.auth_info_internal->auth_blob.size);
2105 status = get_trustdom_auth_blob(p,
2106 p->mem_ctx,
2107 &auth_blob,
2108 &auth_struct);
2109 if (!NT_STATUS_IS_OK(status)) {
2110 return NT_STATUS_UNSUCCESSFUL;
2113 status = lsa_CreateTrustedDomain_common(p,
2114 p->mem_ctx,
2115 session_info,
2116 policy,
2117 r->in.access_mask,
2118 r->in.info,
2119 &auth_struct,
2120 &r->out.trustdom_handle);
2121 if (!NT_STATUS_IS_OK(status)) {
2122 return status;
2125 return NT_STATUS_OK;
2128 /***************************************************************************
2129 _lsa_CreateTrustedDomainEx
2130 ***************************************************************************/
2132 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
2133 struct lsa_CreateTrustedDomainEx *r)
2135 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2136 return NT_STATUS_NOT_IMPLEMENTED;
2139 /***************************************************************************
2140 _lsa_CreateTrustedDomain
2141 ***************************************************************************/
2143 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
2144 struct lsa_CreateTrustedDomain *r)
2146 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2147 return NT_STATUS_NOT_IMPLEMENTED;
2150 /***************************************************************************
2151 _lsa_DeleteTrustedDomain
2152 ***************************************************************************/
2154 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
2155 struct lsa_DeleteTrustedDomain *r)
2157 NTSTATUS status;
2158 struct lsa_info *handle;
2159 struct pdb_trusted_domain *td;
2161 /* find the connection policy handle. */
2162 handle = find_policy_by_hnd(p,
2163 r->in.handle,
2164 LSA_HANDLE_POLICY_TYPE,
2165 struct lsa_info,
2166 &status);
2167 if (!NT_STATUS_IS_OK(status)) {
2168 return NT_STATUS_INVALID_HANDLE;
2171 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
2172 return NT_STATUS_ACCESS_DENIED;
2175 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
2176 if (!NT_STATUS_IS_OK(status)) {
2177 return status;
2180 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
2181 struct dom_sid_buf buf;
2182 DEBUG(10, ("Missing netbios name for trusted domain %s.\n",
2183 dom_sid_str_buf(r->in.dom_sid, &buf)));
2184 return NT_STATUS_UNSUCCESSFUL;
2187 status = pdb_del_trusted_domain(td->netbios_name);
2188 if (!NT_STATUS_IS_OK(status)) {
2189 return status;
2192 return NT_STATUS_OK;
2195 /***************************************************************************
2196 _lsa_CloseTrustedDomainEx
2197 ***************************************************************************/
2199 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
2200 struct lsa_CloseTrustedDomainEx *r)
2202 return NT_STATUS_NOT_IMPLEMENTED;
2205 /***************************************************************************
2206 _lsa_QueryTrustedDomainInfo
2207 ***************************************************************************/
2209 static NTSTATUS pdb_trusted_domain_2_info_ex(TALLOC_CTX *mem_ctx,
2210 struct pdb_trusted_domain *td,
2211 struct lsa_TrustDomainInfoInfoEx *info_ex)
2213 if (td->domain_name == NULL ||
2214 td->netbios_name == NULL ||
2215 is_null_sid(&td->security_identifier)) {
2216 return NT_STATUS_INVALID_PARAMETER;
2219 info_ex->domain_name.string = talloc_strdup(mem_ctx, td->domain_name);
2220 info_ex->netbios_name.string = talloc_strdup(mem_ctx, td->netbios_name);
2221 info_ex->sid = dom_sid_dup(mem_ctx, &td->security_identifier);
2222 if (info_ex->domain_name.string == NULL ||
2223 info_ex->netbios_name.string == NULL ||
2224 info_ex->sid == NULL) {
2225 return NT_STATUS_NO_MEMORY;
2228 info_ex->trust_direction = td->trust_direction;
2229 info_ex->trust_type = td->trust_type;
2230 info_ex->trust_attributes = td->trust_attributes;
2232 return NT_STATUS_OK;
2235 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
2236 struct lsa_QueryTrustedDomainInfo *r)
2238 NTSTATUS status;
2239 struct lsa_info *handle;
2240 union lsa_TrustedDomainInfo *info;
2241 struct pdb_trusted_domain *td;
2242 uint32_t acc_required;
2244 /* find the connection policy handle. */
2245 handle = find_policy_by_hnd(p,
2246 r->in.trustdom_handle,
2247 LSA_HANDLE_TRUST_TYPE,
2248 struct lsa_info,
2249 &status);
2250 if (!NT_STATUS_IS_OK(status)) {
2251 return NT_STATUS_INVALID_HANDLE;
2254 switch (r->in.level) {
2255 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2256 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2257 break;
2258 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2259 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
2260 break;
2261 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2262 acc_required = LSA_TRUSTED_QUERY_POSIX;
2263 break;
2264 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2265 acc_required = LSA_TRUSTED_QUERY_AUTH;
2266 break;
2267 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2268 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2269 break;
2270 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2271 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2272 break;
2273 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2274 acc_required = LSA_TRUSTED_QUERY_AUTH;
2275 break;
2276 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2277 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2278 LSA_TRUSTED_QUERY_POSIX |
2279 LSA_TRUSTED_QUERY_AUTH;
2280 break;
2281 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2282 acc_required = LSA_TRUSTED_QUERY_AUTH;
2283 break;
2284 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2285 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2286 LSA_TRUSTED_QUERY_POSIX |
2287 LSA_TRUSTED_QUERY_AUTH;
2288 break;
2289 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2290 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2291 break;
2292 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2293 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2294 LSA_TRUSTED_QUERY_POSIX |
2295 LSA_TRUSTED_QUERY_AUTH;
2296 break;
2297 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2298 acc_required = LSA_TRUSTED_QUERY_POSIX;
2299 break;
2300 default:
2301 return NT_STATUS_INVALID_PARAMETER;
2304 if (!(handle->access & acc_required)) {
2305 return NT_STATUS_ACCESS_DENIED;
2308 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2309 if (!NT_STATUS_IS_OK(status)) {
2310 return status;
2313 info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
2314 if (!info) {
2315 return NT_STATUS_NO_MEMORY;
2318 switch (r->in.level) {
2319 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2320 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2321 break;
2322 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2323 return NT_STATUS_INVALID_PARAMETER;
2324 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2325 info->posix_offset.posix_offset = *td->trust_posix_offset;
2326 break;
2327 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2328 return NT_STATUS_INVALID_INFO_CLASS;
2329 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2330 return NT_STATUS_INVALID_PARAMETER;
2331 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2332 status = pdb_trusted_domain_2_info_ex(info, td, &info->info_ex);
2333 if (!NT_STATUS_IS_OK(status)) {
2334 return status;
2336 break;
2337 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2338 return NT_STATUS_INVALID_INFO_CLASS;
2339 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2340 status = pdb_trusted_domain_2_info_ex(info, td,
2341 &info->full_info.info_ex);
2342 if (!NT_STATUS_IS_OK(status)) {
2343 return status;
2345 info->full_info.posix_offset.posix_offset = *td->trust_posix_offset;
2346 status = auth_blob_2_auth_info(p->mem_ctx,
2347 td->trust_auth_incoming,
2348 td->trust_auth_outgoing,
2349 &info->full_info.auth_info);
2350 if (!NT_STATUS_IS_OK(status)) {
2351 return status;
2353 break;
2354 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2355 return NT_STATUS_INVALID_INFO_CLASS;
2356 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2357 return NT_STATUS_INVALID_INFO_CLASS;
2358 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2359 return NT_STATUS_INVALID_PARAMETER;
2360 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2361 info->full_info2_internal.posix_offset.posix_offset = *td->trust_posix_offset;
2362 status = auth_blob_2_auth_info(p->mem_ctx,
2363 td->trust_auth_incoming,
2364 td->trust_auth_outgoing,
2365 &info->full_info2_internal.auth_info);
2366 if (!NT_STATUS_IS_OK(status)) {
2367 return status;
2369 break;
2370 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2371 info->enc_types.enc_types = *td->supported_enc_type;
2372 break;
2373 default:
2374 return NT_STATUS_INVALID_PARAMETER;
2377 *r->out.info = info;
2379 return NT_STATUS_OK;
2382 /***************************************************************************
2383 _lsa_QueryTrustedDomainInfoBySid
2384 ***************************************************************************/
2386 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2387 struct lsa_QueryTrustedDomainInfoBySid *r)
2389 NTSTATUS status;
2390 struct policy_handle trustdom_handle;
2391 struct lsa_OpenTrustedDomain o;
2392 struct lsa_QueryTrustedDomainInfo q;
2393 struct lsa_Close c;
2395 o.in.handle = r->in.handle;
2396 o.in.sid = r->in.dom_sid;
2397 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2398 o.out.trustdom_handle = &trustdom_handle;
2400 status = _lsa_OpenTrustedDomain(p, &o);
2401 if (!NT_STATUS_IS_OK(status)) {
2402 return status;
2405 q.in.trustdom_handle = &trustdom_handle;
2406 q.in.level = r->in.level;
2407 q.out.info = r->out.info;
2409 status = _lsa_QueryTrustedDomainInfo(p, &q);
2410 if (!NT_STATUS_IS_OK(status)) {
2411 return status;
2414 c.in.handle = &trustdom_handle;
2415 c.out.handle = &trustdom_handle;
2417 return _lsa_Close(p, &c);
2420 /***************************************************************************
2421 _lsa_QueryTrustedDomainInfoByName
2422 ***************************************************************************/
2424 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2425 struct lsa_QueryTrustedDomainInfoByName *r)
2427 NTSTATUS status;
2428 struct policy_handle trustdom_handle;
2429 struct lsa_OpenTrustedDomainByName o;
2430 struct lsa_QueryTrustedDomainInfo q;
2431 struct lsa_Close c;
2433 o.in.handle = r->in.handle;
2434 o.in.name.string = r->in.trusted_domain->string;
2435 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2436 o.out.trustdom_handle = &trustdom_handle;
2438 status = _lsa_OpenTrustedDomainByName(p, &o);
2439 if (!NT_STATUS_IS_OK(status)) {
2440 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2441 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2443 return status;
2446 q.in.trustdom_handle = &trustdom_handle;
2447 q.in.level = r->in.level;
2448 q.out.info = r->out.info;
2450 status = _lsa_QueryTrustedDomainInfo(p, &q);
2451 if (!NT_STATUS_IS_OK(status)) {
2452 return status;
2455 c.in.handle = &trustdom_handle;
2456 c.out.handle = &trustdom_handle;
2458 return _lsa_Close(p, &c);
2461 /***************************************************************************
2462 _lsa_CreateSecret
2463 ***************************************************************************/
2465 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p,
2466 struct lsa_CreateSecret *r)
2468 struct dcesrv_call_state *dce_call = p->dce_call;
2469 struct auth_session_info *session_info =
2470 dcesrv_call_session_info(dce_call);
2471 NTSTATUS status;
2472 struct lsa_info *handle;
2473 uint32_t acc_granted;
2474 struct security_descriptor *psd;
2475 size_t sd_size;
2477 /* find the connection policy handle. */
2478 handle = find_policy_by_hnd(p,
2479 r->in.handle,
2480 LSA_HANDLE_POLICY_TYPE,
2481 struct lsa_info,
2482 &status);
2483 if (!NT_STATUS_IS_OK(status)) {
2484 return NT_STATUS_INVALID_HANDLE;
2487 /* check if the user has enough rights */
2489 if (!(handle->access & LSA_POLICY_CREATE_SECRET)) {
2490 return NT_STATUS_ACCESS_DENIED;
2493 /* Work out max allowed. */
2494 map_max_allowed_access(session_info->security_token,
2495 session_info->unix_token,
2496 &r->in.access_mask);
2498 /* map the generic bits to the lsa policy ones */
2499 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
2501 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2502 &lsa_secret_mapping,
2503 NULL, 0);
2504 if (!NT_STATUS_IS_OK(status)) {
2505 return status;
2508 status = access_check_object(psd, session_info->security_token,
2509 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2510 r->in.access_mask,
2511 &acc_granted, "_lsa_CreateSecret");
2512 if (!NT_STATUS_IS_OK(status)) {
2513 return status;
2516 if (!r->in.name.string) {
2517 return NT_STATUS_INVALID_PARAMETER;
2520 if (strlen(r->in.name.string) > 128) {
2521 return NT_STATUS_NAME_TOO_LONG;
2524 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
2525 NULL, NULL, NULL, NULL, NULL);
2526 if (NT_STATUS_IS_OK(status)) {
2527 return NT_STATUS_OBJECT_NAME_COLLISION;
2530 status = pdb_set_secret(r->in.name.string, NULL, NULL, psd);
2531 if (!NT_STATUS_IS_OK(status)) {
2532 return status;
2535 status = create_lsa_policy_handle(p->mem_ctx, p,
2536 LSA_HANDLE_SECRET_TYPE,
2537 acc_granted,
2538 NULL,
2539 r->in.name.string,
2540 psd,
2541 r->out.sec_handle);
2542 if (!NT_STATUS_IS_OK(status)) {
2543 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2546 return NT_STATUS_OK;
2549 /***************************************************************************
2550 _lsa_SetSecret
2551 ***************************************************************************/
2553 NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
2554 struct lsa_SetSecret *r)
2556 struct dcesrv_call_state *dce_call = p->dce_call;
2557 struct auth_session_info *session_info =
2558 dcesrv_call_session_info(dce_call);
2559 NTSTATUS status;
2560 struct lsa_info *info = NULL;
2561 DATA_BLOB blob_new, blob_old;
2562 DATA_BLOB cleartext_blob_new = data_blob_null;
2563 DATA_BLOB cleartext_blob_old = data_blob_null;
2564 DATA_BLOB *cleartext_blob_new_p = NULL;
2565 DATA_BLOB *cleartext_blob_old_p = NULL;
2566 DATA_BLOB session_key;
2568 info = find_policy_by_hnd(p,
2569 r->in.sec_handle,
2570 LSA_HANDLE_SECRET_TYPE,
2571 struct lsa_info,
2572 &status);
2573 if (!NT_STATUS_IS_OK(status)) {
2574 return NT_STATUS_INVALID_HANDLE;
2577 if (!(info->access & LSA_SECRET_SET_VALUE)) {
2578 return NT_STATUS_ACCESS_DENIED;
2581 status = session_extract_session_key(
2582 session_info, &session_key, KEY_USE_16BYTES);
2583 if(!NT_STATUS_IS_OK(status)) {
2584 return status;
2587 if (r->in.new_val) {
2588 blob_new = data_blob_const(r->in.new_val->data,
2589 r->in.new_val->length);
2591 status = sess_decrypt_blob(p->mem_ctx, &blob_new,
2592 &session_key,
2593 &cleartext_blob_new);
2594 if (!NT_STATUS_IS_OK(status)) {
2595 return status;
2598 cleartext_blob_new_p = &cleartext_blob_new;
2601 if (r->in.old_val) {
2602 blob_old = data_blob_const(r->in.old_val->data,
2603 r->in.old_val->length);
2605 status = sess_decrypt_blob(p->mem_ctx, &blob_old,
2606 &session_key,
2607 &cleartext_blob_old);
2608 if (!NT_STATUS_IS_OK(status)) {
2609 return status;
2612 cleartext_blob_old_p = &cleartext_blob_old;
2615 status = pdb_set_secret(info->name, cleartext_blob_new_p, cleartext_blob_old_p, NULL);
2616 if (!NT_STATUS_IS_OK(status)) {
2617 return status;
2620 #ifdef DEBUG_PASSWORD
2621 DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
2622 dump_data(10, cleartext_blob_new.data, cleartext_blob_new.length);
2623 DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
2624 dump_data(10, cleartext_blob_old.data, cleartext_blob_old.length);
2625 #endif
2627 return NT_STATUS_OK;
2630 /***************************************************************************
2631 _lsa_QuerySecret
2632 ***************************************************************************/
2634 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
2635 struct lsa_QuerySecret *r)
2637 struct dcesrv_call_state *dce_call = p->dce_call;
2638 struct auth_session_info *session_info =
2639 dcesrv_call_session_info(dce_call);
2640 struct lsa_info *info = NULL;
2641 DATA_BLOB blob_new, blob_old;
2642 DATA_BLOB blob_new_crypt, blob_old_crypt;
2643 DATA_BLOB session_key;
2644 NTTIME nttime_new, nttime_old;
2645 NTSTATUS status;
2647 info = find_policy_by_hnd(p,
2648 r->in.sec_handle,
2649 LSA_HANDLE_SECRET_TYPE,
2650 struct lsa_info,
2651 &status);
2652 if (!NT_STATUS_IS_OK(status)) {
2653 return NT_STATUS_INVALID_HANDLE;
2656 if (!(info->access & LSA_SECRET_QUERY_VALUE)) {
2657 return NT_STATUS_ACCESS_DENIED;
2660 status = pdb_get_secret(p->mem_ctx, info->name,
2661 &blob_new, &nttime_new,
2662 &blob_old, &nttime_old,
2663 NULL);
2664 if (!NT_STATUS_IS_OK(status)) {
2665 return status;
2668 status = session_extract_session_key(
2669 session_info, &session_key, KEY_USE_16BYTES);
2670 if(!NT_STATUS_IS_OK(status)) {
2671 return status;
2674 if (r->in.new_val) {
2675 if (blob_new.length) {
2676 if (!r->out.new_val->buf) {
2677 r->out.new_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2679 if (!r->out.new_val->buf) {
2680 return NT_STATUS_NO_MEMORY;
2683 blob_new_crypt = sess_encrypt_blob(p->mem_ctx, &blob_new,
2684 &session_key);
2685 if (!blob_new_crypt.length) {
2686 return NT_STATUS_NO_MEMORY;
2689 r->out.new_val->buf->data = blob_new_crypt.data;
2690 r->out.new_val->buf->length = blob_new_crypt.length;
2691 r->out.new_val->buf->size = blob_new_crypt.length;
2695 if (r->in.old_val) {
2696 if (blob_old.length) {
2697 if (!r->out.old_val->buf) {
2698 r->out.old_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2700 if (!r->out.old_val->buf) {
2701 return NT_STATUS_NO_MEMORY;
2704 blob_old_crypt = sess_encrypt_blob(p->mem_ctx, &blob_old,
2705 &session_key);
2706 if (!blob_old_crypt.length) {
2707 return NT_STATUS_NO_MEMORY;
2710 r->out.old_val->buf->data = blob_old_crypt.data;
2711 r->out.old_val->buf->length = blob_old_crypt.length;
2712 r->out.old_val->buf->size = blob_old_crypt.length;
2716 if (r->out.new_mtime) {
2717 *r->out.new_mtime = nttime_new;
2720 if (r->out.old_mtime) {
2721 *r->out.old_mtime = nttime_old;
2724 return NT_STATUS_OK;
2727 /***************************************************************************
2728 _lsa_DeleteObject
2729 ***************************************************************************/
2731 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2732 struct lsa_DeleteObject *r)
2734 NTSTATUS status;
2735 struct lsa_info *info = NULL;
2737 info = find_policy_by_hnd(p,
2738 r->in.handle,
2739 DCESRV_HANDLE_ANY,
2740 struct lsa_info,
2741 &status);
2742 if (!NT_STATUS_IS_OK(status)) {
2743 return NT_STATUS_INVALID_HANDLE;
2746 if (!(info->access & SEC_STD_DELETE)) {
2747 return NT_STATUS_ACCESS_DENIED;
2750 switch (info->type) {
2751 case LSA_HANDLE_ACCOUNT_TYPE:
2752 status = privilege_delete_account(&info->sid);
2753 if (!NT_STATUS_IS_OK(status)) {
2754 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2755 nt_errstr(status)));
2756 return status;
2758 break;
2759 case LSA_HANDLE_TRUST_TYPE:
2760 if (!pdb_del_trusteddom_pw(info->name)) {
2761 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2763 status = NT_STATUS_OK;
2764 break;
2765 case LSA_HANDLE_SECRET_TYPE:
2766 status = pdb_delete_secret(info->name);
2767 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2768 return NT_STATUS_INVALID_HANDLE;
2770 break;
2771 default:
2772 return NT_STATUS_INVALID_HANDLE;
2775 close_policy_hnd(p, r->in.handle);
2776 ZERO_STRUCTP(r->out.handle);
2778 return status;
2781 /***************************************************************************
2782 _lsa_EnumPrivs
2783 ***************************************************************************/
2785 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2786 struct lsa_EnumPrivs *r)
2788 struct lsa_info *handle;
2789 uint32_t i;
2790 uint32_t enum_context = *r->in.resume_handle;
2791 int num_privs = num_privileges_in_short_list();
2792 struct lsa_PrivEntry *entries = NULL;
2793 NTSTATUS status;
2795 /* remember that the enum_context starts at 0 and not 1 */
2797 if ( enum_context >= num_privs )
2798 return NT_STATUS_NO_MORE_ENTRIES;
2800 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2801 enum_context, num_privs));
2803 handle = find_policy_by_hnd(p,
2804 r->in.handle,
2805 LSA_HANDLE_POLICY_TYPE,
2806 struct lsa_info,
2807 &status);
2808 if (!NT_STATUS_IS_OK(status)) {
2809 return NT_STATUS_INVALID_HANDLE;
2812 /* check if the user has enough rights
2813 I don't know if it's the right one. not documented. */
2815 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2816 return NT_STATUS_ACCESS_DENIED;
2818 if (num_privs) {
2819 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2820 if (!entries) {
2821 return NT_STATUS_NO_MEMORY;
2823 } else {
2824 entries = NULL;
2827 for (i = 0; i < num_privs; i++) {
2828 if( i < enum_context) {
2830 init_lsa_StringLarge(&entries[i].name, NULL);
2832 entries[i].luid.low = 0;
2833 entries[i].luid.high = 0;
2834 } else {
2836 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2838 entries[i].luid.low = sec_privilege_from_index(i);
2839 entries[i].luid.high = 0;
2843 enum_context = num_privs;
2845 *r->out.resume_handle = enum_context;
2846 r->out.privs->count = num_privs;
2847 r->out.privs->privs = entries;
2849 return NT_STATUS_OK;
2852 /***************************************************************************
2853 _lsa_LookupPrivDisplayName
2854 ***************************************************************************/
2856 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2857 struct lsa_LookupPrivDisplayName *r)
2859 struct lsa_info *handle;
2860 const char *description;
2861 struct lsa_StringLarge *lsa_name;
2862 NTSTATUS status;
2864 handle = find_policy_by_hnd(p,
2865 r->in.handle,
2866 LSA_HANDLE_POLICY_TYPE,
2867 struct lsa_info,
2868 &status);
2869 if (!NT_STATUS_IS_OK(status)) {
2870 return NT_STATUS_INVALID_HANDLE;
2873 /* check if the user has enough rights */
2876 * I don't know if it's the right one. not documented.
2878 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2879 return NT_STATUS_ACCESS_DENIED;
2881 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2883 description = get_privilege_dispname(r->in.name->string);
2884 if (!description) {
2885 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2886 return NT_STATUS_NO_SUCH_PRIVILEGE;
2889 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2891 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2892 if (!lsa_name) {
2893 return NT_STATUS_NO_MEMORY;
2896 init_lsa_StringLarge(lsa_name, description);
2898 *r->out.returned_language_id = r->in.language_id;
2899 *r->out.disp_name = lsa_name;
2901 return NT_STATUS_OK;
2904 /***************************************************************************
2905 _lsa_EnumAccounts
2906 ***************************************************************************/
2908 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2909 struct lsa_EnumAccounts *r)
2911 struct lsa_info *handle;
2912 struct dom_sid *sid_list;
2913 int i, j, num_entries;
2914 NTSTATUS status;
2915 struct lsa_SidPtr *sids = NULL;
2917 handle = find_policy_by_hnd(p,
2918 r->in.handle,
2919 LSA_HANDLE_POLICY_TYPE,
2920 struct lsa_info,
2921 &status);
2922 if (!NT_STATUS_IS_OK(status)) {
2923 return NT_STATUS_INVALID_HANDLE;
2926 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2927 return NT_STATUS_ACCESS_DENIED;
2929 sid_list = NULL;
2930 num_entries = 0;
2932 /* The only way we can currently find out all the SIDs that have been
2933 privileged is to scan all privileges */
2935 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2936 if (!NT_STATUS_IS_OK(status)) {
2937 return status;
2940 if (*r->in.resume_handle >= num_entries) {
2941 return NT_STATUS_NO_MORE_ENTRIES;
2944 if (num_entries - *r->in.resume_handle) {
2945 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2946 num_entries - *r->in.resume_handle);
2947 if (!sids) {
2948 talloc_free(sid_list);
2949 return NT_STATUS_NO_MEMORY;
2952 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2953 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2954 if (!sids[j].sid) {
2955 talloc_free(sid_list);
2956 return NT_STATUS_NO_MEMORY;
2961 talloc_free(sid_list);
2963 *r->out.resume_handle = num_entries;
2964 r->out.sids->num_sids = num_entries;
2965 r->out.sids->sids = sids;
2967 return NT_STATUS_OK;
2970 /***************************************************************************
2971 _lsa_GetUserName
2972 ***************************************************************************/
2974 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2975 struct lsa_GetUserName *r)
2977 struct dcesrv_call_state *dce_call = p->dce_call;
2978 struct auth_session_info *session_info =
2979 dcesrv_call_session_info(dce_call);
2980 const char *username, *domname;
2981 struct lsa_String *account_name = NULL;
2982 struct lsa_String *authority_name = NULL;
2984 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
2985 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
2986 return NT_STATUS_ACCESS_DENIED;
2989 if (r->in.account_name &&
2990 *r->in.account_name) {
2991 return NT_STATUS_INVALID_PARAMETER;
2994 if (r->in.authority_name &&
2995 *r->in.authority_name) {
2996 return NT_STATUS_INVALID_PARAMETER;
2999 if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
3001 * I'm 99% sure this is not the right place to do this,
3002 * global_sid_Anonymous should probably be put into the token
3003 * instead of the guest id -- vl
3005 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
3006 &domname, &username, NULL)) {
3007 return NT_STATUS_NO_MEMORY;
3009 } else {
3010 username = session_info->unix_info->sanitized_username;
3011 domname = session_info->info->domain_name;
3014 account_name = talloc(p->mem_ctx, struct lsa_String);
3015 if (!account_name) {
3016 return NT_STATUS_NO_MEMORY;
3018 init_lsa_String(account_name, username);
3020 if (r->out.authority_name) {
3021 authority_name = talloc(p->mem_ctx, struct lsa_String);
3022 if (!authority_name) {
3023 return NT_STATUS_NO_MEMORY;
3025 init_lsa_String(authority_name, domname);
3028 *r->out.account_name = account_name;
3029 if (r->out.authority_name) {
3030 *r->out.authority_name = authority_name;
3033 return NT_STATUS_OK;
3036 /***************************************************************************
3037 _lsa_CreateAccount
3038 ***************************************************************************/
3040 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
3041 struct lsa_CreateAccount *r)
3043 struct dcesrv_call_state *dce_call = p->dce_call;
3044 struct auth_session_info *session_info =
3045 dcesrv_call_session_info(dce_call);
3046 NTSTATUS status;
3047 struct lsa_info *handle;
3048 uint32_t acc_granted;
3049 struct security_descriptor *psd;
3050 size_t sd_size;
3051 uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
3052 ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
3053 LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3054 SEC_STD_DELETE));
3056 /* find the connection policy handle. */
3057 handle = find_policy_by_hnd(p,
3058 r->in.handle,
3059 LSA_HANDLE_POLICY_TYPE,
3060 struct lsa_info,
3061 &status);
3062 if (!NT_STATUS_IS_OK(status)) {
3063 return NT_STATUS_INVALID_HANDLE;
3066 /* check if the user has enough rights */
3068 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
3069 return NT_STATUS_ACCESS_DENIED;
3072 /* Work out max allowed. */
3073 map_max_allowed_access(session_info->security_token,
3074 session_info->unix_token,
3075 &r->in.access_mask);
3077 /* map the generic bits to the lsa policy ones */
3078 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
3080 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3081 &lsa_account_mapping,
3082 r->in.sid, owner_access);
3083 if (!NT_STATUS_IS_OK(status)) {
3084 return status;
3087 status = access_check_object(psd, session_info->security_token,
3088 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
3089 &acc_granted, "_lsa_CreateAccount");
3090 if (!NT_STATUS_IS_OK(status)) {
3091 return status;
3094 if ( is_privileged_sid( r->in.sid ) )
3095 return NT_STATUS_OBJECT_NAME_COLLISION;
3097 status = create_lsa_policy_handle(p->mem_ctx, p,
3098 LSA_HANDLE_ACCOUNT_TYPE,
3099 acc_granted,
3100 r->in.sid,
3101 NULL,
3102 psd,
3103 r->out.acct_handle);
3104 if (!NT_STATUS_IS_OK(status)) {
3105 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3108 return privilege_create_account(r->in.sid);
3111 /***************************************************************************
3112 _lsa_OpenAccount
3113 ***************************************************************************/
3115 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
3116 struct lsa_OpenAccount *r)
3118 struct dcesrv_call_state *dce_call = p->dce_call;
3119 struct auth_session_info *session_info =
3120 dcesrv_call_session_info(dce_call);
3121 struct security_descriptor *psd = NULL;
3122 size_t sd_size;
3123 uint32_t des_access = r->in.access_mask;
3124 uint32_t acc_granted;
3125 uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
3126 ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
3127 LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3128 SEC_STD_DELETE));
3129 NTSTATUS status;
3131 /* find the connection policy handle. */
3132 (void)find_policy_by_hnd(p,
3133 r->in.handle,
3134 LSA_HANDLE_POLICY_TYPE,
3135 struct lsa_info,
3136 &status);
3137 if (!NT_STATUS_IS_OK(status)) {
3138 return NT_STATUS_INVALID_HANDLE;
3141 /* des_access is for the account here, not the policy
3142 * handle - so don't check against policy handle. */
3144 /* Work out max allowed. */
3145 map_max_allowed_access(session_info->security_token,
3146 session_info->unix_token,
3147 &des_access);
3149 /* map the generic bits to the lsa account ones */
3150 se_map_generic(&des_access, &lsa_account_mapping);
3152 /* get the generic lsa account SD until we store it */
3153 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3154 &lsa_account_mapping,
3155 r->in.sid, owner_access);
3156 if (!NT_STATUS_IS_OK(status)) {
3157 return status;
3160 status = access_check_object(psd, session_info->security_token,
3161 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
3162 &acc_granted, "_lsa_OpenAccount" );
3163 if (!NT_STATUS_IS_OK(status)) {
3164 return status;
3167 /* TODO: Fis the parsing routine before reenabling this check! */
3168 #if 0
3169 if (!lookup_sid(&handle->sid, dom_name, name, &type))
3170 return NT_STATUS_ACCESS_DENIED;
3171 #endif
3173 status = create_lsa_policy_handle(p->mem_ctx, p,
3174 LSA_HANDLE_ACCOUNT_TYPE,
3175 acc_granted,
3176 r->in.sid,
3177 NULL,
3178 psd,
3179 r->out.acct_handle);
3180 if (!NT_STATUS_IS_OK(status)) {
3181 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3184 return NT_STATUS_OK;
3187 /***************************************************************************
3188 _lsa_EnumPrivsAccount
3189 For a given SID, enumerate all the privilege this account has.
3190 ***************************************************************************/
3192 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
3193 struct lsa_EnumPrivsAccount *r)
3195 NTSTATUS status = NT_STATUS_OK;
3196 struct lsa_info *info=NULL;
3197 PRIVILEGE_SET *privileges;
3198 struct lsa_PrivilegeSet *priv_set = NULL;
3199 struct dom_sid_buf buf;
3201 /* find the connection policy handle. */
3202 info = find_policy_by_hnd(p,
3203 r->in.handle,
3204 LSA_HANDLE_ACCOUNT_TYPE,
3205 struct lsa_info,
3206 &status);
3207 if (!NT_STATUS_IS_OK(status)) {
3208 return NT_STATUS_INVALID_HANDLE;
3211 if (!(info->access & LSA_ACCOUNT_VIEW))
3212 return NT_STATUS_ACCESS_DENIED;
3214 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
3215 if (!NT_STATUS_IS_OK(status)) {
3216 return status;
3219 *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
3220 if (!priv_set) {
3221 return NT_STATUS_NO_MEMORY;
3224 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
3225 dom_sid_str_buf(&info->sid, &buf),
3226 privileges->count));
3228 priv_set->count = privileges->count;
3229 priv_set->unknown = 0;
3230 priv_set->set = talloc_move(priv_set, &privileges->set);
3232 return status;
3235 /***************************************************************************
3236 _lsa_GetSystemAccessAccount
3237 ***************************************************************************/
3239 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
3240 struct lsa_GetSystemAccessAccount *r)
3242 NTSTATUS status;
3243 struct lsa_info *info = NULL;
3244 struct lsa_EnumPrivsAccount e;
3245 struct lsa_PrivilegeSet *privset;
3247 /* find the connection policy handle. */
3249 info = find_policy_by_hnd(p,
3250 r->in.handle,
3251 LSA_HANDLE_ACCOUNT_TYPE,
3252 struct lsa_info,
3253 &status);
3254 if (!NT_STATUS_IS_OK(status)) {
3255 return NT_STATUS_INVALID_HANDLE;
3258 if (!(info->access & LSA_ACCOUNT_VIEW))
3259 return NT_STATUS_ACCESS_DENIED;
3261 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
3262 if (!privset) {
3263 return NT_STATUS_NO_MEMORY;
3266 e.in.handle = r->in.handle;
3267 e.out.privs = &privset;
3269 status = _lsa_EnumPrivsAccount(p, &e);
3270 if (!NT_STATUS_IS_OK(status)) {
3271 DEBUG(10,("_lsa_GetSystemAccessAccount: "
3272 "failed to call _lsa_EnumPrivsAccount(): %s\n",
3273 nt_errstr(status)));
3274 return status;
3277 /* Samba4 would iterate over the privset to merge the policy mode bits,
3278 * not sure samba3 can do the same here, so just return what we did in
3279 * the past - gd */
3282 0x01 -> Log on locally
3283 0x02 -> Access this computer from network
3284 0x04 -> Log on as a batch job
3285 0x10 -> Log on as a service
3287 they can be ORed together
3290 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
3291 LSA_POLICY_MODE_NETWORK;
3293 return NT_STATUS_OK;
3296 /***************************************************************************
3297 update the systemaccount information
3298 ***************************************************************************/
3300 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
3301 struct lsa_SetSystemAccessAccount *r)
3303 struct lsa_info *info=NULL;
3304 NTSTATUS status;
3305 GROUP_MAP *map;
3307 /* find the connection policy handle. */
3308 info = find_policy_by_hnd(p,
3309 r->in.handle,
3310 LSA_HANDLE_ACCOUNT_TYPE,
3311 struct lsa_info,
3312 &status);
3313 if (!NT_STATUS_IS_OK(status)) {
3314 return NT_STATUS_INVALID_HANDLE;
3317 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
3318 return NT_STATUS_ACCESS_DENIED;
3321 map = talloc_zero(p->mem_ctx, GROUP_MAP);
3322 if (!map) {
3323 return NT_STATUS_NO_MEMORY;
3326 if (!pdb_getgrsid(map, info->sid)) {
3327 TALLOC_FREE(map);
3328 return NT_STATUS_NO_SUCH_GROUP;
3331 status = pdb_update_group_mapping_entry(map);
3332 TALLOC_FREE(map);
3333 return status;
3336 /***************************************************************************
3337 _lsa_AddPrivilegesToAccount
3338 For a given SID, add some privileges.
3339 ***************************************************************************/
3341 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
3342 struct lsa_AddPrivilegesToAccount *r)
3344 struct lsa_info *info = NULL;
3345 struct lsa_PrivilegeSet *set = NULL;
3346 NTSTATUS status;
3348 /* find the connection policy handle. */
3349 info = find_policy_by_hnd(p,
3350 r->in.handle,
3351 LSA_HANDLE_ACCOUNT_TYPE,
3352 struct lsa_info,
3353 &status);
3354 if (!NT_STATUS_IS_OK(status)) {
3355 return NT_STATUS_INVALID_HANDLE;
3358 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3359 return NT_STATUS_ACCESS_DENIED;
3362 set = r->in.privs;
3364 if ( !grant_privilege_set( &info->sid, set ) ) {
3365 struct dom_sid_buf buf;
3366 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
3367 dom_sid_str_buf(&info->sid, &buf)));
3368 return NT_STATUS_NO_SUCH_PRIVILEGE;
3371 return NT_STATUS_OK;
3374 /***************************************************************************
3375 _lsa_RemovePrivilegesFromAccount
3376 For a given SID, remove some privileges.
3377 ***************************************************************************/
3379 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
3380 struct lsa_RemovePrivilegesFromAccount *r)
3382 struct lsa_info *info = NULL;
3383 struct lsa_PrivilegeSet *set = NULL;
3384 NTSTATUS status;
3386 /* find the connection policy handle. */
3387 info = find_policy_by_hnd(p,
3388 r->in.handle,
3389 LSA_HANDLE_ACCOUNT_TYPE,
3390 struct lsa_info,
3391 &status);
3392 if (!NT_STATUS_IS_OK(status)) {
3393 return NT_STATUS_INVALID_HANDLE;
3396 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3397 return NT_STATUS_ACCESS_DENIED;
3400 set = r->in.privs;
3402 if ( !revoke_privilege_set( &info->sid, set) ) {
3403 struct dom_sid_buf buf;
3404 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
3405 dom_sid_str_buf(&info->sid, &buf)));
3406 return NT_STATUS_NO_SUCH_PRIVILEGE;
3409 return NT_STATUS_OK;
3412 /***************************************************************************
3413 _lsa_LookupPrivName
3414 ***************************************************************************/
3416 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
3417 struct lsa_LookupPrivName *r)
3419 struct lsa_info *info = NULL;
3420 const char *name;
3421 struct lsa_StringLarge *lsa_name;
3422 NTSTATUS status;
3424 /* find the connection policy handle. */
3425 info = find_policy_by_hnd(p,
3426 r->in.handle,
3427 LSA_HANDLE_POLICY_TYPE,
3428 struct lsa_info,
3429 &status);
3430 if (!NT_STATUS_IS_OK(status)) {
3431 return NT_STATUS_INVALID_HANDLE;
3434 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
3435 return NT_STATUS_ACCESS_DENIED;
3438 if (r->in.luid->high != 0) {
3439 return NT_STATUS_NO_SUCH_PRIVILEGE;
3442 name = sec_privilege_name(r->in.luid->low);
3443 if (!name) {
3444 return NT_STATUS_NO_SUCH_PRIVILEGE;
3447 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
3448 if (!lsa_name) {
3449 return NT_STATUS_NO_MEMORY;
3452 lsa_name->string = talloc_strdup(lsa_name, name);
3453 if (!lsa_name->string) {
3454 TALLOC_FREE(lsa_name);
3455 return NT_STATUS_NO_MEMORY;
3458 *r->out.name = lsa_name;
3460 return NT_STATUS_OK;
3463 /***************************************************************************
3464 _lsa_QuerySecurity
3465 ***************************************************************************/
3467 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
3468 struct lsa_QuerySecurity *r)
3470 struct lsa_info *handle=NULL;
3471 struct security_descriptor *psd = NULL;
3472 size_t sd_size = 0;
3473 NTSTATUS status;
3475 /* find the connection policy handle. */
3476 handle = find_policy_by_hnd(p,
3477 r->in.handle,
3478 DCESRV_HANDLE_ANY,
3479 struct lsa_info,
3480 &status);
3481 if (!NT_STATUS_IS_OK(status)) {
3482 return NT_STATUS_INVALID_HANDLE;
3485 switch (handle->type) {
3486 case LSA_HANDLE_POLICY_TYPE:
3487 case LSA_HANDLE_ACCOUNT_TYPE:
3488 case LSA_HANDLE_TRUST_TYPE:
3489 case LSA_HANDLE_SECRET_TYPE:
3490 psd = handle->sd;
3491 sd_size = ndr_size_security_descriptor(psd, 0);
3492 status = NT_STATUS_OK;
3493 break;
3494 default:
3495 status = NT_STATUS_INVALID_HANDLE;
3496 break;
3499 if (!NT_STATUS_IS_OK(status)) {
3500 return status;
3503 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
3504 if (!*r->out.sdbuf) {
3505 return NT_STATUS_NO_MEMORY;
3508 return status;
3511 /***************************************************************************
3512 _lsa_AddAccountRights
3513 ***************************************************************************/
3515 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
3516 struct lsa_AddAccountRights *r)
3518 struct dcesrv_call_state *dce_call = p->dce_call;
3519 struct auth_session_info *session_info =
3520 dcesrv_call_session_info(dce_call);
3521 int i = 0;
3522 uint32_t acc_granted = 0;
3523 struct security_descriptor *psd = NULL;
3524 size_t sd_size;
3525 struct dom_sid sid;
3526 NTSTATUS status;
3528 /* find the connection policy handle. */
3529 (void)find_policy_by_hnd(p,
3530 r->in.handle,
3531 LSA_HANDLE_POLICY_TYPE,
3532 struct lsa_info,
3533 &status);
3534 if (!NT_STATUS_IS_OK(status)) {
3535 return NT_STATUS_INVALID_HANDLE;
3538 /* get the generic lsa account SD for this SID until we store it */
3539 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3540 &lsa_account_mapping,
3541 NULL, 0);
3542 if (!NT_STATUS_IS_OK(status)) {
3543 return status;
3547 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3548 * on the policy handle. If it does, ask for
3549 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3550 * on the account sid. We don't check here so just use the latter. JRA.
3553 status = access_check_object(psd, session_info->security_token,
3554 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3555 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3556 &acc_granted, "_lsa_AddAccountRights" );
3557 if (!NT_STATUS_IS_OK(status)) {
3558 return status;
3561 /* according to an NT4 PDC, you can add privileges to SIDs even without
3562 call_lsa_create_account() first. And you can use any arbitrary SID. */
3564 sid_copy( &sid, r->in.sid );
3566 for ( i=0; i < r->in.rights->count; i++ ) {
3568 const char *privname = r->in.rights->names[i].string;
3570 /* only try to add non-null strings */
3572 if ( !privname )
3573 continue;
3575 if ( !grant_privilege_by_name( &sid, privname ) ) {
3576 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3577 privname ));
3578 return NT_STATUS_NO_SUCH_PRIVILEGE;
3582 return NT_STATUS_OK;
3585 /***************************************************************************
3586 _lsa_RemoveAccountRights
3587 ***************************************************************************/
3589 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
3590 struct lsa_RemoveAccountRights *r)
3592 struct dcesrv_call_state *dce_call = p->dce_call;
3593 struct auth_session_info *session_info =
3594 dcesrv_call_session_info(dce_call);
3595 int i = 0;
3596 struct security_descriptor *psd = NULL;
3597 size_t sd_size;
3598 struct dom_sid sid;
3599 const char *privname = NULL;
3600 uint32_t acc_granted = 0;
3601 NTSTATUS status;
3603 /* find the connection policy handle. */
3604 (void)find_policy_by_hnd(p,
3605 r->in.handle,
3606 LSA_HANDLE_POLICY_TYPE,
3607 struct lsa_info,
3608 &status);
3609 if (!NT_STATUS_IS_OK(status)) {
3610 return NT_STATUS_INVALID_HANDLE;
3613 /* get the generic lsa account SD for this SID until we store it */
3614 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3615 &lsa_account_mapping,
3616 NULL, 0);
3617 if (!NT_STATUS_IS_OK(status)) {
3618 return status;
3622 * From the MS DOCs. We need
3623 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3624 * and DELETE on the account sid.
3627 status = access_check_object(psd, session_info->security_token,
3628 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3629 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3630 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
3631 &acc_granted, "_lsa_RemoveAccountRights");
3632 if (!NT_STATUS_IS_OK(status)) {
3633 return status;
3636 sid_copy( &sid, r->in.sid );
3638 if ( r->in.remove_all ) {
3639 if ( !revoke_all_privileges( &sid ) )
3640 return NT_STATUS_ACCESS_DENIED;
3642 return NT_STATUS_OK;
3645 for ( i=0; i < r->in.rights->count; i++ ) {
3647 privname = r->in.rights->names[i].string;
3649 /* only try to add non-null strings */
3651 if ( !privname )
3652 continue;
3654 if ( !revoke_privilege_by_name( &sid, privname ) ) {
3655 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3656 privname ));
3657 return NT_STATUS_NO_SUCH_PRIVILEGE;
3661 return NT_STATUS_OK;
3664 /*******************************************************************
3665 ********************************************************************/
3667 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3668 struct lsa_RightSet *r,
3669 PRIVILEGE_SET *privileges)
3671 uint32_t i;
3672 const char *privname;
3673 const char **privname_array = NULL;
3674 size_t num_priv = 0;
3676 for (i=0; i<privileges->count; i++) {
3677 if (privileges->set[i].luid.high) {
3678 continue;
3680 privname = sec_privilege_name(privileges->set[i].luid.low);
3681 if (privname) {
3682 if (!add_string_to_array(mem_ctx, privname,
3683 &privname_array, &num_priv)) {
3684 return NT_STATUS_NO_MEMORY;
3689 if (num_priv) {
3691 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3692 num_priv);
3693 if (!r->names) {
3694 return NT_STATUS_NO_MEMORY;
3697 for (i=0; i<num_priv; i++) {
3698 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3701 r->count = num_priv;
3704 return NT_STATUS_OK;
3707 /***************************************************************************
3708 _lsa_EnumAccountRights
3709 ***************************************************************************/
3711 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3712 struct lsa_EnumAccountRights *r)
3714 NTSTATUS status;
3715 struct lsa_info *info = NULL;
3716 PRIVILEGE_SET *privileges;
3717 struct dom_sid_buf buf;
3719 /* find the connection policy handle. */
3721 info = find_policy_by_hnd(p,
3722 r->in.handle,
3723 LSA_HANDLE_POLICY_TYPE,
3724 struct lsa_info,
3725 &status);
3726 if (!NT_STATUS_IS_OK(status)) {
3727 return NT_STATUS_INVALID_HANDLE;
3730 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3731 return NT_STATUS_ACCESS_DENIED;
3734 /* according to an NT4 PDC, you can add privileges to SIDs even without
3735 call_lsa_create_account() first. And you can use any arbitrary SID. */
3737 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3738 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3739 * the lsa database */
3741 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3742 if (!NT_STATUS_IS_OK(status)) {
3743 return status;
3746 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3747 dom_sid_str_buf(r->in.sid, &buf),
3748 privileges->count));
3750 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3752 return status;
3755 /***************************************************************************
3756 _lsa_LookupPrivValue
3757 ***************************************************************************/
3759 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3760 struct lsa_LookupPrivValue *r)
3762 struct lsa_info *info = NULL;
3763 const char *name = NULL;
3764 NTSTATUS status;
3766 /* find the connection policy handle. */
3768 info = find_policy_by_hnd(p,
3769 r->in.handle,
3770 LSA_HANDLE_POLICY_TYPE,
3771 struct lsa_info,
3772 &status);
3773 if (!NT_STATUS_IS_OK(status)) {
3774 return NT_STATUS_INVALID_HANDLE;
3777 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3778 return NT_STATUS_ACCESS_DENIED;
3780 name = r->in.name->string;
3782 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3784 r->out.luid->low = sec_privilege_id(name);
3785 r->out.luid->high = 0;
3786 if (r->out.luid->low == SEC_PRIV_INVALID) {
3787 return NT_STATUS_NO_SUCH_PRIVILEGE;
3789 return NT_STATUS_OK;
3792 /***************************************************************************
3793 _lsa_EnumAccountsWithUserRight
3794 ***************************************************************************/
3796 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3797 struct lsa_EnumAccountsWithUserRight *r)
3799 NTSTATUS status;
3800 struct lsa_info *info = NULL;
3801 struct dom_sid *sids = NULL;
3802 int num_sids = 0;
3803 uint32_t i;
3804 enum sec_privilege privilege;
3806 info = find_policy_by_hnd(p,
3807 r->in.handle,
3808 LSA_HANDLE_POLICY_TYPE,
3809 struct lsa_info,
3810 &status);
3811 if (!NT_STATUS_IS_OK(status)) {
3812 return NT_STATUS_INVALID_HANDLE;
3815 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3816 return NT_STATUS_ACCESS_DENIED;
3819 if (!r->in.name || !r->in.name->string) {
3820 return NT_STATUS_NO_SUCH_PRIVILEGE;
3823 privilege = sec_privilege_id(r->in.name->string);
3824 if (privilege == SEC_PRIV_INVALID) {
3825 return NT_STATUS_NO_SUCH_PRIVILEGE;
3828 status = privilege_enum_sids(privilege, p->mem_ctx,
3829 &sids, &num_sids);
3830 if (!NT_STATUS_IS_OK(status)) {
3831 return status;
3834 r->out.sids->num_sids = num_sids;
3835 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3836 r->out.sids->num_sids);
3838 for (i=0; i < r->out.sids->num_sids; i++) {
3839 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3840 &sids[i]);
3841 if (!r->out.sids->sids[i].sid) {
3842 TALLOC_FREE(r->out.sids->sids);
3843 r->out.sids->num_sids = 0;
3844 return NT_STATUS_NO_MEMORY;
3848 return NT_STATUS_OK;
3851 /***************************************************************************
3852 _lsa_Delete
3853 ***************************************************************************/
3855 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3856 struct lsa_Delete *r)
3858 return NT_STATUS_NOT_SUPPORTED;
3861 static NTSTATUS info_ex_2_pdb_trusted_domain(
3862 struct lsa_TrustDomainInfoInfoEx *info_ex,
3863 struct pdb_trusted_domain *td)
3865 if (info_ex->domain_name.string == NULL ||
3866 info_ex->netbios_name.string == NULL ||
3867 info_ex->sid == NULL) {
3868 return NT_STATUS_INVALID_PARAMETER;
3871 td->domain_name = talloc_strdup(td, info_ex->domain_name.string);
3872 td->netbios_name = talloc_strdup(td, info_ex->netbios_name.string);
3873 sid_copy(&td->security_identifier, info_ex->sid);
3874 if (td->domain_name == NULL ||
3875 td->netbios_name == NULL ||
3876 is_null_sid(&td->security_identifier)) {
3877 return NT_STATUS_NO_MEMORY;
3879 td->trust_direction = info_ex->trust_direction;
3880 td->trust_type = info_ex->trust_type;
3881 td->trust_attributes = info_ex->trust_attributes;
3883 return NT_STATUS_OK;
3886 static NTSTATUS setInfoTrustedDomain_base(struct pipes_struct *p,
3887 TALLOC_CTX *mem_ctx,
3888 struct lsa_info *policy,
3889 enum lsa_TrustDomInfoEnum level,
3890 union lsa_TrustedDomainInfo *info)
3892 struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
3893 DATA_BLOB auth_blob;
3894 struct trustDomainPasswords auth_struct;
3895 NTSTATUS nt_status;
3897 struct pdb_trusted_domain *td;
3898 struct pdb_trusted_domain *orig_td;
3900 td = talloc_zero(mem_ctx, struct pdb_trusted_domain);
3901 if (td == NULL) {
3902 return NT_STATUS_NO_MEMORY;
3905 switch (level) {
3906 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
3907 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3908 return NT_STATUS_ACCESS_DENIED;
3910 td->trust_posix_offset = &info->posix_offset.posix_offset;
3911 break;
3912 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
3913 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3914 return NT_STATUS_ACCESS_DENIED;
3916 nt_status = info_ex_2_pdb_trusted_domain(&info->info_ex, td);
3917 if (!NT_STATUS_IS_OK(nt_status)) {
3918 return nt_status;
3920 break;
3921 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
3922 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3923 return NT_STATUS_ACCESS_DENIED;
3925 nt_status = auth_info_2_auth_blob(td, &info->auth_info,
3926 &td->trust_auth_incoming,
3927 &td->trust_auth_outgoing);
3928 if (!NT_STATUS_IS_OK(nt_status)) {
3929 return nt_status;
3931 break;
3932 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
3933 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3934 return NT_STATUS_ACCESS_DENIED;
3936 td->trust_posix_offset = &info->full_info.posix_offset.posix_offset;
3937 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info.info_ex,
3938 td);
3939 if (!NT_STATUS_IS_OK(nt_status)) {
3940 return nt_status;
3942 nt_status = auth_info_2_auth_blob(td,
3943 &info->full_info.auth_info,
3944 &td->trust_auth_incoming,
3945 &td->trust_auth_outgoing);
3946 if (!NT_STATUS_IS_OK(nt_status)) {
3947 return nt_status;
3949 break;
3950 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
3951 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3952 return NT_STATUS_ACCESS_DENIED;
3954 auth_info_int = &info->auth_info_internal;
3955 break;
3956 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
3957 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3958 return NT_STATUS_ACCESS_DENIED;
3960 td->trust_posix_offset = &info->full_info_internal.posix_offset.posix_offset;
3961 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info_internal.info_ex,
3962 td);
3963 if (!NT_STATUS_IS_OK(nt_status)) {
3964 return nt_status;
3966 auth_info_int = &info->full_info_internal.auth_info;
3967 break;
3968 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
3969 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3970 return NT_STATUS_ACCESS_DENIED;
3972 td->supported_enc_type = &info->enc_types.enc_types;
3973 break;
3974 default:
3975 return NT_STATUS_INVALID_PARAMETER;
3978 /* decode auth_info_int if set */
3979 if (auth_info_int) {
3981 /* now decrypt blob */
3982 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
3983 auth_info_int->auth_blob.size);
3985 nt_status = get_trustdom_auth_blob(p, mem_ctx,
3986 &auth_blob, &auth_struct);
3987 if (!NT_STATUS_IS_OK(nt_status)) {
3988 return nt_status;
3990 } else {
3991 memset(&auth_struct, 0, sizeof(auth_struct));
3994 /* TODO: verify only one object matches the dns/netbios/sid triplet and that
3995 * this is the one we already have */
3997 /* TODO: check if the trust direction is changed and we need to add or remove
3998 * auth data */
4000 /* TODO: check if trust type shall be changed and return an error in this case
4001 * */
4002 nt_status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &policy->sid,
4003 &orig_td);
4004 if (!NT_STATUS_IS_OK(nt_status)) {
4005 return nt_status;
4009 /* TODO: should we fetch previous values from the existing entry
4010 * and append them ? */
4011 if (auth_struct.incoming.count) {
4012 nt_status = get_trustauth_inout_blob(mem_ctx,
4013 &auth_struct.incoming,
4014 &td->trust_auth_incoming);
4015 if (!NT_STATUS_IS_OK(nt_status)) {
4016 return nt_status;
4018 } else {
4019 ZERO_STRUCT(td->trust_auth_incoming);
4022 if (auth_struct.outgoing.count) {
4023 nt_status = get_trustauth_inout_blob(mem_ctx,
4024 &auth_struct.outgoing,
4025 &td->trust_auth_outgoing);
4026 if (!NT_STATUS_IS_OK(nt_status)) {
4027 return nt_status;
4029 } else {
4030 ZERO_STRUCT(td->trust_auth_outgoing);
4033 nt_status = pdb_set_trusted_domain(orig_td->domain_name, td);
4034 if (!NT_STATUS_IS_OK(nt_status)) {
4035 return nt_status;
4038 return NT_STATUS_OK;
4041 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
4042 struct lsa_SetTrustedDomainInfo *r)
4044 NTSTATUS status;
4045 struct policy_handle trustdom_handle;
4046 struct lsa_OpenTrustedDomain o;
4047 struct lsa_SetInformationTrustedDomain s;
4048 struct lsa_Close c;
4050 o.in.handle = r->in.handle;
4051 o.in.sid = r->in.dom_sid;
4052 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4053 o.out.trustdom_handle = &trustdom_handle;
4055 status = _lsa_OpenTrustedDomain(p, &o);
4056 if (!NT_STATUS_IS_OK(status)) {
4057 return status;
4060 s.in.trustdom_handle = &trustdom_handle;
4061 s.in.level = r->in.level;
4062 s.in.info = r->in.info;
4064 status = _lsa_SetInformationTrustedDomain(p, &s);
4065 if (!NT_STATUS_IS_OK(status)) {
4066 return status;
4069 c.in.handle = &trustdom_handle;
4070 c.out.handle = &trustdom_handle;
4072 return _lsa_Close(p, &c);
4075 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
4076 struct lsa_SetTrustedDomainInfoByName *r)
4078 NTSTATUS status;
4079 struct policy_handle trustdom_handle;
4080 struct lsa_OpenTrustedDomainByName o;
4081 struct lsa_SetInformationTrustedDomain s;
4082 struct lsa_Close c;
4084 o.in.handle = r->in.handle;
4085 o.in.name.string = r->in.trusted_domain->string;
4086 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4087 o.out.trustdom_handle = &trustdom_handle;
4089 status = _lsa_OpenTrustedDomainByName(p, &o);
4090 if (!NT_STATUS_IS_OK(status)) {
4091 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
4092 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4094 return status;
4097 s.in.trustdom_handle = &trustdom_handle;
4098 s.in.level = r->in.level;
4099 s.in.info = r->in.info;
4101 status = _lsa_SetInformationTrustedDomain(p, &s);
4102 if (!NT_STATUS_IS_OK(status)) {
4103 return status;
4106 c.in.handle = &trustdom_handle;
4107 c.out.handle = &trustdom_handle;
4109 return _lsa_Close(p, &c);
4112 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
4113 struct lsa_SetInformationTrustedDomain *r)
4115 struct lsa_info *policy;
4116 NTSTATUS status;
4118 policy = find_policy_by_hnd(p,
4119 r->in.trustdom_handle,
4120 LSA_HANDLE_TRUST_TYPE,
4121 struct lsa_info,
4122 &status);
4123 if (!NT_STATUS_IS_OK(status)) {
4124 return NT_STATUS_INVALID_HANDLE;
4127 return setInfoTrustedDomain_base(p, p->mem_ctx, policy,
4128 r->in.level, r->in.info);
4133 * From here on the server routines are just dummy ones to make smbd link with
4134 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
4135 * pulling the server stubs across one by one.
4138 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
4140 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4141 return NT_STATUS_NOT_IMPLEMENTED;
4144 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
4145 struct lsa_ChangePassword *r)
4147 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4148 return NT_STATUS_NOT_IMPLEMENTED;
4151 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
4153 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4154 return NT_STATUS_NOT_IMPLEMENTED;
4157 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
4159 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4160 return NT_STATUS_NOT_IMPLEMENTED;
4163 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
4164 struct lsa_GetQuotasForAccount *r)
4166 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4167 return NT_STATUS_NOT_IMPLEMENTED;
4170 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
4171 struct lsa_SetQuotasForAccount *r)
4173 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4174 return NT_STATUS_NOT_IMPLEMENTED;
4177 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
4178 struct lsa_StorePrivateData *r)
4180 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4181 return NT_STATUS_NOT_IMPLEMENTED;
4184 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
4185 struct lsa_RetrievePrivateData *r)
4187 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4188 return NT_STATUS_NOT_IMPLEMENTED;
4191 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
4192 struct lsa_SetInfoPolicy2 *r)
4194 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4195 return NT_STATUS_NOT_IMPLEMENTED;
4198 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
4199 struct lsa_EnumTrustedDomainsEx *r)
4201 struct lsa_info *info;
4202 uint32_t count;
4203 struct pdb_trusted_domain **domains;
4204 struct lsa_TrustDomainInfoInfoEx *entries;
4205 int i;
4206 NTSTATUS nt_status;
4208 /* bail out early if pdb backend is not capable of ex trusted domains,
4209 * if we don't do that, the client might not call
4210 * _lsa_EnumTrustedDomains() afterwards - gd */
4212 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
4213 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4214 return NT_STATUS_NOT_IMPLEMENTED;
4217 info = find_policy_by_hnd(p,
4218 r->in.handle,
4219 LSA_HANDLE_POLICY_TYPE,
4220 struct lsa_info,
4221 &nt_status);
4222 if (!NT_STATUS_IS_OK(nt_status)) {
4223 return NT_STATUS_INVALID_HANDLE;
4226 /* check if the user has enough rights */
4227 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
4228 return NT_STATUS_ACCESS_DENIED;
4230 become_root();
4231 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
4232 unbecome_root();
4234 if (!NT_STATUS_IS_OK(nt_status)) {
4235 return nt_status;
4238 entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
4239 count);
4240 if (!entries) {
4241 return NT_STATUS_NO_MEMORY;
4244 for (i=0; i<count; i++) {
4245 init_lsa_StringLarge(&entries[i].domain_name,
4246 domains[i]->domain_name);
4247 init_lsa_StringLarge(&entries[i].netbios_name,
4248 domains[i]->netbios_name);
4249 entries[i].sid = &domains[i]->security_identifier;
4250 entries[i].trust_direction = domains[i]->trust_direction;
4251 entries[i].trust_type = domains[i]->trust_type;
4252 entries[i].trust_attributes = domains[i]->trust_attributes;
4255 if (*r->in.resume_handle >= count) {
4256 *r->out.resume_handle = -1;
4257 TALLOC_FREE(entries);
4258 return NT_STATUS_NO_MORE_ENTRIES;
4261 /* return the rest, limit by max_size. Note that we
4262 use the w2k3 element size value of 60 */
4263 r->out.domains->count = count - *r->in.resume_handle;
4264 r->out.domains->count = MIN(r->out.domains->count,
4265 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
4267 r->out.domains->domains = entries + *r->in.resume_handle;
4269 if (r->out.domains->count < count - *r->in.resume_handle) {
4270 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
4271 return STATUS_MORE_ENTRIES;
4274 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
4275 * always be larger than the previous input resume handle, in
4276 * particular when hitting the last query it is vital to set the
4277 * resume handle correctly to avoid infinite client loops, as
4278 * seen e.g. with Windows XP SP3 when resume handle is 0 and
4279 * status is NT_STATUS_OK - gd */
4281 *r->out.resume_handle = (uint32_t)-1;
4283 return NT_STATUS_OK;
4286 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
4287 struct lsa_QueryDomainInformationPolicy *r)
4289 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4290 return NT_STATUS_NOT_IMPLEMENTED;
4293 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
4294 struct lsa_SetDomainInformationPolicy *r)
4296 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4297 return NT_STATUS_NOT_IMPLEMENTED;
4300 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
4302 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4303 return NT_STATUS_NOT_IMPLEMENTED;
4306 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
4308 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4309 return NT_STATUS_NOT_IMPLEMENTED;
4312 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
4314 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4315 return NT_STATUS_NOT_IMPLEMENTED;
4318 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
4320 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4321 return NT_STATUS_NOT_IMPLEMENTED;
4324 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
4325 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
4327 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4328 return NT_STATUS_NOT_IMPLEMENTED;
4331 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
4332 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
4334 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4335 return NT_STATUS_NOT_IMPLEMENTED;
4338 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
4340 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4341 return NT_STATUS_NOT_IMPLEMENTED;
4344 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
4345 struct lsa_CREDRGETTARGETINFO *r)
4347 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4348 return NT_STATUS_NOT_IMPLEMENTED;
4351 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
4352 struct lsa_CREDRPROFILELOADED *r)
4354 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4355 return NT_STATUS_NOT_IMPLEMENTED;
4358 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
4359 struct lsa_CREDRGETSESSIONTYPES *r)
4361 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4362 return NT_STATUS_NOT_IMPLEMENTED;
4365 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
4366 struct lsa_LSARREGISTERAUDITEVENT *r)
4368 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4369 return NT_STATUS_NOT_IMPLEMENTED;
4372 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
4373 struct lsa_LSARGENAUDITEVENT *r)
4375 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4376 return NT_STATUS_NOT_IMPLEMENTED;
4379 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
4380 struct lsa_LSARUNREGISTERAUDITEVENT *r)
4382 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4383 return NT_STATUS_NOT_IMPLEMENTED;
4386 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
4387 struct lsa_lsaRQueryForestTrustInformation *r)
4389 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4390 return NT_STATUS_NOT_IMPLEMENTED;
4393 #define DNS_CMP_MATCH 0
4394 #define DNS_CMP_FIRST_IS_CHILD 1
4395 #define DNS_CMP_SECOND_IS_CHILD 2
4396 #define DNS_CMP_NO_MATCH 3
4398 /* this function assumes names are well formed DNS names.
4399 * it doesn't validate them */
4400 static int dns_cmp(const char *s1, size_t l1,
4401 const char *s2, size_t l2)
4403 const char *p1, *p2;
4404 size_t t1, t2;
4405 int cret;
4407 if (l1 == l2) {
4408 if (strcasecmp_m(s1, s2) == 0) {
4409 return DNS_CMP_MATCH;
4411 return DNS_CMP_NO_MATCH;
4414 if (l1 > l2) {
4415 p1 = s1;
4416 p2 = s2;
4417 t1 = l1;
4418 t2 = l2;
4419 cret = DNS_CMP_FIRST_IS_CHILD;
4420 } else {
4421 p1 = s2;
4422 p2 = s1;
4423 t1 = l2;
4424 t2 = l1;
4425 cret = DNS_CMP_SECOND_IS_CHILD;
4428 if (p1[t1 - t2 - 1] != '.') {
4429 return DNS_CMP_NO_MATCH;
4432 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
4433 return cret;
4436 return DNS_CMP_NO_MATCH;
4439 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
4440 struct lsa_ForestTrustInformation *lfti,
4441 struct ForestTrustInfo *fti)
4443 struct lsa_ForestTrustRecord *lrec;
4444 struct ForestTrustInfoRecord *rec;
4445 struct lsa_StringLarge *tln;
4446 struct lsa_ForestTrustDomainInfo *info;
4447 uint32_t i;
4449 fti->version = 1;
4450 fti->count = lfti->count;
4451 fti->records = talloc_array(mem_ctx,
4452 struct ForestTrustInfoRecordArmor,
4453 fti->count);
4454 if (!fti->records) {
4455 return NT_STATUS_NO_MEMORY;
4457 for (i = 0; i < fti->count; i++) {
4458 lrec = lfti->entries[i];
4459 rec = &fti->records[i].record;
4461 rec->flags = lrec->flags;
4462 rec->timestamp = lrec->time;
4463 rec->type = (enum ForestTrustInfoRecordType)lrec->type;
4465 switch (lrec->type) {
4466 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
4467 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4468 tln = &lrec->forest_trust_data.top_level_name;
4469 rec->data.name.string =
4470 talloc_strdup(mem_ctx, tln->string);
4471 if (!rec->data.name.string) {
4472 return NT_STATUS_NO_MEMORY;
4474 rec->data.name.size = strlen(rec->data.name.string);
4475 break;
4476 case LSA_FOREST_TRUST_DOMAIN_INFO:
4477 info = &lrec->forest_trust_data.domain_info;
4478 rec->data.info.sid = *info->domain_sid;
4479 rec->data.info.dns_name.string =
4480 talloc_strdup(mem_ctx,
4481 info->dns_domain_name.string);
4482 if (!rec->data.info.dns_name.string) {
4483 return NT_STATUS_NO_MEMORY;
4485 rec->data.info.dns_name.size =
4486 strlen(rec->data.info.dns_name.string);
4487 rec->data.info.netbios_name.string =
4488 talloc_strdup(mem_ctx,
4489 info->netbios_domain_name.string);
4490 if (!rec->data.info.netbios_name.string) {
4491 return NT_STATUS_NO_MEMORY;
4493 rec->data.info.netbios_name.size =
4494 strlen(rec->data.info.netbios_name.string);
4495 break;
4496 default:
4497 return NT_STATUS_INVALID_DOMAIN_STATE;
4501 return NT_STATUS_OK;
4504 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4505 uint32_t index, uint32_t collision_type,
4506 uint32_t conflict_type, const char *tdo_name);
4508 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
4509 const char *tdo_name,
4510 struct ForestTrustInfo *tdo_fti,
4511 struct ForestTrustInfo *new_fti,
4512 struct lsa_ForestTrustCollisionInfo *c_info)
4514 struct ForestTrustInfoRecord *nrec;
4515 struct ForestTrustInfoRecord *trec;
4516 const char *dns_name;
4517 const char *nb_name = NULL;
4518 struct dom_sid *sid = NULL;
4519 const char *tname = NULL;
4520 size_t dns_len = 0;
4521 size_t tlen = 0;
4522 uint32_t new_fti_idx;
4523 uint32_t i;
4524 /* use always TDO type, until we understand when Xref can be used */
4525 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
4526 bool tln_conflict;
4527 bool sid_conflict;
4528 bool nb_conflict;
4529 bool exclusion;
4530 bool ex_rule = false;
4531 int ret;
4533 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
4535 nrec = &new_fti->records[new_fti_idx].record;
4536 dns_name = NULL;
4537 tln_conflict = false;
4538 sid_conflict = false;
4539 nb_conflict = false;
4540 exclusion = false;
4542 switch (nrec->type) {
4543 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4544 /* exclusions do not conflict by definition */
4545 break;
4547 case FOREST_TRUST_TOP_LEVEL_NAME:
4548 dns_name = nrec->data.name.string;
4549 dns_len = nrec->data.name.size;
4550 break;
4552 case LSA_FOREST_TRUST_DOMAIN_INFO:
4553 dns_name = nrec->data.info.dns_name.string;
4554 dns_len = nrec->data.info.dns_name.size;
4555 nb_name = nrec->data.info.netbios_name.string;
4556 sid = &nrec->data.info.sid;
4557 break;
4560 if (!dns_name) continue;
4562 /* check if this is already taken and not excluded */
4563 for (i = 0; i < tdo_fti->count; i++) {
4564 trec = &tdo_fti->records[i].record;
4566 switch (trec->type) {
4567 case FOREST_TRUST_TOP_LEVEL_NAME:
4568 ex_rule = false;
4569 tname = trec->data.name.string;
4570 tlen = trec->data.name.size;
4571 break;
4572 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
4573 ex_rule = true;
4574 tname = trec->data.name.string;
4575 tlen = trec->data.name.size;
4576 break;
4577 case FOREST_TRUST_DOMAIN_INFO:
4578 ex_rule = false;
4579 tname = trec->data.info.dns_name.string;
4580 tlen = trec->data.info.dns_name.size;
4581 break;
4582 default:
4583 return NT_STATUS_INVALID_PARAMETER;
4585 ret = dns_cmp(dns_name, dns_len, tname, tlen);
4586 switch (ret) {
4587 case DNS_CMP_MATCH:
4588 /* if it matches exclusion,
4589 * it doesn't conflict */
4590 if (ex_rule) {
4591 exclusion = true;
4592 break;
4595 FALL_THROUGH;
4596 case DNS_CMP_FIRST_IS_CHILD:
4597 case DNS_CMP_SECOND_IS_CHILD:
4598 tln_conflict = true;
4600 FALL_THROUGH;
4601 default:
4602 break;
4605 /* explicit exclusion, no dns name conflict here */
4606 if (exclusion) {
4607 tln_conflict = false;
4610 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
4611 continue;
4614 /* also test for domain info */
4615 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
4616 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
4617 sid_conflict = true;
4619 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
4620 strcasecmp_m(trec->data.info.netbios_name.string,
4621 nb_name) == 0) {
4622 nb_conflict = true;
4626 if (tln_conflict) {
4627 (void)add_collision(c_info, new_fti_idx,
4628 collision_type,
4629 LSA_TLN_DISABLED_CONFLICT,
4630 tdo_name);
4632 if (sid_conflict) {
4633 (void)add_collision(c_info, new_fti_idx,
4634 collision_type,
4635 LSA_SID_DISABLED_CONFLICT,
4636 tdo_name);
4638 if (nb_conflict) {
4639 (void)add_collision(c_info, new_fti_idx,
4640 collision_type,
4641 LSA_NB_DISABLED_CONFLICT,
4642 tdo_name);
4646 return NT_STATUS_OK;
4649 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4650 uint32_t idx, uint32_t collision_type,
4651 uint32_t conflict_type, const char *tdo_name)
4653 struct lsa_ForestTrustCollisionRecord **es;
4654 uint32_t i = c_info->count;
4656 es = talloc_realloc(c_info, c_info->entries,
4657 struct lsa_ForestTrustCollisionRecord *, i + 1);
4658 if (!es) {
4659 return NT_STATUS_NO_MEMORY;
4661 c_info->entries = es;
4662 c_info->count = i + 1;
4664 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4665 if (!es[i]) {
4666 return NT_STATUS_NO_MEMORY;
4669 es[i]->index = idx;
4670 es[i]->type = collision_type;
4671 es[i]->flags = conflict_type;
4672 es[i]->name.string = talloc_strdup(es[i], tdo_name);
4673 if (!es[i]->name.string) {
4674 return NT_STATUS_NO_MEMORY;
4676 es[i]->name.size = strlen(es[i]->name.string);
4678 return NT_STATUS_OK;
4681 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
4682 struct pdb_trusted_domain *td,
4683 struct ForestTrustInfo *info)
4685 enum ndr_err_code ndr_err;
4687 if (td->trust_forest_trust_info.length == 0 ||
4688 td->trust_forest_trust_info.data == NULL) {
4689 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4691 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
4692 info,
4693 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
4694 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4695 return NT_STATUS_INVALID_DOMAIN_STATE;
4698 return NT_STATUS_OK;
4701 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
4702 struct ForestTrustInfo *fti)
4704 struct ForestTrustDataDomainInfo *info;
4705 struct ForestTrustInfoRecord *rec;
4707 fti->version = 1;
4708 fti->count = 2;
4709 fti->records = talloc_array(fti,
4710 struct ForestTrustInfoRecordArmor, 2);
4711 if (!fti->records) {
4712 return NT_STATUS_NO_MEMORY;
4715 /* TLN info */
4716 rec = &fti->records[0].record;
4718 rec->flags = 0;
4719 rec->timestamp = 0;
4720 rec->type = FOREST_TRUST_TOP_LEVEL_NAME;
4722 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
4723 if (!rec->data.name.string) {
4724 return NT_STATUS_NO_MEMORY;
4726 rec->data.name.size = strlen(rec->data.name.string);
4728 /* DOMAIN info */
4729 rec = &fti->records[1].record;
4731 rec->flags = 0;
4732 rec->timestamp = 0;
4733 rec->type = FOREST_TRUST_DOMAIN_INFO;
4735 info = &rec->data.info;
4737 info->sid = dom_info->sid;
4738 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
4739 if (!info->dns_name.string) {
4740 return NT_STATUS_NO_MEMORY;
4742 info->dns_name.size = strlen(info->dns_name.string);
4743 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
4744 if (!info->netbios_name.string) {
4745 return NT_STATUS_NO_MEMORY;
4747 info->netbios_name.size = strlen(info->netbios_name.string);
4749 return NT_STATUS_OK;
4752 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
4753 struct lsa_lsaRSetForestTrustInformation *r)
4755 NTSTATUS status;
4756 int i;
4757 int j;
4758 struct lsa_info *handle;
4759 uint32_t num_domains;
4760 struct pdb_trusted_domain **domains;
4761 struct ForestTrustInfo *nfti;
4762 struct ForestTrustInfo *fti;
4763 struct lsa_ForestTrustCollisionInfo *c_info;
4764 struct pdb_domain_info *dom_info;
4765 enum ndr_err_code ndr_err;
4767 if (!IS_DC) {
4768 return NT_STATUS_NOT_SUPPORTED;
4771 handle = find_policy_by_hnd(p,
4772 r->in.handle,
4773 LSA_HANDLE_TRUST_TYPE,
4774 struct lsa_info,
4775 &status);
4776 if (!NT_STATUS_IS_OK(status)) {
4777 return NT_STATUS_INVALID_HANDLE;
4780 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
4781 return NT_STATUS_ACCESS_DENIED;
4784 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
4785 if (!NT_STATUS_IS_OK(status)) {
4786 return status;
4788 if (num_domains == 0) {
4789 return NT_STATUS_NO_SUCH_DOMAIN;
4792 for (i = 0; i < num_domains; i++) {
4793 if (domains[i]->domain_name == NULL) {
4794 return NT_STATUS_INVALID_DOMAIN_STATE;
4796 if (strcasecmp_m(domains[i]->domain_name,
4797 r->in.trusted_domain_name->string) == 0) {
4798 break;
4801 if (i >= num_domains) {
4802 return NT_STATUS_NO_SUCH_DOMAIN;
4805 if (!(domains[i]->trust_attributes &
4806 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4807 return NT_STATUS_INVALID_PARAMETER;
4810 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4811 return NT_STATUS_INVALID_PARAMETER;
4814 /* The following section until COPY_END is a copy from
4815 * source4/rpmc_server/lsa/scesrc_lsa.c */
4816 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
4817 if (!nfti) {
4818 return NT_STATUS_NO_MEMORY;
4821 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4822 if (!NT_STATUS_IS_OK(status)) {
4823 return status;
4826 c_info = talloc_zero(r->out.collision_info,
4827 struct lsa_ForestTrustCollisionInfo);
4828 if (!c_info) {
4829 return NT_STATUS_NO_MEMORY;
4832 /* first check own info, then other domains */
4833 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4834 if (!fti) {
4835 return NT_STATUS_NO_MEMORY;
4838 dom_info = pdb_get_domain_info(p->mem_ctx);
4840 status = own_ft_info(dom_info, fti);
4841 if (!NT_STATUS_IS_OK(status)) {
4842 return status;
4845 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
4846 if (!NT_STATUS_IS_OK(status)) {
4847 return status;
4850 for (j = 0; j < num_domains; j++) {
4851 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4852 if (!fti) {
4853 return NT_STATUS_NO_MEMORY;
4856 status = get_ft_info(p->mem_ctx, domains[j], fti);
4857 if (!NT_STATUS_IS_OK(status)) {
4858 if (NT_STATUS_EQUAL(status,
4859 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4860 continue;
4862 return status;
4865 if (domains[j]->domain_name == NULL) {
4866 return NT_STATUS_INVALID_DOMAIN_STATE;
4869 status = check_ft_info(c_info, domains[j]->domain_name,
4870 fti, nfti, c_info);
4871 if (!NT_STATUS_IS_OK(status)) {
4872 return status;
4876 if (c_info->count != 0) {
4877 *r->out.collision_info = c_info;
4880 if (r->in.check_only != 0) {
4881 return NT_STATUS_OK;
4884 /* COPY_END */
4886 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
4887 p->mem_ctx, nfti,
4888 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4889 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4890 return NT_STATUS_INVALID_PARAMETER;
4893 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
4894 if (!NT_STATUS_IS_OK(status)) {
4895 return status;
4898 return NT_STATUS_OK;
4901 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
4902 struct lsa_CREDRRENAME *r)
4904 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4905 return NT_STATUS_NOT_IMPLEMENTED;
4908 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
4909 struct lsa_LSAROPENPOLICYSCE *r)
4911 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4912 return NT_STATUS_NOT_IMPLEMENTED;
4915 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4916 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4918 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4919 return NT_STATUS_NOT_IMPLEMENTED;
4922 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4923 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4925 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4926 return NT_STATUS_NOT_IMPLEMENTED;
4929 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4930 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4932 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4933 return NT_STATUS_NOT_IMPLEMENTED;
4936 void _lsa_Opnum82NotUsedOnWire(struct pipes_struct *p,
4937 struct lsa_Opnum82NotUsedOnWire *r)
4939 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4942 void _lsa_Opnum83NotUsedOnWire(struct pipes_struct *p,
4943 struct lsa_Opnum83NotUsedOnWire *r)
4945 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4948 void _lsa_Opnum84NotUsedOnWire(struct pipes_struct *p,
4949 struct lsa_Opnum84NotUsedOnWire *r)
4951 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4954 void _lsa_Opnum85NotUsedOnWire(struct pipes_struct *p,
4955 struct lsa_Opnum85NotUsedOnWire *r)
4957 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4960 void _lsa_Opnum86NotUsedOnWire(struct pipes_struct *p,
4961 struct lsa_Opnum86NotUsedOnWire *r)
4963 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4966 void _lsa_Opnum87NotUsedOnWire(struct pipes_struct *p,
4967 struct lsa_Opnum87NotUsedOnWire *r)
4969 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4972 void _lsa_Opnum88NotUsedOnWire(struct pipes_struct *p,
4973 struct lsa_Opnum88NotUsedOnWire *r)
4975 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4978 void _lsa_Opnum89NotUsedOnWire(struct pipes_struct *p,
4979 struct lsa_Opnum89NotUsedOnWire *r)
4981 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4984 void _lsa_Opnum90NotUsedOnWire(struct pipes_struct *p,
4985 struct lsa_Opnum90NotUsedOnWire *r)
4987 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4990 void _lsa_Opnum91NotUsedOnWire(struct pipes_struct *p,
4991 struct lsa_Opnum91NotUsedOnWire *r)
4993 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4996 void _lsa_Opnum92NotUsedOnWire(struct pipes_struct *p,
4997 struct lsa_Opnum92NotUsedOnWire *r)
4999 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5002 void _lsa_Opnum93NotUsedOnWire(struct pipes_struct *p,
5003 struct lsa_Opnum93NotUsedOnWire *r)
5005 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5008 void _lsa_Opnum94NotUsedOnWire(struct pipes_struct *p,
5009 struct lsa_Opnum94NotUsedOnWire *r)
5011 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5014 void _lsa_Opnum95NotUsedOnWire(struct pipes_struct *p,
5015 struct lsa_Opnum95NotUsedOnWire *r)
5017 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5020 void _lsa_Opnum96NotUsedOnWire(struct pipes_struct *p,
5021 struct lsa_Opnum96NotUsedOnWire *r)
5023 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5026 void _lsa_Opnum97NotUsedOnWire(struct pipes_struct *p,
5027 struct lsa_Opnum97NotUsedOnWire *r)
5029 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5032 void _lsa_Opnum98NotUsedOnWire(struct pipes_struct *p,
5033 struct lsa_Opnum98NotUsedOnWire *r)
5035 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5038 void _lsa_Opnum99NotUsedOnWire(struct pipes_struct *p,
5039 struct lsa_Opnum99NotUsedOnWire *r)
5041 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5044 void _lsa_Opnum100NotUsedOnWire(struct pipes_struct *p,
5045 struct lsa_Opnum100NotUsedOnWire *r)
5047 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5050 void _lsa_Opnum101NotUsedOnWire(struct pipes_struct *p,
5051 struct lsa_Opnum101NotUsedOnWire *r)
5053 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5056 void _lsa_Opnum102NotUsedOnWire(struct pipes_struct *p,
5057 struct lsa_Opnum102NotUsedOnWire *r)
5059 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5062 void _lsa_Opnum103NotUsedOnWire(struct pipes_struct *p,
5063 struct lsa_Opnum103NotUsedOnWire *r)
5065 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5068 void _lsa_Opnum104NotUsedOnWire(struct pipes_struct *p,
5069 struct lsa_Opnum104NotUsedOnWire *r)
5071 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5074 void _lsa_Opnum105NotUsedOnWire(struct pipes_struct *p,
5075 struct lsa_Opnum105NotUsedOnWire *r)
5077 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5080 void _lsa_Opnum106NotUsedOnWire(struct pipes_struct *p,
5081 struct lsa_Opnum106NotUsedOnWire *r)
5083 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5086 void _lsa_Opnum107NotUsedOnWire(struct pipes_struct *p,
5087 struct lsa_Opnum107NotUsedOnWire *r)
5089 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5092 void _lsa_Opnum108NotUsedOnWire(struct pipes_struct *p,
5093 struct lsa_Opnum108NotUsedOnWire *r)
5095 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5098 void _lsa_Opnum109NotUsedOnWire(struct pipes_struct *p,
5099 struct lsa_Opnum109NotUsedOnWire *r)
5101 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5104 void _lsa_Opnum110NotUsedOnWire(struct pipes_struct *p,
5105 struct lsa_Opnum110NotUsedOnWire *r)
5107 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5110 void _lsa_Opnum111NotUsedOnWire(struct pipes_struct *p,
5111 struct lsa_Opnum111NotUsedOnWire *r)
5113 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5116 void _lsa_Opnum112NotUsedOnWire(struct pipes_struct *p,
5117 struct lsa_Opnum112NotUsedOnWire *r)
5119 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5122 void _lsa_Opnum113NotUsedOnWire(struct pipes_struct *p,
5123 struct lsa_Opnum113NotUsedOnWire *r)
5125 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5128 void _lsa_Opnum114NotUsedOnWire(struct pipes_struct *p,
5129 struct lsa_Opnum114NotUsedOnWire *r)
5131 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5134 void _lsa_Opnum115NotUsedOnWire(struct pipes_struct *p,
5135 struct lsa_Opnum115NotUsedOnWire *r)
5137 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5140 void _lsa_Opnum116NotUsedOnWire(struct pipes_struct *p,
5141 struct lsa_Opnum116NotUsedOnWire *r)
5143 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5146 void _lsa_Opnum117NotUsedOnWire(struct pipes_struct *p,
5147 struct lsa_Opnum117NotUsedOnWire *r)
5149 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5152 void _lsa_Opnum118NotUsedOnWire(struct pipes_struct *p,
5153 struct lsa_Opnum118NotUsedOnWire *r)
5155 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5158 void _lsa_Opnum119NotUsedOnWire(struct pipes_struct *p,
5159 struct lsa_Opnum119NotUsedOnWire *r)
5161 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5164 void _lsa_Opnum120NotUsedOnWire(struct pipes_struct *p,
5165 struct lsa_Opnum120NotUsedOnWire *r)
5167 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5170 void _lsa_Opnum121NotUsedOnWire(struct pipes_struct *p,
5171 struct lsa_Opnum121NotUsedOnWire *r)
5173 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5176 void _lsa_Opnum122NotUsedOnWire(struct pipes_struct *p,
5177 struct lsa_Opnum122NotUsedOnWire *r)
5179 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5182 void _lsa_Opnum123NotUsedOnWire(struct pipes_struct *p,
5183 struct lsa_Opnum123NotUsedOnWire *r)
5185 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5188 void _lsa_Opnum124NotUsedOnWire(struct pipes_struct *p,
5189 struct lsa_Opnum124NotUsedOnWire *r)
5191 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5194 void _lsa_Opnum125NotUsedOnWire(struct pipes_struct *p,
5195 struct lsa_Opnum125NotUsedOnWire *r)
5197 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5200 void _lsa_Opnum126NotUsedOnWire(struct pipes_struct *p,
5201 struct lsa_Opnum126NotUsedOnWire *r)
5203 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5206 void _lsa_Opnum127NotUsedOnWire(struct pipes_struct *p,
5207 struct lsa_Opnum127NotUsedOnWire *r)
5209 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5212 void _lsa_Opnum128NotUsedOnWire(struct pipes_struct *p,
5213 struct lsa_Opnum128NotUsedOnWire *r)
5215 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5218 /***************************************************************************
5219 _lsa_CreateTrustedDomainEx3
5220 ***************************************************************************/
5222 NTSTATUS _lsa_CreateTrustedDomainEx3(struct pipes_struct *p,
5223 struct lsa_CreateTrustedDomainEx3 *r)
5225 struct dcesrv_call_state *dce_call = p->dce_call;
5226 struct auth_session_info *session_info =
5227 dcesrv_call_session_info(dce_call);
5228 struct lsa_info *policy;
5229 NTSTATUS status;
5230 struct trustDomainPasswords auth_struct = {
5231 .incoming_size = 0,
5234 if (!IS_DC) {
5235 return NT_STATUS_NOT_SUPPORTED;
5238 policy = find_policy_by_hnd(p,
5239 r->in.policy_handle,
5240 LSA_HANDLE_POLICY_TYPE,
5241 struct lsa_info,
5242 &status);
5243 if (!NT_STATUS_IS_OK(status)) {
5244 return NT_STATUS_INVALID_HANDLE;
5247 status = lsa_CreateTrustedDomain_precheck(p->mem_ctx,
5248 policy,
5249 session_info,
5250 r->in.info);
5251 if (!NT_STATUS_IS_OK(status)) {
5252 return status;
5256 status = get_trustdom_auth_blob_aes(dce_call,
5257 p->mem_ctx,
5258 r->in.auth_info_internal,
5259 &auth_struct);
5260 if (!NT_STATUS_IS_OK(status)) {
5261 return NT_STATUS_UNSUCCESSFUL;
5264 status = lsa_CreateTrustedDomain_common(p,
5265 p->mem_ctx,
5266 session_info,
5267 policy,
5268 r->in.access_mask,
5269 r->in.info,
5270 &auth_struct,
5271 &r->out.trustdom_handle);
5272 if (!NT_STATUS_IS_OK(status)) {
5273 return status;
5276 return NT_STATUS_OK;
5279 /***************************************************************************
5280 _lsa_OpenPolicy3
5281 ***************************************************************************/
5283 NTSTATUS _lsa_OpenPolicy3(struct pipes_struct *p,
5284 struct lsa_OpenPolicy3 *r)
5286 struct dcesrv_call_state *dce_call = p->dce_call;
5287 struct auth_session_info *session_info =
5288 dcesrv_call_session_info(dce_call);
5289 struct security_descriptor *psd = NULL;
5290 size_t sd_size;
5291 uint32_t des_access = r->in.access_mask;
5292 uint32_t acc_granted;
5293 NTSTATUS status;
5295 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
5296 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
5297 return NT_STATUS_ACCESS_DENIED;
5300 ZERO_STRUCTP(r->out.handle);
5303 * The attributes have no effect and MUST be ignored, except the
5304 * root_dir which MUST be NULL.
5306 if (r->in.attr != NULL && r->in.attr->root_dir != NULL) {
5307 return NT_STATUS_INVALID_PARAMETER;
5310 switch (r->in.in_version) {
5311 case 1:
5312 *r->out.out_version = 1;
5314 r->out.out_revision_info->info1.revision = 1;
5315 /* TODO: Enable as soon as we support it */
5316 #if 0
5317 r->out.out_revision_info->info1.supported_features =
5318 LSA_FEATURE_TDO_AUTH_INFO_AES_CIPHER;
5319 #endif
5321 break;
5322 default:
5323 return NT_STATUS_NOT_SUPPORTED;
5326 /* Work out max allowed. */
5327 map_max_allowed_access(session_info->security_token,
5328 session_info->unix_token,
5329 &des_access);
5331 /* map the generic bits to the lsa policy ones */
5332 se_map_generic(&des_access, &lsa_policy_mapping);
5334 /* get the generic lsa policy SD until we store it */
5335 status = make_lsa_object_sd(p->mem_ctx,
5336 &psd,
5337 &sd_size,
5338 &lsa_policy_mapping,
5339 NULL,
5341 if (!NT_STATUS_IS_OK(status)) {
5342 return status;
5345 status = access_check_object(psd,
5346 session_info->security_token,
5347 SEC_PRIV_INVALID,
5348 SEC_PRIV_INVALID,
5350 des_access,
5351 &acc_granted,
5352 "_lsa_OpenPolicy2");
5353 if (!NT_STATUS_IS_OK(status)) {
5354 return status;
5357 status = create_lsa_policy_handle(p->mem_ctx,
5359 LSA_HANDLE_POLICY_TYPE,
5360 acc_granted,
5361 get_global_sam_sid(),
5362 NULL,
5363 psd,
5364 r->out.handle);
5365 if (!NT_STATUS_IS_OK(status)) {
5366 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5369 return NT_STATUS_OK;
5372 void _lsa_Opnum131NotUsedOnWire(struct pipes_struct *p,
5373 struct lsa_Opnum131NotUsedOnWire *r)
5375 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5378 NTSTATUS _lsa_lsaRQueryForestTrustInformation2(struct pipes_struct *p,
5379 struct lsa_lsaRQueryForestTrustInformation2 *r)
5381 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5382 return NT_STATUS_NOT_IMPLEMENTED;
5385 NTSTATUS _lsa_lsaRSetForestTrustInformation2(struct pipes_struct *p,
5386 struct lsa_lsaRSetForestTrustInformation2 *r)
5388 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5389 return NT_STATUS_NOT_IMPLEMENTED;
5392 #include "librpc/rpc/dcesrv_core.h"
5394 #define DCESRV_INTERFACE_LSARPC_BIND(context, iface) \
5395 dcesrv_interface_lsarpc_bind(context, iface)
5397 static NTSTATUS dcesrv_interface_lsarpc_bind(
5398 struct dcesrv_connection_context *context,
5399 const struct dcesrv_interface *iface)
5401 return dcesrv_interface_bind_reject_connect(context, iface);
5404 static NTSTATUS lsarpc__op_init_server(struct dcesrv_context *dce_ctx,
5405 const struct dcesrv_endpoint_server *ep_server);
5406 static const struct dcesrv_interface dcesrv_lsarpc_interface;
5408 #define NCACN_NP_PIPE_NETLOGON "ncacn_np:[\\pipe\\netlogon]"
5409 #define NCACN_NP_PIPE_LSASS "ncacn_np:[\\pipe\\lsass]"
5411 #define DCESRV_INTERFACE_LSARPC_NCACN_NP_SECONDARY_ENDPOINT \
5412 NCACN_NP_PIPE_LSASS
5414 #define DCESRV_INTERFACE_LSARPC_INIT_SERVER \
5415 dcesrv_interface_lsarpc_init_server
5417 static NTSTATUS dcesrv_interface_lsarpc_init_server(
5418 struct dcesrv_context *dce_ctx,
5419 const struct dcesrv_endpoint_server *ep_server)
5421 NTSTATUS ret = dcesrv_interface_register(dce_ctx,
5422 NCACN_NP_PIPE_NETLOGON,
5423 NCACN_NP_PIPE_LSASS,
5424 &dcesrv_lsarpc_interface,
5425 NULL);
5426 if (!NT_STATUS_IS_OK(ret)) {
5427 DBG_ERR("Failed to register endpoint "
5428 "'\\pipe\\netlogon'\n");
5429 return ret;
5432 return lsarpc__op_init_server(dce_ctx, ep_server);
5435 /* include the generated boilerplate */
5436 #include "librpc/gen_ndr/ndr_lsa_scompat.c"