drsuapi.idl: fix source_dsa spelling
[samba4-gss.git] / source3 / rpc_server / lsa / srv_lsa_nt.c
blob6d4d861fad9aa59061c7b501e3a7a2e3fde76800
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 "../lib/util/dns_cmp.h"
34 #include "ntdomain.h"
35 #include "librpc/gen_ndr/ndr_lsa.h"
36 #include "librpc/gen_ndr/ndr_lsa_scompat.h"
37 #include "secrets.h"
38 #include "../librpc/gen_ndr/netlogon.h"
39 #include "rpc_client/init_lsa.h"
40 #include "../libcli/security/security.h"
41 #include "../libcli/security/dom_sid.h"
42 #include "../librpc/gen_ndr/drsblobs.h"
43 #include "../librpc/gen_ndr/ndr_drsblobs.h"
44 #include "../libcli/security/dom_sid.h"
45 #include "../librpc/gen_ndr/ndr_security.h"
46 #include "passdb.h"
47 #include "auth.h"
48 #include "lib/privileges.h"
49 #include "rpc_server/srv_access_check.h"
50 #include "../librpc/gen_ndr/ndr_wkssvc.h"
51 #include "../libcli/auth/libcli_auth.h"
52 #include "../libcli/lsarpc/util_lsarpc.h"
53 #include "lsa.h"
54 #include "librpc/rpc/dcesrv_core.h"
55 #include "librpc/rpc/dcerpc_helper.h"
56 #include "lib/param/loadparm.h"
57 #include "source3/lib/substitute.h"
58 #include "librpc/rpc/dcerpc_lsa.h"
60 #include "lib/crypto/gnutls_helpers.h"
61 #include <gnutls/gnutls.h>
62 #include <gnutls/crypto.h>
64 #undef strcasecmp
66 #undef DBGC_CLASS
67 #define DBGC_CLASS DBGC_RPC_SRV
69 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
71 enum lsa_handle_type {
72 LSA_HANDLE_POLICY_TYPE = 1,
73 LSA_HANDLE_ACCOUNT_TYPE = 2,
74 LSA_HANDLE_TRUST_TYPE = 3,
75 LSA_HANDLE_SECRET_TYPE = 4};
77 struct lsa_info {
78 struct dom_sid sid;
79 const char *name;
80 uint32_t access;
81 enum lsa_handle_type type;
82 struct security_descriptor *sd;
85 const struct generic_mapping lsa_account_mapping = {
86 LSA_ACCOUNT_READ,
87 LSA_ACCOUNT_WRITE,
88 LSA_ACCOUNT_EXECUTE,
89 LSA_ACCOUNT_ALL_ACCESS
92 const struct generic_mapping lsa_policy_mapping = {
93 LSA_POLICY_READ,
94 LSA_POLICY_WRITE,
95 LSA_POLICY_EXECUTE,
96 LSA_POLICY_ALL_ACCESS
99 const struct generic_mapping lsa_secret_mapping = {
100 LSA_SECRET_READ,
101 LSA_SECRET_WRITE,
102 LSA_SECRET_EXECUTE,
103 LSA_SECRET_ALL_ACCESS
106 const struct generic_mapping lsa_trusted_domain_mapping = {
107 LSA_TRUSTED_DOMAIN_READ,
108 LSA_TRUSTED_DOMAIN_WRITE,
109 LSA_TRUSTED_DOMAIN_EXECUTE,
110 LSA_TRUSTED_DOMAIN_ALL_ACCESS
113 /***************************************************************************
114 initialize a lsa_DomainInfo structure.
115 ***************************************************************************/
117 static void init_dom_query_3(struct lsa_DomainInfo *r,
118 const char *name,
119 struct dom_sid *sid)
121 init_lsa_StringLarge(&r->name, name);
122 r->sid = sid;
125 /***************************************************************************
126 initialize a lsa_DomainInfo structure.
127 ***************************************************************************/
129 static void init_dom_query_5(struct lsa_DomainInfo *r,
130 const char *name,
131 struct dom_sid *sid)
133 init_lsa_StringLarge(&r->name, name);
134 r->sid = sid;
137 /***************************************************************************
138 lookup_lsa_rids. Must be called as root for lookup_name to work.
139 ***************************************************************************/
141 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
142 struct lsa_RefDomainList *ref,
143 struct lsa_TranslatedSid *prid,
144 uint32_t num_entries,
145 struct lsa_String *name,
146 int flags,
147 uint32_t *pmapped_count)
149 uint32_t mapped_count, i;
151 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
153 mapped_count = 0;
154 *pmapped_count = 0;
156 for (i = 0; i < num_entries; i++) {
157 struct dom_sid sid;
158 uint32_t rid;
159 int dom_idx;
160 const char *full_name;
161 const char *domain;
162 enum lsa_SidType type;
164 /* Split name into domain and user component */
166 /* follow w2k8 behavior and return the builtin domain when no
167 * input has been passed in */
169 if (name[i].string) {
170 full_name = name[i].string;
171 } else {
172 full_name = "BUILTIN";
175 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
177 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
178 &sid, &type)) {
179 type = SID_NAME_UNKNOWN;
182 switch (type) {
183 case SID_NAME_USER:
184 case SID_NAME_DOM_GRP:
185 case SID_NAME_DOMAIN:
186 case SID_NAME_ALIAS:
187 case SID_NAME_WKN_GRP:
188 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
189 /* Leave these unchanged */
190 break;
191 default:
192 /* Don't hand out anything but the list above */
193 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
194 type = SID_NAME_UNKNOWN;
195 break;
198 rid = 0;
199 dom_idx = -1;
201 if (type != SID_NAME_UNKNOWN) {
202 if (type == SID_NAME_DOMAIN) {
203 rid = (uint32_t)-1;
204 } else {
205 sid_split_rid(&sid, &rid);
207 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
208 mapped_count++;
211 prid[i].sid_type = type;
212 prid[i].rid = rid;
213 prid[i].sid_index = dom_idx;
216 *pmapped_count = mapped_count;
217 return NT_STATUS_OK;
220 /***************************************************************************
221 lookup_lsa_sids. Must be called as root for lookup_name to work.
222 ***************************************************************************/
224 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
225 struct lsa_RefDomainList *ref,
226 struct lsa_TranslatedSid3 *trans_sids,
227 uint32_t num_entries,
228 struct lsa_String *name,
229 int flags,
230 uint32_t *pmapped_count)
232 uint32_t mapped_count, i;
234 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
236 mapped_count = 0;
237 *pmapped_count = 0;
239 for (i = 0; i < num_entries; i++) {
240 struct dom_sid sid;
241 uint32_t rid;
242 int dom_idx;
243 const char *full_name;
244 const char *domain;
245 enum lsa_SidType type;
247 ZERO_STRUCT(sid);
249 /* Split name into domain and user component */
251 full_name = name[i].string;
252 if (full_name == NULL) {
253 return NT_STATUS_NO_MEMORY;
256 DEBUG(5, ("lookup_lsa_sids: looking up name %s\n", full_name));
258 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
259 &sid, &type)) {
260 type = SID_NAME_UNKNOWN;
263 switch (type) {
264 case SID_NAME_USER:
265 case SID_NAME_DOM_GRP:
266 case SID_NAME_DOMAIN:
267 case SID_NAME_ALIAS:
268 case SID_NAME_WKN_GRP:
269 DEBUG(5, ("lookup_lsa_sids: %s found\n", full_name));
270 /* Leave these unchanged */
271 break;
272 default:
273 /* Don't hand out anything but the list above */
274 DEBUG(5, ("lookup_lsa_sids: %s not found\n", full_name));
275 type = SID_NAME_UNKNOWN;
276 break;
279 rid = 0;
280 dom_idx = -1;
282 if (type != SID_NAME_UNKNOWN) {
283 struct dom_sid domain_sid;
284 sid_copy(&domain_sid, &sid);
285 sid_split_rid(&domain_sid, &rid);
286 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
287 mapped_count++;
290 /* Initialize the lsa_TranslatedSid3 return. */
291 trans_sids[i].sid_type = type;
292 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
293 trans_sids[i].sid_index = dom_idx;
296 *pmapped_count = mapped_count;
297 return NT_STATUS_OK;
300 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
301 const struct generic_mapping *map,
302 struct dom_sid *sid, uint32_t sid_access)
304 struct dom_sid adm_sid;
305 struct security_ace ace[5] = {};
306 size_t i = 0;
308 struct security_acl *psa = NULL;
310 /* READ|EXECUTE access for Everyone */
312 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
313 map->generic_execute | map->generic_read, 0);
315 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
317 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
318 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
319 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
320 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
322 /* Add Full Access for Domain Admins */
323 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
324 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
325 map->generic_all, 0);
327 /* If we have a sid, give it some special access */
329 if (sid) {
330 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
331 sid_access, 0);
334 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
335 return NT_STATUS_NO_MEMORY;
337 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
338 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
339 psa, sd_size)) == NULL)
340 return NT_STATUS_NO_MEMORY;
342 return NT_STATUS_OK;
345 /***************************************************************************
346 ***************************************************************************/
348 static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
349 struct pipes_struct *p,
350 enum lsa_handle_type type,
351 uint32_t acc_granted,
352 struct dom_sid *sid,
353 const char *name,
354 const struct security_descriptor *sd,
355 struct policy_handle *handle)
357 struct lsa_info *info;
359 ZERO_STRUCTP(handle);
361 info = talloc_zero(mem_ctx, struct lsa_info);
362 if (!info) {
363 return NT_STATUS_NO_MEMORY;
366 info->type = type;
367 info->access = acc_granted;
369 if (sid) {
370 sid_copy(&info->sid, sid);
373 info->name = talloc_strdup(info, name);
375 if (sd != NULL) {
376 info->sd = security_descriptor_copy(info, sd);
377 if (info->sd == NULL) {
378 talloc_free(info);
379 return NT_STATUS_NO_MEMORY;
383 if (!create_policy_hnd(p, handle, type, info)) {
384 talloc_free(info);
385 ZERO_STRUCTP(handle);
386 return NT_STATUS_NO_MEMORY;
389 return NT_STATUS_OK;
392 /***************************************************************************
393 _lsa_OpenPolicy2
394 ***************************************************************************/
396 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
397 struct lsa_OpenPolicy2 *r)
399 struct dcesrv_call_state *dce_call = p->dce_call;
400 struct auth_session_info *session_info =
401 dcesrv_call_session_info(dce_call);
402 struct security_descriptor *psd = NULL;
403 size_t sd_size;
404 uint32_t des_access = r->in.access_mask;
405 uint32_t acc_granted;
406 NTSTATUS status;
408 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
409 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
410 return NT_STATUS_ACCESS_DENIED;
413 /* Work out max allowed. */
414 map_max_allowed_access(session_info->security_token,
415 session_info->unix_token,
416 &des_access);
418 /* map the generic bits to the lsa policy ones */
419 se_map_generic(&des_access, &lsa_policy_mapping);
421 /* get the generic lsa policy SD until we store it */
422 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
423 NULL, 0);
424 if (!NT_STATUS_IS_OK(status)) {
425 return status;
428 status = access_check_object(psd, session_info->security_token,
429 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
430 &acc_granted, "_lsa_OpenPolicy2" );
431 if (!NT_STATUS_IS_OK(status)) {
432 return status;
435 status = create_lsa_policy_handle(p->mem_ctx, p,
436 LSA_HANDLE_POLICY_TYPE,
437 acc_granted,
438 get_global_sam_sid(),
439 NULL,
440 psd,
441 r->out.handle);
442 if (!NT_STATUS_IS_OK(status)) {
443 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
446 return NT_STATUS_OK;
449 /***************************************************************************
450 _lsa_OpenPolicy
451 ***************************************************************************/
453 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
454 struct lsa_OpenPolicy *r)
456 struct lsa_OpenPolicy2 o;
458 /* _lsa_OpenPolicy2 will check if this is a NCACN_NP connection */
460 o.in.system_name = NULL; /* should be ignored */
461 o.in.attr = r->in.attr;
462 o.in.access_mask = r->in.access_mask;
464 o.out.handle = r->out.handle;
466 return _lsa_OpenPolicy2(p, &o);
469 /***************************************************************************
470 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
471 ufff, done :) mimir
472 ***************************************************************************/
474 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
475 struct lsa_EnumTrustDom *r)
477 struct lsa_info *info;
478 uint32_t i, count;
479 struct trustdom_info **domains;
480 struct lsa_DomainInfo *entries;
481 NTSTATUS nt_status;
483 info = find_policy_by_hnd(p,
484 r->in.handle,
485 LSA_HANDLE_POLICY_TYPE,
486 struct lsa_info,
487 &nt_status);
488 if (!NT_STATUS_IS_OK(nt_status)) {
489 return NT_STATUS_INVALID_HANDLE;
492 /* check if the user has enough rights */
493 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
494 return NT_STATUS_ACCESS_DENIED;
496 become_root();
497 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
498 unbecome_root();
500 if (!NT_STATUS_IS_OK(nt_status)) {
501 return nt_status;
504 entries = talloc_zero_array(p->mem_ctx, struct lsa_DomainInfo, count);
505 if (!entries) {
506 return NT_STATUS_NO_MEMORY;
509 for (i=0; i<count; i++) {
510 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
511 entries[i].sid = &domains[i]->sid;
514 if (*r->in.resume_handle >= count) {
515 *r->out.resume_handle = -1;
516 TALLOC_FREE(entries);
517 return NT_STATUS_NO_MORE_ENTRIES;
520 /* return the rest, limit by max_size. Note that we
521 use the w2k3 element size value of 60 */
522 r->out.domains->count = count - *r->in.resume_handle;
523 r->out.domains->count = MIN(r->out.domains->count,
524 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
526 r->out.domains->domains = entries + *r->in.resume_handle;
528 if (r->out.domains->count < count - *r->in.resume_handle) {
529 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
530 return STATUS_MORE_ENTRIES;
533 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
534 * always be larger than the previous input resume handle, in
535 * particular when hitting the last query it is vital to set the
536 * resume handle correctly to avoid infinite client loops, as
537 * seen e.g. with Windows XP SP3 when resume handle is 0 and
538 * status is NT_STATUS_OK - gd */
540 *r->out.resume_handle = (uint32_t)-1;
542 return NT_STATUS_OK;
545 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
546 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
547 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
549 /***************************************************************************
550 _lsa_QueryInfoPolicy
551 ***************************************************************************/
553 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
554 struct lsa_QueryInfoPolicy *r)
556 NTSTATUS status = NT_STATUS_OK;
557 struct lsa_info *handle;
558 struct dom_sid domain_sid;
559 const char *name;
560 struct dom_sid *sid = NULL;
561 union lsa_PolicyInformation *info = NULL;
562 uint32_t acc_required = 0;
564 handle = find_policy_by_hnd(p,
565 r->in.handle,
566 LSA_HANDLE_POLICY_TYPE,
567 struct lsa_info,
568 &status);
569 if (!NT_STATUS_IS_OK(status)) {
570 return NT_STATUS_INVALID_HANDLE;
573 switch (r->in.level) {
574 case LSA_POLICY_INFO_AUDIT_LOG:
575 case LSA_POLICY_INFO_AUDIT_EVENTS:
576 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
577 break;
578 case LSA_POLICY_INFO_DOMAIN:
579 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
580 break;
581 case LSA_POLICY_INFO_PD:
582 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
583 break;
584 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
585 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
586 break;
587 case LSA_POLICY_INFO_ROLE:
588 case LSA_POLICY_INFO_REPLICA:
589 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
590 break;
591 case LSA_POLICY_INFO_QUOTA:
592 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
593 break;
594 case LSA_POLICY_INFO_MOD:
595 case LSA_POLICY_INFO_AUDIT_FULL_SET:
596 /* according to MS-LSAD 3.1.4.4.3 */
597 return NT_STATUS_INVALID_PARAMETER;
598 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
599 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
600 break;
601 case LSA_POLICY_INFO_DNS:
602 case LSA_POLICY_INFO_DNS_INT:
603 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
604 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
605 break;
606 default:
607 break;
610 if (!(handle->access & acc_required)) {
611 /* return NT_STATUS_ACCESS_DENIED; */
614 info = talloc_zero(p->mem_ctx, union lsa_PolicyInformation);
615 if (!info) {
616 return NT_STATUS_NO_MEMORY;
619 switch (r->in.level) {
620 /* according to MS-LSAD 3.1.4.4.3 */
621 case LSA_POLICY_INFO_MOD:
622 case LSA_POLICY_INFO_AUDIT_FULL_SET:
623 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
624 return NT_STATUS_INVALID_PARAMETER;
625 case LSA_POLICY_INFO_AUDIT_LOG:
626 info->audit_log.percent_full = 0;
627 info->audit_log.maximum_log_size = 0;
628 info->audit_log.retention_time = 0;
629 info->audit_log.shutdown_in_progress = 0;
630 info->audit_log.time_to_shutdown = 0;
631 info->audit_log.next_audit_record = 0;
632 status = NT_STATUS_OK;
633 break;
634 case LSA_POLICY_INFO_PD:
635 info->pd.name.string = NULL;
636 status = NT_STATUS_OK;
637 break;
638 case LSA_POLICY_INFO_REPLICA:
639 info->replica.source.string = NULL;
640 info->replica.account.string = NULL;
641 status = NT_STATUS_OK;
642 break;
643 case LSA_POLICY_INFO_QUOTA:
644 info->quota.paged_pool = 0;
645 info->quota.non_paged_pool = 0;
646 info->quota.min_wss = 0;
647 info->quota.max_wss = 0;
648 info->quota.pagefile = 0;
649 info->quota.unknown = 0;
650 status = NT_STATUS_OK;
651 break;
652 case LSA_POLICY_INFO_AUDIT_EVENTS:
655 uint32_t policy_def = LSA_AUDIT_POLICY_ALL;
657 /* check if the user has enough rights */
658 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
659 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
660 return NT_STATUS_ACCESS_DENIED;
663 /* fake info: We audit everything. ;) */
665 info->audit_events.auditing_mode = true;
666 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
667 info->audit_events.settings = talloc_zero_array(p->mem_ctx,
668 enum lsa_PolicyAuditPolicy,
669 info->audit_events.count);
670 if (!info->audit_events.settings) {
671 return NT_STATUS_NO_MEMORY;
674 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
675 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
676 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
677 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
678 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
679 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
680 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
682 break;
684 case LSA_POLICY_INFO_DOMAIN:
685 /* check if the user has enough rights */
686 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
687 return NT_STATUS_ACCESS_DENIED;
689 /* Request PolicyPrimaryDomainInformation. */
690 switch (lp_server_role()) {
691 case ROLE_DOMAIN_PDC:
692 case ROLE_DOMAIN_BDC:
693 case ROLE_IPA_DC:
694 name = get_global_sam_name();
695 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
696 if (!sid) {
697 return NT_STATUS_NO_MEMORY;
699 break;
700 case ROLE_DOMAIN_MEMBER:
701 name = lp_workgroup();
702 /* We need to return the Domain SID here. */
703 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
704 sid = dom_sid_dup(p->mem_ctx, &domain_sid);
705 if (!sid) {
706 return NT_STATUS_NO_MEMORY;
708 } else {
709 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
711 break;
712 case ROLE_STANDALONE:
713 name = lp_workgroup();
714 sid = NULL;
715 break;
716 default:
717 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
719 init_dom_query_3(&info->domain, name, sid);
720 break;
721 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
722 /* check if the user has enough rights */
723 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
724 return NT_STATUS_ACCESS_DENIED;
726 /* Request PolicyAccountDomainInformation. */
727 name = get_global_sam_name();
728 sid = get_global_sam_sid();
730 init_dom_query_5(&info->account_domain, name, sid);
731 break;
732 case LSA_POLICY_INFO_ROLE:
733 /* check if the user has enough rights */
734 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
735 return NT_STATUS_ACCESS_DENIED;
737 switch (lp_server_role()) {
738 case ROLE_DOMAIN_BDC:
740 * only a BDC is a backup controller
741 * of the domain, it controls.
743 info->role.role = LSA_ROLE_BACKUP;
744 break;
745 default:
747 * any other role is a primary
748 * of the domain, it controls.
750 info->role.role = LSA_ROLE_PRIMARY;
751 break;
753 break;
754 case LSA_POLICY_INFO_DNS:
755 case LSA_POLICY_INFO_DNS_INT: {
756 struct pdb_domain_info *dominfo;
758 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
759 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
760 "without ADS passdb backend\n"));
761 status = NT_STATUS_INVALID_INFO_CLASS;
762 break;
765 dominfo = pdb_get_domain_info(info);
766 if (dominfo == NULL) {
767 status = NT_STATUS_NO_MEMORY;
768 break;
771 init_lsa_StringLarge(&info->dns.name,
772 dominfo->name);
773 init_lsa_StringLarge(&info->dns.dns_domain,
774 dominfo->dns_domain);
775 init_lsa_StringLarge(&info->dns.dns_forest,
776 dominfo->dns_forest);
777 info->dns.domain_guid = dominfo->guid;
778 info->dns.sid = &dominfo->sid;
779 break;
781 default:
782 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
783 r->in.level));
784 status = NT_STATUS_INVALID_INFO_CLASS;
785 break;
788 *r->out.info = info;
790 return status;
793 /***************************************************************************
794 _lsa_QueryInfoPolicy2
795 ***************************************************************************/
797 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
798 struct lsa_QueryInfoPolicy2 *r2)
800 struct lsa_QueryInfoPolicy r;
802 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
803 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
804 return NT_STATUS_NOT_IMPLEMENTED;
807 ZERO_STRUCT(r);
808 r.in.handle = r2->in.handle;
809 r.in.level = r2->in.level;
810 r.out.info = r2->out.info;
812 return _lsa_QueryInfoPolicy(p, &r);
815 /***************************************************************************
816 _lsa_lookup_sids_internal
817 ***************************************************************************/
819 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
820 TALLOC_CTX *mem_ctx,
821 uint16_t level, /* input */
822 int num_sids, /* input */
823 struct lsa_SidPtr *sid, /* input */
824 struct lsa_RefDomainList **pp_ref, /* input/output */
825 struct lsa_TranslatedName2 **pp_names,/* input/output */
826 uint32_t *pp_mapped_count) /* input/output */
828 NTSTATUS status;
829 int i;
830 const struct dom_sid **sids = NULL;
831 struct lsa_RefDomainList *ref = NULL;
832 uint32_t mapped_count = 0;
833 struct lsa_dom_info *dom_infos = NULL;
834 struct lsa_name_info *name_infos = NULL;
835 struct lsa_TranslatedName2 *names = NULL;
837 *pp_mapped_count = 0;
838 *pp_names = NULL;
839 *pp_ref = NULL;
841 if (num_sids == 0) {
842 return NT_STATUS_OK;
845 sids = talloc_array(p->mem_ctx, const struct dom_sid *, num_sids);
846 ref = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
848 if (sids == NULL || ref == NULL) {
849 return NT_STATUS_NO_MEMORY;
852 for (i=0; i<num_sids; i++) {
853 sids[i] = sid[i].sid;
856 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
857 &dom_infos, &name_infos);
859 if (!NT_STATUS_IS_OK(status)) {
860 return status;
863 names = talloc_array(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
864 if (names == NULL) {
865 return NT_STATUS_NO_MEMORY;
868 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
870 if (!dom_infos[i].valid) {
871 break;
874 if (init_lsa_ref_domain_list(mem_ctx, ref,
875 dom_infos[i].name,
876 &dom_infos[i].sid) != i) {
877 DEBUG(0, ("Domain %s mentioned twice??\n",
878 dom_infos[i].name));
879 return NT_STATUS_INTERNAL_ERROR;
883 for (i=0; i<num_sids; i++) {
884 struct lsa_name_info *name = &name_infos[i];
886 if (name->type == SID_NAME_UNKNOWN) {
887 name->dom_idx = -1;
888 /* Unknown sids should return the string
889 * representation of the SID. Windows 2003 behaves
890 * rather erratic here, in many cases it returns the
891 * RID as 8 bytes hex, in others it returns the full
892 * SID. We (Jerry/VL) could not figure out which the
893 * hard cases are, so leave it with the SID. */
894 name->name = dom_sid_string(p->mem_ctx, sids[i]);
895 if (name->name == NULL) {
896 return NT_STATUS_NO_MEMORY;
898 } else {
899 mapped_count += 1;
902 names[i].sid_type = name->type;
903 names[i].name.string = name->name;
904 names[i].sid_index = name->dom_idx;
905 names[i].unknown = 0;
908 status = NT_STATUS_NONE_MAPPED;
909 if (mapped_count > 0) {
910 status = (mapped_count < num_sids) ?
911 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
914 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
915 num_sids, mapped_count, nt_errstr(status)));
917 *pp_mapped_count = mapped_count;
918 *pp_names = names;
919 *pp_ref = ref;
921 return status;
924 /***************************************************************************
925 _lsa_LookupSids
926 ***************************************************************************/
928 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
929 struct lsa_LookupSids *r)
931 NTSTATUS status;
932 struct lsa_info *handle;
933 int num_sids = r->in.sids->num_sids;
934 uint32_t mapped_count = 0;
935 struct lsa_RefDomainList *domains = NULL;
936 struct lsa_TranslatedName *names_out = NULL;
937 struct lsa_TranslatedName2 *names = NULL;
938 int i;
940 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
941 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
942 return NT_STATUS_ACCESS_DENIED;
945 if ((r->in.level < 1) || (r->in.level > 6)) {
946 return NT_STATUS_INVALID_PARAMETER;
949 handle = find_policy_by_hnd(p,
950 r->in.handle,
951 LSA_HANDLE_POLICY_TYPE,
952 struct lsa_info,
953 &status);
954 if (!NT_STATUS_IS_OK(status)) {
955 return NT_STATUS_INVALID_HANDLE;
958 /* check if the user has enough rights */
959 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
960 return NT_STATUS_ACCESS_DENIED;
963 if (num_sids > MAX_LOOKUP_SIDS) {
964 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
965 MAX_LOOKUP_SIDS, num_sids));
966 return NT_STATUS_NONE_MAPPED;
969 status = _lsa_lookup_sids_internal(p,
970 p->mem_ctx,
971 r->in.level,
972 num_sids,
973 r->in.sids->sids,
974 &domains,
975 &names,
976 &mapped_count);
978 /* Only return here when there is a real error.
979 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
980 the requested sids could be resolved. Older versions of XP (pre SP3)
981 rely that we return with the string representations of those SIDs in
982 that case. If we don't, XP crashes - Guenther
985 if (NT_STATUS_IS_ERR(status) &&
986 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
987 return status;
990 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
991 names_out = talloc_array(p->mem_ctx, struct lsa_TranslatedName,
992 num_sids);
993 if (!names_out) {
994 return NT_STATUS_NO_MEMORY;
997 for (i=0; i<num_sids; i++) {
998 names_out[i].sid_type = names[i].sid_type;
999 names_out[i].name = names[i].name;
1000 names_out[i].sid_index = names[i].sid_index;
1003 *r->out.domains = domains;
1004 r->out.names->count = num_sids;
1005 r->out.names->names = names_out;
1006 *r->out.count = mapped_count;
1008 return status;
1011 static NTSTATUS _lsa_LookupSids_common(struct pipes_struct *p,
1012 struct lsa_LookupSids2 *r)
1014 struct dcesrv_call_state *dce_call = p->dce_call;
1015 NTSTATUS status;
1016 struct lsa_info *handle;
1017 int num_sids = r->in.sids->num_sids;
1018 uint32_t mapped_count = 0;
1019 struct lsa_RefDomainList *domains = NULL;
1020 struct lsa_TranslatedName2 *names = NULL;
1021 bool check_policy = true;
1023 switch (dce_call->pkt.u.request.opnum) {
1024 case NDR_LSA_LOOKUPSIDS3:
1025 check_policy = false;
1026 break;
1027 case NDR_LSA_LOOKUPSIDS2:
1028 default:
1029 check_policy = true;
1032 if ((r->in.level < 1) || (r->in.level > 6)) {
1033 return NT_STATUS_INVALID_PARAMETER;
1036 if (check_policy) {
1037 handle = find_policy_by_hnd(p,
1038 r->in.handle,
1039 LSA_HANDLE_POLICY_TYPE,
1040 struct lsa_info,
1041 &status);
1042 if (!NT_STATUS_IS_OK(status)) {
1043 return NT_STATUS_INVALID_HANDLE;
1046 /* check if the user has enough rights */
1047 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1048 return NT_STATUS_ACCESS_DENIED;
1052 if (num_sids > MAX_LOOKUP_SIDS) {
1053 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1054 MAX_LOOKUP_SIDS, num_sids));
1055 return NT_STATUS_NONE_MAPPED;
1058 status = _lsa_lookup_sids_internal(p,
1059 p->mem_ctx,
1060 r->in.level,
1061 num_sids,
1062 r->in.sids->sids,
1063 &domains,
1064 &names,
1065 &mapped_count);
1067 *r->out.domains = domains;
1068 r->out.names->count = num_sids;
1069 r->out.names->names = names;
1070 *r->out.count = mapped_count;
1072 return status;
1075 /***************************************************************************
1076 _lsa_LookupSids2
1077 ***************************************************************************/
1079 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1080 struct lsa_LookupSids2 *r)
1082 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1083 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1084 return NT_STATUS_ACCESS_DENIED;
1087 return _lsa_LookupSids_common(p, r);
1090 /***************************************************************************
1091 _lsa_LookupSids3
1092 ***************************************************************************/
1094 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1095 struct lsa_LookupSids3 *r)
1097 struct dcesrv_call_state *dce_call = p->dce_call;
1098 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1099 enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
1100 struct lsa_LookupSids2 q;
1102 if (p->transport != NCACN_IP_TCP) {
1103 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1104 return NT_STATUS_ACCESS_DENIED;
1107 dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
1109 /* No policy handle on this call. Restrict to crypto connections. */
1110 if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
1111 auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1112 DEBUG(1, ("_lsa_LookupSids3: The client %s is not using "
1113 "a secure connection over netlogon\n",
1114 get_remote_machine_name() ));
1115 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1116 return NT_STATUS_ACCESS_DENIED;
1119 q.in.handle = NULL;
1120 q.in.sids = r->in.sids;
1121 q.in.level = r->in.level;
1122 q.in.lookup_options = r->in.lookup_options;
1123 q.in.client_revision = r->in.client_revision;
1124 q.in.names = r->in.names;
1125 q.in.count = r->in.count;
1127 q.out.domains = r->out.domains;
1128 q.out.names = r->out.names;
1129 q.out.count = r->out.count;
1131 return _lsa_LookupSids_common(p, &q);
1134 /***************************************************************************
1135 ***************************************************************************/
1137 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1139 int flags;
1141 switch (level) {
1142 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1143 flags = LOOKUP_NAME_ALL;
1144 break;
1145 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1146 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1147 break;
1148 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1149 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1150 break;
1151 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1152 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1153 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1154 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1155 default:
1156 flags = LOOKUP_NAME_NONE;
1157 break;
1160 return flags;
1163 /***************************************************************************
1164 _lsa_LookupNames
1165 ***************************************************************************/
1167 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1168 struct lsa_LookupNames *r)
1170 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1171 struct lsa_info *handle;
1172 struct lsa_String *names = r->in.names;
1173 uint32_t num_entries = r->in.num_names;
1174 struct lsa_RefDomainList *domains = NULL;
1175 struct lsa_TranslatedSid *rids = NULL;
1176 uint32_t mapped_count = 0;
1177 int flags = 0;
1179 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1180 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1181 return NT_STATUS_ACCESS_DENIED;
1184 if (num_entries > MAX_LOOKUP_SIDS) {
1185 num_entries = MAX_LOOKUP_SIDS;
1186 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1187 num_entries));
1190 flags = lsa_lookup_level_to_flags(r->in.level);
1192 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1193 if (!domains) {
1194 return NT_STATUS_NO_MEMORY;
1197 if (num_entries) {
1198 rids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid,
1199 num_entries);
1200 if (!rids) {
1201 return NT_STATUS_NO_MEMORY;
1203 } else {
1204 rids = NULL;
1207 handle = find_policy_by_hnd(p,
1208 r->in.handle,
1209 LSA_HANDLE_POLICY_TYPE,
1210 struct lsa_info,
1211 &status);
1212 if (!NT_STATUS_IS_OK(status)) {
1213 status = NT_STATUS_INVALID_HANDLE;
1214 goto done;
1217 /* check if the user has enough rights */
1218 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1219 status = NT_STATUS_ACCESS_DENIED;
1220 goto done;
1223 /* set up the LSA Lookup RIDs response */
1224 become_root(); /* lookup_name can require root privs */
1225 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1226 names, flags, &mapped_count);
1227 unbecome_root();
1229 done:
1231 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1232 if (mapped_count == 0) {
1233 status = NT_STATUS_NONE_MAPPED;
1234 } else if (mapped_count != num_entries) {
1235 status = STATUS_SOME_UNMAPPED;
1239 *r->out.count = mapped_count;
1240 *r->out.domains = domains;
1241 r->out.sids->sids = rids;
1242 r->out.sids->count = num_entries;
1244 return status;
1247 /***************************************************************************
1248 _lsa_LookupNames2
1249 ***************************************************************************/
1251 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1252 struct lsa_LookupNames2 *r)
1254 NTSTATUS status;
1255 struct lsa_LookupNames q;
1256 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1257 struct lsa_TransSidArray *sid_array = NULL;
1258 uint32_t i;
1260 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1261 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1262 return NT_STATUS_ACCESS_DENIED;
1265 sid_array = talloc_zero(p->mem_ctx, struct lsa_TransSidArray);
1266 if (!sid_array) {
1267 return NT_STATUS_NO_MEMORY;
1270 q.in.handle = r->in.handle;
1271 q.in.num_names = r->in.num_names;
1272 q.in.names = r->in.names;
1273 q.in.level = r->in.level;
1274 q.in.sids = sid_array;
1275 q.in.count = r->in.count;
1276 /* we do not know what this is for */
1277 /* = r->in.unknown1; */
1278 /* = r->in.unknown2; */
1280 q.out.domains = r->out.domains;
1281 q.out.sids = sid_array;
1282 q.out.count = r->out.count;
1284 status = _lsa_LookupNames(p, &q);
1286 sid_array2->count = sid_array->count;
1287 sid_array2->sids = talloc_array(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1288 if (!sid_array2->sids) {
1289 return NT_STATUS_NO_MEMORY;
1292 for (i=0; i<sid_array->count; i++) {
1293 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1294 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1295 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1296 sid_array2->sids[i].unknown = 0;
1299 r->out.sids = sid_array2;
1301 return status;
1304 static NTSTATUS _lsa_LookupNames_common(struct pipes_struct *p,
1305 struct lsa_LookupNames3 *r)
1307 struct dcesrv_call_state *dce_call = p->dce_call;
1308 NTSTATUS status;
1309 struct lsa_info *handle;
1310 struct lsa_String *names = r->in.names;
1311 uint32_t num_entries = r->in.num_names;
1312 struct lsa_RefDomainList *domains = NULL;
1313 struct lsa_TranslatedSid3 *trans_sids = NULL;
1314 uint32_t mapped_count = 0;
1315 int flags = 0;
1316 bool check_policy = true;
1318 switch (dce_call->pkt.u.request.opnum) {
1319 case NDR_LSA_LOOKUPNAMES4:
1320 check_policy = false;
1321 break;
1322 case NDR_LSA_LOOKUPNAMES3:
1323 default:
1324 check_policy = true;
1327 if (num_entries > MAX_LOOKUP_SIDS) {
1328 num_entries = MAX_LOOKUP_SIDS;
1329 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1332 flags = lsa_lookup_level_to_flags(r->in.level);
1334 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1335 if (!domains) {
1336 return NT_STATUS_NO_MEMORY;
1339 if (num_entries) {
1340 trans_sids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid3,
1341 num_entries);
1342 if (!trans_sids) {
1343 return NT_STATUS_NO_MEMORY;
1345 } else {
1346 trans_sids = NULL;
1349 if (check_policy) {
1351 handle = find_policy_by_hnd(p,
1352 r->in.handle,
1353 LSA_HANDLE_POLICY_TYPE,
1354 struct lsa_info,
1355 &status);
1356 if (!NT_STATUS_IS_OK(status)) {
1357 status = NT_STATUS_INVALID_HANDLE;
1358 goto done;
1361 /* check if the user has enough rights */
1362 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1363 status = NT_STATUS_ACCESS_DENIED;
1364 goto done;
1368 /* set up the LSA Lookup SIDs response */
1369 become_root(); /* lookup_name can require root privs */
1370 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1371 names, flags, &mapped_count);
1372 unbecome_root();
1374 done:
1376 if (NT_STATUS_IS_OK(status)) {
1377 if (mapped_count == 0) {
1378 status = NT_STATUS_NONE_MAPPED;
1379 } else if (mapped_count != num_entries) {
1380 status = STATUS_SOME_UNMAPPED;
1384 *r->out.count = mapped_count;
1385 *r->out.domains = domains;
1386 r->out.sids->sids = trans_sids;
1387 r->out.sids->count = num_entries;
1389 return status;
1392 /***************************************************************************
1393 _lsa_LookupNames3
1394 ***************************************************************************/
1396 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1397 struct lsa_LookupNames3 *r)
1399 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1400 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1401 return NT_STATUS_ACCESS_DENIED;
1404 return _lsa_LookupNames_common(p, r);
1407 /***************************************************************************
1408 _lsa_LookupNames4
1409 ***************************************************************************/
1411 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1412 struct lsa_LookupNames4 *r)
1414 struct dcesrv_call_state *dce_call = p->dce_call;
1415 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1416 enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
1417 struct lsa_LookupNames3 q;
1419 if (p->transport != NCACN_IP_TCP) {
1420 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1421 return NT_STATUS_ACCESS_DENIED;
1424 dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
1426 /* No policy handle on this call. Restrict to crypto connections. */
1427 if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
1428 auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1429 DEBUG(1, ("_lsa_LookupNames4: The client %s is not using "
1430 "a secure connection over netlogon\n",
1431 get_remote_machine_name()));
1432 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1433 return NT_STATUS_ACCESS_DENIED;
1436 q.in.handle = NULL;
1437 q.in.num_names = r->in.num_names;
1438 q.in.names = r->in.names;
1439 q.in.level = r->in.level;
1440 q.in.lookup_options = r->in.lookup_options;
1441 q.in.client_revision = r->in.client_revision;
1442 q.in.sids = r->in.sids;
1443 q.in.count = r->in.count;
1445 q.out.domains = r->out.domains;
1446 q.out.sids = r->out.sids;
1447 q.out.count = r->out.count;
1449 return _lsa_LookupNames_common(p, &q);
1452 /***************************************************************************
1453 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1454 ***************************************************************************/
1456 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1458 NTSTATUS status;
1460 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1461 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1462 return NT_STATUS_ACCESS_DENIED;
1465 (void)find_policy_by_hnd(p,
1466 r->in.handle,
1467 DCESRV_HANDLE_ANY,
1468 struct lsa_info,
1469 &status);
1470 if (!NT_STATUS_IS_OK(status)) {
1471 return NT_STATUS_INVALID_HANDLE;
1474 close_policy_hnd(p, r->in.handle);
1475 ZERO_STRUCTP(r->out.handle);
1476 return NT_STATUS_OK;
1479 /***************************************************************************
1480 ***************************************************************************/
1482 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1483 const struct dom_sid *sid,
1484 struct trustdom_info **info)
1486 NTSTATUS status;
1487 uint32_t num_domains = 0;
1488 struct trustdom_info **domains = NULL;
1489 int i;
1491 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1492 if (!NT_STATUS_IS_OK(status)) {
1493 return status;
1496 for (i=0; i < num_domains; i++) {
1497 if (dom_sid_equal(&domains[i]->sid, sid)) {
1498 break;
1502 if (i == num_domains) {
1503 return NT_STATUS_INVALID_PARAMETER;
1506 *info = domains[i];
1508 return NT_STATUS_OK;
1511 /***************************************************************************
1512 ***************************************************************************/
1514 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1515 const char *netbios_domain_name,
1516 struct trustdom_info **info_p)
1518 NTSTATUS status;
1519 struct trustdom_info *info;
1520 struct pdb_trusted_domain *td;
1522 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1523 if (!NT_STATUS_IS_OK(status)) {
1524 return status;
1527 info = talloc(mem_ctx, struct trustdom_info);
1528 if (!info) {
1529 return NT_STATUS_NO_MEMORY;
1532 info->name = talloc_strdup(info, netbios_domain_name);
1533 NT_STATUS_HAVE_NO_MEMORY(info->name);
1535 sid_copy(&info->sid, &td->security_identifier);
1537 *info_p = info;
1539 return NT_STATUS_OK;
1542 /***************************************************************************
1543 _lsa_OpenSecret
1544 ***************************************************************************/
1546 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p,
1547 struct lsa_OpenSecret *r)
1549 struct dcesrv_call_state *dce_call = p->dce_call;
1550 struct auth_session_info *session_info =
1551 dcesrv_call_session_info(dce_call);
1552 struct security_descriptor *psd;
1553 NTSTATUS status;
1554 uint32_t acc_granted;
1556 (void)find_policy_by_hnd(p,
1557 r->in.handle,
1558 LSA_HANDLE_POLICY_TYPE,
1559 struct lsa_info,
1560 &status);
1561 if (!NT_STATUS_IS_OK(status)) {
1562 return NT_STATUS_INVALID_HANDLE;
1565 if (!r->in.name.string) {
1566 return NT_STATUS_INVALID_PARAMETER;
1569 /* Work out max allowed. */
1570 map_max_allowed_access(session_info->security_token,
1571 session_info->unix_token,
1572 &r->in.access_mask);
1574 /* map the generic bits to the lsa policy ones */
1575 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
1577 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
1578 NULL,
1579 NULL,
1580 NULL,
1581 NULL,
1582 &psd);
1583 if (!NT_STATUS_IS_OK(status)) {
1584 return status;
1587 status = access_check_object(psd, session_info->security_token,
1588 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1589 r->in.access_mask,
1590 &acc_granted, "_lsa_OpenSecret");
1591 if (!NT_STATUS_IS_OK(status)) {
1592 return status;
1595 status = create_lsa_policy_handle(p->mem_ctx, p,
1596 LSA_HANDLE_SECRET_TYPE,
1597 acc_granted,
1598 NULL,
1599 r->in.name.string,
1600 psd,
1601 r->out.sec_handle);
1602 if (!NT_STATUS_IS_OK(status)) {
1603 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1606 return NT_STATUS_OK;
1609 /***************************************************************************
1610 _lsa_OpenTrustedDomain_base
1611 ***************************************************************************/
1613 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1614 uint32_t access_mask,
1615 struct trustdom_info *info,
1616 struct policy_handle *handle)
1618 struct dcesrv_call_state *dce_call = p->dce_call;
1619 struct auth_session_info *session_info =
1620 dcesrv_call_session_info(dce_call);
1621 struct security_descriptor *psd = NULL;
1622 size_t sd_size;
1623 uint32_t acc_granted;
1624 NTSTATUS status;
1626 /* des_access is for the account here, not the policy
1627 * handle - so don't check against policy handle. */
1629 /* Work out max allowed. */
1630 map_max_allowed_access(session_info->security_token,
1631 session_info->unix_token,
1632 &access_mask);
1634 /* map the generic bits to the lsa account ones */
1635 se_map_generic(&access_mask, &lsa_trusted_domain_mapping);
1637 /* get the generic lsa account SD until we store it */
1638 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1639 &lsa_trusted_domain_mapping,
1640 NULL, 0);
1641 if (!NT_STATUS_IS_OK(status)) {
1642 return status;
1645 status = access_check_object(psd, session_info->security_token,
1646 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1647 access_mask, &acc_granted,
1648 "_lsa_OpenTrustedDomain");
1649 if (!NT_STATUS_IS_OK(status)) {
1650 return status;
1653 status = create_lsa_policy_handle(p->mem_ctx, p,
1654 LSA_HANDLE_TRUST_TYPE,
1655 acc_granted,
1656 &info->sid,
1657 info->name,
1658 psd,
1659 handle);
1660 if (!NT_STATUS_IS_OK(status)) {
1661 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1664 return NT_STATUS_OK;
1667 /***************************************************************************
1668 _lsa_OpenTrustedDomain
1669 ***************************************************************************/
1671 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1672 struct lsa_OpenTrustedDomain *r)
1674 struct trustdom_info *info = NULL;
1675 NTSTATUS status;
1677 (void)find_policy_by_hnd(p,
1678 r->in.handle,
1679 LSA_HANDLE_POLICY_TYPE,
1680 struct lsa_info,
1681 &status);
1682 if (!NT_STATUS_IS_OK(status)) {
1683 return NT_STATUS_INVALID_HANDLE;
1686 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1687 r->in.sid,
1688 &info);
1689 if (!NT_STATUS_IS_OK(status)) {
1690 return status;
1693 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1694 r->out.trustdom_handle);
1697 /***************************************************************************
1698 _lsa_OpenTrustedDomainByName
1699 ***************************************************************************/
1701 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1702 struct lsa_OpenTrustedDomainByName *r)
1704 struct trustdom_info *info = NULL;
1705 NTSTATUS status;
1707 (void)find_policy_by_hnd(p,
1708 r->in.handle,
1709 LSA_HANDLE_POLICY_TYPE,
1710 struct lsa_info,
1711 &status);
1712 if (!NT_STATUS_IS_OK(status)) {
1713 return NT_STATUS_INVALID_HANDLE;
1716 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1717 r->in.name.string,
1718 &info);
1719 if (!NT_STATUS_IS_OK(status)) {
1720 return status;
1723 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1724 r->out.trustdom_handle);
1727 static NTSTATUS get_trustdom_auth_blob_aes(
1728 struct dcesrv_call_state *dce_call,
1729 TALLOC_CTX *mem_ctx,
1730 struct lsa_TrustDomainInfoAuthInfoInternalAES *auth_info,
1731 struct trustDomainPasswords *auth_struct)
1733 DATA_BLOB session_key = data_blob_null;
1734 DATA_BLOB salt = data_blob(auth_info->salt, sizeof(auth_info->salt));
1735 DATA_BLOB auth_blob = data_blob(auth_info->cipher.data,
1736 auth_info->cipher.size);
1737 DATA_BLOB ciphertext = data_blob_null;
1738 enum ndr_err_code ndr_err;
1739 NTSTATUS status;
1742 * The data blob starts with 512 bytes of random data and has two 32bit
1743 * size parameters.
1745 if (auth_blob.length < 520) {
1746 return NT_STATUS_INVALID_PARAMETER;
1749 status = dcesrv_transport_session_key(dce_call, &session_key);
1750 if (!NT_STATUS_IS_OK(status)) {
1751 return status;
1754 status = samba_gnutls_aead_aes_256_cbc_hmac_sha512_decrypt(
1755 mem_ctx,
1756 &auth_blob,
1757 &session_key,
1758 &lsa_aes256_enc_key_salt,
1759 &lsa_aes256_mac_key_salt,
1760 &salt,
1761 auth_info->auth_data,
1762 &ciphertext);
1763 if (!NT_STATUS_IS_OK(status)) {
1764 return status;
1767 ndr_err = ndr_pull_struct_blob(
1768 &ciphertext,
1769 mem_ctx,
1770 auth_struct,
1771 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
1772 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1773 return NT_STATUS_INVALID_PARAMETER;
1776 return NT_STATUS_OK;
1779 static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
1780 TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
1781 struct trustDomainPasswords *auth_struct)
1783 struct dcesrv_call_state *dce_call = p->dce_call;
1784 struct auth_session_info *session_info =
1785 dcesrv_call_session_info(dce_call);
1786 enum ndr_err_code ndr_err;
1787 DATA_BLOB lsession_key;
1788 gnutls_cipher_hd_t cipher_hnd = NULL;
1789 gnutls_datum_t my_session_key;
1790 NTSTATUS status;
1791 int rc;
1792 bool encrypted;
1794 encrypted = dcerpc_is_transport_encrypted(session_info);
1795 if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
1796 !encrypted) {
1797 return NT_STATUS_ACCESS_DENIED;
1800 status = session_extract_session_key(
1801 session_info, &lsession_key, KEY_USE_16BYTES);
1802 if (!NT_STATUS_IS_OK(status)) {
1803 return NT_STATUS_INVALID_PARAMETER;
1806 my_session_key = (gnutls_datum_t) {
1807 .data = lsession_key.data,
1808 .size = lsession_key.length,
1811 GNUTLS_FIPS140_SET_LAX_MODE();
1812 rc = gnutls_cipher_init(&cipher_hnd,
1813 GNUTLS_CIPHER_ARCFOUR_128,
1814 &my_session_key,
1815 NULL);
1816 if (rc < 0) {
1817 GNUTLS_FIPS140_SET_STRICT_MODE();
1818 status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
1819 goto out;
1822 rc = gnutls_cipher_decrypt(cipher_hnd,
1823 auth_blob->data,
1824 auth_blob->length);
1825 gnutls_cipher_deinit(cipher_hnd);
1826 GNUTLS_FIPS140_SET_STRICT_MODE();
1827 if (rc < 0) {
1828 status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
1829 goto out;
1832 ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
1833 auth_struct,
1834 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
1835 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1836 status = NT_STATUS_INVALID_PARAMETER;
1837 goto out;
1840 status = NT_STATUS_OK;
1841 out:
1842 return status;
1845 static NTSTATUS get_trustauth_inout_blob(TALLOC_CTX *mem_ctx,
1846 struct trustAuthInOutBlob *iopw,
1847 DATA_BLOB *trustauth_blob)
1849 enum ndr_err_code ndr_err;
1851 if (iopw->current.count != iopw->count) {
1852 return NT_STATUS_INVALID_PARAMETER;
1855 if (iopw->previous.count > iopw->current.count) {
1856 return NT_STATUS_INVALID_PARAMETER;
1859 if (iopw->previous.count == 0) {
1861 * If the previous credentials are not present
1862 * we need to make a copy.
1864 iopw->previous = iopw->current;
1867 if (iopw->previous.count < iopw->current.count) {
1868 struct AuthenticationInformationArray *c = &iopw->current;
1869 struct AuthenticationInformationArray *p = &iopw->previous;
1872 * The previous array needs to have the same size
1873 * as the current one.
1875 * We may have to fill with TRUST_AUTH_TYPE_NONE
1876 * elements.
1878 p->array = talloc_realloc(mem_ctx, p->array,
1879 struct AuthenticationInformation,
1880 c->count);
1881 if (p->array == NULL) {
1882 return NT_STATUS_NO_MEMORY;
1885 while (p->count < c->count) {
1886 struct AuthenticationInformation *a =
1887 &p->array[p->count++];
1889 *a = (struct AuthenticationInformation) {
1890 .LastUpdateTime = p->array[0].LastUpdateTime,
1891 .AuthType = TRUST_AUTH_TYPE_NONE,
1896 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
1897 iopw,
1898 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
1899 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1900 return NT_STATUS_INVALID_PARAMETER;
1903 return NT_STATUS_OK;
1906 static NTSTATUS lsa_CreateTrustedDomain_precheck(
1907 TALLOC_CTX *mem_ctx,
1908 struct lsa_info *policy,
1909 struct auth_session_info *session_info,
1910 struct lsa_TrustDomainInfoInfoEx *info)
1912 const char *netbios_name = NULL;
1913 const char *dns_name = NULL;
1914 bool ok;
1916 netbios_name = info->netbios_name.string;
1917 if (netbios_name == NULL) {
1918 return NT_STATUS_INVALID_PARAMETER;
1921 dns_name = info->domain_name.string;
1922 if (dns_name == NULL) {
1923 return NT_STATUS_INVALID_PARAMETER;
1926 if (info->sid == NULL) {
1927 return NT_STATUS_INVALID_SID;
1930 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1931 return NT_STATUS_ACCESS_DENIED;
1935 * We expect S-1-5-21-A-B-C, but we don't
1936 * allow S-1-5-21-0-0-0 as this is used
1937 * for claims and compound identities.
1939 ok = dom_sid_is_valid_account_domain(info->sid);
1940 if (!ok) {
1941 return NT_STATUS_INVALID_PARAMETER;
1944 if (strcasecmp(netbios_name, "BUILTIN") == 0 ||
1945 strcasecmp(dns_name, "BUILTIN") == 0)
1947 return NT_STATUS_INVALID_PARAMETER;
1950 if (policy->name != NULL &&
1951 (strcasecmp(netbios_name, policy->name) == 0 ||
1952 strcasecmp(dns_name, policy->name) == 0))
1954 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
1957 if (session_info->unix_token->uid != sec_initial_uid() &&
1958 !nt_token_check_domain_rid(session_info->security_token,
1959 DOMAIN_RID_ADMINS))
1961 return NT_STATUS_ACCESS_DENIED;
1964 return NT_STATUS_OK;
1967 static NTSTATUS lsa_CreateTrustedDomain_common(
1968 struct pipes_struct *p,
1969 TALLOC_CTX *mem_ctx,
1970 struct auth_session_info *session_info,
1971 struct lsa_info *policy,
1972 uint32_t access_mask,
1973 struct lsa_TrustDomainInfoInfoEx *info,
1974 struct trustDomainPasswords *auth_struct,
1975 struct policy_handle **ptrustdom_handle)
1977 struct security_descriptor *psd = NULL;
1978 size_t sd_size = 0;
1979 uint32_t acc_granted = 0;
1980 struct pdb_trusted_domain td = {
1981 .trust_type = 0,
1983 NTSTATUS status;
1985 /* Work out max allowed. */
1986 map_max_allowed_access(session_info->security_token,
1987 session_info->unix_token,
1988 &access_mask);
1990 /* map the generic bits to the lsa policy ones */
1991 se_map_generic(&access_mask, &lsa_account_mapping);
1993 status = make_lsa_object_sd(
1994 mem_ctx, &psd, &sd_size, &lsa_trusted_domain_mapping, NULL, 0);
1995 if (!NT_STATUS_IS_OK(status)) {
1996 return status;
1999 status = access_check_object(psd,
2000 session_info->security_token,
2001 SEC_PRIV_INVALID,
2002 SEC_PRIV_INVALID,
2004 access_mask,
2005 &acc_granted,
2006 "lsa_CreateTrustedDomain_common");
2007 if (!NT_STATUS_IS_OK(status)) {
2008 return status;
2011 td.domain_name = talloc_strdup(mem_ctx, info->domain_name.string);
2012 if (td.domain_name == NULL) {
2013 return NT_STATUS_NO_MEMORY;
2015 td.netbios_name = talloc_strdup(mem_ctx, info->netbios_name.string);
2016 if (td.netbios_name == NULL) {
2017 return NT_STATUS_NO_MEMORY;
2019 sid_copy(&td.security_identifier, info->sid);
2020 td.trust_direction = info->trust_direction;
2021 td.trust_type = info->trust_type;
2022 td.trust_attributes = info->trust_attributes;
2024 status = get_trustauth_inout_blob(mem_ctx,
2025 &auth_struct->incoming,
2026 &td.trust_auth_incoming);
2027 if (!NT_STATUS_IS_OK(status)) {
2028 return NT_STATUS_UNSUCCESSFUL;
2031 status = get_trustauth_inout_blob(mem_ctx,
2032 &auth_struct->outgoing,
2033 &td.trust_auth_outgoing);
2034 if (!NT_STATUS_IS_OK(status)) {
2035 return NT_STATUS_UNSUCCESSFUL;
2038 status = pdb_set_trusted_domain(info->domain_name.string, &td);
2039 if (!NT_STATUS_IS_OK(status)) {
2040 DBG_ERR("pdb_set_trusted_domain failed: %s\n",
2041 nt_errstr(status));
2042 return status;
2045 status = create_lsa_policy_handle(mem_ctx, p,
2046 LSA_HANDLE_TRUST_TYPE,
2047 acc_granted,
2048 info->sid,
2049 info->netbios_name.string,
2050 psd,
2051 *ptrustdom_handle);
2052 if (!NT_STATUS_IS_OK(status)) {
2053 pdb_del_trusted_domain(info->netbios_name.string);
2054 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2057 return NT_STATUS_OK;
2060 /***************************************************************************
2061 _lsa_CreateTrustedDomainEx2
2062 ***************************************************************************/
2064 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
2065 struct lsa_CreateTrustedDomainEx2 *r)
2067 struct dcesrv_call_state *dce_call = p->dce_call;
2068 struct auth_session_info *session_info =
2069 dcesrv_call_session_info(dce_call);
2070 struct lsa_info *policy;
2071 NTSTATUS status;
2072 struct trustDomainPasswords auth_struct = {
2073 .incoming_size = 0,
2075 DATA_BLOB auth_blob = data_blob_null;
2077 if (!IS_DC) {
2078 return NT_STATUS_NOT_SUPPORTED;
2081 policy = find_policy_by_hnd(p,
2082 r->in.policy_handle,
2083 LSA_HANDLE_POLICY_TYPE,
2084 struct lsa_info,
2085 &status);
2086 if (!NT_STATUS_IS_OK(status)) {
2087 return NT_STATUS_INVALID_HANDLE;
2090 status = lsa_CreateTrustedDomain_precheck(p->mem_ctx,
2091 policy,
2092 session_info,
2093 r->in.info);
2094 if (!NT_STATUS_IS_OK(status)) {
2095 return status;
2099 if (r->in.auth_info_internal->auth_blob.size == 0) {
2100 return NT_STATUS_INVALID_PARAMETER;
2103 auth_blob = data_blob_const(r->in.auth_info_internal->auth_blob.data,
2104 r->in.auth_info_internal->auth_blob.size);
2106 status = get_trustdom_auth_blob(p,
2107 p->mem_ctx,
2108 &auth_blob,
2109 &auth_struct);
2110 if (!NT_STATUS_IS_OK(status)) {
2111 return NT_STATUS_UNSUCCESSFUL;
2114 status = lsa_CreateTrustedDomain_common(p,
2115 p->mem_ctx,
2116 session_info,
2117 policy,
2118 r->in.access_mask,
2119 r->in.info,
2120 &auth_struct,
2121 &r->out.trustdom_handle);
2122 if (!NT_STATUS_IS_OK(status)) {
2123 return status;
2126 return NT_STATUS_OK;
2129 /***************************************************************************
2130 _lsa_CreateTrustedDomainEx
2131 ***************************************************************************/
2133 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
2134 struct lsa_CreateTrustedDomainEx *r)
2136 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2137 return NT_STATUS_NOT_IMPLEMENTED;
2140 /***************************************************************************
2141 _lsa_CreateTrustedDomain
2142 ***************************************************************************/
2144 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
2145 struct lsa_CreateTrustedDomain *r)
2147 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2148 return NT_STATUS_NOT_IMPLEMENTED;
2151 /***************************************************************************
2152 _lsa_DeleteTrustedDomain
2153 ***************************************************************************/
2155 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
2156 struct lsa_DeleteTrustedDomain *r)
2158 NTSTATUS status;
2159 struct lsa_info *handle;
2160 struct pdb_trusted_domain *td;
2162 /* find the connection policy handle. */
2163 handle = find_policy_by_hnd(p,
2164 r->in.handle,
2165 LSA_HANDLE_POLICY_TYPE,
2166 struct lsa_info,
2167 &status);
2168 if (!NT_STATUS_IS_OK(status)) {
2169 return NT_STATUS_INVALID_HANDLE;
2172 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
2173 return NT_STATUS_ACCESS_DENIED;
2176 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
2177 if (!NT_STATUS_IS_OK(status)) {
2178 return status;
2181 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
2182 struct dom_sid_buf buf;
2183 DEBUG(10, ("Missing netbios name for trusted domain %s.\n",
2184 dom_sid_str_buf(r->in.dom_sid, &buf)));
2185 return NT_STATUS_UNSUCCESSFUL;
2188 status = pdb_del_trusted_domain(td->netbios_name);
2189 if (!NT_STATUS_IS_OK(status)) {
2190 return status;
2193 return NT_STATUS_OK;
2196 /***************************************************************************
2197 _lsa_CloseTrustedDomainEx
2198 ***************************************************************************/
2200 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
2201 struct lsa_CloseTrustedDomainEx *r)
2203 return NT_STATUS_NOT_IMPLEMENTED;
2206 /***************************************************************************
2207 _lsa_QueryTrustedDomainInfo
2208 ***************************************************************************/
2210 static NTSTATUS pdb_trusted_domain_2_info_ex(TALLOC_CTX *mem_ctx,
2211 struct pdb_trusted_domain *td,
2212 struct lsa_TrustDomainInfoInfoEx *info_ex)
2214 if (td->domain_name == NULL ||
2215 td->netbios_name == NULL ||
2216 is_null_sid(&td->security_identifier)) {
2217 return NT_STATUS_INVALID_PARAMETER;
2220 info_ex->domain_name.string = talloc_strdup(mem_ctx, td->domain_name);
2221 info_ex->netbios_name.string = talloc_strdup(mem_ctx, td->netbios_name);
2222 info_ex->sid = dom_sid_dup(mem_ctx, &td->security_identifier);
2223 if (info_ex->domain_name.string == NULL ||
2224 info_ex->netbios_name.string == NULL ||
2225 info_ex->sid == NULL) {
2226 return NT_STATUS_NO_MEMORY;
2229 info_ex->trust_direction = td->trust_direction;
2230 info_ex->trust_type = td->trust_type;
2231 info_ex->trust_attributes = td->trust_attributes;
2233 return NT_STATUS_OK;
2236 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
2237 struct lsa_QueryTrustedDomainInfo *r)
2239 NTSTATUS status;
2240 struct lsa_info *handle;
2241 union lsa_TrustedDomainInfo *info;
2242 struct pdb_trusted_domain *td;
2243 uint32_t acc_required;
2245 /* find the connection policy handle. */
2246 handle = find_policy_by_hnd(p,
2247 r->in.trustdom_handle,
2248 LSA_HANDLE_TRUST_TYPE,
2249 struct lsa_info,
2250 &status);
2251 if (!NT_STATUS_IS_OK(status)) {
2252 return NT_STATUS_INVALID_HANDLE;
2255 switch (r->in.level) {
2256 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2257 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2258 break;
2259 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2260 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
2261 break;
2262 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2263 acc_required = LSA_TRUSTED_QUERY_POSIX;
2264 break;
2265 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2266 acc_required = LSA_TRUSTED_QUERY_AUTH;
2267 break;
2268 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2269 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2270 break;
2271 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2272 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2273 break;
2274 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2275 acc_required = LSA_TRUSTED_QUERY_AUTH;
2276 break;
2277 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2278 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2279 LSA_TRUSTED_QUERY_POSIX |
2280 LSA_TRUSTED_QUERY_AUTH;
2281 break;
2282 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2283 acc_required = LSA_TRUSTED_QUERY_AUTH;
2284 break;
2285 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2286 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2287 LSA_TRUSTED_QUERY_POSIX |
2288 LSA_TRUSTED_QUERY_AUTH;
2289 break;
2290 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2291 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2292 break;
2293 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2294 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2295 LSA_TRUSTED_QUERY_POSIX |
2296 LSA_TRUSTED_QUERY_AUTH;
2297 break;
2298 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2299 acc_required = LSA_TRUSTED_QUERY_POSIX;
2300 break;
2301 default:
2302 return NT_STATUS_INVALID_PARAMETER;
2305 if (!(handle->access & acc_required)) {
2306 return NT_STATUS_ACCESS_DENIED;
2309 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2310 if (!NT_STATUS_IS_OK(status)) {
2311 return status;
2314 info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
2315 if (!info) {
2316 return NT_STATUS_NO_MEMORY;
2319 switch (r->in.level) {
2320 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2321 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2322 break;
2323 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2324 return NT_STATUS_INVALID_PARAMETER;
2325 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2326 info->posix_offset.posix_offset = *td->trust_posix_offset;
2327 break;
2328 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2329 return NT_STATUS_INVALID_INFO_CLASS;
2330 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2331 return NT_STATUS_INVALID_PARAMETER;
2332 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2333 status = pdb_trusted_domain_2_info_ex(info, td, &info->info_ex);
2334 if (!NT_STATUS_IS_OK(status)) {
2335 return status;
2337 break;
2338 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2339 return NT_STATUS_INVALID_INFO_CLASS;
2340 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2341 status = pdb_trusted_domain_2_info_ex(info, td,
2342 &info->full_info.info_ex);
2343 if (!NT_STATUS_IS_OK(status)) {
2344 return status;
2346 info->full_info.posix_offset.posix_offset = *td->trust_posix_offset;
2347 status = auth_blob_2_auth_info(p->mem_ctx,
2348 td->trust_auth_incoming,
2349 td->trust_auth_outgoing,
2350 &info->full_info.auth_info);
2351 if (!NT_STATUS_IS_OK(status)) {
2352 return status;
2354 break;
2355 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2356 return NT_STATUS_INVALID_INFO_CLASS;
2357 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2358 return NT_STATUS_INVALID_INFO_CLASS;
2359 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2360 return NT_STATUS_INVALID_PARAMETER;
2361 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2362 info->full_info2_internal.posix_offset.posix_offset = *td->trust_posix_offset;
2363 status = auth_blob_2_auth_info(p->mem_ctx,
2364 td->trust_auth_incoming,
2365 td->trust_auth_outgoing,
2366 &info->full_info2_internal.auth_info);
2367 if (!NT_STATUS_IS_OK(status)) {
2368 return status;
2370 break;
2371 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2372 info->enc_types.enc_types = *td->supported_enc_type;
2373 break;
2374 default:
2375 return NT_STATUS_INVALID_PARAMETER;
2378 *r->out.info = info;
2380 return NT_STATUS_OK;
2383 /***************************************************************************
2384 _lsa_QueryTrustedDomainInfoBySid
2385 ***************************************************************************/
2387 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2388 struct lsa_QueryTrustedDomainInfoBySid *r)
2390 NTSTATUS status;
2391 struct policy_handle trustdom_handle;
2392 struct lsa_OpenTrustedDomain o;
2393 struct lsa_QueryTrustedDomainInfo q;
2394 struct lsa_Close c;
2396 o.in.handle = r->in.handle;
2397 o.in.sid = r->in.dom_sid;
2398 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2399 o.out.trustdom_handle = &trustdom_handle;
2401 status = _lsa_OpenTrustedDomain(p, &o);
2402 if (!NT_STATUS_IS_OK(status)) {
2403 return status;
2406 q.in.trustdom_handle = &trustdom_handle;
2407 q.in.level = r->in.level;
2408 q.out.info = r->out.info;
2410 status = _lsa_QueryTrustedDomainInfo(p, &q);
2411 if (!NT_STATUS_IS_OK(status)) {
2412 return status;
2415 c.in.handle = &trustdom_handle;
2416 c.out.handle = &trustdom_handle;
2418 return _lsa_Close(p, &c);
2421 /***************************************************************************
2422 _lsa_QueryTrustedDomainInfoByName
2423 ***************************************************************************/
2425 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2426 struct lsa_QueryTrustedDomainInfoByName *r)
2428 NTSTATUS status;
2429 struct policy_handle trustdom_handle;
2430 struct lsa_OpenTrustedDomainByName o;
2431 struct lsa_QueryTrustedDomainInfo q;
2432 struct lsa_Close c;
2434 o.in.handle = r->in.handle;
2435 o.in.name.string = r->in.trusted_domain->string;
2436 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2437 o.out.trustdom_handle = &trustdom_handle;
2439 status = _lsa_OpenTrustedDomainByName(p, &o);
2440 if (!NT_STATUS_IS_OK(status)) {
2441 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2442 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2444 return status;
2447 q.in.trustdom_handle = &trustdom_handle;
2448 q.in.level = r->in.level;
2449 q.out.info = r->out.info;
2451 status = _lsa_QueryTrustedDomainInfo(p, &q);
2452 if (!NT_STATUS_IS_OK(status)) {
2453 return status;
2456 c.in.handle = &trustdom_handle;
2457 c.out.handle = &trustdom_handle;
2459 return _lsa_Close(p, &c);
2462 /***************************************************************************
2463 _lsa_CreateSecret
2464 ***************************************************************************/
2466 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p,
2467 struct lsa_CreateSecret *r)
2469 struct dcesrv_call_state *dce_call = p->dce_call;
2470 struct auth_session_info *session_info =
2471 dcesrv_call_session_info(dce_call);
2472 NTSTATUS status;
2473 struct lsa_info *handle;
2474 uint32_t acc_granted;
2475 struct security_descriptor *psd;
2476 size_t sd_size;
2478 /* find the connection policy handle. */
2479 handle = find_policy_by_hnd(p,
2480 r->in.handle,
2481 LSA_HANDLE_POLICY_TYPE,
2482 struct lsa_info,
2483 &status);
2484 if (!NT_STATUS_IS_OK(status)) {
2485 return NT_STATUS_INVALID_HANDLE;
2488 /* check if the user has enough rights */
2490 if (!(handle->access & LSA_POLICY_CREATE_SECRET)) {
2491 return NT_STATUS_ACCESS_DENIED;
2494 /* Work out max allowed. */
2495 map_max_allowed_access(session_info->security_token,
2496 session_info->unix_token,
2497 &r->in.access_mask);
2499 /* map the generic bits to the lsa policy ones */
2500 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
2502 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2503 &lsa_secret_mapping,
2504 NULL, 0);
2505 if (!NT_STATUS_IS_OK(status)) {
2506 return status;
2509 status = access_check_object(psd, session_info->security_token,
2510 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2511 r->in.access_mask,
2512 &acc_granted, "_lsa_CreateSecret");
2513 if (!NT_STATUS_IS_OK(status)) {
2514 return status;
2517 if (!r->in.name.string) {
2518 return NT_STATUS_INVALID_PARAMETER;
2521 if (strlen(r->in.name.string) > 128) {
2522 return NT_STATUS_NAME_TOO_LONG;
2525 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
2526 NULL, NULL, NULL, NULL, NULL);
2527 if (NT_STATUS_IS_OK(status)) {
2528 return NT_STATUS_OBJECT_NAME_COLLISION;
2531 status = pdb_set_secret(r->in.name.string, NULL, NULL, psd);
2532 if (!NT_STATUS_IS_OK(status)) {
2533 return status;
2536 status = create_lsa_policy_handle(p->mem_ctx, p,
2537 LSA_HANDLE_SECRET_TYPE,
2538 acc_granted,
2539 NULL,
2540 r->in.name.string,
2541 psd,
2542 r->out.sec_handle);
2543 if (!NT_STATUS_IS_OK(status)) {
2544 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2547 return NT_STATUS_OK;
2550 /***************************************************************************
2551 _lsa_SetSecret
2552 ***************************************************************************/
2554 NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
2555 struct lsa_SetSecret *r)
2557 struct dcesrv_call_state *dce_call = p->dce_call;
2558 struct auth_session_info *session_info =
2559 dcesrv_call_session_info(dce_call);
2560 NTSTATUS status;
2561 struct lsa_info *info = NULL;
2562 DATA_BLOB blob_new, blob_old;
2563 DATA_BLOB cleartext_blob_new = data_blob_null;
2564 DATA_BLOB cleartext_blob_old = data_blob_null;
2565 DATA_BLOB *cleartext_blob_new_p = NULL;
2566 DATA_BLOB *cleartext_blob_old_p = NULL;
2567 DATA_BLOB session_key;
2569 info = find_policy_by_hnd(p,
2570 r->in.sec_handle,
2571 LSA_HANDLE_SECRET_TYPE,
2572 struct lsa_info,
2573 &status);
2574 if (!NT_STATUS_IS_OK(status)) {
2575 return NT_STATUS_INVALID_HANDLE;
2578 if (!(info->access & LSA_SECRET_SET_VALUE)) {
2579 return NT_STATUS_ACCESS_DENIED;
2582 status = session_extract_session_key(
2583 session_info, &session_key, KEY_USE_16BYTES);
2584 if(!NT_STATUS_IS_OK(status)) {
2585 return status;
2588 if (r->in.new_val) {
2589 blob_new = data_blob_const(r->in.new_val->data,
2590 r->in.new_val->length);
2592 status = sess_decrypt_blob(p->mem_ctx, &blob_new,
2593 &session_key,
2594 &cleartext_blob_new);
2595 if (!NT_STATUS_IS_OK(status)) {
2596 return status;
2599 cleartext_blob_new_p = &cleartext_blob_new;
2602 if (r->in.old_val) {
2603 blob_old = data_blob_const(r->in.old_val->data,
2604 r->in.old_val->length);
2606 status = sess_decrypt_blob(p->mem_ctx, &blob_old,
2607 &session_key,
2608 &cleartext_blob_old);
2609 if (!NT_STATUS_IS_OK(status)) {
2610 return status;
2613 cleartext_blob_old_p = &cleartext_blob_old;
2616 status = pdb_set_secret(info->name, cleartext_blob_new_p, cleartext_blob_old_p, NULL);
2617 if (!NT_STATUS_IS_OK(status)) {
2618 return status;
2621 #ifdef DEBUG_PASSWORD
2622 DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
2623 dump_data(10, cleartext_blob_new.data, cleartext_blob_new.length);
2624 DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
2625 dump_data(10, cleartext_blob_old.data, cleartext_blob_old.length);
2626 #endif
2628 return NT_STATUS_OK;
2631 /***************************************************************************
2632 _lsa_QuerySecret
2633 ***************************************************************************/
2635 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
2636 struct lsa_QuerySecret *r)
2638 struct dcesrv_call_state *dce_call = p->dce_call;
2639 struct auth_session_info *session_info =
2640 dcesrv_call_session_info(dce_call);
2641 struct lsa_info *info = NULL;
2642 DATA_BLOB blob_new, blob_old;
2643 DATA_BLOB blob_new_crypt, blob_old_crypt;
2644 DATA_BLOB session_key;
2645 NTTIME nttime_new, nttime_old;
2646 NTSTATUS status;
2648 info = find_policy_by_hnd(p,
2649 r->in.sec_handle,
2650 LSA_HANDLE_SECRET_TYPE,
2651 struct lsa_info,
2652 &status);
2653 if (!NT_STATUS_IS_OK(status)) {
2654 return NT_STATUS_INVALID_HANDLE;
2657 if (!(info->access & LSA_SECRET_QUERY_VALUE)) {
2658 return NT_STATUS_ACCESS_DENIED;
2661 status = pdb_get_secret(p->mem_ctx, info->name,
2662 &blob_new, &nttime_new,
2663 &blob_old, &nttime_old,
2664 NULL);
2665 if (!NT_STATUS_IS_OK(status)) {
2666 return status;
2669 status = session_extract_session_key(
2670 session_info, &session_key, KEY_USE_16BYTES);
2671 if(!NT_STATUS_IS_OK(status)) {
2672 return status;
2675 if (r->in.new_val) {
2676 if (blob_new.length) {
2677 if (!r->out.new_val->buf) {
2678 r->out.new_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2680 if (!r->out.new_val->buf) {
2681 return NT_STATUS_NO_MEMORY;
2684 blob_new_crypt = sess_encrypt_blob(p->mem_ctx, &blob_new,
2685 &session_key);
2686 if (!blob_new_crypt.length) {
2687 return NT_STATUS_NO_MEMORY;
2690 r->out.new_val->buf->data = blob_new_crypt.data;
2691 r->out.new_val->buf->length = blob_new_crypt.length;
2692 r->out.new_val->buf->size = blob_new_crypt.length;
2696 if (r->in.old_val) {
2697 if (blob_old.length) {
2698 if (!r->out.old_val->buf) {
2699 r->out.old_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2701 if (!r->out.old_val->buf) {
2702 return NT_STATUS_NO_MEMORY;
2705 blob_old_crypt = sess_encrypt_blob(p->mem_ctx, &blob_old,
2706 &session_key);
2707 if (!blob_old_crypt.length) {
2708 return NT_STATUS_NO_MEMORY;
2711 r->out.old_val->buf->data = blob_old_crypt.data;
2712 r->out.old_val->buf->length = blob_old_crypt.length;
2713 r->out.old_val->buf->size = blob_old_crypt.length;
2717 if (r->out.new_mtime) {
2718 *r->out.new_mtime = nttime_new;
2721 if (r->out.old_mtime) {
2722 *r->out.old_mtime = nttime_old;
2725 return NT_STATUS_OK;
2728 /***************************************************************************
2729 _lsa_DeleteObject
2730 ***************************************************************************/
2732 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2733 struct lsa_DeleteObject *r)
2735 NTSTATUS status;
2736 struct lsa_info *info = NULL;
2738 info = find_policy_by_hnd(p,
2739 r->in.handle,
2740 DCESRV_HANDLE_ANY,
2741 struct lsa_info,
2742 &status);
2743 if (!NT_STATUS_IS_OK(status)) {
2744 return NT_STATUS_INVALID_HANDLE;
2747 if (!(info->access & SEC_STD_DELETE)) {
2748 return NT_STATUS_ACCESS_DENIED;
2751 switch (info->type) {
2752 case LSA_HANDLE_ACCOUNT_TYPE:
2753 status = privilege_delete_account(&info->sid);
2754 if (!NT_STATUS_IS_OK(status)) {
2755 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2756 nt_errstr(status)));
2757 return status;
2759 break;
2760 case LSA_HANDLE_TRUST_TYPE:
2761 if (!pdb_del_trusteddom_pw(info->name)) {
2762 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2764 status = NT_STATUS_OK;
2765 break;
2766 case LSA_HANDLE_SECRET_TYPE:
2767 status = pdb_delete_secret(info->name);
2768 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2769 return NT_STATUS_INVALID_HANDLE;
2771 break;
2772 default:
2773 return NT_STATUS_INVALID_HANDLE;
2776 close_policy_hnd(p, r->in.handle);
2777 ZERO_STRUCTP(r->out.handle);
2779 return status;
2782 /***************************************************************************
2783 _lsa_EnumPrivs
2784 ***************************************************************************/
2786 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2787 struct lsa_EnumPrivs *r)
2789 struct lsa_info *handle;
2790 uint32_t i;
2791 uint32_t enum_context = *r->in.resume_handle;
2792 int num_privs = num_privileges_in_short_list();
2793 struct lsa_PrivEntry *entries = NULL;
2794 NTSTATUS status;
2796 /* remember that the enum_context starts at 0 and not 1 */
2798 if ( enum_context >= num_privs )
2799 return NT_STATUS_NO_MORE_ENTRIES;
2801 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2802 enum_context, num_privs));
2804 handle = find_policy_by_hnd(p,
2805 r->in.handle,
2806 LSA_HANDLE_POLICY_TYPE,
2807 struct lsa_info,
2808 &status);
2809 if (!NT_STATUS_IS_OK(status)) {
2810 return NT_STATUS_INVALID_HANDLE;
2813 /* check if the user has enough rights
2814 I don't know if it's the right one. not documented. */
2816 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2817 return NT_STATUS_ACCESS_DENIED;
2819 if (num_privs) {
2820 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2821 if (!entries) {
2822 return NT_STATUS_NO_MEMORY;
2824 } else {
2825 entries = NULL;
2828 for (i = 0; i < num_privs; i++) {
2829 if( i < enum_context) {
2831 init_lsa_StringLarge(&entries[i].name, NULL);
2833 entries[i].luid.low = 0;
2834 entries[i].luid.high = 0;
2835 } else {
2837 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2839 entries[i].luid.low = sec_privilege_from_index(i);
2840 entries[i].luid.high = 0;
2844 enum_context = num_privs;
2846 *r->out.resume_handle = enum_context;
2847 r->out.privs->count = num_privs;
2848 r->out.privs->privs = entries;
2850 return NT_STATUS_OK;
2853 /***************************************************************************
2854 _lsa_LookupPrivDisplayName
2855 ***************************************************************************/
2857 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2858 struct lsa_LookupPrivDisplayName *r)
2860 struct lsa_info *handle;
2861 const char *description;
2862 struct lsa_StringLarge *lsa_name;
2863 NTSTATUS status;
2865 handle = find_policy_by_hnd(p,
2866 r->in.handle,
2867 LSA_HANDLE_POLICY_TYPE,
2868 struct lsa_info,
2869 &status);
2870 if (!NT_STATUS_IS_OK(status)) {
2871 return NT_STATUS_INVALID_HANDLE;
2874 /* check if the user has enough rights */
2877 * I don't know if it's the right one. not documented.
2879 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2880 return NT_STATUS_ACCESS_DENIED;
2882 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2884 description = get_privilege_dispname(r->in.name->string);
2885 if (!description) {
2886 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2887 return NT_STATUS_NO_SUCH_PRIVILEGE;
2890 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2892 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2893 if (!lsa_name) {
2894 return NT_STATUS_NO_MEMORY;
2897 init_lsa_StringLarge(lsa_name, description);
2899 *r->out.returned_language_id = r->in.language_id;
2900 *r->out.disp_name = lsa_name;
2902 return NT_STATUS_OK;
2905 /***************************************************************************
2906 _lsa_EnumAccounts
2907 ***************************************************************************/
2909 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2910 struct lsa_EnumAccounts *r)
2912 struct lsa_info *handle;
2913 struct dom_sid *sid_list;
2914 int i, j, num_entries;
2915 NTSTATUS status;
2916 struct lsa_SidPtr *sids = NULL;
2918 handle = find_policy_by_hnd(p,
2919 r->in.handle,
2920 LSA_HANDLE_POLICY_TYPE,
2921 struct lsa_info,
2922 &status);
2923 if (!NT_STATUS_IS_OK(status)) {
2924 return NT_STATUS_INVALID_HANDLE;
2927 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2928 return NT_STATUS_ACCESS_DENIED;
2930 sid_list = NULL;
2931 num_entries = 0;
2933 /* The only way we can currently find out all the SIDs that have been
2934 privileged is to scan all privileges */
2936 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2937 if (!NT_STATUS_IS_OK(status)) {
2938 return status;
2941 if (*r->in.resume_handle >= num_entries) {
2942 return NT_STATUS_NO_MORE_ENTRIES;
2945 if (num_entries - *r->in.resume_handle) {
2946 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2947 num_entries - *r->in.resume_handle);
2948 if (!sids) {
2949 talloc_free(sid_list);
2950 return NT_STATUS_NO_MEMORY;
2953 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2954 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2955 if (!sids[j].sid) {
2956 talloc_free(sid_list);
2957 return NT_STATUS_NO_MEMORY;
2962 talloc_free(sid_list);
2964 *r->out.resume_handle = num_entries;
2965 r->out.sids->num_sids = num_entries;
2966 r->out.sids->sids = sids;
2968 return NT_STATUS_OK;
2971 /***************************************************************************
2972 _lsa_GetUserName
2973 ***************************************************************************/
2975 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2976 struct lsa_GetUserName *r)
2978 struct dcesrv_call_state *dce_call = p->dce_call;
2979 struct auth_session_info *session_info =
2980 dcesrv_call_session_info(dce_call);
2981 const char *username, *domname;
2982 struct lsa_String *account_name = NULL;
2983 struct lsa_String *authority_name = NULL;
2985 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
2986 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
2987 return NT_STATUS_ACCESS_DENIED;
2990 if (r->in.account_name &&
2991 *r->in.account_name) {
2992 return NT_STATUS_INVALID_PARAMETER;
2995 if (r->in.authority_name &&
2996 *r->in.authority_name) {
2997 return NT_STATUS_INVALID_PARAMETER;
3000 if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
3002 * I'm 99% sure this is not the right place to do this,
3003 * global_sid_Anonymous should probably be put into the token
3004 * instead of the guest id -- vl
3006 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
3007 &domname, &username, NULL)) {
3008 return NT_STATUS_NO_MEMORY;
3010 } else {
3011 username = session_info->unix_info->sanitized_username;
3012 domname = session_info->info->domain_name;
3015 account_name = talloc(p->mem_ctx, struct lsa_String);
3016 if (!account_name) {
3017 return NT_STATUS_NO_MEMORY;
3019 init_lsa_String(account_name, username);
3021 if (r->out.authority_name) {
3022 authority_name = talloc(p->mem_ctx, struct lsa_String);
3023 if (!authority_name) {
3024 return NT_STATUS_NO_MEMORY;
3026 init_lsa_String(authority_name, domname);
3029 *r->out.account_name = account_name;
3030 if (r->out.authority_name) {
3031 *r->out.authority_name = authority_name;
3034 return NT_STATUS_OK;
3037 /***************************************************************************
3038 _lsa_CreateAccount
3039 ***************************************************************************/
3041 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
3042 struct lsa_CreateAccount *r)
3044 struct dcesrv_call_state *dce_call = p->dce_call;
3045 struct auth_session_info *session_info =
3046 dcesrv_call_session_info(dce_call);
3047 NTSTATUS status;
3048 struct lsa_info *handle;
3049 uint32_t acc_granted;
3050 struct security_descriptor *psd;
3051 size_t sd_size;
3052 uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
3053 ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
3054 LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3055 SEC_STD_DELETE));
3057 /* find the connection policy handle. */
3058 handle = find_policy_by_hnd(p,
3059 r->in.handle,
3060 LSA_HANDLE_POLICY_TYPE,
3061 struct lsa_info,
3062 &status);
3063 if (!NT_STATUS_IS_OK(status)) {
3064 return NT_STATUS_INVALID_HANDLE;
3067 /* check if the user has enough rights */
3069 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
3070 return NT_STATUS_ACCESS_DENIED;
3073 /* Work out max allowed. */
3074 map_max_allowed_access(session_info->security_token,
3075 session_info->unix_token,
3076 &r->in.access_mask);
3078 /* map the generic bits to the lsa policy ones */
3079 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
3081 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3082 &lsa_account_mapping,
3083 r->in.sid, owner_access);
3084 if (!NT_STATUS_IS_OK(status)) {
3085 return status;
3088 status = access_check_object(psd, session_info->security_token,
3089 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
3090 &acc_granted, "_lsa_CreateAccount");
3091 if (!NT_STATUS_IS_OK(status)) {
3092 return status;
3095 if ( is_privileged_sid( r->in.sid ) )
3096 return NT_STATUS_OBJECT_NAME_COLLISION;
3098 status = create_lsa_policy_handle(p->mem_ctx, p,
3099 LSA_HANDLE_ACCOUNT_TYPE,
3100 acc_granted,
3101 r->in.sid,
3102 NULL,
3103 psd,
3104 r->out.acct_handle);
3105 if (!NT_STATUS_IS_OK(status)) {
3106 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3109 return privilege_create_account(r->in.sid);
3112 /***************************************************************************
3113 _lsa_OpenAccount
3114 ***************************************************************************/
3116 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
3117 struct lsa_OpenAccount *r)
3119 struct dcesrv_call_state *dce_call = p->dce_call;
3120 struct auth_session_info *session_info =
3121 dcesrv_call_session_info(dce_call);
3122 struct security_descriptor *psd = NULL;
3123 size_t sd_size;
3124 uint32_t des_access = r->in.access_mask;
3125 uint32_t acc_granted;
3126 uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
3127 ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
3128 LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3129 SEC_STD_DELETE));
3130 NTSTATUS status;
3132 /* find the connection policy handle. */
3133 (void)find_policy_by_hnd(p,
3134 r->in.handle,
3135 LSA_HANDLE_POLICY_TYPE,
3136 struct lsa_info,
3137 &status);
3138 if (!NT_STATUS_IS_OK(status)) {
3139 return NT_STATUS_INVALID_HANDLE;
3142 /* des_access is for the account here, not the policy
3143 * handle - so don't check against policy handle. */
3145 /* Work out max allowed. */
3146 map_max_allowed_access(session_info->security_token,
3147 session_info->unix_token,
3148 &des_access);
3150 /* map the generic bits to the lsa account ones */
3151 se_map_generic(&des_access, &lsa_account_mapping);
3153 /* get the generic lsa account SD until we store it */
3154 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3155 &lsa_account_mapping,
3156 r->in.sid, owner_access);
3157 if (!NT_STATUS_IS_OK(status)) {
3158 return status;
3161 status = access_check_object(psd, session_info->security_token,
3162 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
3163 &acc_granted, "_lsa_OpenAccount" );
3164 if (!NT_STATUS_IS_OK(status)) {
3165 return status;
3168 /* TODO: Fis the parsing routine before reenabling this check! */
3169 #if 0
3170 if (!lookup_sid(&handle->sid, dom_name, name, &type))
3171 return NT_STATUS_ACCESS_DENIED;
3172 #endif
3174 status = create_lsa_policy_handle(p->mem_ctx, p,
3175 LSA_HANDLE_ACCOUNT_TYPE,
3176 acc_granted,
3177 r->in.sid,
3178 NULL,
3179 psd,
3180 r->out.acct_handle);
3181 if (!NT_STATUS_IS_OK(status)) {
3182 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3185 return NT_STATUS_OK;
3188 /***************************************************************************
3189 _lsa_EnumPrivsAccount
3190 For a given SID, enumerate all the privilege this account has.
3191 ***************************************************************************/
3193 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
3194 struct lsa_EnumPrivsAccount *r)
3196 NTSTATUS status = NT_STATUS_OK;
3197 struct lsa_info *info=NULL;
3198 PRIVILEGE_SET *privileges;
3199 struct lsa_PrivilegeSet *priv_set = NULL;
3200 struct dom_sid_buf buf;
3202 /* find the connection policy handle. */
3203 info = find_policy_by_hnd(p,
3204 r->in.handle,
3205 LSA_HANDLE_ACCOUNT_TYPE,
3206 struct lsa_info,
3207 &status);
3208 if (!NT_STATUS_IS_OK(status)) {
3209 return NT_STATUS_INVALID_HANDLE;
3212 if (!(info->access & LSA_ACCOUNT_VIEW))
3213 return NT_STATUS_ACCESS_DENIED;
3215 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
3216 if (!NT_STATUS_IS_OK(status)) {
3217 return status;
3220 *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
3221 if (!priv_set) {
3222 return NT_STATUS_NO_MEMORY;
3225 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
3226 dom_sid_str_buf(&info->sid, &buf),
3227 privileges->count));
3229 priv_set->count = privileges->count;
3230 priv_set->unknown = 0;
3231 priv_set->set = talloc_move(priv_set, &privileges->set);
3233 return status;
3236 /***************************************************************************
3237 _lsa_GetSystemAccessAccount
3238 ***************************************************************************/
3240 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
3241 struct lsa_GetSystemAccessAccount *r)
3243 NTSTATUS status;
3244 struct lsa_info *info = NULL;
3245 struct lsa_EnumPrivsAccount e;
3246 struct lsa_PrivilegeSet *privset;
3248 /* find the connection policy handle. */
3250 info = find_policy_by_hnd(p,
3251 r->in.handle,
3252 LSA_HANDLE_ACCOUNT_TYPE,
3253 struct lsa_info,
3254 &status);
3255 if (!NT_STATUS_IS_OK(status)) {
3256 return NT_STATUS_INVALID_HANDLE;
3259 if (!(info->access & LSA_ACCOUNT_VIEW))
3260 return NT_STATUS_ACCESS_DENIED;
3262 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
3263 if (!privset) {
3264 return NT_STATUS_NO_MEMORY;
3267 e.in.handle = r->in.handle;
3268 e.out.privs = &privset;
3270 status = _lsa_EnumPrivsAccount(p, &e);
3271 if (!NT_STATUS_IS_OK(status)) {
3272 DEBUG(10,("_lsa_GetSystemAccessAccount: "
3273 "failed to call _lsa_EnumPrivsAccount(): %s\n",
3274 nt_errstr(status)));
3275 return status;
3278 /* Samba4 would iterate over the privset to merge the policy mode bits,
3279 * not sure samba3 can do the same here, so just return what we did in
3280 * the past - gd */
3283 0x01 -> Log on locally
3284 0x02 -> Access this computer from network
3285 0x04 -> Log on as a batch job
3286 0x10 -> Log on as a service
3288 they can be ORed together
3291 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
3292 LSA_POLICY_MODE_NETWORK;
3294 return NT_STATUS_OK;
3297 /***************************************************************************
3298 update the systemaccount information
3299 ***************************************************************************/
3301 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
3302 struct lsa_SetSystemAccessAccount *r)
3304 struct lsa_info *info=NULL;
3305 NTSTATUS status;
3306 GROUP_MAP *map;
3308 /* find the connection policy handle. */
3309 info = find_policy_by_hnd(p,
3310 r->in.handle,
3311 LSA_HANDLE_ACCOUNT_TYPE,
3312 struct lsa_info,
3313 &status);
3314 if (!NT_STATUS_IS_OK(status)) {
3315 return NT_STATUS_INVALID_HANDLE;
3318 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
3319 return NT_STATUS_ACCESS_DENIED;
3322 map = talloc_zero(p->mem_ctx, GROUP_MAP);
3323 if (!map) {
3324 return NT_STATUS_NO_MEMORY;
3327 if (!pdb_getgrsid(map, info->sid)) {
3328 TALLOC_FREE(map);
3329 return NT_STATUS_NO_SUCH_GROUP;
3332 status = pdb_update_group_mapping_entry(map);
3333 TALLOC_FREE(map);
3334 return status;
3337 /***************************************************************************
3338 _lsa_AddPrivilegesToAccount
3339 For a given SID, add some privileges.
3340 ***************************************************************************/
3342 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
3343 struct lsa_AddPrivilegesToAccount *r)
3345 struct lsa_info *info = NULL;
3346 struct lsa_PrivilegeSet *set = NULL;
3347 NTSTATUS status;
3349 /* find the connection policy handle. */
3350 info = find_policy_by_hnd(p,
3351 r->in.handle,
3352 LSA_HANDLE_ACCOUNT_TYPE,
3353 struct lsa_info,
3354 &status);
3355 if (!NT_STATUS_IS_OK(status)) {
3356 return NT_STATUS_INVALID_HANDLE;
3359 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3360 return NT_STATUS_ACCESS_DENIED;
3363 set = r->in.privs;
3365 if ( !grant_privilege_set( &info->sid, set ) ) {
3366 struct dom_sid_buf buf;
3367 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
3368 dom_sid_str_buf(&info->sid, &buf)));
3369 return NT_STATUS_NO_SUCH_PRIVILEGE;
3372 return NT_STATUS_OK;
3375 /***************************************************************************
3376 _lsa_RemovePrivilegesFromAccount
3377 For a given SID, remove some privileges.
3378 ***************************************************************************/
3380 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
3381 struct lsa_RemovePrivilegesFromAccount *r)
3383 struct lsa_info *info = NULL;
3384 struct lsa_PrivilegeSet *set = NULL;
3385 NTSTATUS status;
3387 /* find the connection policy handle. */
3388 info = find_policy_by_hnd(p,
3389 r->in.handle,
3390 LSA_HANDLE_ACCOUNT_TYPE,
3391 struct lsa_info,
3392 &status);
3393 if (!NT_STATUS_IS_OK(status)) {
3394 return NT_STATUS_INVALID_HANDLE;
3397 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3398 return NT_STATUS_ACCESS_DENIED;
3401 set = r->in.privs;
3403 if ( !revoke_privilege_set( &info->sid, set) ) {
3404 struct dom_sid_buf buf;
3405 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
3406 dom_sid_str_buf(&info->sid, &buf)));
3407 return NT_STATUS_NO_SUCH_PRIVILEGE;
3410 return NT_STATUS_OK;
3413 /***************************************************************************
3414 _lsa_LookupPrivName
3415 ***************************************************************************/
3417 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
3418 struct lsa_LookupPrivName *r)
3420 struct lsa_info *info = NULL;
3421 const char *name;
3422 struct lsa_StringLarge *lsa_name;
3423 NTSTATUS status;
3425 /* find the connection policy handle. */
3426 info = find_policy_by_hnd(p,
3427 r->in.handle,
3428 LSA_HANDLE_POLICY_TYPE,
3429 struct lsa_info,
3430 &status);
3431 if (!NT_STATUS_IS_OK(status)) {
3432 return NT_STATUS_INVALID_HANDLE;
3435 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
3436 return NT_STATUS_ACCESS_DENIED;
3439 if (r->in.luid->high != 0) {
3440 return NT_STATUS_NO_SUCH_PRIVILEGE;
3443 name = sec_privilege_name(r->in.luid->low);
3444 if (!name) {
3445 return NT_STATUS_NO_SUCH_PRIVILEGE;
3448 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
3449 if (!lsa_name) {
3450 return NT_STATUS_NO_MEMORY;
3453 lsa_name->string = talloc_strdup(lsa_name, name);
3454 if (!lsa_name->string) {
3455 TALLOC_FREE(lsa_name);
3456 return NT_STATUS_NO_MEMORY;
3459 *r->out.name = lsa_name;
3461 return NT_STATUS_OK;
3464 /***************************************************************************
3465 _lsa_QuerySecurity
3466 ***************************************************************************/
3468 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
3469 struct lsa_QuerySecurity *r)
3471 struct lsa_info *handle=NULL;
3472 struct security_descriptor *psd = NULL;
3473 size_t sd_size = 0;
3474 NTSTATUS status;
3476 /* find the connection policy handle. */
3477 handle = find_policy_by_hnd(p,
3478 r->in.handle,
3479 DCESRV_HANDLE_ANY,
3480 struct lsa_info,
3481 &status);
3482 if (!NT_STATUS_IS_OK(status)) {
3483 return NT_STATUS_INVALID_HANDLE;
3486 switch (handle->type) {
3487 case LSA_HANDLE_POLICY_TYPE:
3488 case LSA_HANDLE_ACCOUNT_TYPE:
3489 case LSA_HANDLE_TRUST_TYPE:
3490 case LSA_HANDLE_SECRET_TYPE:
3491 psd = handle->sd;
3492 sd_size = ndr_size_security_descriptor(psd, 0);
3493 status = NT_STATUS_OK;
3494 break;
3495 default:
3496 status = NT_STATUS_INVALID_HANDLE;
3497 break;
3500 if (!NT_STATUS_IS_OK(status)) {
3501 return status;
3504 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
3505 if (!*r->out.sdbuf) {
3506 return NT_STATUS_NO_MEMORY;
3509 return status;
3512 /***************************************************************************
3513 _lsa_AddAccountRights
3514 ***************************************************************************/
3516 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
3517 struct lsa_AddAccountRights *r)
3519 struct dcesrv_call_state *dce_call = p->dce_call;
3520 struct auth_session_info *session_info =
3521 dcesrv_call_session_info(dce_call);
3522 int i = 0;
3523 uint32_t acc_granted = 0;
3524 struct security_descriptor *psd = NULL;
3525 size_t sd_size;
3526 struct dom_sid sid;
3527 NTSTATUS status;
3529 /* find the connection policy handle. */
3530 (void)find_policy_by_hnd(p,
3531 r->in.handle,
3532 LSA_HANDLE_POLICY_TYPE,
3533 struct lsa_info,
3534 &status);
3535 if (!NT_STATUS_IS_OK(status)) {
3536 return NT_STATUS_INVALID_HANDLE;
3539 /* get the generic lsa account SD for this SID until we store it */
3540 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3541 &lsa_account_mapping,
3542 NULL, 0);
3543 if (!NT_STATUS_IS_OK(status)) {
3544 return status;
3548 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3549 * on the policy handle. If it does, ask for
3550 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3551 * on the account sid. We don't check here so just use the latter. JRA.
3554 status = access_check_object(psd, session_info->security_token,
3555 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3556 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3557 &acc_granted, "_lsa_AddAccountRights" );
3558 if (!NT_STATUS_IS_OK(status)) {
3559 return status;
3562 /* according to an NT4 PDC, you can add privileges to SIDs even without
3563 call_lsa_create_account() first. And you can use any arbitrary SID. */
3565 sid_copy( &sid, r->in.sid );
3567 for ( i=0; i < r->in.rights->count; i++ ) {
3569 const char *privname = r->in.rights->names[i].string;
3571 /* only try to add non-null strings */
3573 if ( !privname )
3574 continue;
3576 if ( !grant_privilege_by_name( &sid, privname ) ) {
3577 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3578 privname ));
3579 return NT_STATUS_NO_SUCH_PRIVILEGE;
3583 return NT_STATUS_OK;
3586 /***************************************************************************
3587 _lsa_RemoveAccountRights
3588 ***************************************************************************/
3590 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
3591 struct lsa_RemoveAccountRights *r)
3593 struct dcesrv_call_state *dce_call = p->dce_call;
3594 struct auth_session_info *session_info =
3595 dcesrv_call_session_info(dce_call);
3596 int i = 0;
3597 struct security_descriptor *psd = NULL;
3598 size_t sd_size;
3599 struct dom_sid sid;
3600 const char *privname = NULL;
3601 uint32_t acc_granted = 0;
3602 NTSTATUS status;
3604 /* find the connection policy handle. */
3605 (void)find_policy_by_hnd(p,
3606 r->in.handle,
3607 LSA_HANDLE_POLICY_TYPE,
3608 struct lsa_info,
3609 &status);
3610 if (!NT_STATUS_IS_OK(status)) {
3611 return NT_STATUS_INVALID_HANDLE;
3614 /* get the generic lsa account SD for this SID until we store it */
3615 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3616 &lsa_account_mapping,
3617 NULL, 0);
3618 if (!NT_STATUS_IS_OK(status)) {
3619 return status;
3623 * From the MS DOCs. We need
3624 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3625 * and DELETE on the account sid.
3628 status = access_check_object(psd, session_info->security_token,
3629 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3630 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3631 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
3632 &acc_granted, "_lsa_RemoveAccountRights");
3633 if (!NT_STATUS_IS_OK(status)) {
3634 return status;
3637 sid_copy( &sid, r->in.sid );
3639 if ( r->in.remove_all ) {
3640 if ( !revoke_all_privileges( &sid ) )
3641 return NT_STATUS_ACCESS_DENIED;
3643 return NT_STATUS_OK;
3646 for ( i=0; i < r->in.rights->count; i++ ) {
3648 privname = r->in.rights->names[i].string;
3650 /* only try to add non-null strings */
3652 if ( !privname )
3653 continue;
3655 if ( !revoke_privilege_by_name( &sid, privname ) ) {
3656 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3657 privname ));
3658 return NT_STATUS_NO_SUCH_PRIVILEGE;
3662 return NT_STATUS_OK;
3665 /*******************************************************************
3666 ********************************************************************/
3668 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3669 struct lsa_RightSet *r,
3670 PRIVILEGE_SET *privileges)
3672 uint32_t i;
3673 const char *privname;
3674 const char **privname_array = NULL;
3675 size_t num_priv = 0;
3677 for (i=0; i<privileges->count; i++) {
3678 if (privileges->set[i].luid.high) {
3679 continue;
3681 privname = sec_privilege_name(privileges->set[i].luid.low);
3682 if (privname) {
3683 if (!add_string_to_array(mem_ctx, privname,
3684 &privname_array, &num_priv)) {
3685 return NT_STATUS_NO_MEMORY;
3690 if (num_priv) {
3692 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3693 num_priv);
3694 if (!r->names) {
3695 return NT_STATUS_NO_MEMORY;
3698 for (i=0; i<num_priv; i++) {
3699 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3702 r->count = num_priv;
3705 return NT_STATUS_OK;
3708 /***************************************************************************
3709 _lsa_EnumAccountRights
3710 ***************************************************************************/
3712 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3713 struct lsa_EnumAccountRights *r)
3715 NTSTATUS status;
3716 struct lsa_info *info = NULL;
3717 PRIVILEGE_SET *privileges;
3718 struct dom_sid_buf buf;
3720 /* find the connection policy handle. */
3722 info = find_policy_by_hnd(p,
3723 r->in.handle,
3724 LSA_HANDLE_POLICY_TYPE,
3725 struct lsa_info,
3726 &status);
3727 if (!NT_STATUS_IS_OK(status)) {
3728 return NT_STATUS_INVALID_HANDLE;
3731 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3732 return NT_STATUS_ACCESS_DENIED;
3735 /* according to an NT4 PDC, you can add privileges to SIDs even without
3736 call_lsa_create_account() first. And you can use any arbitrary SID. */
3738 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3739 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3740 * the lsa database */
3742 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3743 if (!NT_STATUS_IS_OK(status)) {
3744 return status;
3747 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3748 dom_sid_str_buf(r->in.sid, &buf),
3749 privileges->count));
3751 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3753 return status;
3756 /***************************************************************************
3757 _lsa_LookupPrivValue
3758 ***************************************************************************/
3760 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3761 struct lsa_LookupPrivValue *r)
3763 struct lsa_info *info = NULL;
3764 const char *name = NULL;
3765 NTSTATUS status;
3767 /* find the connection policy handle. */
3769 info = find_policy_by_hnd(p,
3770 r->in.handle,
3771 LSA_HANDLE_POLICY_TYPE,
3772 struct lsa_info,
3773 &status);
3774 if (!NT_STATUS_IS_OK(status)) {
3775 return NT_STATUS_INVALID_HANDLE;
3778 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3779 return NT_STATUS_ACCESS_DENIED;
3781 name = r->in.name->string;
3783 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3785 r->out.luid->low = sec_privilege_id(name);
3786 r->out.luid->high = 0;
3787 if (r->out.luid->low == SEC_PRIV_INVALID) {
3788 return NT_STATUS_NO_SUCH_PRIVILEGE;
3790 return NT_STATUS_OK;
3793 /***************************************************************************
3794 _lsa_EnumAccountsWithUserRight
3795 ***************************************************************************/
3797 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3798 struct lsa_EnumAccountsWithUserRight *r)
3800 NTSTATUS status;
3801 struct lsa_info *info = NULL;
3802 struct dom_sid *sids = NULL;
3803 int num_sids = 0;
3804 uint32_t i;
3805 enum sec_privilege privilege;
3807 info = find_policy_by_hnd(p,
3808 r->in.handle,
3809 LSA_HANDLE_POLICY_TYPE,
3810 struct lsa_info,
3811 &status);
3812 if (!NT_STATUS_IS_OK(status)) {
3813 return NT_STATUS_INVALID_HANDLE;
3816 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3817 return NT_STATUS_ACCESS_DENIED;
3820 if (!r->in.name || !r->in.name->string) {
3821 return NT_STATUS_NO_SUCH_PRIVILEGE;
3824 privilege = sec_privilege_id(r->in.name->string);
3825 if (privilege == SEC_PRIV_INVALID) {
3826 return NT_STATUS_NO_SUCH_PRIVILEGE;
3829 status = privilege_enum_sids(privilege, p->mem_ctx,
3830 &sids, &num_sids);
3831 if (!NT_STATUS_IS_OK(status)) {
3832 return status;
3835 r->out.sids->num_sids = num_sids;
3836 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3837 r->out.sids->num_sids);
3839 for (i=0; i < r->out.sids->num_sids; i++) {
3840 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3841 &sids[i]);
3842 if (!r->out.sids->sids[i].sid) {
3843 TALLOC_FREE(r->out.sids->sids);
3844 r->out.sids->num_sids = 0;
3845 return NT_STATUS_NO_MEMORY;
3849 return NT_STATUS_OK;
3852 /***************************************************************************
3853 _lsa_Delete
3854 ***************************************************************************/
3856 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3857 struct lsa_Delete *r)
3859 return NT_STATUS_NOT_SUPPORTED;
3862 static NTSTATUS info_ex_2_pdb_trusted_domain(
3863 struct lsa_TrustDomainInfoInfoEx *info_ex,
3864 struct pdb_trusted_domain *td)
3866 if (info_ex->domain_name.string == NULL ||
3867 info_ex->netbios_name.string == NULL ||
3868 info_ex->sid == NULL) {
3869 return NT_STATUS_INVALID_PARAMETER;
3872 td->domain_name = talloc_strdup(td, info_ex->domain_name.string);
3873 td->netbios_name = talloc_strdup(td, info_ex->netbios_name.string);
3874 sid_copy(&td->security_identifier, info_ex->sid);
3875 if (td->domain_name == NULL ||
3876 td->netbios_name == NULL ||
3877 is_null_sid(&td->security_identifier)) {
3878 return NT_STATUS_NO_MEMORY;
3880 td->trust_direction = info_ex->trust_direction;
3881 td->trust_type = info_ex->trust_type;
3882 td->trust_attributes = info_ex->trust_attributes;
3884 return NT_STATUS_OK;
3887 static NTSTATUS setInfoTrustedDomain_base(struct pipes_struct *p,
3888 TALLOC_CTX *mem_ctx,
3889 struct lsa_info *policy,
3890 enum lsa_TrustDomInfoEnum level,
3891 union lsa_TrustedDomainInfo *info)
3893 struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
3894 DATA_BLOB auth_blob;
3895 struct trustDomainPasswords auth_struct;
3896 NTSTATUS nt_status;
3898 struct pdb_trusted_domain *td;
3899 struct pdb_trusted_domain *orig_td;
3901 td = talloc_zero(mem_ctx, struct pdb_trusted_domain);
3902 if (td == NULL) {
3903 return NT_STATUS_NO_MEMORY;
3906 switch (level) {
3907 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
3908 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3909 return NT_STATUS_ACCESS_DENIED;
3911 td->trust_posix_offset = &info->posix_offset.posix_offset;
3912 break;
3913 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
3914 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3915 return NT_STATUS_ACCESS_DENIED;
3917 nt_status = info_ex_2_pdb_trusted_domain(&info->info_ex, td);
3918 if (!NT_STATUS_IS_OK(nt_status)) {
3919 return nt_status;
3921 break;
3922 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
3923 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3924 return NT_STATUS_ACCESS_DENIED;
3926 nt_status = auth_info_2_auth_blob(td, &info->auth_info,
3927 &td->trust_auth_incoming,
3928 &td->trust_auth_outgoing);
3929 if (!NT_STATUS_IS_OK(nt_status)) {
3930 return nt_status;
3932 break;
3933 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
3934 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3935 return NT_STATUS_ACCESS_DENIED;
3937 td->trust_posix_offset = &info->full_info.posix_offset.posix_offset;
3938 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info.info_ex,
3939 td);
3940 if (!NT_STATUS_IS_OK(nt_status)) {
3941 return nt_status;
3943 nt_status = auth_info_2_auth_blob(td,
3944 &info->full_info.auth_info,
3945 &td->trust_auth_incoming,
3946 &td->trust_auth_outgoing);
3947 if (!NT_STATUS_IS_OK(nt_status)) {
3948 return nt_status;
3950 break;
3951 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
3952 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3953 return NT_STATUS_ACCESS_DENIED;
3955 auth_info_int = &info->auth_info_internal;
3956 break;
3957 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
3958 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3959 return NT_STATUS_ACCESS_DENIED;
3961 td->trust_posix_offset = &info->full_info_internal.posix_offset.posix_offset;
3962 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info_internal.info_ex,
3963 td);
3964 if (!NT_STATUS_IS_OK(nt_status)) {
3965 return nt_status;
3967 auth_info_int = &info->full_info_internal.auth_info;
3968 break;
3969 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
3970 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3971 return NT_STATUS_ACCESS_DENIED;
3973 td->supported_enc_type = &info->enc_types.enc_types;
3974 break;
3975 default:
3976 return NT_STATUS_INVALID_PARAMETER;
3979 /* decode auth_info_int if set */
3980 if (auth_info_int) {
3982 /* now decrypt blob */
3983 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
3984 auth_info_int->auth_blob.size);
3986 nt_status = get_trustdom_auth_blob(p, mem_ctx,
3987 &auth_blob, &auth_struct);
3988 if (!NT_STATUS_IS_OK(nt_status)) {
3989 return nt_status;
3991 } else {
3992 memset(&auth_struct, 0, sizeof(auth_struct));
3995 /* TODO: verify only one object matches the dns/netbios/sid triplet and that
3996 * this is the one we already have */
3998 /* TODO: check if the trust direction is changed and we need to add or remove
3999 * auth data */
4001 /* TODO: check if trust type shall be changed and return an error in this case
4002 * */
4003 nt_status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &policy->sid,
4004 &orig_td);
4005 if (!NT_STATUS_IS_OK(nt_status)) {
4006 return nt_status;
4010 /* TODO: should we fetch previous values from the existing entry
4011 * and append them ? */
4012 if (auth_struct.incoming.count) {
4013 nt_status = get_trustauth_inout_blob(mem_ctx,
4014 &auth_struct.incoming,
4015 &td->trust_auth_incoming);
4016 if (!NT_STATUS_IS_OK(nt_status)) {
4017 return nt_status;
4019 } else {
4020 ZERO_STRUCT(td->trust_auth_incoming);
4023 if (auth_struct.outgoing.count) {
4024 nt_status = get_trustauth_inout_blob(mem_ctx,
4025 &auth_struct.outgoing,
4026 &td->trust_auth_outgoing);
4027 if (!NT_STATUS_IS_OK(nt_status)) {
4028 return nt_status;
4030 } else {
4031 ZERO_STRUCT(td->trust_auth_outgoing);
4034 nt_status = pdb_set_trusted_domain(orig_td->domain_name, td);
4035 if (!NT_STATUS_IS_OK(nt_status)) {
4036 return nt_status;
4039 return NT_STATUS_OK;
4042 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
4043 struct lsa_SetTrustedDomainInfo *r)
4045 NTSTATUS status;
4046 struct policy_handle trustdom_handle;
4047 struct lsa_OpenTrustedDomain o;
4048 struct lsa_SetInformationTrustedDomain s;
4049 struct lsa_Close c;
4051 o.in.handle = r->in.handle;
4052 o.in.sid = r->in.dom_sid;
4053 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4054 o.out.trustdom_handle = &trustdom_handle;
4056 status = _lsa_OpenTrustedDomain(p, &o);
4057 if (!NT_STATUS_IS_OK(status)) {
4058 return status;
4061 s.in.trustdom_handle = &trustdom_handle;
4062 s.in.level = r->in.level;
4063 s.in.info = r->in.info;
4065 status = _lsa_SetInformationTrustedDomain(p, &s);
4066 if (!NT_STATUS_IS_OK(status)) {
4067 return status;
4070 c.in.handle = &trustdom_handle;
4071 c.out.handle = &trustdom_handle;
4073 return _lsa_Close(p, &c);
4076 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
4077 struct lsa_SetTrustedDomainInfoByName *r)
4079 NTSTATUS status;
4080 struct policy_handle trustdom_handle;
4081 struct lsa_OpenTrustedDomainByName o;
4082 struct lsa_SetInformationTrustedDomain s;
4083 struct lsa_Close c;
4085 o.in.handle = r->in.handle;
4086 o.in.name.string = r->in.trusted_domain->string;
4087 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4088 o.out.trustdom_handle = &trustdom_handle;
4090 status = _lsa_OpenTrustedDomainByName(p, &o);
4091 if (!NT_STATUS_IS_OK(status)) {
4092 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
4093 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4095 return status;
4098 s.in.trustdom_handle = &trustdom_handle;
4099 s.in.level = r->in.level;
4100 s.in.info = r->in.info;
4102 status = _lsa_SetInformationTrustedDomain(p, &s);
4103 if (!NT_STATUS_IS_OK(status)) {
4104 return status;
4107 c.in.handle = &trustdom_handle;
4108 c.out.handle = &trustdom_handle;
4110 return _lsa_Close(p, &c);
4113 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
4114 struct lsa_SetInformationTrustedDomain *r)
4116 struct lsa_info *policy;
4117 NTSTATUS status;
4119 policy = find_policy_by_hnd(p,
4120 r->in.trustdom_handle,
4121 LSA_HANDLE_TRUST_TYPE,
4122 struct lsa_info,
4123 &status);
4124 if (!NT_STATUS_IS_OK(status)) {
4125 return NT_STATUS_INVALID_HANDLE;
4128 return setInfoTrustedDomain_base(p, p->mem_ctx, policy,
4129 r->in.level, r->in.info);
4134 * From here on the server routines are just dummy ones to make smbd link with
4135 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
4136 * pulling the server stubs across one by one.
4139 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
4141 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4142 return NT_STATUS_NOT_IMPLEMENTED;
4145 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
4146 struct lsa_ChangePassword *r)
4148 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4149 return NT_STATUS_NOT_IMPLEMENTED;
4152 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
4154 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4155 return NT_STATUS_NOT_IMPLEMENTED;
4158 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
4160 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4161 return NT_STATUS_NOT_IMPLEMENTED;
4164 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
4165 struct lsa_GetQuotasForAccount *r)
4167 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4168 return NT_STATUS_NOT_IMPLEMENTED;
4171 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
4172 struct lsa_SetQuotasForAccount *r)
4174 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4175 return NT_STATUS_NOT_IMPLEMENTED;
4178 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
4179 struct lsa_StorePrivateData *r)
4181 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4182 return NT_STATUS_NOT_IMPLEMENTED;
4185 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
4186 struct lsa_RetrievePrivateData *r)
4188 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4189 return NT_STATUS_NOT_IMPLEMENTED;
4192 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
4193 struct lsa_SetInfoPolicy2 *r)
4195 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4196 return NT_STATUS_NOT_IMPLEMENTED;
4199 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
4200 struct lsa_EnumTrustedDomainsEx *r)
4202 struct lsa_info *info;
4203 uint32_t count;
4204 struct pdb_trusted_domain **domains;
4205 struct lsa_TrustDomainInfoInfoEx *entries;
4206 int i;
4207 NTSTATUS nt_status;
4209 /* bail out early if pdb backend is not capable of ex trusted domains,
4210 * if we don't do that, the client might not call
4211 * _lsa_EnumTrustedDomains() afterwards - gd */
4213 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
4214 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4215 return NT_STATUS_NOT_IMPLEMENTED;
4218 info = find_policy_by_hnd(p,
4219 r->in.handle,
4220 LSA_HANDLE_POLICY_TYPE,
4221 struct lsa_info,
4222 &nt_status);
4223 if (!NT_STATUS_IS_OK(nt_status)) {
4224 return NT_STATUS_INVALID_HANDLE;
4227 /* check if the user has enough rights */
4228 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
4229 return NT_STATUS_ACCESS_DENIED;
4231 become_root();
4232 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
4233 unbecome_root();
4235 if (!NT_STATUS_IS_OK(nt_status)) {
4236 return nt_status;
4239 entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
4240 count);
4241 if (!entries) {
4242 return NT_STATUS_NO_MEMORY;
4245 for (i=0; i<count; i++) {
4246 init_lsa_StringLarge(&entries[i].domain_name,
4247 domains[i]->domain_name);
4248 init_lsa_StringLarge(&entries[i].netbios_name,
4249 domains[i]->netbios_name);
4250 entries[i].sid = &domains[i]->security_identifier;
4251 entries[i].trust_direction = domains[i]->trust_direction;
4252 entries[i].trust_type = domains[i]->trust_type;
4253 entries[i].trust_attributes = domains[i]->trust_attributes;
4256 if (*r->in.resume_handle >= count) {
4257 *r->out.resume_handle = -1;
4258 TALLOC_FREE(entries);
4259 return NT_STATUS_NO_MORE_ENTRIES;
4262 /* return the rest, limit by max_size. Note that we
4263 use the w2k3 element size value of 60 */
4264 r->out.domains->count = count - *r->in.resume_handle;
4265 r->out.domains->count = MIN(r->out.domains->count,
4266 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
4268 r->out.domains->domains = entries + *r->in.resume_handle;
4270 if (r->out.domains->count < count - *r->in.resume_handle) {
4271 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
4272 return STATUS_MORE_ENTRIES;
4275 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
4276 * always be larger than the previous input resume handle, in
4277 * particular when hitting the last query it is vital to set the
4278 * resume handle correctly to avoid infinite client loops, as
4279 * seen e.g. with Windows XP SP3 when resume handle is 0 and
4280 * status is NT_STATUS_OK - gd */
4282 *r->out.resume_handle = (uint32_t)-1;
4284 return NT_STATUS_OK;
4287 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
4288 struct lsa_QueryDomainInformationPolicy *r)
4290 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4291 return NT_STATUS_NOT_IMPLEMENTED;
4294 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
4295 struct lsa_SetDomainInformationPolicy *r)
4297 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4298 return NT_STATUS_NOT_IMPLEMENTED;
4301 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
4303 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4304 return NT_STATUS_NOT_IMPLEMENTED;
4307 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
4309 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4310 return NT_STATUS_NOT_IMPLEMENTED;
4313 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
4315 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4316 return NT_STATUS_NOT_IMPLEMENTED;
4319 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
4321 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4322 return NT_STATUS_NOT_IMPLEMENTED;
4325 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
4326 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
4328 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4329 return NT_STATUS_NOT_IMPLEMENTED;
4332 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
4333 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
4335 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4336 return NT_STATUS_NOT_IMPLEMENTED;
4339 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
4341 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4342 return NT_STATUS_NOT_IMPLEMENTED;
4345 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
4346 struct lsa_CREDRGETTARGETINFO *r)
4348 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4349 return NT_STATUS_NOT_IMPLEMENTED;
4352 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
4353 struct lsa_CREDRPROFILELOADED *r)
4355 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4356 return NT_STATUS_NOT_IMPLEMENTED;
4359 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
4360 struct lsa_CREDRGETSESSIONTYPES *r)
4362 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4363 return NT_STATUS_NOT_IMPLEMENTED;
4366 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
4367 struct lsa_LSARREGISTERAUDITEVENT *r)
4369 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4370 return NT_STATUS_NOT_IMPLEMENTED;
4373 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
4374 struct lsa_LSARGENAUDITEVENT *r)
4376 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4377 return NT_STATUS_NOT_IMPLEMENTED;
4380 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
4381 struct lsa_LSARUNREGISTERAUDITEVENT *r)
4383 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4384 return NT_STATUS_NOT_IMPLEMENTED;
4387 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
4388 struct lsa_lsaRQueryForestTrustInformation *r)
4390 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4391 return NT_STATUS_NOT_IMPLEMENTED;
4394 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
4395 struct lsa_ForestTrustInformation *lfti,
4396 struct ForestTrustInfo *fti)
4398 struct lsa_ForestTrustRecord *lrec;
4399 struct ForestTrustInfoRecord *rec;
4400 struct lsa_StringLarge *tln;
4401 struct lsa_ForestTrustDomainInfo *info;
4402 uint32_t i;
4404 fti->version = 1;
4405 fti->count = lfti->count;
4406 fti->records = talloc_array(mem_ctx,
4407 struct ForestTrustInfoRecordArmor,
4408 fti->count);
4409 if (!fti->records) {
4410 return NT_STATUS_NO_MEMORY;
4412 for (i = 0; i < fti->count; i++) {
4413 lrec = lfti->entries[i];
4414 rec = &fti->records[i].record;
4416 rec->flags = lrec->flags;
4417 rec->timestamp = lrec->time;
4418 rec->type = (enum ForestTrustInfoRecordType)lrec->type;
4420 switch (lrec->type) {
4421 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
4422 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4423 tln = &lrec->forest_trust_data.top_level_name;
4424 rec->data.name.string =
4425 talloc_strdup(mem_ctx, tln->string);
4426 if (!rec->data.name.string) {
4427 return NT_STATUS_NO_MEMORY;
4429 rec->data.name.size = strlen(rec->data.name.string);
4430 break;
4431 case LSA_FOREST_TRUST_DOMAIN_INFO:
4432 info = &lrec->forest_trust_data.domain_info;
4433 rec->data.info.sid = *info->domain_sid;
4434 rec->data.info.dns_name.string =
4435 talloc_strdup(mem_ctx,
4436 info->dns_domain_name.string);
4437 if (!rec->data.info.dns_name.string) {
4438 return NT_STATUS_NO_MEMORY;
4440 rec->data.info.dns_name.size =
4441 strlen(rec->data.info.dns_name.string);
4442 rec->data.info.netbios_name.string =
4443 talloc_strdup(mem_ctx,
4444 info->netbios_domain_name.string);
4445 if (!rec->data.info.netbios_name.string) {
4446 return NT_STATUS_NO_MEMORY;
4448 rec->data.info.netbios_name.size =
4449 strlen(rec->data.info.netbios_name.string);
4450 break;
4451 default:
4452 return NT_STATUS_INVALID_DOMAIN_STATE;
4456 return NT_STATUS_OK;
4459 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4460 uint32_t index, uint32_t collision_type,
4461 uint32_t conflict_type, const char *tdo_name);
4463 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
4464 const char *tdo_name,
4465 struct ForestTrustInfo *tdo_fti,
4466 struct ForestTrustInfo *new_fti,
4467 struct lsa_ForestTrustCollisionInfo *c_info)
4469 struct ForestTrustInfoRecord *nrec;
4470 struct ForestTrustInfoRecord *trec;
4471 const char *dns_name;
4472 const char *nb_name = NULL;
4473 struct dom_sid *sid = NULL;
4474 const char *tname = NULL;
4475 uint32_t new_fti_idx;
4476 uint32_t i;
4477 /* use always TDO type, until we understand when Xref can be used */
4478 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
4479 bool tln_conflict;
4480 bool sid_conflict;
4481 bool nb_conflict;
4482 bool exclusion;
4483 bool ex_rule = false;
4484 int ret;
4486 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
4488 nrec = &new_fti->records[new_fti_idx].record;
4489 dns_name = NULL;
4490 tln_conflict = false;
4491 sid_conflict = false;
4492 nb_conflict = false;
4493 exclusion = false;
4495 switch (nrec->type) {
4496 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
4497 /* exclusions do not conflict by definition */
4498 break;
4500 case FOREST_TRUST_TOP_LEVEL_NAME:
4501 dns_name = nrec->data.name.string;
4502 break;
4504 case FOREST_TRUST_DOMAIN_INFO:
4505 dns_name = nrec->data.info.dns_name.string;
4506 nb_name = nrec->data.info.netbios_name.string;
4507 sid = &nrec->data.info.sid;
4508 break;
4510 case FOREST_TRUST_BINARY_DATA:
4511 break;
4513 case FOREST_TRUST_SCANNER_INFO:
4515 * We don't have a scanner yet,
4516 * so we don't check this here
4518 break;
4521 if (!dns_name) continue;
4523 /* check if this is already taken and not excluded */
4524 for (i = 0; i < tdo_fti->count; i++) {
4525 trec = &tdo_fti->records[i].record;
4527 switch (trec->type) {
4528 case FOREST_TRUST_TOP_LEVEL_NAME:
4529 ex_rule = false;
4530 tname = trec->data.name.string;
4531 break;
4532 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
4533 ex_rule = true;
4534 tname = trec->data.name.string;
4535 break;
4536 case FOREST_TRUST_DOMAIN_INFO:
4537 ex_rule = false;
4538 tname = trec->data.info.dns_name.string;
4539 break;
4540 default:
4541 return NT_STATUS_INVALID_PARAMETER;
4543 ret = dns_cmp(dns_name, tname);
4544 switch (ret) {
4545 case DNS_CMP_MATCH:
4546 /* if it matches exclusion,
4547 * it doesn't conflict */
4548 if (ex_rule) {
4549 exclusion = true;
4550 break;
4553 FALL_THROUGH;
4554 case DNS_CMP_FIRST_IS_CHILD:
4555 case DNS_CMP_SECOND_IS_CHILD:
4556 tln_conflict = true;
4558 FALL_THROUGH;
4559 default:
4560 break;
4563 /* explicit exclusion, no dns name conflict here */
4564 if (exclusion) {
4565 tln_conflict = false;
4568 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
4569 continue;
4572 /* also test for domain info */
4573 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
4574 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
4575 sid_conflict = true;
4577 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
4578 strcasecmp_m(trec->data.info.netbios_name.string,
4579 nb_name) == 0) {
4580 nb_conflict = true;
4584 if (tln_conflict) {
4585 (void)add_collision(c_info, new_fti_idx,
4586 collision_type,
4587 LSA_TLN_DISABLED_CONFLICT,
4588 tdo_name);
4590 if (sid_conflict) {
4591 (void)add_collision(c_info, new_fti_idx,
4592 collision_type,
4593 LSA_SID_DISABLED_CONFLICT,
4594 tdo_name);
4596 if (nb_conflict) {
4597 (void)add_collision(c_info, new_fti_idx,
4598 collision_type,
4599 LSA_NB_DISABLED_CONFLICT,
4600 tdo_name);
4604 return NT_STATUS_OK;
4607 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4608 uint32_t idx, uint32_t collision_type,
4609 uint32_t conflict_type, const char *tdo_name)
4611 struct lsa_ForestTrustCollisionRecord **es;
4612 uint32_t i = c_info->count;
4614 es = talloc_realloc(c_info, c_info->entries,
4615 struct lsa_ForestTrustCollisionRecord *, i + 1);
4616 if (!es) {
4617 return NT_STATUS_NO_MEMORY;
4619 c_info->entries = es;
4620 c_info->count = i + 1;
4622 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4623 if (!es[i]) {
4624 return NT_STATUS_NO_MEMORY;
4627 es[i]->index = idx;
4628 es[i]->type = collision_type;
4629 es[i]->flags = conflict_type;
4630 es[i]->name.string = talloc_strdup(es[i], tdo_name);
4631 if (!es[i]->name.string) {
4632 return NT_STATUS_NO_MEMORY;
4634 es[i]->name.size = strlen(es[i]->name.string);
4636 return NT_STATUS_OK;
4639 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
4640 struct pdb_trusted_domain *td,
4641 struct ForestTrustInfo *info)
4643 enum ndr_err_code ndr_err;
4645 if (td->trust_forest_trust_info.length == 0 ||
4646 td->trust_forest_trust_info.data == NULL) {
4647 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4649 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
4650 info,
4651 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
4652 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4653 return NT_STATUS_INVALID_DOMAIN_STATE;
4656 return NT_STATUS_OK;
4659 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
4660 struct ForestTrustInfo *fti)
4662 struct ForestTrustDataDomainInfo *info;
4663 struct ForestTrustInfoRecord *rec;
4665 fti->version = 1;
4666 fti->count = 2;
4667 fti->records = talloc_array(fti,
4668 struct ForestTrustInfoRecordArmor, 2);
4669 if (!fti->records) {
4670 return NT_STATUS_NO_MEMORY;
4673 /* TLN info */
4674 rec = &fti->records[0].record;
4676 rec->flags = 0;
4677 rec->timestamp = 0;
4678 rec->type = FOREST_TRUST_TOP_LEVEL_NAME;
4680 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
4681 if (!rec->data.name.string) {
4682 return NT_STATUS_NO_MEMORY;
4684 rec->data.name.size = strlen(rec->data.name.string);
4686 /* DOMAIN info */
4687 rec = &fti->records[1].record;
4689 rec->flags = 0;
4690 rec->timestamp = 0;
4691 rec->type = FOREST_TRUST_DOMAIN_INFO;
4693 info = &rec->data.info;
4695 info->sid = dom_info->sid;
4696 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
4697 if (!info->dns_name.string) {
4698 return NT_STATUS_NO_MEMORY;
4700 info->dns_name.size = strlen(info->dns_name.string);
4701 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
4702 if (!info->netbios_name.string) {
4703 return NT_STATUS_NO_MEMORY;
4705 info->netbios_name.size = strlen(info->netbios_name.string);
4707 return NT_STATUS_OK;
4710 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
4711 struct lsa_lsaRSetForestTrustInformation *r)
4713 NTSTATUS status;
4714 int i;
4715 int j;
4716 struct lsa_info *handle;
4717 uint32_t num_domains;
4718 struct pdb_trusted_domain **domains;
4719 struct ForestTrustInfo *nfti;
4720 struct ForestTrustInfo *fti;
4721 struct lsa_ForestTrustCollisionInfo *c_info;
4722 struct pdb_domain_info *dom_info;
4723 enum ndr_err_code ndr_err;
4725 if (!IS_DC) {
4726 return NT_STATUS_NOT_SUPPORTED;
4729 handle = find_policy_by_hnd(p,
4730 r->in.handle,
4731 LSA_HANDLE_TRUST_TYPE,
4732 struct lsa_info,
4733 &status);
4734 if (!NT_STATUS_IS_OK(status)) {
4735 return NT_STATUS_INVALID_HANDLE;
4738 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
4739 return NT_STATUS_ACCESS_DENIED;
4742 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
4743 if (!NT_STATUS_IS_OK(status)) {
4744 return status;
4746 if (num_domains == 0) {
4747 return NT_STATUS_NO_SUCH_DOMAIN;
4750 for (i = 0; i < num_domains; i++) {
4751 if (domains[i]->domain_name == NULL) {
4752 return NT_STATUS_INVALID_DOMAIN_STATE;
4754 if (strcasecmp_m(domains[i]->domain_name,
4755 r->in.trusted_domain_name->string) == 0) {
4756 break;
4759 if (i >= num_domains) {
4760 return NT_STATUS_NO_SUCH_DOMAIN;
4763 if (!(domains[i]->trust_attributes &
4764 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4765 return NT_STATUS_INVALID_PARAMETER;
4768 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4769 return NT_STATUS_INVALID_PARAMETER;
4772 /* The following section until COPY_END is a copy from
4773 * source4/rpmc_server/lsa/scesrc_lsa.c */
4774 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
4775 if (!nfti) {
4776 return NT_STATUS_NO_MEMORY;
4779 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4780 if (!NT_STATUS_IS_OK(status)) {
4781 return status;
4784 c_info = talloc_zero(r->out.collision_info,
4785 struct lsa_ForestTrustCollisionInfo);
4786 if (!c_info) {
4787 return NT_STATUS_NO_MEMORY;
4790 /* first check own info, then other domains */
4791 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4792 if (!fti) {
4793 return NT_STATUS_NO_MEMORY;
4796 dom_info = pdb_get_domain_info(p->mem_ctx);
4798 status = own_ft_info(dom_info, fti);
4799 if (!NT_STATUS_IS_OK(status)) {
4800 return status;
4803 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
4804 if (!NT_STATUS_IS_OK(status)) {
4805 return status;
4808 for (j = 0; j < num_domains; j++) {
4809 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4810 if (!fti) {
4811 return NT_STATUS_NO_MEMORY;
4814 status = get_ft_info(p->mem_ctx, domains[j], fti);
4815 if (!NT_STATUS_IS_OK(status)) {
4816 if (NT_STATUS_EQUAL(status,
4817 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4818 continue;
4820 return status;
4823 if (domains[j]->domain_name == NULL) {
4824 return NT_STATUS_INVALID_DOMAIN_STATE;
4827 status = check_ft_info(c_info, domains[j]->domain_name,
4828 fti, nfti, c_info);
4829 if (!NT_STATUS_IS_OK(status)) {
4830 return status;
4834 if (c_info->count != 0) {
4835 *r->out.collision_info = c_info;
4838 if (r->in.check_only != 0) {
4839 return NT_STATUS_OK;
4842 /* COPY_END */
4844 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
4845 p->mem_ctx, nfti,
4846 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4847 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4848 return NT_STATUS_INVALID_PARAMETER;
4851 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
4852 if (!NT_STATUS_IS_OK(status)) {
4853 return status;
4856 return NT_STATUS_OK;
4859 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
4860 struct lsa_CREDRRENAME *r)
4862 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4863 return NT_STATUS_NOT_IMPLEMENTED;
4866 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
4867 struct lsa_LSAROPENPOLICYSCE *r)
4869 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4870 return NT_STATUS_NOT_IMPLEMENTED;
4873 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4874 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4876 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4877 return NT_STATUS_NOT_IMPLEMENTED;
4880 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4881 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4883 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4884 return NT_STATUS_NOT_IMPLEMENTED;
4887 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4888 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4890 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4891 return NT_STATUS_NOT_IMPLEMENTED;
4894 void _lsa_Opnum82NotUsedOnWire(struct pipes_struct *p,
4895 struct lsa_Opnum82NotUsedOnWire *r)
4897 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4900 void _lsa_Opnum83NotUsedOnWire(struct pipes_struct *p,
4901 struct lsa_Opnum83NotUsedOnWire *r)
4903 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4906 void _lsa_Opnum84NotUsedOnWire(struct pipes_struct *p,
4907 struct lsa_Opnum84NotUsedOnWire *r)
4909 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4912 void _lsa_Opnum85NotUsedOnWire(struct pipes_struct *p,
4913 struct lsa_Opnum85NotUsedOnWire *r)
4915 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4918 void _lsa_Opnum86NotUsedOnWire(struct pipes_struct *p,
4919 struct lsa_Opnum86NotUsedOnWire *r)
4921 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4924 void _lsa_Opnum87NotUsedOnWire(struct pipes_struct *p,
4925 struct lsa_Opnum87NotUsedOnWire *r)
4927 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4930 void _lsa_Opnum88NotUsedOnWire(struct pipes_struct *p,
4931 struct lsa_Opnum88NotUsedOnWire *r)
4933 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4936 void _lsa_Opnum89NotUsedOnWire(struct pipes_struct *p,
4937 struct lsa_Opnum89NotUsedOnWire *r)
4939 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4942 void _lsa_Opnum90NotUsedOnWire(struct pipes_struct *p,
4943 struct lsa_Opnum90NotUsedOnWire *r)
4945 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4948 void _lsa_Opnum91NotUsedOnWire(struct pipes_struct *p,
4949 struct lsa_Opnum91NotUsedOnWire *r)
4951 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4954 void _lsa_Opnum92NotUsedOnWire(struct pipes_struct *p,
4955 struct lsa_Opnum92NotUsedOnWire *r)
4957 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4960 void _lsa_Opnum93NotUsedOnWire(struct pipes_struct *p,
4961 struct lsa_Opnum93NotUsedOnWire *r)
4963 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4966 void _lsa_Opnum94NotUsedOnWire(struct pipes_struct *p,
4967 struct lsa_Opnum94NotUsedOnWire *r)
4969 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4972 void _lsa_Opnum95NotUsedOnWire(struct pipes_struct *p,
4973 struct lsa_Opnum95NotUsedOnWire *r)
4975 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4978 void _lsa_Opnum96NotUsedOnWire(struct pipes_struct *p,
4979 struct lsa_Opnum96NotUsedOnWire *r)
4981 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4984 void _lsa_Opnum97NotUsedOnWire(struct pipes_struct *p,
4985 struct lsa_Opnum97NotUsedOnWire *r)
4987 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4990 void _lsa_Opnum98NotUsedOnWire(struct pipes_struct *p,
4991 struct lsa_Opnum98NotUsedOnWire *r)
4993 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4996 void _lsa_Opnum99NotUsedOnWire(struct pipes_struct *p,
4997 struct lsa_Opnum99NotUsedOnWire *r)
4999 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5002 void _lsa_Opnum100NotUsedOnWire(struct pipes_struct *p,
5003 struct lsa_Opnum100NotUsedOnWire *r)
5005 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5008 void _lsa_Opnum101NotUsedOnWire(struct pipes_struct *p,
5009 struct lsa_Opnum101NotUsedOnWire *r)
5011 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5014 void _lsa_Opnum102NotUsedOnWire(struct pipes_struct *p,
5015 struct lsa_Opnum102NotUsedOnWire *r)
5017 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5020 void _lsa_Opnum103NotUsedOnWire(struct pipes_struct *p,
5021 struct lsa_Opnum103NotUsedOnWire *r)
5023 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5026 void _lsa_Opnum104NotUsedOnWire(struct pipes_struct *p,
5027 struct lsa_Opnum104NotUsedOnWire *r)
5029 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5032 void _lsa_Opnum105NotUsedOnWire(struct pipes_struct *p,
5033 struct lsa_Opnum105NotUsedOnWire *r)
5035 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5038 void _lsa_Opnum106NotUsedOnWire(struct pipes_struct *p,
5039 struct lsa_Opnum106NotUsedOnWire *r)
5041 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5044 void _lsa_Opnum107NotUsedOnWire(struct pipes_struct *p,
5045 struct lsa_Opnum107NotUsedOnWire *r)
5047 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5050 void _lsa_Opnum108NotUsedOnWire(struct pipes_struct *p,
5051 struct lsa_Opnum108NotUsedOnWire *r)
5053 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5056 void _lsa_Opnum109NotUsedOnWire(struct pipes_struct *p,
5057 struct lsa_Opnum109NotUsedOnWire *r)
5059 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5062 void _lsa_Opnum110NotUsedOnWire(struct pipes_struct *p,
5063 struct lsa_Opnum110NotUsedOnWire *r)
5065 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5068 void _lsa_Opnum111NotUsedOnWire(struct pipes_struct *p,
5069 struct lsa_Opnum111NotUsedOnWire *r)
5071 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5074 void _lsa_Opnum112NotUsedOnWire(struct pipes_struct *p,
5075 struct lsa_Opnum112NotUsedOnWire *r)
5077 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5080 void _lsa_Opnum113NotUsedOnWire(struct pipes_struct *p,
5081 struct lsa_Opnum113NotUsedOnWire *r)
5083 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5086 void _lsa_Opnum114NotUsedOnWire(struct pipes_struct *p,
5087 struct lsa_Opnum114NotUsedOnWire *r)
5089 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5092 void _lsa_Opnum115NotUsedOnWire(struct pipes_struct *p,
5093 struct lsa_Opnum115NotUsedOnWire *r)
5095 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5098 void _lsa_Opnum116NotUsedOnWire(struct pipes_struct *p,
5099 struct lsa_Opnum116NotUsedOnWire *r)
5101 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5104 void _lsa_Opnum117NotUsedOnWire(struct pipes_struct *p,
5105 struct lsa_Opnum117NotUsedOnWire *r)
5107 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5110 void _lsa_Opnum118NotUsedOnWire(struct pipes_struct *p,
5111 struct lsa_Opnum118NotUsedOnWire *r)
5113 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5116 void _lsa_Opnum119NotUsedOnWire(struct pipes_struct *p,
5117 struct lsa_Opnum119NotUsedOnWire *r)
5119 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5122 void _lsa_Opnum120NotUsedOnWire(struct pipes_struct *p,
5123 struct lsa_Opnum120NotUsedOnWire *r)
5125 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5128 void _lsa_Opnum121NotUsedOnWire(struct pipes_struct *p,
5129 struct lsa_Opnum121NotUsedOnWire *r)
5131 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5134 void _lsa_Opnum122NotUsedOnWire(struct pipes_struct *p,
5135 struct lsa_Opnum122NotUsedOnWire *r)
5137 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5140 void _lsa_Opnum123NotUsedOnWire(struct pipes_struct *p,
5141 struct lsa_Opnum123NotUsedOnWire *r)
5143 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5146 void _lsa_Opnum124NotUsedOnWire(struct pipes_struct *p,
5147 struct lsa_Opnum124NotUsedOnWire *r)
5149 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5152 void _lsa_Opnum125NotUsedOnWire(struct pipes_struct *p,
5153 struct lsa_Opnum125NotUsedOnWire *r)
5155 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5158 void _lsa_Opnum126NotUsedOnWire(struct pipes_struct *p,
5159 struct lsa_Opnum126NotUsedOnWire *r)
5161 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5164 void _lsa_Opnum127NotUsedOnWire(struct pipes_struct *p,
5165 struct lsa_Opnum127NotUsedOnWire *r)
5167 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5170 void _lsa_Opnum128NotUsedOnWire(struct pipes_struct *p,
5171 struct lsa_Opnum128NotUsedOnWire *r)
5173 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5176 /***************************************************************************
5177 _lsa_CreateTrustedDomainEx3
5178 ***************************************************************************/
5180 NTSTATUS _lsa_CreateTrustedDomainEx3(struct pipes_struct *p,
5181 struct lsa_CreateTrustedDomainEx3 *r)
5183 struct dcesrv_call_state *dce_call = p->dce_call;
5184 struct auth_session_info *session_info =
5185 dcesrv_call_session_info(dce_call);
5186 struct lsa_info *policy;
5187 NTSTATUS status;
5188 struct trustDomainPasswords auth_struct = {
5189 .incoming_size = 0,
5192 if (!IS_DC) {
5193 return NT_STATUS_NOT_SUPPORTED;
5196 policy = find_policy_by_hnd(p,
5197 r->in.policy_handle,
5198 LSA_HANDLE_POLICY_TYPE,
5199 struct lsa_info,
5200 &status);
5201 if (!NT_STATUS_IS_OK(status)) {
5202 return NT_STATUS_INVALID_HANDLE;
5205 status = lsa_CreateTrustedDomain_precheck(p->mem_ctx,
5206 policy,
5207 session_info,
5208 r->in.info);
5209 if (!NT_STATUS_IS_OK(status)) {
5210 return status;
5214 status = get_trustdom_auth_blob_aes(dce_call,
5215 p->mem_ctx,
5216 r->in.auth_info_internal,
5217 &auth_struct);
5218 if (!NT_STATUS_IS_OK(status)) {
5219 return NT_STATUS_UNSUCCESSFUL;
5222 status = lsa_CreateTrustedDomain_common(p,
5223 p->mem_ctx,
5224 session_info,
5225 policy,
5226 r->in.access_mask,
5227 r->in.info,
5228 &auth_struct,
5229 &r->out.trustdom_handle);
5230 if (!NT_STATUS_IS_OK(status)) {
5231 return status;
5234 return NT_STATUS_OK;
5237 /***************************************************************************
5238 _lsa_OpenPolicy3
5239 ***************************************************************************/
5241 NTSTATUS _lsa_OpenPolicy3(struct pipes_struct *p,
5242 struct lsa_OpenPolicy3 *r)
5244 struct dcesrv_call_state *dce_call = p->dce_call;
5245 struct auth_session_info *session_info =
5246 dcesrv_call_session_info(dce_call);
5247 struct security_descriptor *psd = NULL;
5248 size_t sd_size;
5249 uint32_t des_access = r->in.access_mask;
5250 uint32_t acc_granted;
5251 NTSTATUS status;
5253 if (p->transport != NCACN_NP && p->transport != NCALRPC) {
5254 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
5255 return NT_STATUS_ACCESS_DENIED;
5258 ZERO_STRUCTP(r->out.handle);
5261 * The attributes have no effect and MUST be ignored, except the
5262 * root_dir which MUST be NULL.
5264 if (r->in.attr != NULL && r->in.attr->root_dir != NULL) {
5265 return NT_STATUS_INVALID_PARAMETER;
5268 switch (r->in.in_version) {
5269 case 1:
5270 *r->out.out_version = 1;
5272 r->out.out_revision_info->info1.revision = 1;
5273 /* TODO: Enable as soon as we support it */
5274 #if 0
5275 r->out.out_revision_info->info1.supported_features =
5276 LSA_FEATURE_TDO_AUTH_INFO_AES_CIPHER;
5277 #endif
5279 break;
5280 default:
5281 return NT_STATUS_NOT_SUPPORTED;
5284 /* Work out max allowed. */
5285 map_max_allowed_access(session_info->security_token,
5286 session_info->unix_token,
5287 &des_access);
5289 /* map the generic bits to the lsa policy ones */
5290 se_map_generic(&des_access, &lsa_policy_mapping);
5292 /* get the generic lsa policy SD until we store it */
5293 status = make_lsa_object_sd(p->mem_ctx,
5294 &psd,
5295 &sd_size,
5296 &lsa_policy_mapping,
5297 NULL,
5299 if (!NT_STATUS_IS_OK(status)) {
5300 return status;
5303 status = access_check_object(psd,
5304 session_info->security_token,
5305 SEC_PRIV_INVALID,
5306 SEC_PRIV_INVALID,
5308 des_access,
5309 &acc_granted,
5310 "_lsa_OpenPolicy2");
5311 if (!NT_STATUS_IS_OK(status)) {
5312 return status;
5315 status = create_lsa_policy_handle(p->mem_ctx,
5317 LSA_HANDLE_POLICY_TYPE,
5318 acc_granted,
5319 get_global_sam_sid(),
5320 NULL,
5321 psd,
5322 r->out.handle);
5323 if (!NT_STATUS_IS_OK(status)) {
5324 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5327 return NT_STATUS_OK;
5330 void _lsa_Opnum131NotUsedOnWire(struct pipes_struct *p,
5331 struct lsa_Opnum131NotUsedOnWire *r)
5333 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5336 NTSTATUS _lsa_lsaRQueryForestTrustInformation2(struct pipes_struct *p,
5337 struct lsa_lsaRQueryForestTrustInformation2 *r)
5339 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5340 return NT_STATUS_NOT_IMPLEMENTED;
5343 NTSTATUS _lsa_lsaRSetForestTrustInformation2(struct pipes_struct *p,
5344 struct lsa_lsaRSetForestTrustInformation2 *r)
5346 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5347 return NT_STATUS_NOT_IMPLEMENTED;
5350 #include "librpc/rpc/dcesrv_core.h"
5352 #define DCESRV_INTERFACE_LSARPC_BIND(context, iface) \
5353 dcesrv_interface_lsarpc_bind(context, iface)
5355 static NTSTATUS dcesrv_interface_lsarpc_bind(
5356 struct dcesrv_connection_context *context,
5357 const struct dcesrv_interface *iface)
5359 return dcesrv_interface_bind_reject_connect(context, iface);
5362 static NTSTATUS lsarpc__op_init_server(struct dcesrv_context *dce_ctx,
5363 const struct dcesrv_endpoint_server *ep_server);
5364 static const struct dcesrv_interface dcesrv_lsarpc_interface;
5366 #define NCACN_NP_PIPE_NETLOGON "ncacn_np:[\\pipe\\netlogon]"
5367 #define NCACN_NP_PIPE_LSASS "ncacn_np:[\\pipe\\lsass]"
5369 #define DCESRV_INTERFACE_LSARPC_NCACN_NP_SECONDARY_ENDPOINT \
5370 NCACN_NP_PIPE_LSASS
5372 #define DCESRV_INTERFACE_LSARPC_INIT_SERVER \
5373 dcesrv_interface_lsarpc_init_server
5375 static NTSTATUS dcesrv_interface_lsarpc_init_server(
5376 struct dcesrv_context *dce_ctx,
5377 const struct dcesrv_endpoint_server *ep_server)
5379 NTSTATUS ret = dcesrv_interface_register(dce_ctx,
5380 NCACN_NP_PIPE_NETLOGON,
5381 NCACN_NP_PIPE_LSASS,
5382 &dcesrv_lsarpc_interface,
5383 NULL);
5384 if (!NT_STATUS_IS_OK(ret)) {
5385 DBG_ERR("Failed to register endpoint "
5386 "'\\pipe\\netlogon'\n");
5387 return ret;
5390 return lsarpc__op_init_server(dce_ctx, ep_server);
5393 /* include the generated boilerplate */
5394 #include "librpc/gen_ndr/ndr_lsa_scompat.c"