s3-lsa: implement _lsa_CreateSecret().
[Samba/gebeck_regimport.git] / source3 / rpc_server / lsa / srv_lsa_nt.c
blob056a270a26086f62b0a739b2bc27cb18cc2b138c
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Jeremy Allison 2001, 2006.
8 * Copyright (C) Rafal Szczesniak 2002,
9 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
10 * Copyright (C) Simo Sorce 2003.
11 * Copyright (C) Gerald (Jerry) Carter 2005.
12 * Copyright (C) Volker Lendecke 2005.
13 * Copyright (C) Guenther Deschner 2008.
14 * Copyright (C) Andrew Bartlett 2010.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
30 /* This is the implementation of the lsa server code. */
32 #include "includes.h"
33 #include "ntdomain.h"
34 #include "../librpc/gen_ndr/srv_lsa.h"
35 #include "secrets.h"
36 #include "../librpc/gen_ndr/netlogon.h"
37 #include "rpc_client/init_lsa.h"
38 #include "../libcli/security/security.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../librpc/gen_ndr/drsblobs.h"
41 #include "../librpc/gen_ndr/ndr_drsblobs.h"
42 #include "../lib/crypto/arcfour.h"
43 #include "../libcli/security/dom_sid.h"
44 #include "../librpc/gen_ndr/ndr_security.h"
45 #include "passdb.h"
46 #include "auth.h"
47 #include "lib/privileges.h"
48 #include "rpc_server/srv_access_check.h"
50 #undef DBGC_CLASS
51 #define DBGC_CLASS DBGC_RPC_SRV
53 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
55 enum lsa_handle_type {
56 LSA_HANDLE_POLICY_TYPE = 1,
57 LSA_HANDLE_ACCOUNT_TYPE = 2,
58 LSA_HANDLE_TRUST_TYPE = 3,
59 LSA_HANDLE_SECRET_TYPE = 4};
61 struct lsa_info {
62 struct dom_sid sid;
63 const char *name;
64 uint32 access;
65 enum lsa_handle_type type;
66 struct security_descriptor *sd;
69 const struct generic_mapping lsa_account_mapping = {
70 LSA_ACCOUNT_READ,
71 LSA_ACCOUNT_WRITE,
72 LSA_ACCOUNT_EXECUTE,
73 LSA_ACCOUNT_ALL_ACCESS
76 const struct generic_mapping lsa_policy_mapping = {
77 LSA_POLICY_READ,
78 LSA_POLICY_WRITE,
79 LSA_POLICY_EXECUTE,
80 LSA_POLICY_ALL_ACCESS
83 const struct generic_mapping lsa_secret_mapping = {
84 LSA_SECRET_READ,
85 LSA_SECRET_WRITE,
86 LSA_SECRET_EXECUTE,
87 LSA_SECRET_ALL_ACCESS
90 const struct generic_mapping lsa_trusted_domain_mapping = {
91 LSA_TRUSTED_DOMAIN_READ,
92 LSA_TRUSTED_DOMAIN_WRITE,
93 LSA_TRUSTED_DOMAIN_EXECUTE,
94 LSA_TRUSTED_DOMAIN_ALL_ACCESS
97 /***************************************************************************
98 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
99 ***************************************************************************/
101 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
102 struct lsa_RefDomainList *ref,
103 const char *dom_name,
104 struct dom_sid *dom_sid)
106 int num = 0;
108 if (dom_name != NULL) {
109 for (num = 0; num < ref->count; num++) {
110 if (dom_sid_equal(dom_sid, ref->domains[num].sid)) {
111 return num;
114 } else {
115 num = ref->count;
118 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
119 /* index not found, already at maximum domain limit */
120 return -1;
123 ref->count = num + 1;
124 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
126 ref->domains = talloc_realloc(mem_ctx, ref->domains,
127 struct lsa_DomainInfo, ref->count);
128 if (!ref->domains) {
129 return -1;
132 ZERO_STRUCT(ref->domains[num]);
134 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
135 ref->domains[num].sid = dom_sid_dup(mem_ctx, dom_sid);
136 if (!ref->domains[num].sid) {
137 return -1;
140 return num;
144 /***************************************************************************
145 initialize a lsa_DomainInfo structure.
146 ***************************************************************************/
148 static void init_dom_query_3(struct lsa_DomainInfo *r,
149 const char *name,
150 struct dom_sid *sid)
152 init_lsa_StringLarge(&r->name, name);
153 r->sid = sid;
156 /***************************************************************************
157 initialize a lsa_DomainInfo structure.
158 ***************************************************************************/
160 static void init_dom_query_5(struct lsa_DomainInfo *r,
161 const char *name,
162 struct dom_sid *sid)
164 init_lsa_StringLarge(&r->name, name);
165 r->sid = sid;
168 /***************************************************************************
169 lookup_lsa_rids. Must be called as root for lookup_name to work.
170 ***************************************************************************/
172 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
173 struct lsa_RefDomainList *ref,
174 struct lsa_TranslatedSid *prid,
175 uint32_t num_entries,
176 struct lsa_String *name,
177 int flags,
178 uint32_t *pmapped_count)
180 uint32 mapped_count, i;
182 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
184 mapped_count = 0;
185 *pmapped_count = 0;
187 for (i = 0; i < num_entries; i++) {
188 struct dom_sid sid;
189 uint32 rid;
190 int dom_idx;
191 const char *full_name;
192 const char *domain;
193 enum lsa_SidType type;
195 /* Split name into domain and user component */
197 /* follow w2k8 behavior and return the builtin domain when no
198 * input has been passed in */
200 if (name[i].string) {
201 full_name = name[i].string;
202 } else {
203 full_name = "BUILTIN";
206 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
208 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
209 &sid, &type)) {
210 type = SID_NAME_UNKNOWN;
213 switch (type) {
214 case SID_NAME_USER:
215 case SID_NAME_DOM_GRP:
216 case SID_NAME_DOMAIN:
217 case SID_NAME_ALIAS:
218 case SID_NAME_WKN_GRP:
219 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
220 /* Leave these unchanged */
221 break;
222 default:
223 /* Don't hand out anything but the list above */
224 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
225 type = SID_NAME_UNKNOWN;
226 break;
229 rid = 0;
230 dom_idx = -1;
232 if (type != SID_NAME_UNKNOWN) {
233 if (type == SID_NAME_DOMAIN) {
234 rid = (uint32_t)-1;
235 } else {
236 sid_split_rid(&sid, &rid);
238 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
239 mapped_count++;
242 prid[i].sid_type = type;
243 prid[i].rid = rid;
244 prid[i].sid_index = dom_idx;
247 *pmapped_count = mapped_count;
248 return NT_STATUS_OK;
251 /***************************************************************************
252 lookup_lsa_sids. Must be called as root for lookup_name to work.
253 ***************************************************************************/
255 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
256 struct lsa_RefDomainList *ref,
257 struct lsa_TranslatedSid3 *trans_sids,
258 uint32_t num_entries,
259 struct lsa_String *name,
260 int flags,
261 uint32 *pmapped_count)
263 uint32 mapped_count, i;
265 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
267 mapped_count = 0;
268 *pmapped_count = 0;
270 for (i = 0; i < num_entries; i++) {
271 struct dom_sid sid;
272 uint32 rid;
273 int dom_idx;
274 const char *full_name;
275 const char *domain;
276 enum lsa_SidType type;
278 ZERO_STRUCT(sid);
280 /* Split name into domain and user component */
282 full_name = name[i].string;
283 if (full_name == NULL) {
284 return NT_STATUS_NO_MEMORY;
287 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
289 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
290 &sid, &type)) {
291 type = SID_NAME_UNKNOWN;
294 switch (type) {
295 case SID_NAME_USER:
296 case SID_NAME_DOM_GRP:
297 case SID_NAME_DOMAIN:
298 case SID_NAME_ALIAS:
299 case SID_NAME_WKN_GRP:
300 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
301 /* Leave these unchanged */
302 break;
303 default:
304 /* Don't hand out anything but the list above */
305 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
306 type = SID_NAME_UNKNOWN;
307 break;
310 rid = 0;
311 dom_idx = -1;
313 if (type != SID_NAME_UNKNOWN) {
314 struct dom_sid domain_sid;
315 sid_copy(&domain_sid, &sid);
316 sid_split_rid(&domain_sid, &rid);
317 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
318 mapped_count++;
321 /* Initialize the lsa_TranslatedSid3 return. */
322 trans_sids[i].sid_type = type;
323 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
324 trans_sids[i].sid_index = dom_idx;
327 *pmapped_count = mapped_count;
328 return NT_STATUS_OK;
331 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
332 const struct generic_mapping *map,
333 struct dom_sid *sid, uint32_t sid_access)
335 struct dom_sid adm_sid;
336 struct security_ace ace[5];
337 size_t i = 0;
339 struct security_acl *psa = NULL;
341 /* READ|EXECUTE access for Everyone */
343 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
344 map->generic_execute | map->generic_read, 0);
346 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
348 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
349 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
350 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
351 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
353 /* Add Full Access for Domain Admins */
354 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
355 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
356 map->generic_all, 0);
358 /* If we have a sid, give it some special access */
360 if (sid) {
361 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
362 sid_access, 0);
365 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
366 return NT_STATUS_NO_MEMORY;
368 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
369 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
370 psa, sd_size)) == NULL)
371 return NT_STATUS_NO_MEMORY;
373 return NT_STATUS_OK;
376 /***************************************************************************
377 ***************************************************************************/
379 static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
380 struct pipes_struct *p,
381 enum lsa_handle_type type,
382 uint32_t acc_granted,
383 struct dom_sid *sid,
384 const char *name,
385 const struct security_descriptor *sd,
386 struct policy_handle *handle)
388 struct lsa_info *info;
390 ZERO_STRUCTP(handle);
392 info = talloc_zero(mem_ctx, struct lsa_info);
393 if (!info) {
394 return NT_STATUS_NO_MEMORY;
397 info->type = type;
398 info->access = acc_granted;
400 if (sid) {
401 sid_copy(&info->sid, sid);
404 info->name = talloc_strdup(info, name);
406 if (sd) {
407 info->sd = dup_sec_desc(info, sd);
408 if (!info->sd) {
409 talloc_free(info);
410 return NT_STATUS_NO_MEMORY;
414 if (!create_policy_hnd(p, handle, info)) {
415 talloc_free(info);
416 ZERO_STRUCTP(handle);
417 return NT_STATUS_NO_MEMORY;
420 return NT_STATUS_OK;
423 /***************************************************************************
424 _lsa_OpenPolicy2
425 ***************************************************************************/
427 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
428 struct lsa_OpenPolicy2 *r)
430 struct security_descriptor *psd = NULL;
431 size_t sd_size;
432 uint32 des_access = r->in.access_mask;
433 uint32 acc_granted;
434 NTSTATUS status;
436 /* Work out max allowed. */
437 map_max_allowed_access(p->session_info->security_token,
438 p->session_info->unix_token,
439 &des_access);
441 /* map the generic bits to the lsa policy ones */
442 se_map_generic(&des_access, &lsa_policy_mapping);
444 /* get the generic lsa policy SD until we store it */
445 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
446 NULL, 0);
447 if (!NT_STATUS_IS_OK(status)) {
448 return status;
451 status = access_check_object(psd, p->session_info->security_token,
452 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
453 &acc_granted, "_lsa_OpenPolicy2" );
454 if (!NT_STATUS_IS_OK(status)) {
455 return status;
458 status = create_lsa_policy_handle(p->mem_ctx, p,
459 LSA_HANDLE_POLICY_TYPE,
460 acc_granted,
461 get_global_sam_sid(),
462 NULL,
463 psd,
464 r->out.handle);
465 if (!NT_STATUS_IS_OK(status)) {
466 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
469 return NT_STATUS_OK;
472 /***************************************************************************
473 _lsa_OpenPolicy
474 ***************************************************************************/
476 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
477 struct lsa_OpenPolicy *r)
479 struct lsa_OpenPolicy2 o;
481 o.in.system_name = NULL; /* should be ignored */
482 o.in.attr = r->in.attr;
483 o.in.access_mask = r->in.access_mask;
485 o.out.handle = r->out.handle;
487 return _lsa_OpenPolicy2(p, &o);
490 /***************************************************************************
491 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
492 ufff, done :) mimir
493 ***************************************************************************/
495 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
496 struct lsa_EnumTrustDom *r)
498 struct lsa_info *info;
499 uint32_t count;
500 struct trustdom_info **domains;
501 struct lsa_DomainInfo *entries;
502 int i;
503 NTSTATUS nt_status;
505 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
506 return NT_STATUS_INVALID_HANDLE;
508 if (info->type != LSA_HANDLE_POLICY_TYPE) {
509 return NT_STATUS_INVALID_HANDLE;
512 /* check if the user has enough rights */
513 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
514 return NT_STATUS_ACCESS_DENIED;
516 become_root();
517 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
518 unbecome_root();
520 if (!NT_STATUS_IS_OK(nt_status)) {
521 return nt_status;
524 entries = talloc_zero_array(p->mem_ctx, struct lsa_DomainInfo, count);
525 if (!entries) {
526 return NT_STATUS_NO_MEMORY;
529 for (i=0; i<count; i++) {
530 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
531 entries[i].sid = &domains[i]->sid;
534 if (*r->in.resume_handle >= count) {
535 *r->out.resume_handle = -1;
536 TALLOC_FREE(entries);
537 return NT_STATUS_NO_MORE_ENTRIES;
540 /* return the rest, limit by max_size. Note that we
541 use the w2k3 element size value of 60 */
542 r->out.domains->count = count - *r->in.resume_handle;
543 r->out.domains->count = MIN(r->out.domains->count,
544 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
546 r->out.domains->domains = entries + *r->in.resume_handle;
548 if (r->out.domains->count < count - *r->in.resume_handle) {
549 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
550 return STATUS_MORE_ENTRIES;
553 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
554 * always be larger than the previous input resume handle, in
555 * particular when hitting the last query it is vital to set the
556 * resume handle correctly to avoid infinite client loops, as
557 * seen e.g. with Windows XP SP3 when resume handle is 0 and
558 * status is NT_STATUS_OK - gd */
560 *r->out.resume_handle = (uint32_t)-1;
562 return NT_STATUS_OK;
565 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
566 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
567 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
569 /***************************************************************************
570 _lsa_QueryInfoPolicy
571 ***************************************************************************/
573 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
574 struct lsa_QueryInfoPolicy *r)
576 NTSTATUS status = NT_STATUS_OK;
577 struct lsa_info *handle;
578 struct dom_sid domain_sid;
579 const char *name;
580 struct dom_sid *sid = NULL;
581 union lsa_PolicyInformation *info = NULL;
582 uint32_t acc_required = 0;
584 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
585 return NT_STATUS_INVALID_HANDLE;
587 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
588 return NT_STATUS_INVALID_HANDLE;
591 switch (r->in.level) {
592 case LSA_POLICY_INFO_AUDIT_LOG:
593 case LSA_POLICY_INFO_AUDIT_EVENTS:
594 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
595 break;
596 case LSA_POLICY_INFO_DOMAIN:
597 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
598 break;
599 case LSA_POLICY_INFO_PD:
600 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
601 break;
602 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
603 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
604 break;
605 case LSA_POLICY_INFO_ROLE:
606 case LSA_POLICY_INFO_REPLICA:
607 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
608 break;
609 case LSA_POLICY_INFO_QUOTA:
610 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
611 break;
612 case LSA_POLICY_INFO_MOD:
613 case LSA_POLICY_INFO_AUDIT_FULL_SET:
614 /* according to MS-LSAD 3.1.4.4.3 */
615 return NT_STATUS_INVALID_PARAMETER;
616 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
617 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
618 break;
619 case LSA_POLICY_INFO_DNS:
620 case LSA_POLICY_INFO_DNS_INT:
621 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
622 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
623 break;
624 default:
625 break;
628 if (!(handle->access & acc_required)) {
629 /* return NT_STATUS_ACCESS_DENIED; */
632 info = talloc_zero(p->mem_ctx, union lsa_PolicyInformation);
633 if (!info) {
634 return NT_STATUS_NO_MEMORY;
637 switch (r->in.level) {
638 /* according to MS-LSAD 3.1.4.4.3 */
639 case LSA_POLICY_INFO_MOD:
640 case LSA_POLICY_INFO_AUDIT_FULL_SET:
641 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
642 return NT_STATUS_INVALID_PARAMETER;
643 case LSA_POLICY_INFO_AUDIT_LOG:
644 info->audit_log.percent_full = 0;
645 info->audit_log.maximum_log_size = 0;
646 info->audit_log.retention_time = 0;
647 info->audit_log.shutdown_in_progress = 0;
648 info->audit_log.time_to_shutdown = 0;
649 info->audit_log.next_audit_record = 0;
650 status = NT_STATUS_OK;
651 break;
652 case LSA_POLICY_INFO_PD:
653 info->pd.name.string = NULL;
654 status = NT_STATUS_OK;
655 break;
656 case LSA_POLICY_INFO_REPLICA:
657 info->replica.source.string = NULL;
658 info->replica.account.string = NULL;
659 status = NT_STATUS_OK;
660 break;
661 case LSA_POLICY_INFO_QUOTA:
662 info->quota.paged_pool = 0;
663 info->quota.non_paged_pool = 0;
664 info->quota.min_wss = 0;
665 info->quota.max_wss = 0;
666 info->quota.pagefile = 0;
667 info->quota.unknown = 0;
668 status = NT_STATUS_OK;
669 break;
670 case LSA_POLICY_INFO_AUDIT_EVENTS:
673 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
675 /* check if the user has enough rights */
676 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
677 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
678 return NT_STATUS_ACCESS_DENIED;
681 /* fake info: We audit everything. ;) */
683 info->audit_events.auditing_mode = true;
684 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
685 info->audit_events.settings = talloc_zero_array(p->mem_ctx,
686 enum lsa_PolicyAuditPolicy,
687 info->audit_events.count);
688 if (!info->audit_events.settings) {
689 return NT_STATUS_NO_MEMORY;
692 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
693 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
694 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
695 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
696 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
697 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
698 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
700 break;
702 case LSA_POLICY_INFO_DOMAIN:
703 /* check if the user has enough rights */
704 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
705 return NT_STATUS_ACCESS_DENIED;
707 /* Request PolicyPrimaryDomainInformation. */
708 switch (lp_server_role()) {
709 case ROLE_DOMAIN_PDC:
710 case ROLE_DOMAIN_BDC:
711 name = get_global_sam_name();
712 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
713 if (!sid) {
714 return NT_STATUS_NO_MEMORY;
716 break;
717 case ROLE_DOMAIN_MEMBER:
718 name = lp_workgroup();
719 /* We need to return the Domain SID here. */
720 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
721 sid = dom_sid_dup(p->mem_ctx, &domain_sid);
722 if (!sid) {
723 return NT_STATUS_NO_MEMORY;
725 } else {
726 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
728 break;
729 case ROLE_STANDALONE:
730 name = lp_workgroup();
731 sid = NULL;
732 break;
733 default:
734 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
736 init_dom_query_3(&info->domain, name, sid);
737 break;
738 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
739 /* check if the user has enough rights */
740 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
741 return NT_STATUS_ACCESS_DENIED;
743 /* Request PolicyAccountDomainInformation. */
744 name = get_global_sam_name();
745 sid = get_global_sam_sid();
747 init_dom_query_5(&info->account_domain, name, sid);
748 break;
749 case LSA_POLICY_INFO_ROLE:
750 /* check if the user has enough rights */
751 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
752 return NT_STATUS_ACCESS_DENIED;
754 switch (lp_server_role()) {
755 case ROLE_DOMAIN_BDC:
757 * only a BDC is a backup controller
758 * of the domain, it controls.
760 info->role.role = LSA_ROLE_BACKUP;
761 break;
762 default:
764 * any other role is a primary
765 * of the domain, it controls.
767 info->role.role = LSA_ROLE_PRIMARY;
768 break;
770 break;
771 case LSA_POLICY_INFO_DNS:
772 case LSA_POLICY_INFO_DNS_INT: {
773 struct pdb_domain_info *dominfo;
775 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
776 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
777 "without ADS passdb backend\n"));
778 status = NT_STATUS_INVALID_INFO_CLASS;
779 break;
782 dominfo = pdb_get_domain_info(info);
783 if (dominfo == NULL) {
784 status = NT_STATUS_NO_MEMORY;
785 break;
788 init_lsa_StringLarge(&info->dns.name,
789 dominfo->name);
790 init_lsa_StringLarge(&info->dns.dns_domain,
791 dominfo->dns_domain);
792 init_lsa_StringLarge(&info->dns.dns_forest,
793 dominfo->dns_forest);
794 info->dns.domain_guid = dominfo->guid;
795 info->dns.sid = &dominfo->sid;
796 break;
798 default:
799 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
800 r->in.level));
801 status = NT_STATUS_INVALID_INFO_CLASS;
802 break;
805 *r->out.info = info;
807 return status;
810 /***************************************************************************
811 _lsa_QueryInfoPolicy2
812 ***************************************************************************/
814 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
815 struct lsa_QueryInfoPolicy2 *r2)
817 struct lsa_QueryInfoPolicy r;
819 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
820 p->rng_fault_state = True;
821 return NT_STATUS_NOT_IMPLEMENTED;
824 ZERO_STRUCT(r);
825 r.in.handle = r2->in.handle;
826 r.in.level = r2->in.level;
827 r.out.info = r2->out.info;
829 return _lsa_QueryInfoPolicy(p, &r);
832 /***************************************************************************
833 _lsa_lookup_sids_internal
834 ***************************************************************************/
836 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
837 TALLOC_CTX *mem_ctx,
838 uint16_t level, /* input */
839 int num_sids, /* input */
840 struct lsa_SidPtr *sid, /* input */
841 struct lsa_RefDomainList **pp_ref, /* input/output */
842 struct lsa_TranslatedName2 **pp_names,/* input/output */
843 uint32_t *pp_mapped_count) /* input/output */
845 NTSTATUS status;
846 int i;
847 const struct dom_sid **sids = NULL;
848 struct lsa_RefDomainList *ref = NULL;
849 uint32 mapped_count = 0;
850 struct lsa_dom_info *dom_infos = NULL;
851 struct lsa_name_info *name_infos = NULL;
852 struct lsa_TranslatedName2 *names = NULL;
854 *pp_mapped_count = 0;
855 *pp_names = NULL;
856 *pp_ref = NULL;
858 if (num_sids == 0) {
859 return NT_STATUS_OK;
862 sids = talloc_array(p->mem_ctx, const struct dom_sid *, num_sids);
863 ref = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
865 if (sids == NULL || ref == NULL) {
866 return NT_STATUS_NO_MEMORY;
869 for (i=0; i<num_sids; i++) {
870 sids[i] = sid[i].sid;
873 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
874 &dom_infos, &name_infos);
876 if (!NT_STATUS_IS_OK(status)) {
877 return status;
880 names = talloc_array(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
881 if (names == NULL) {
882 return NT_STATUS_NO_MEMORY;
885 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
887 if (!dom_infos[i].valid) {
888 break;
891 if (init_lsa_ref_domain_list(mem_ctx, ref,
892 dom_infos[i].name,
893 &dom_infos[i].sid) != i) {
894 DEBUG(0, ("Domain %s mentioned twice??\n",
895 dom_infos[i].name));
896 return NT_STATUS_INTERNAL_ERROR;
900 for (i=0; i<num_sids; i++) {
901 struct lsa_name_info *name = &name_infos[i];
903 if (name->type == SID_NAME_UNKNOWN) {
904 name->dom_idx = -1;
905 /* Unknown sids should return the string
906 * representation of the SID. Windows 2003 behaves
907 * rather erratic here, in many cases it returns the
908 * RID as 8 bytes hex, in others it returns the full
909 * SID. We (Jerry/VL) could not figure out which the
910 * hard cases are, so leave it with the SID. */
911 name->name = dom_sid_string(p->mem_ctx, sids[i]);
912 if (name->name == NULL) {
913 return NT_STATUS_NO_MEMORY;
915 } else {
916 mapped_count += 1;
919 names[i].sid_type = name->type;
920 names[i].name.string = name->name;
921 names[i].sid_index = name->dom_idx;
922 names[i].unknown = 0;
925 status = NT_STATUS_NONE_MAPPED;
926 if (mapped_count > 0) {
927 status = (mapped_count < num_sids) ?
928 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
931 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
932 num_sids, mapped_count, nt_errstr(status)));
934 *pp_mapped_count = mapped_count;
935 *pp_names = names;
936 *pp_ref = ref;
938 return status;
941 /***************************************************************************
942 _lsa_LookupSids
943 ***************************************************************************/
945 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
946 struct lsa_LookupSids *r)
948 NTSTATUS status;
949 struct lsa_info *handle;
950 int num_sids = r->in.sids->num_sids;
951 uint32 mapped_count = 0;
952 struct lsa_RefDomainList *domains = NULL;
953 struct lsa_TranslatedName *names_out = NULL;
954 struct lsa_TranslatedName2 *names = NULL;
955 int i;
957 if ((r->in.level < 1) || (r->in.level > 6)) {
958 return NT_STATUS_INVALID_PARAMETER;
961 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
962 return NT_STATUS_INVALID_HANDLE;
965 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
966 return NT_STATUS_INVALID_HANDLE;
969 /* check if the user has enough rights */
970 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
971 return NT_STATUS_ACCESS_DENIED;
974 if (num_sids > MAX_LOOKUP_SIDS) {
975 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
976 MAX_LOOKUP_SIDS, num_sids));
977 return NT_STATUS_NONE_MAPPED;
980 status = _lsa_lookup_sids_internal(p,
981 p->mem_ctx,
982 r->in.level,
983 num_sids,
984 r->in.sids->sids,
985 &domains,
986 &names,
987 &mapped_count);
989 /* Only return here when there is a real error.
990 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
991 the requested sids could be resolved. Older versions of XP (pre SP3)
992 rely that we return with the string representations of those SIDs in
993 that case. If we don't, XP crashes - Guenther
996 if (NT_STATUS_IS_ERR(status) &&
997 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
998 return status;
1001 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
1002 names_out = talloc_array(p->mem_ctx, struct lsa_TranslatedName,
1003 num_sids);
1004 if (!names_out) {
1005 return NT_STATUS_NO_MEMORY;
1008 for (i=0; i<num_sids; i++) {
1009 names_out[i].sid_type = names[i].sid_type;
1010 names_out[i].name = names[i].name;
1011 names_out[i].sid_index = names[i].sid_index;
1014 *r->out.domains = domains;
1015 r->out.names->count = num_sids;
1016 r->out.names->names = names_out;
1017 *r->out.count = mapped_count;
1019 return status;
1022 /***************************************************************************
1023 _lsa_LookupSids2
1024 ***************************************************************************/
1026 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1027 struct lsa_LookupSids2 *r)
1029 NTSTATUS status;
1030 struct lsa_info *handle;
1031 int num_sids = r->in.sids->num_sids;
1032 uint32 mapped_count = 0;
1033 struct lsa_RefDomainList *domains = NULL;
1034 struct lsa_TranslatedName2 *names = NULL;
1035 bool check_policy = true;
1037 switch (p->opnum) {
1038 case NDR_LSA_LOOKUPSIDS3:
1039 check_policy = false;
1040 break;
1041 case NDR_LSA_LOOKUPSIDS2:
1042 default:
1043 check_policy = true;
1046 if ((r->in.level < 1) || (r->in.level > 6)) {
1047 return NT_STATUS_INVALID_PARAMETER;
1050 if (check_policy) {
1051 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1052 return NT_STATUS_INVALID_HANDLE;
1055 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1056 return NT_STATUS_INVALID_HANDLE;
1059 /* check if the user has enough rights */
1060 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1061 return NT_STATUS_ACCESS_DENIED;
1065 if (num_sids > MAX_LOOKUP_SIDS) {
1066 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1067 MAX_LOOKUP_SIDS, num_sids));
1068 return NT_STATUS_NONE_MAPPED;
1071 status = _lsa_lookup_sids_internal(p,
1072 p->mem_ctx,
1073 r->in.level,
1074 num_sids,
1075 r->in.sids->sids,
1076 &domains,
1077 &names,
1078 &mapped_count);
1080 *r->out.domains = domains;
1081 r->out.names->count = num_sids;
1082 r->out.names->names = names;
1083 *r->out.count = mapped_count;
1085 return status;
1088 /***************************************************************************
1089 _lsa_LookupSids3
1090 ***************************************************************************/
1092 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1093 struct lsa_LookupSids3 *r)
1095 struct lsa_LookupSids2 q;
1097 /* No policy handle on this call. Restrict to crypto connections. */
1098 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1099 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1100 get_remote_machine_name() ));
1101 return NT_STATUS_INVALID_PARAMETER;
1104 q.in.handle = NULL;
1105 q.in.sids = r->in.sids;
1106 q.in.level = r->in.level;
1107 q.in.lookup_options = r->in.lookup_options;
1108 q.in.client_revision = r->in.client_revision;
1109 q.in.names = r->in.names;
1110 q.in.count = r->in.count;
1112 q.out.domains = r->out.domains;
1113 q.out.names = r->out.names;
1114 q.out.count = r->out.count;
1116 return _lsa_LookupSids2(p, &q);
1119 /***************************************************************************
1120 ***************************************************************************/
1122 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1124 int flags;
1126 switch (level) {
1127 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1128 flags = LOOKUP_NAME_ALL;
1129 break;
1130 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1131 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1132 break;
1133 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1134 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1135 break;
1136 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1137 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1138 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1139 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1140 default:
1141 flags = LOOKUP_NAME_NONE;
1142 break;
1145 return flags;
1148 /***************************************************************************
1149 _lsa_LookupNames
1150 ***************************************************************************/
1152 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1153 struct lsa_LookupNames *r)
1155 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1156 struct lsa_info *handle;
1157 struct lsa_String *names = r->in.names;
1158 uint32 num_entries = r->in.num_names;
1159 struct lsa_RefDomainList *domains = NULL;
1160 struct lsa_TranslatedSid *rids = NULL;
1161 uint32 mapped_count = 0;
1162 int flags = 0;
1164 if (num_entries > MAX_LOOKUP_SIDS) {
1165 num_entries = MAX_LOOKUP_SIDS;
1166 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1167 num_entries));
1170 flags = lsa_lookup_level_to_flags(r->in.level);
1172 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1173 if (!domains) {
1174 return NT_STATUS_NO_MEMORY;
1177 if (num_entries) {
1178 rids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid,
1179 num_entries);
1180 if (!rids) {
1181 return NT_STATUS_NO_MEMORY;
1183 } else {
1184 rids = NULL;
1187 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1188 status = NT_STATUS_INVALID_HANDLE;
1189 goto done;
1192 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1193 return NT_STATUS_INVALID_HANDLE;
1196 /* check if the user has enough rights */
1197 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1198 status = NT_STATUS_ACCESS_DENIED;
1199 goto done;
1202 /* set up the LSA Lookup RIDs response */
1203 become_root(); /* lookup_name can require root privs */
1204 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1205 names, flags, &mapped_count);
1206 unbecome_root();
1208 done:
1210 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1211 if (mapped_count == 0) {
1212 status = NT_STATUS_NONE_MAPPED;
1213 } else if (mapped_count != num_entries) {
1214 status = STATUS_SOME_UNMAPPED;
1218 *r->out.count = mapped_count;
1219 *r->out.domains = domains;
1220 r->out.sids->sids = rids;
1221 r->out.sids->count = num_entries;
1223 return status;
1226 /***************************************************************************
1227 _lsa_LookupNames2
1228 ***************************************************************************/
1230 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1231 struct lsa_LookupNames2 *r)
1233 NTSTATUS status;
1234 struct lsa_LookupNames q;
1235 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1236 struct lsa_TransSidArray *sid_array = NULL;
1237 uint32_t i;
1239 sid_array = talloc_zero(p->mem_ctx, struct lsa_TransSidArray);
1240 if (!sid_array) {
1241 return NT_STATUS_NO_MEMORY;
1244 q.in.handle = r->in.handle;
1245 q.in.num_names = r->in.num_names;
1246 q.in.names = r->in.names;
1247 q.in.level = r->in.level;
1248 q.in.sids = sid_array;
1249 q.in.count = r->in.count;
1250 /* we do not know what this is for */
1251 /* = r->in.unknown1; */
1252 /* = r->in.unknown2; */
1254 q.out.domains = r->out.domains;
1255 q.out.sids = sid_array;
1256 q.out.count = r->out.count;
1258 status = _lsa_LookupNames(p, &q);
1260 sid_array2->count = sid_array->count;
1261 sid_array2->sids = talloc_array(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1262 if (!sid_array2->sids) {
1263 return NT_STATUS_NO_MEMORY;
1266 for (i=0; i<sid_array->count; i++) {
1267 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1268 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1269 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1270 sid_array2->sids[i].unknown = 0;
1273 r->out.sids = sid_array2;
1275 return status;
1278 /***************************************************************************
1279 _lsa_LookupNames3
1280 ***************************************************************************/
1282 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1283 struct lsa_LookupNames3 *r)
1285 NTSTATUS status;
1286 struct lsa_info *handle;
1287 struct lsa_String *names = r->in.names;
1288 uint32 num_entries = r->in.num_names;
1289 struct lsa_RefDomainList *domains = NULL;
1290 struct lsa_TranslatedSid3 *trans_sids = NULL;
1291 uint32 mapped_count = 0;
1292 int flags = 0;
1293 bool check_policy = true;
1295 switch (p->opnum) {
1296 case NDR_LSA_LOOKUPNAMES4:
1297 check_policy = false;
1298 break;
1299 case NDR_LSA_LOOKUPNAMES3:
1300 default:
1301 check_policy = true;
1304 if (num_entries > MAX_LOOKUP_SIDS) {
1305 num_entries = MAX_LOOKUP_SIDS;
1306 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1309 /* Probably the lookup_level is some sort of bitmask. */
1310 if (r->in.level == 1) {
1311 flags = LOOKUP_NAME_ALL;
1314 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1315 if (!domains) {
1316 return NT_STATUS_NO_MEMORY;
1319 if (num_entries) {
1320 trans_sids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid3,
1321 num_entries);
1322 if (!trans_sids) {
1323 return NT_STATUS_NO_MEMORY;
1325 } else {
1326 trans_sids = NULL;
1329 if (check_policy) {
1331 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1332 status = NT_STATUS_INVALID_HANDLE;
1333 goto done;
1336 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1337 return NT_STATUS_INVALID_HANDLE;
1340 /* check if the user has enough rights */
1341 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1342 status = NT_STATUS_ACCESS_DENIED;
1343 goto done;
1347 /* set up the LSA Lookup SIDs response */
1348 become_root(); /* lookup_name can require root privs */
1349 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1350 names, flags, &mapped_count);
1351 unbecome_root();
1353 done:
1355 if (NT_STATUS_IS_OK(status)) {
1356 if (mapped_count == 0) {
1357 status = NT_STATUS_NONE_MAPPED;
1358 } else if (mapped_count != num_entries) {
1359 status = STATUS_SOME_UNMAPPED;
1363 *r->out.count = mapped_count;
1364 *r->out.domains = domains;
1365 r->out.sids->sids = trans_sids;
1366 r->out.sids->count = num_entries;
1368 return status;
1371 /***************************************************************************
1372 _lsa_LookupNames4
1373 ***************************************************************************/
1375 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1376 struct lsa_LookupNames4 *r)
1378 struct lsa_LookupNames3 q;
1380 /* No policy handle on this call. Restrict to crypto connections. */
1381 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1382 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1383 get_remote_machine_name() ));
1384 return NT_STATUS_INVALID_PARAMETER;
1387 q.in.handle = NULL;
1388 q.in.num_names = r->in.num_names;
1389 q.in.names = r->in.names;
1390 q.in.level = r->in.level;
1391 q.in.lookup_options = r->in.lookup_options;
1392 q.in.client_revision = r->in.client_revision;
1393 q.in.sids = r->in.sids;
1394 q.in.count = r->in.count;
1396 q.out.domains = r->out.domains;
1397 q.out.sids = r->out.sids;
1398 q.out.count = r->out.count;
1400 return _lsa_LookupNames3(p, &q);
1403 /***************************************************************************
1404 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1405 ***************************************************************************/
1407 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1409 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1410 return NT_STATUS_INVALID_HANDLE;
1413 close_policy_hnd(p, r->in.handle);
1414 ZERO_STRUCTP(r->out.handle);
1415 return NT_STATUS_OK;
1418 /***************************************************************************
1419 ***************************************************************************/
1421 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1422 const struct dom_sid *sid,
1423 struct trustdom_info **info)
1425 NTSTATUS status;
1426 uint32_t num_domains = 0;
1427 struct trustdom_info **domains = NULL;
1428 int i;
1430 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1431 if (!NT_STATUS_IS_OK(status)) {
1432 return status;
1435 for (i=0; i < num_domains; i++) {
1436 if (dom_sid_equal(&domains[i]->sid, sid)) {
1437 break;
1441 if (i == num_domains) {
1442 return NT_STATUS_INVALID_PARAMETER;
1445 *info = domains[i];
1447 return NT_STATUS_OK;
1450 /***************************************************************************
1451 ***************************************************************************/
1453 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1454 const char *netbios_domain_name,
1455 struct trustdom_info **info_p)
1457 NTSTATUS status;
1458 struct trustdom_info *info;
1459 struct pdb_trusted_domain *td;
1461 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1462 if (!NT_STATUS_IS_OK(status)) {
1463 return status;
1466 info = talloc(mem_ctx, struct trustdom_info);
1467 if (!info) {
1468 return NT_STATUS_NO_MEMORY;
1471 info->name = talloc_strdup(info, netbios_domain_name);
1472 NT_STATUS_HAVE_NO_MEMORY(info->name);
1474 sid_copy(&info->sid, &td->security_identifier);
1476 *info_p = info;
1478 return NT_STATUS_OK;
1481 /***************************************************************************
1482 _lsa_OpenSecret
1483 ***************************************************************************/
1485 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p,
1486 struct lsa_OpenSecret *r)
1488 struct lsa_info *handle;
1489 struct security_descriptor *psd;
1490 NTSTATUS status;
1491 uint32_t acc_granted;
1493 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1494 return NT_STATUS_INVALID_HANDLE;
1497 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1498 return NT_STATUS_INVALID_HANDLE;
1501 if (!r->in.name.string) {
1502 return NT_STATUS_INVALID_PARAMETER;
1505 /* Work out max allowed. */
1506 map_max_allowed_access(p->session_info->security_token,
1507 p->session_info->unix_token,
1508 &r->in.access_mask);
1510 /* map the generic bits to the lsa policy ones */
1511 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
1513 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
1514 NULL,
1515 NULL,
1516 NULL,
1517 NULL,
1518 &psd);
1519 if (!NT_STATUS_IS_OK(status)) {
1520 return status;
1523 status = access_check_object(psd, p->session_info->security_token,
1524 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1525 r->in.access_mask,
1526 &acc_granted, "_lsa_OpenSecret");
1527 if (!NT_STATUS_IS_OK(status)) {
1528 return status;
1531 status = create_lsa_policy_handle(p->mem_ctx, p,
1532 LSA_HANDLE_SECRET_TYPE,
1533 acc_granted,
1534 NULL,
1535 r->in.name.string,
1536 psd,
1537 r->out.sec_handle);
1538 if (!NT_STATUS_IS_OK(status)) {
1539 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1542 return NT_STATUS_OK;
1545 /***************************************************************************
1546 _lsa_OpenTrustedDomain_base
1547 ***************************************************************************/
1549 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1550 uint32_t access_mask,
1551 struct trustdom_info *info,
1552 struct policy_handle *handle)
1554 struct security_descriptor *psd = NULL;
1555 size_t sd_size;
1556 uint32_t acc_granted;
1557 NTSTATUS status;
1559 /* des_access is for the account here, not the policy
1560 * handle - so don't check against policy handle. */
1562 /* Work out max allowed. */
1563 map_max_allowed_access(p->session_info->security_token,
1564 p->session_info->unix_token,
1565 &access_mask);
1567 /* map the generic bits to the lsa account ones */
1568 se_map_generic(&access_mask, &lsa_account_mapping);
1570 /* get the generic lsa account SD until we store it */
1571 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1572 &lsa_trusted_domain_mapping,
1573 NULL, 0);
1574 if (!NT_STATUS_IS_OK(status)) {
1575 return status;
1578 status = access_check_object(psd, p->session_info->security_token,
1579 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1580 access_mask, &acc_granted,
1581 "_lsa_OpenTrustedDomain");
1582 if (!NT_STATUS_IS_OK(status)) {
1583 return status;
1586 status = create_lsa_policy_handle(p->mem_ctx, p,
1587 LSA_HANDLE_TRUST_TYPE,
1588 acc_granted,
1589 &info->sid,
1590 info->name,
1591 psd,
1592 handle);
1593 if (!NT_STATUS_IS_OK(status)) {
1594 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1597 return NT_STATUS_OK;
1600 /***************************************************************************
1601 _lsa_OpenTrustedDomain
1602 ***************************************************************************/
1604 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1605 struct lsa_OpenTrustedDomain *r)
1607 struct lsa_info *handle = NULL;
1608 struct trustdom_info *info = NULL;
1609 NTSTATUS status;
1611 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1612 return NT_STATUS_INVALID_HANDLE;
1615 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1616 return NT_STATUS_INVALID_HANDLE;
1619 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1620 r->in.sid,
1621 &info);
1622 if (!NT_STATUS_IS_OK(status)) {
1623 return status;
1626 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1627 r->out.trustdom_handle);
1630 /***************************************************************************
1631 _lsa_OpenTrustedDomainByName
1632 ***************************************************************************/
1634 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1635 struct lsa_OpenTrustedDomainByName *r)
1637 struct lsa_info *handle = NULL;
1638 struct trustdom_info *info = NULL;
1639 NTSTATUS status;
1641 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1642 return NT_STATUS_INVALID_HANDLE;
1645 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1646 return NT_STATUS_INVALID_HANDLE;
1649 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1650 r->in.name.string,
1651 &info);
1652 if (!NT_STATUS_IS_OK(status)) {
1653 return status;
1656 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1657 r->out.trustdom_handle);
1660 static NTSTATUS add_trusted_domain_user(TALLOC_CTX *mem_ctx,
1661 const char *netbios_name,
1662 const char *domain_name,
1663 const struct trustDomainPasswords *auth_struct)
1665 NTSTATUS status;
1666 struct samu *sam_acct;
1667 char *acct_name;
1668 uint32_t rid;
1669 struct dom_sid user_sid;
1670 int i;
1671 char *dummy;
1672 size_t dummy_size;
1674 sam_acct = samu_new(mem_ctx);
1675 if (sam_acct == NULL) {
1676 return NT_STATUS_NO_MEMORY;
1679 acct_name = talloc_asprintf(mem_ctx, "%s$", netbios_name);
1680 if (acct_name == NULL) {
1681 return NT_STATUS_NO_MEMORY;
1683 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1684 return NT_STATUS_UNSUCCESSFUL;
1687 if (!pdb_set_domain(sam_acct, domain_name, PDB_SET)) {
1688 return NT_STATUS_UNSUCCESSFUL;
1691 if (!pdb_set_acct_ctrl(sam_acct, ACB_DOMTRUST, PDB_SET)) {
1692 return NT_STATUS_UNSUCCESSFUL;
1695 if (!pdb_new_rid(&rid)) {
1696 return NT_STATUS_DS_NO_MORE_RIDS;
1698 sid_compose(&user_sid, get_global_sam_sid(), rid);
1699 if (!pdb_set_user_sid(sam_acct, &user_sid, PDB_SET)) {
1700 return NT_STATUS_UNSUCCESSFUL;
1703 for (i = 0; i < auth_struct->incoming.count; i++) {
1704 switch (auth_struct->incoming.current.array[i].AuthType) {
1705 case TRUST_AUTH_TYPE_CLEAR:
1706 if (!convert_string_talloc(mem_ctx,
1707 CH_UTF16LE,
1708 CH_UNIX,
1709 auth_struct->incoming.current.array[i].AuthInfo.clear.password,
1710 auth_struct->incoming.current.array[i].AuthInfo.clear.size,
1711 &dummy,
1712 &dummy_size)) {
1713 return NT_STATUS_UNSUCCESSFUL;
1715 if (!pdb_set_plaintext_passwd(sam_acct, dummy)) {
1716 return NT_STATUS_UNSUCCESSFUL;
1718 break;
1719 default:
1720 continue;
1724 status = pdb_add_sam_account(sam_acct);
1725 if (!NT_STATUS_IS_OK(status)) {
1726 return status;
1729 return NT_STATUS_OK;
1732 /***************************************************************************
1733 _lsa_CreateTrustedDomainEx2
1734 ***************************************************************************/
1736 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1737 struct lsa_CreateTrustedDomainEx2 *r)
1739 struct lsa_info *policy;
1740 NTSTATUS status;
1741 uint32_t acc_granted;
1742 struct security_descriptor *psd;
1743 size_t sd_size;
1744 struct pdb_trusted_domain td;
1745 struct trustDomainPasswords auth_struct;
1746 enum ndr_err_code ndr_err;
1747 DATA_BLOB auth_blob;
1749 if (!IS_DC) {
1750 return NT_STATUS_NOT_SUPPORTED;
1753 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1754 return NT_STATUS_INVALID_HANDLE;
1757 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1758 return NT_STATUS_ACCESS_DENIED;
1761 if (p->session_info->unix_token->uid != sec_initial_uid() &&
1762 !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1763 return NT_STATUS_ACCESS_DENIED;
1766 /* Work out max allowed. */
1767 map_max_allowed_access(p->session_info->security_token,
1768 p->session_info->unix_token,
1769 &r->in.access_mask);
1771 /* map the generic bits to the lsa policy ones */
1772 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1774 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1775 &lsa_trusted_domain_mapping,
1776 NULL, 0);
1777 if (!NT_STATUS_IS_OK(status)) {
1778 return status;
1781 status = access_check_object(psd, p->session_info->security_token,
1782 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1783 r->in.access_mask, &acc_granted,
1784 "_lsa_CreateTrustedDomainEx2");
1785 if (!NT_STATUS_IS_OK(status)) {
1786 return status;
1789 ZERO_STRUCT(td);
1791 td.domain_name = talloc_strdup(p->mem_ctx,
1792 r->in.info->domain_name.string);
1793 if (td.domain_name == NULL) {
1794 return NT_STATUS_NO_MEMORY;
1796 td.netbios_name = talloc_strdup(p->mem_ctx,
1797 r->in.info->netbios_name.string);
1798 if (td.netbios_name == NULL) {
1799 return NT_STATUS_NO_MEMORY;
1801 sid_copy(&td.security_identifier, r->in.info->sid);
1802 td.trust_direction = r->in.info->trust_direction;
1803 td.trust_type = r->in.info->trust_type;
1804 td.trust_attributes = r->in.info->trust_attributes;
1806 if (r->in.auth_info_internal->auth_blob.size != 0) {
1807 auth_blob.length = r->in.auth_info_internal->auth_blob.size;
1808 auth_blob.data = r->in.auth_info_internal->auth_blob.data;
1810 arcfour_crypt_blob(auth_blob.data, auth_blob.length,
1811 &p->session_info->session_key);
1813 ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
1814 &auth_struct,
1815 (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
1816 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1817 return NT_STATUS_UNSUCCESSFUL;
1820 ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
1821 &auth_struct.incoming,
1822 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1823 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1824 return NT_STATUS_UNSUCCESSFUL;
1827 ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
1828 &auth_struct.outgoing,
1829 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1830 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1831 return NT_STATUS_UNSUCCESSFUL;
1833 } else {
1834 td.trust_auth_incoming.data = NULL;
1835 td.trust_auth_incoming.length = 0;
1836 td.trust_auth_outgoing.data = NULL;
1837 td.trust_auth_outgoing.length = 0;
1840 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1841 if (!NT_STATUS_IS_OK(status)) {
1842 return status;
1845 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1846 status = add_trusted_domain_user(p->mem_ctx,
1847 r->in.info->netbios_name.string,
1848 r->in.info->domain_name.string,
1849 &auth_struct);
1850 if (!NT_STATUS_IS_OK(status)) {
1851 return status;
1855 status = create_lsa_policy_handle(p->mem_ctx, p,
1856 LSA_HANDLE_TRUST_TYPE,
1857 acc_granted,
1858 r->in.info->sid,
1859 r->in.info->netbios_name.string,
1860 psd,
1861 r->out.trustdom_handle);
1862 if (!NT_STATUS_IS_OK(status)) {
1863 pdb_del_trusteddom_pw(r->in.info->netbios_name.string);
1864 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1867 return NT_STATUS_OK;
1870 /***************************************************************************
1871 _lsa_CreateTrustedDomainEx
1872 ***************************************************************************/
1874 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1875 struct lsa_CreateTrustedDomainEx *r)
1877 struct lsa_CreateTrustedDomainEx2 q;
1878 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1880 ZERO_STRUCT(auth_info);
1882 q.in.policy_handle = r->in.policy_handle;
1883 q.in.info = r->in.info;
1884 q.in.auth_info_internal = &auth_info;
1885 q.in.access_mask = r->in.access_mask;
1886 q.out.trustdom_handle = r->out.trustdom_handle;
1888 return _lsa_CreateTrustedDomainEx2(p, &q);
1891 /***************************************************************************
1892 _lsa_CreateTrustedDomain
1893 ***************************************************************************/
1895 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1896 struct lsa_CreateTrustedDomain *r)
1898 struct lsa_CreateTrustedDomainEx2 c;
1899 struct lsa_TrustDomainInfoInfoEx info;
1900 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1902 ZERO_STRUCT(auth_info);
1904 info.domain_name = r->in.info->name;
1905 info.netbios_name = r->in.info->name;
1906 info.sid = r->in.info->sid;
1907 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1908 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1909 info.trust_attributes = 0;
1911 c.in.policy_handle = r->in.policy_handle;
1912 c.in.info = &info;
1913 c.in.auth_info_internal = &auth_info;
1914 c.in.access_mask = r->in.access_mask;
1915 c.out.trustdom_handle = r->out.trustdom_handle;
1917 return _lsa_CreateTrustedDomainEx2(p, &c);
1920 /***************************************************************************
1921 _lsa_DeleteTrustedDomain
1922 ***************************************************************************/
1924 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1925 struct lsa_DeleteTrustedDomain *r)
1927 NTSTATUS status;
1928 struct lsa_info *handle;
1929 struct pdb_trusted_domain *td;
1930 struct samu *sam_acct;
1931 char *acct_name;
1933 /* find the connection policy handle. */
1934 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1935 return NT_STATUS_INVALID_HANDLE;
1938 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1939 return NT_STATUS_INVALID_HANDLE;
1942 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1943 return NT_STATUS_ACCESS_DENIED;
1946 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1947 if (!NT_STATUS_IS_OK(status)) {
1948 return status;
1951 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1952 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1953 sid_string_tos(r->in.dom_sid)));
1954 return NT_STATUS_UNSUCCESSFUL;
1957 if (td->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1958 sam_acct = samu_new(p->mem_ctx);
1959 if (sam_acct == NULL) {
1960 return NT_STATUS_NO_MEMORY;
1963 acct_name = talloc_asprintf(p->mem_ctx, "%s$", td->netbios_name);
1964 if (acct_name == NULL) {
1965 return NT_STATUS_NO_MEMORY;
1967 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1968 return NT_STATUS_UNSUCCESSFUL;
1970 status = pdb_delete_sam_account(sam_acct);
1971 if (!NT_STATUS_IS_OK(status)) {
1972 return status;
1976 status = pdb_del_trusted_domain(td->netbios_name);
1977 if (!NT_STATUS_IS_OK(status)) {
1978 return status;
1981 return NT_STATUS_OK;
1984 /***************************************************************************
1985 _lsa_CloseTrustedDomainEx
1986 ***************************************************************************/
1988 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1989 struct lsa_CloseTrustedDomainEx *r)
1991 return NT_STATUS_NOT_IMPLEMENTED;
1994 /***************************************************************************
1995 _lsa_QueryTrustedDomainInfo
1996 ***************************************************************************/
1998 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
1999 struct lsa_QueryTrustedDomainInfo *r)
2001 NTSTATUS status;
2002 struct lsa_info *handle;
2003 union lsa_TrustedDomainInfo *info;
2004 struct pdb_trusted_domain *td;
2005 uint32_t acc_required;
2007 /* find the connection policy handle. */
2008 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
2009 return NT_STATUS_INVALID_HANDLE;
2012 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
2013 return NT_STATUS_INVALID_HANDLE;
2016 switch (r->in.level) {
2017 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2018 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2019 break;
2020 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2021 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
2022 break;
2023 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2024 acc_required = LSA_TRUSTED_QUERY_POSIX;
2025 break;
2026 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2027 acc_required = LSA_TRUSTED_QUERY_AUTH;
2028 break;
2029 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2030 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2031 break;
2032 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2033 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2034 break;
2035 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2036 acc_required = LSA_TRUSTED_QUERY_AUTH;
2037 break;
2038 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2039 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2040 LSA_TRUSTED_QUERY_POSIX |
2041 LSA_TRUSTED_QUERY_AUTH;
2042 break;
2043 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2044 acc_required = LSA_TRUSTED_QUERY_AUTH;
2045 break;
2046 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2047 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2048 LSA_TRUSTED_QUERY_POSIX |
2049 LSA_TRUSTED_QUERY_AUTH;
2050 break;
2051 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2052 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2053 break;
2054 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2055 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2056 LSA_TRUSTED_QUERY_POSIX |
2057 LSA_TRUSTED_QUERY_AUTH;
2058 break;
2059 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2060 acc_required = LSA_TRUSTED_QUERY_POSIX;
2061 break;
2062 default:
2063 return NT_STATUS_INVALID_PARAMETER;
2066 if (!(handle->access & acc_required)) {
2067 return NT_STATUS_ACCESS_DENIED;
2070 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2071 if (!NT_STATUS_IS_OK(status)) {
2072 return status;
2075 info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
2076 if (!info) {
2077 return NT_STATUS_NO_MEMORY;
2080 switch (r->in.level) {
2081 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2082 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2083 break;
2084 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2085 return NT_STATUS_INVALID_PARAMETER;
2086 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2087 break;
2088 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2089 return NT_STATUS_INVALID_INFO_CLASS;
2090 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2091 return NT_STATUS_INVALID_PARAMETER;
2092 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2093 init_lsa_StringLarge(&info->info_ex.domain_name, td->domain_name);
2094 init_lsa_StringLarge(&info->info_ex.netbios_name, td->netbios_name);
2095 info->info_ex.sid = dom_sid_dup(info, &td->security_identifier);
2096 if (!info->info_ex.sid) {
2097 return NT_STATUS_NO_MEMORY;
2099 info->info_ex.trust_direction = td->trust_direction;
2100 info->info_ex.trust_type = td->trust_type;
2101 info->info_ex.trust_attributes = td->trust_attributes;
2102 break;
2103 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2104 return NT_STATUS_INVALID_INFO_CLASS;
2105 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2106 break;
2107 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2108 return NT_STATUS_INVALID_INFO_CLASS;
2109 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2110 return NT_STATUS_INVALID_INFO_CLASS;
2111 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2112 return NT_STATUS_INVALID_PARAMETER;
2113 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2114 break;
2115 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2116 break;
2117 default:
2118 return NT_STATUS_INVALID_PARAMETER;
2121 *r->out.info = info;
2123 return NT_STATUS_OK;
2126 /***************************************************************************
2127 _lsa_QueryTrustedDomainInfoBySid
2128 ***************************************************************************/
2130 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2131 struct lsa_QueryTrustedDomainInfoBySid *r)
2133 NTSTATUS status;
2134 struct policy_handle trustdom_handle;
2135 struct lsa_OpenTrustedDomain o;
2136 struct lsa_QueryTrustedDomainInfo q;
2137 struct lsa_Close c;
2139 o.in.handle = r->in.handle;
2140 o.in.sid = r->in.dom_sid;
2141 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2142 o.out.trustdom_handle = &trustdom_handle;
2144 status = _lsa_OpenTrustedDomain(p, &o);
2145 if (!NT_STATUS_IS_OK(status)) {
2146 return status;
2149 q.in.trustdom_handle = &trustdom_handle;
2150 q.in.level = r->in.level;
2151 q.out.info = r->out.info;
2153 status = _lsa_QueryTrustedDomainInfo(p, &q);
2154 if (!NT_STATUS_IS_OK(status)) {
2155 return status;
2158 c.in.handle = &trustdom_handle;
2159 c.out.handle = &trustdom_handle;
2161 return _lsa_Close(p, &c);
2164 /***************************************************************************
2165 _lsa_QueryTrustedDomainInfoByName
2166 ***************************************************************************/
2168 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2169 struct lsa_QueryTrustedDomainInfoByName *r)
2171 NTSTATUS status;
2172 struct policy_handle trustdom_handle;
2173 struct lsa_OpenTrustedDomainByName o;
2174 struct lsa_QueryTrustedDomainInfo q;
2175 struct lsa_Close c;
2177 o.in.handle = r->in.handle;
2178 o.in.name.string = r->in.trusted_domain->string;
2179 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2180 o.out.trustdom_handle = &trustdom_handle;
2182 status = _lsa_OpenTrustedDomainByName(p, &o);
2183 if (!NT_STATUS_IS_OK(status)) {
2184 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2185 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2187 return status;
2190 q.in.trustdom_handle = &trustdom_handle;
2191 q.in.level = r->in.level;
2192 q.out.info = r->out.info;
2194 status = _lsa_QueryTrustedDomainInfo(p, &q);
2195 if (!NT_STATUS_IS_OK(status)) {
2196 return status;
2199 c.in.handle = &trustdom_handle;
2200 c.out.handle = &trustdom_handle;
2202 return _lsa_Close(p, &c);
2205 /***************************************************************************
2206 _lsa_CreateSecret
2207 ***************************************************************************/
2209 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p,
2210 struct lsa_CreateSecret *r)
2212 NTSTATUS status;
2213 struct lsa_info *handle;
2214 uint32_t acc_granted;
2215 struct security_descriptor *psd;
2216 size_t sd_size;
2218 /* find the connection policy handle. */
2219 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
2220 return NT_STATUS_INVALID_HANDLE;
2223 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2224 return NT_STATUS_INVALID_HANDLE;
2227 /* check if the user has enough rights */
2229 if (!(handle->access & LSA_POLICY_CREATE_SECRET)) {
2230 return NT_STATUS_ACCESS_DENIED;
2233 /* Work out max allowed. */
2234 map_max_allowed_access(p->session_info->security_token,
2235 p->session_info->unix_token,
2236 &r->in.access_mask);
2238 /* map the generic bits to the lsa policy ones */
2239 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
2241 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2242 &lsa_secret_mapping,
2243 NULL, 0);
2244 if (!NT_STATUS_IS_OK(status)) {
2245 return status;
2248 status = access_check_object(psd, p->session_info->security_token,
2249 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2250 r->in.access_mask,
2251 &acc_granted, "_lsa_CreateSecret");
2252 if (!NT_STATUS_IS_OK(status)) {
2253 return status;
2256 if (!r->in.name.string) {
2257 return NT_STATUS_INVALID_PARAMETER;
2260 if (strlen(r->in.name.string) > 128) {
2261 return NT_STATUS_NAME_TOO_LONG;
2264 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
2265 NULL, NULL, NULL, NULL, NULL);
2266 if (NT_STATUS_IS_OK(status)) {
2267 return NT_STATUS_OBJECT_NAME_COLLISION;
2270 status = pdb_set_secret(r->in.name.string, NULL, NULL, psd);
2271 if (!NT_STATUS_IS_OK(status)) {
2272 return status;
2275 status = create_lsa_policy_handle(p->mem_ctx, p,
2276 LSA_HANDLE_SECRET_TYPE,
2277 acc_granted,
2278 NULL,
2279 r->in.name.string,
2280 psd,
2281 r->out.sec_handle);
2282 if (!NT_STATUS_IS_OK(status)) {
2283 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2286 return NT_STATUS_OK;
2289 /***************************************************************************
2290 ***************************************************************************/
2292 NTSTATUS _lsa_SetSecret(struct pipes_struct *p, struct lsa_SetSecret *r)
2294 return NT_STATUS_ACCESS_DENIED;
2297 /***************************************************************************
2298 _lsa_DeleteObject
2299 ***************************************************************************/
2301 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2302 struct lsa_DeleteObject *r)
2304 NTSTATUS status;
2305 struct lsa_info *info = NULL;
2307 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2308 return NT_STATUS_INVALID_HANDLE;
2311 if (!(info->access & SEC_STD_DELETE)) {
2312 return NT_STATUS_ACCESS_DENIED;
2315 switch (info->type) {
2316 case LSA_HANDLE_ACCOUNT_TYPE:
2317 status = privilege_delete_account(&info->sid);
2318 if (!NT_STATUS_IS_OK(status)) {
2319 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2320 nt_errstr(status)));
2321 return status;
2323 break;
2324 case LSA_HANDLE_TRUST_TYPE:
2325 if (!pdb_del_trusteddom_pw(info->name)) {
2326 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2328 status = NT_STATUS_OK;
2329 break;
2330 default:
2331 return NT_STATUS_INVALID_HANDLE;
2334 close_policy_hnd(p, r->in.handle);
2335 ZERO_STRUCTP(r->out.handle);
2337 return status;
2340 /***************************************************************************
2341 _lsa_EnumPrivs
2342 ***************************************************************************/
2344 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2345 struct lsa_EnumPrivs *r)
2347 struct lsa_info *handle;
2348 uint32 i;
2349 uint32 enum_context = *r->in.resume_handle;
2350 int num_privs = num_privileges_in_short_list();
2351 struct lsa_PrivEntry *entries = NULL;
2353 /* remember that the enum_context starts at 0 and not 1 */
2355 if ( enum_context >= num_privs )
2356 return NT_STATUS_NO_MORE_ENTRIES;
2358 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2359 enum_context, num_privs));
2361 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2362 return NT_STATUS_INVALID_HANDLE;
2364 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2365 return NT_STATUS_INVALID_HANDLE;
2368 /* check if the user has enough rights
2369 I don't know if it's the right one. not documented. */
2371 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2372 return NT_STATUS_ACCESS_DENIED;
2374 if (num_privs) {
2375 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2376 if (!entries) {
2377 return NT_STATUS_NO_MEMORY;
2379 } else {
2380 entries = NULL;
2383 for (i = 0; i < num_privs; i++) {
2384 if( i < enum_context) {
2386 init_lsa_StringLarge(&entries[i].name, NULL);
2388 entries[i].luid.low = 0;
2389 entries[i].luid.high = 0;
2390 } else {
2392 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2394 entries[i].luid.low = sec_privilege_from_index(i);
2395 entries[i].luid.high = 0;
2399 enum_context = num_privs;
2401 *r->out.resume_handle = enum_context;
2402 r->out.privs->count = num_privs;
2403 r->out.privs->privs = entries;
2405 return NT_STATUS_OK;
2408 /***************************************************************************
2409 _lsa_LookupPrivDisplayName
2410 ***************************************************************************/
2412 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2413 struct lsa_LookupPrivDisplayName *r)
2415 struct lsa_info *handle;
2416 const char *description;
2417 struct lsa_StringLarge *lsa_name;
2419 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2420 return NT_STATUS_INVALID_HANDLE;
2422 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2423 return NT_STATUS_INVALID_HANDLE;
2426 /* check if the user has enough rights */
2429 * I don't know if it's the right one. not documented.
2431 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2432 return NT_STATUS_ACCESS_DENIED;
2434 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2436 description = get_privilege_dispname(r->in.name->string);
2437 if (!description) {
2438 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2439 return NT_STATUS_NO_SUCH_PRIVILEGE;
2442 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2444 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2445 if (!lsa_name) {
2446 return NT_STATUS_NO_MEMORY;
2449 init_lsa_StringLarge(lsa_name, description);
2451 *r->out.returned_language_id = r->in.language_id;
2452 *r->out.disp_name = lsa_name;
2454 return NT_STATUS_OK;
2457 /***************************************************************************
2458 _lsa_EnumAccounts
2459 ***************************************************************************/
2461 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2462 struct lsa_EnumAccounts *r)
2464 struct lsa_info *handle;
2465 struct dom_sid *sid_list;
2466 int i, j, num_entries;
2467 NTSTATUS status;
2468 struct lsa_SidPtr *sids = NULL;
2470 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2471 return NT_STATUS_INVALID_HANDLE;
2473 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2474 return NT_STATUS_INVALID_HANDLE;
2477 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2478 return NT_STATUS_ACCESS_DENIED;
2480 sid_list = NULL;
2481 num_entries = 0;
2483 /* The only way we can currently find out all the SIDs that have been
2484 privileged is to scan all privileges */
2486 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2487 if (!NT_STATUS_IS_OK(status)) {
2488 return status;
2491 if (*r->in.resume_handle >= num_entries) {
2492 return NT_STATUS_NO_MORE_ENTRIES;
2495 if (num_entries - *r->in.resume_handle) {
2496 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2497 num_entries - *r->in.resume_handle);
2498 if (!sids) {
2499 talloc_free(sid_list);
2500 return NT_STATUS_NO_MEMORY;
2503 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2504 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2505 if (!sids[j].sid) {
2506 talloc_free(sid_list);
2507 return NT_STATUS_NO_MEMORY;
2512 talloc_free(sid_list);
2514 *r->out.resume_handle = num_entries;
2515 r->out.sids->num_sids = num_entries;
2516 r->out.sids->sids = sids;
2518 return NT_STATUS_OK;
2521 /***************************************************************************
2522 _lsa_GetUserName
2523 ***************************************************************************/
2525 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2526 struct lsa_GetUserName *r)
2528 const char *username, *domname;
2529 struct lsa_String *account_name = NULL;
2530 struct lsa_String *authority_name = NULL;
2532 if (r->in.account_name &&
2533 *r->in.account_name) {
2534 return NT_STATUS_INVALID_PARAMETER;
2537 if (r->in.authority_name &&
2538 *r->in.authority_name) {
2539 return NT_STATUS_INVALID_PARAMETER;
2542 if (security_session_user_level(p->session_info, NULL) < SECURITY_USER) {
2544 * I'm 99% sure this is not the right place to do this,
2545 * global_sid_Anonymous should probably be put into the token
2546 * instead of the guest id -- vl
2548 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2549 &domname, &username, NULL)) {
2550 return NT_STATUS_NO_MEMORY;
2552 } else {
2553 username = p->session_info->unix_info->sanitized_username;
2554 domname = p->session_info->info->domain_name;
2557 account_name = talloc(p->mem_ctx, struct lsa_String);
2558 if (!account_name) {
2559 return NT_STATUS_NO_MEMORY;
2561 init_lsa_String(account_name, username);
2563 if (r->out.authority_name) {
2564 authority_name = talloc(p->mem_ctx, struct lsa_String);
2565 if (!authority_name) {
2566 return NT_STATUS_NO_MEMORY;
2568 init_lsa_String(authority_name, domname);
2571 *r->out.account_name = account_name;
2572 if (r->out.authority_name) {
2573 *r->out.authority_name = authority_name;
2576 return NT_STATUS_OK;
2579 /***************************************************************************
2580 _lsa_CreateAccount
2581 ***************************************************************************/
2583 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2584 struct lsa_CreateAccount *r)
2586 NTSTATUS status;
2587 struct lsa_info *handle;
2588 uint32_t acc_granted;
2589 struct security_descriptor *psd;
2590 size_t sd_size;
2592 /* find the connection policy handle. */
2593 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2594 return NT_STATUS_INVALID_HANDLE;
2596 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2597 return NT_STATUS_INVALID_HANDLE;
2600 /* check if the user has enough rights */
2602 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2603 return NT_STATUS_ACCESS_DENIED;
2606 /* Work out max allowed. */
2607 map_max_allowed_access(p->session_info->security_token,
2608 p->session_info->unix_token,
2609 &r->in.access_mask);
2611 /* map the generic bits to the lsa policy ones */
2612 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2614 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2615 &lsa_account_mapping,
2616 r->in.sid, LSA_POLICY_ALL_ACCESS);
2617 if (!NT_STATUS_IS_OK(status)) {
2618 return status;
2621 status = access_check_object(psd, p->session_info->security_token,
2622 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2623 &acc_granted, "_lsa_CreateAccount");
2624 if (!NT_STATUS_IS_OK(status)) {
2625 return status;
2628 if ( is_privileged_sid( r->in.sid ) )
2629 return NT_STATUS_OBJECT_NAME_COLLISION;
2631 status = create_lsa_policy_handle(p->mem_ctx, p,
2632 LSA_HANDLE_ACCOUNT_TYPE,
2633 acc_granted,
2634 r->in.sid,
2635 NULL,
2636 psd,
2637 r->out.acct_handle);
2638 if (!NT_STATUS_IS_OK(status)) {
2639 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2642 return privilege_create_account(r->in.sid);
2645 /***************************************************************************
2646 _lsa_OpenAccount
2647 ***************************************************************************/
2649 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2650 struct lsa_OpenAccount *r)
2652 struct lsa_info *handle;
2653 struct security_descriptor *psd = NULL;
2654 size_t sd_size;
2655 uint32_t des_access = r->in.access_mask;
2656 uint32_t acc_granted;
2657 NTSTATUS status;
2659 /* find the connection policy handle. */
2660 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2661 return NT_STATUS_INVALID_HANDLE;
2663 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2664 return NT_STATUS_INVALID_HANDLE;
2667 /* des_access is for the account here, not the policy
2668 * handle - so don't check against policy handle. */
2670 /* Work out max allowed. */
2671 map_max_allowed_access(p->session_info->security_token,
2672 p->session_info->unix_token,
2673 &des_access);
2675 /* map the generic bits to the lsa account ones */
2676 se_map_generic(&des_access, &lsa_account_mapping);
2678 /* get the generic lsa account SD until we store it */
2679 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2680 &lsa_account_mapping,
2681 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2682 if (!NT_STATUS_IS_OK(status)) {
2683 return status;
2686 status = access_check_object(psd, p->session_info->security_token,
2687 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2688 &acc_granted, "_lsa_OpenAccount" );
2689 if (!NT_STATUS_IS_OK(status)) {
2690 return status;
2693 /* TODO: Fis the parsing routine before reenabling this check! */
2694 #if 0
2695 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2696 return NT_STATUS_ACCESS_DENIED;
2697 #endif
2699 status = create_lsa_policy_handle(p->mem_ctx, p,
2700 LSA_HANDLE_ACCOUNT_TYPE,
2701 acc_granted,
2702 r->in.sid,
2703 NULL,
2704 psd,
2705 r->out.acct_handle);
2706 if (!NT_STATUS_IS_OK(status)) {
2707 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2710 return NT_STATUS_OK;
2713 /***************************************************************************
2714 _lsa_EnumPrivsAccount
2715 For a given SID, enumerate all the privilege this account has.
2716 ***************************************************************************/
2718 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2719 struct lsa_EnumPrivsAccount *r)
2721 NTSTATUS status = NT_STATUS_OK;
2722 struct lsa_info *info=NULL;
2723 PRIVILEGE_SET *privileges;
2724 struct lsa_PrivilegeSet *priv_set = NULL;
2726 /* find the connection policy handle. */
2727 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2728 return NT_STATUS_INVALID_HANDLE;
2730 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2731 return NT_STATUS_INVALID_HANDLE;
2734 if (!(info->access & LSA_ACCOUNT_VIEW))
2735 return NT_STATUS_ACCESS_DENIED;
2737 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2738 if (!NT_STATUS_IS_OK(status)) {
2739 return status;
2742 *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2743 if (!priv_set) {
2744 return NT_STATUS_NO_MEMORY;
2747 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2748 sid_string_dbg(&info->sid),
2749 privileges->count));
2751 priv_set->count = privileges->count;
2752 priv_set->unknown = 0;
2753 priv_set->set = talloc_move(priv_set, &privileges->set);
2755 return status;
2758 /***************************************************************************
2759 _lsa_GetSystemAccessAccount
2760 ***************************************************************************/
2762 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2763 struct lsa_GetSystemAccessAccount *r)
2765 NTSTATUS status;
2766 struct lsa_info *info = NULL;
2767 struct lsa_EnumPrivsAccount e;
2768 struct lsa_PrivilegeSet *privset;
2770 /* find the connection policy handle. */
2772 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2773 return NT_STATUS_INVALID_HANDLE;
2775 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2776 return NT_STATUS_INVALID_HANDLE;
2779 if (!(info->access & LSA_ACCOUNT_VIEW))
2780 return NT_STATUS_ACCESS_DENIED;
2782 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2783 if (!privset) {
2784 return NT_STATUS_NO_MEMORY;
2787 e.in.handle = r->in.handle;
2788 e.out.privs = &privset;
2790 status = _lsa_EnumPrivsAccount(p, &e);
2791 if (!NT_STATUS_IS_OK(status)) {
2792 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2793 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2794 nt_errstr(status)));
2795 return status;
2798 /* Samba4 would iterate over the privset to merge the policy mode bits,
2799 * not sure samba3 can do the same here, so just return what we did in
2800 * the past - gd */
2803 0x01 -> Log on locally
2804 0x02 -> Access this computer from network
2805 0x04 -> Log on as a batch job
2806 0x10 -> Log on as a service
2808 they can be ORed together
2811 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2812 LSA_POLICY_MODE_NETWORK;
2814 return NT_STATUS_OK;
2817 /***************************************************************************
2818 update the systemaccount information
2819 ***************************************************************************/
2821 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2822 struct lsa_SetSystemAccessAccount *r)
2824 struct lsa_info *info=NULL;
2825 GROUP_MAP map;
2827 /* find the connection policy handle. */
2828 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2829 return NT_STATUS_INVALID_HANDLE;
2831 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2832 return NT_STATUS_INVALID_HANDLE;
2835 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2836 return NT_STATUS_ACCESS_DENIED;
2839 if (!pdb_getgrsid(&map, info->sid))
2840 return NT_STATUS_NO_SUCH_GROUP;
2842 return pdb_update_group_mapping_entry(&map);
2845 /***************************************************************************
2846 _lsa_AddPrivilegesToAccount
2847 For a given SID, add some privileges.
2848 ***************************************************************************/
2850 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
2851 struct lsa_AddPrivilegesToAccount *r)
2853 struct lsa_info *info = NULL;
2854 struct lsa_PrivilegeSet *set = NULL;
2856 /* find the connection policy handle. */
2857 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2858 return NT_STATUS_INVALID_HANDLE;
2860 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2861 return NT_STATUS_INVALID_HANDLE;
2864 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2865 return NT_STATUS_ACCESS_DENIED;
2868 set = r->in.privs;
2870 if ( !grant_privilege_set( &info->sid, set ) ) {
2871 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2872 sid_string_dbg(&info->sid) ));
2873 return NT_STATUS_NO_SUCH_PRIVILEGE;
2876 return NT_STATUS_OK;
2879 /***************************************************************************
2880 _lsa_RemovePrivilegesFromAccount
2881 For a given SID, remove some privileges.
2882 ***************************************************************************/
2884 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2885 struct lsa_RemovePrivilegesFromAccount *r)
2887 struct lsa_info *info = NULL;
2888 struct lsa_PrivilegeSet *set = NULL;
2890 /* find the connection policy handle. */
2891 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2892 return NT_STATUS_INVALID_HANDLE;
2894 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2895 return NT_STATUS_INVALID_HANDLE;
2898 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2899 return NT_STATUS_ACCESS_DENIED;
2902 set = r->in.privs;
2904 if ( !revoke_privilege_set( &info->sid, set) ) {
2905 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2906 sid_string_dbg(&info->sid) ));
2907 return NT_STATUS_NO_SUCH_PRIVILEGE;
2910 return NT_STATUS_OK;
2913 /***************************************************************************
2914 _lsa_LookupPrivName
2915 ***************************************************************************/
2917 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2918 struct lsa_LookupPrivName *r)
2920 struct lsa_info *info = NULL;
2921 const char *name;
2922 struct lsa_StringLarge *lsa_name;
2924 /* find the connection policy handle. */
2925 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2926 return NT_STATUS_INVALID_HANDLE;
2929 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2930 return NT_STATUS_INVALID_HANDLE;
2933 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2934 return NT_STATUS_ACCESS_DENIED;
2937 if (r->in.luid->high != 0) {
2938 return NT_STATUS_NO_SUCH_PRIVILEGE;
2941 name = sec_privilege_name(r->in.luid->low);
2942 if (!name) {
2943 return NT_STATUS_NO_SUCH_PRIVILEGE;
2946 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2947 if (!lsa_name) {
2948 return NT_STATUS_NO_MEMORY;
2951 lsa_name->string = talloc_strdup(lsa_name, name);
2952 if (!lsa_name->string) {
2953 TALLOC_FREE(lsa_name);
2954 return NT_STATUS_NO_MEMORY;
2957 *r->out.name = lsa_name;
2959 return NT_STATUS_OK;
2962 /***************************************************************************
2963 _lsa_QuerySecurity
2964 ***************************************************************************/
2966 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
2967 struct lsa_QuerySecurity *r)
2969 struct lsa_info *handle=NULL;
2970 struct security_descriptor *psd = NULL;
2971 size_t sd_size = 0;
2972 NTSTATUS status;
2974 /* find the connection policy handle. */
2975 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2976 return NT_STATUS_INVALID_HANDLE;
2978 switch (handle->type) {
2979 case LSA_HANDLE_POLICY_TYPE:
2980 case LSA_HANDLE_ACCOUNT_TYPE:
2981 case LSA_HANDLE_TRUST_TYPE:
2982 psd = handle->sd;
2983 sd_size = ndr_size_security_descriptor(psd, 0);
2984 status = NT_STATUS_OK;
2985 break;
2986 default:
2987 status = NT_STATUS_INVALID_HANDLE;
2988 break;
2991 if (!NT_STATUS_IS_OK(status)) {
2992 return status;
2995 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2996 if (!*r->out.sdbuf) {
2997 return NT_STATUS_NO_MEMORY;
3000 return status;
3003 /***************************************************************************
3004 _lsa_AddAccountRights
3005 ***************************************************************************/
3007 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
3008 struct lsa_AddAccountRights *r)
3010 struct lsa_info *info = NULL;
3011 int i = 0;
3012 uint32_t acc_granted = 0;
3013 struct security_descriptor *psd = NULL;
3014 size_t sd_size;
3015 struct dom_sid sid;
3016 NTSTATUS status;
3018 /* find the connection policy handle. */
3019 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3020 return NT_STATUS_INVALID_HANDLE;
3022 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3023 return NT_STATUS_INVALID_HANDLE;
3026 /* get the generic lsa account SD for this SID until we store it */
3027 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3028 &lsa_account_mapping,
3029 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
3030 if (!NT_STATUS_IS_OK(status)) {
3031 return status;
3035 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3036 * on the policy handle. If it does, ask for
3037 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3038 * on the account sid. We don't check here so just use the latter. JRA.
3041 status = access_check_object(psd, p->session_info->security_token,
3042 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3043 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3044 &acc_granted, "_lsa_AddAccountRights" );
3045 if (!NT_STATUS_IS_OK(status)) {
3046 return status;
3049 /* according to an NT4 PDC, you can add privileges to SIDs even without
3050 call_lsa_create_account() first. And you can use any arbitrary SID. */
3052 sid_copy( &sid, r->in.sid );
3054 for ( i=0; i < r->in.rights->count; i++ ) {
3056 const char *privname = r->in.rights->names[i].string;
3058 /* only try to add non-null strings */
3060 if ( !privname )
3061 continue;
3063 if ( !grant_privilege_by_name( &sid, privname ) ) {
3064 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3065 privname ));
3066 return NT_STATUS_NO_SUCH_PRIVILEGE;
3070 return NT_STATUS_OK;
3073 /***************************************************************************
3074 _lsa_RemoveAccountRights
3075 ***************************************************************************/
3077 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
3078 struct lsa_RemoveAccountRights *r)
3080 struct lsa_info *info = NULL;
3081 int i = 0;
3082 struct security_descriptor *psd = NULL;
3083 size_t sd_size;
3084 struct dom_sid sid;
3085 const char *privname = NULL;
3086 uint32_t acc_granted = 0;
3087 NTSTATUS status;
3089 /* find the connection policy handle. */
3090 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3091 return NT_STATUS_INVALID_HANDLE;
3093 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3094 return NT_STATUS_INVALID_HANDLE;
3097 /* get the generic lsa account SD for this SID until we store it */
3098 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3099 &lsa_account_mapping,
3100 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
3101 if (!NT_STATUS_IS_OK(status)) {
3102 return status;
3106 * From the MS DOCs. We need
3107 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3108 * and DELETE on the account sid.
3111 status = access_check_object(psd, p->session_info->security_token,
3112 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3113 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3114 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
3115 &acc_granted, "_lsa_RemoveAccountRights");
3116 if (!NT_STATUS_IS_OK(status)) {
3117 return status;
3120 sid_copy( &sid, r->in.sid );
3122 if ( r->in.remove_all ) {
3123 if ( !revoke_all_privileges( &sid ) )
3124 return NT_STATUS_ACCESS_DENIED;
3126 return NT_STATUS_OK;
3129 for ( i=0; i < r->in.rights->count; i++ ) {
3131 privname = r->in.rights->names[i].string;
3133 /* only try to add non-null strings */
3135 if ( !privname )
3136 continue;
3138 if ( !revoke_privilege_by_name( &sid, privname ) ) {
3139 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3140 privname ));
3141 return NT_STATUS_NO_SUCH_PRIVILEGE;
3145 return NT_STATUS_OK;
3148 /*******************************************************************
3149 ********************************************************************/
3151 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3152 struct lsa_RightSet *r,
3153 PRIVILEGE_SET *privileges)
3155 uint32 i;
3156 const char *privname;
3157 const char **privname_array = NULL;
3158 int num_priv = 0;
3160 for (i=0; i<privileges->count; i++) {
3161 if (privileges->set[i].luid.high) {
3162 continue;
3164 privname = sec_privilege_name(privileges->set[i].luid.low);
3165 if (privname) {
3166 if (!add_string_to_array(mem_ctx, privname,
3167 &privname_array, &num_priv)) {
3168 return NT_STATUS_NO_MEMORY;
3173 if (num_priv) {
3175 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3176 num_priv);
3177 if (!r->names) {
3178 return NT_STATUS_NO_MEMORY;
3181 for (i=0; i<num_priv; i++) {
3182 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3185 r->count = num_priv;
3188 return NT_STATUS_OK;
3191 /***************************************************************************
3192 _lsa_EnumAccountRights
3193 ***************************************************************************/
3195 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3196 struct lsa_EnumAccountRights *r)
3198 NTSTATUS status;
3199 struct lsa_info *info = NULL;
3200 PRIVILEGE_SET *privileges;
3202 /* find the connection policy handle. */
3204 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3205 return NT_STATUS_INVALID_HANDLE;
3207 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3208 return NT_STATUS_INVALID_HANDLE;
3211 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3212 return NT_STATUS_ACCESS_DENIED;
3215 /* according to an NT4 PDC, you can add privileges to SIDs even without
3216 call_lsa_create_account() first. And you can use any arbitrary SID. */
3218 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3219 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3220 * the lsa database */
3222 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3223 if (!NT_STATUS_IS_OK(status)) {
3224 return status;
3227 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3228 sid_string_dbg(r->in.sid), privileges->count));
3230 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3232 return status;
3235 /***************************************************************************
3236 _lsa_LookupPrivValue
3237 ***************************************************************************/
3239 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3240 struct lsa_LookupPrivValue *r)
3242 struct lsa_info *info = NULL;
3243 const char *name = NULL;
3245 /* find the connection policy handle. */
3247 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3248 return NT_STATUS_INVALID_HANDLE;
3250 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3251 return NT_STATUS_INVALID_HANDLE;
3254 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3255 return NT_STATUS_ACCESS_DENIED;
3257 name = r->in.name->string;
3259 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3261 r->out.luid->low = sec_privilege_id(name);
3262 r->out.luid->high = 0;
3263 if (r->out.luid->low == SEC_PRIV_INVALID) {
3264 return NT_STATUS_NO_SUCH_PRIVILEGE;
3266 return NT_STATUS_OK;
3269 /***************************************************************************
3270 _lsa_EnumAccountsWithUserRight
3271 ***************************************************************************/
3273 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3274 struct lsa_EnumAccountsWithUserRight *r)
3276 NTSTATUS status;
3277 struct lsa_info *info = NULL;
3278 struct dom_sid *sids = NULL;
3279 int num_sids = 0;
3280 uint32_t i;
3281 enum sec_privilege privilege;
3283 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3284 return NT_STATUS_INVALID_HANDLE;
3287 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3288 return NT_STATUS_INVALID_HANDLE;
3291 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3292 return NT_STATUS_ACCESS_DENIED;
3295 if (!r->in.name || !r->in.name->string) {
3296 return NT_STATUS_NO_SUCH_PRIVILEGE;
3299 privilege = sec_privilege_id(r->in.name->string);
3300 if (privilege == SEC_PRIV_INVALID) {
3301 return NT_STATUS_NO_SUCH_PRIVILEGE;
3304 status = privilege_enum_sids(privilege, p->mem_ctx,
3305 &sids, &num_sids);
3306 if (!NT_STATUS_IS_OK(status)) {
3307 return status;
3310 r->out.sids->num_sids = num_sids;
3311 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3312 r->out.sids->num_sids);
3314 for (i=0; i < r->out.sids->num_sids; i++) {
3315 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3316 &sids[i]);
3317 if (!r->out.sids->sids[i].sid) {
3318 TALLOC_FREE(r->out.sids->sids);
3319 r->out.sids->num_sids = 0;
3320 return NT_STATUS_NO_MEMORY;
3324 return NT_STATUS_OK;
3327 /***************************************************************************
3328 _lsa_Delete
3329 ***************************************************************************/
3331 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3332 struct lsa_Delete *r)
3334 return NT_STATUS_NOT_SUPPORTED;
3338 * From here on the server routines are just dummy ones to make smbd link with
3339 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3340 * pulling the server stubs across one by one.
3343 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3345 p->rng_fault_state = True;
3346 return NT_STATUS_NOT_IMPLEMENTED;
3349 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3350 struct lsa_ChangePassword *r)
3352 p->rng_fault_state = True;
3353 return NT_STATUS_NOT_IMPLEMENTED;
3356 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3358 p->rng_fault_state = True;
3359 return NT_STATUS_NOT_IMPLEMENTED;
3362 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3364 p->rng_fault_state = True;
3365 return NT_STATUS_NOT_IMPLEMENTED;
3368 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3369 struct lsa_GetQuotasForAccount *r)
3371 p->rng_fault_state = True;
3372 return NT_STATUS_NOT_IMPLEMENTED;
3375 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3376 struct lsa_SetQuotasForAccount *r)
3378 p->rng_fault_state = True;
3379 return NT_STATUS_NOT_IMPLEMENTED;
3382 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3383 struct lsa_SetInformationTrustedDomain *r)
3385 p->rng_fault_state = True;
3386 return NT_STATUS_NOT_IMPLEMENTED;
3389 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
3391 p->rng_fault_state = True;
3392 return NT_STATUS_NOT_IMPLEMENTED;
3395 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3396 struct lsa_SetTrustedDomainInfo *r)
3398 p->rng_fault_state = True;
3399 return NT_STATUS_NOT_IMPLEMENTED;
3402 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3403 struct lsa_StorePrivateData *r)
3405 p->rng_fault_state = True;
3406 return NT_STATUS_NOT_IMPLEMENTED;
3409 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3410 struct lsa_RetrievePrivateData *r)
3412 p->rng_fault_state = True;
3413 return NT_STATUS_NOT_IMPLEMENTED;
3416 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3417 struct lsa_SetInfoPolicy2 *r)
3419 p->rng_fault_state = True;
3420 return NT_STATUS_NOT_IMPLEMENTED;
3423 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3424 struct lsa_SetTrustedDomainInfoByName *r)
3426 p->rng_fault_state = True;
3427 return NT_STATUS_NOT_IMPLEMENTED;
3430 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3431 struct lsa_EnumTrustedDomainsEx *r)
3433 struct lsa_info *info;
3434 uint32_t count;
3435 struct pdb_trusted_domain **domains;
3436 struct lsa_TrustDomainInfoInfoEx *entries;
3437 int i;
3438 NTSTATUS nt_status;
3440 /* bail out early if pdb backend is not capable of ex trusted domains,
3441 * if we dont do that, the client might not call
3442 * _lsa_EnumTrustedDomains() afterwards - gd */
3444 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3445 p->rng_fault_state = True;
3446 return NT_STATUS_NOT_IMPLEMENTED;
3449 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3450 return NT_STATUS_INVALID_HANDLE;
3452 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3453 return NT_STATUS_INVALID_HANDLE;
3456 /* check if the user has enough rights */
3457 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3458 return NT_STATUS_ACCESS_DENIED;
3460 become_root();
3461 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3462 unbecome_root();
3464 if (!NT_STATUS_IS_OK(nt_status)) {
3465 return nt_status;
3468 entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3469 count);
3470 if (!entries) {
3471 return NT_STATUS_NO_MEMORY;
3474 for (i=0; i<count; i++) {
3475 init_lsa_StringLarge(&entries[i].netbios_name,
3476 domains[i]->netbios_name);
3477 entries[i].sid = &domains[i]->security_identifier;
3480 if (*r->in.resume_handle >= count) {
3481 *r->out.resume_handle = -1;
3482 TALLOC_FREE(entries);
3483 return NT_STATUS_NO_MORE_ENTRIES;
3486 /* return the rest, limit by max_size. Note that we
3487 use the w2k3 element size value of 60 */
3488 r->out.domains->count = count - *r->in.resume_handle;
3489 r->out.domains->count = MIN(r->out.domains->count,
3490 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3492 r->out.domains->domains = entries + *r->in.resume_handle;
3494 if (r->out.domains->count < count - *r->in.resume_handle) {
3495 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3496 return STATUS_MORE_ENTRIES;
3499 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3500 * always be larger than the previous input resume handle, in
3501 * particular when hitting the last query it is vital to set the
3502 * resume handle correctly to avoid infinite client loops, as
3503 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3504 * status is NT_STATUS_OK - gd */
3506 *r->out.resume_handle = (uint32_t)-1;
3508 return NT_STATUS_OK;
3511 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3512 struct lsa_QueryDomainInformationPolicy *r)
3514 p->rng_fault_state = True;
3515 return NT_STATUS_NOT_IMPLEMENTED;
3518 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3519 struct lsa_SetDomainInformationPolicy *r)
3521 p->rng_fault_state = True;
3522 return NT_STATUS_NOT_IMPLEMENTED;
3525 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3527 p->rng_fault_state = True;
3528 return NT_STATUS_NOT_IMPLEMENTED;
3531 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3533 p->rng_fault_state = True;
3534 return NT_STATUS_NOT_IMPLEMENTED;
3537 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3539 p->rng_fault_state = True;
3540 return NT_STATUS_NOT_IMPLEMENTED;
3543 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3545 p->rng_fault_state = True;
3546 return NT_STATUS_NOT_IMPLEMENTED;
3549 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3550 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3552 p->rng_fault_state = True;
3553 return NT_STATUS_NOT_IMPLEMENTED;
3556 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3557 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3559 p->rng_fault_state = True;
3560 return NT_STATUS_NOT_IMPLEMENTED;
3563 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3565 p->rng_fault_state = True;
3566 return NT_STATUS_NOT_IMPLEMENTED;
3569 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3570 struct lsa_CREDRGETTARGETINFO *r)
3572 p->rng_fault_state = True;
3573 return NT_STATUS_NOT_IMPLEMENTED;
3576 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3577 struct lsa_CREDRPROFILELOADED *r)
3579 p->rng_fault_state = True;
3580 return NT_STATUS_NOT_IMPLEMENTED;
3583 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3584 struct lsa_CREDRGETSESSIONTYPES *r)
3586 p->rng_fault_state = True;
3587 return NT_STATUS_NOT_IMPLEMENTED;
3590 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3591 struct lsa_LSARREGISTERAUDITEVENT *r)
3593 p->rng_fault_state = True;
3594 return NT_STATUS_NOT_IMPLEMENTED;
3597 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3598 struct lsa_LSARGENAUDITEVENT *r)
3600 p->rng_fault_state = True;
3601 return NT_STATUS_NOT_IMPLEMENTED;
3604 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3605 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3607 p->rng_fault_state = True;
3608 return NT_STATUS_NOT_IMPLEMENTED;
3611 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3612 struct lsa_lsaRQueryForestTrustInformation *r)
3614 p->rng_fault_state = True;
3615 return NT_STATUS_NOT_IMPLEMENTED;
3618 #define DNS_CMP_MATCH 0
3619 #define DNS_CMP_FIRST_IS_CHILD 1
3620 #define DNS_CMP_SECOND_IS_CHILD 2
3621 #define DNS_CMP_NO_MATCH 3
3623 /* this function assumes names are well formed DNS names.
3624 * it doesn't validate them */
3625 static int dns_cmp(const char *s1, size_t l1,
3626 const char *s2, size_t l2)
3628 const char *p1, *p2;
3629 size_t t1, t2;
3630 int cret;
3632 if (l1 == l2) {
3633 if (strcasecmp_m(s1, s2) == 0) {
3634 return DNS_CMP_MATCH;
3636 return DNS_CMP_NO_MATCH;
3639 if (l1 > l2) {
3640 p1 = s1;
3641 p2 = s2;
3642 t1 = l1;
3643 t2 = l2;
3644 cret = DNS_CMP_FIRST_IS_CHILD;
3645 } else {
3646 p1 = s2;
3647 p2 = s1;
3648 t1 = l2;
3649 t2 = l1;
3650 cret = DNS_CMP_SECOND_IS_CHILD;
3653 if (p1[t1 - t2 - 1] != '.') {
3654 return DNS_CMP_NO_MATCH;
3657 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
3658 return cret;
3661 return DNS_CMP_NO_MATCH;
3664 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3665 struct lsa_ForestTrustInformation *lfti,
3666 struct ForestTrustInfo *fti)
3668 struct lsa_ForestTrustRecord *lrec;
3669 struct ForestTrustInfoRecord *rec;
3670 struct lsa_StringLarge *tln;
3671 struct lsa_ForestTrustDomainInfo *info;
3672 uint32_t i;
3674 fti->version = 1;
3675 fti->count = lfti->count;
3676 fti->records = talloc_array(mem_ctx,
3677 struct ForestTrustInfoRecordArmor,
3678 fti->count);
3679 if (!fti->records) {
3680 return NT_STATUS_NO_MEMORY;
3682 for (i = 0; i < fti->count; i++) {
3683 lrec = lfti->entries[i];
3684 rec = &fti->records[i].record;
3686 rec->flags = lrec->flags;
3687 rec->timestamp = lrec->time;
3688 rec->type = lrec->type;
3690 switch (lrec->type) {
3691 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3692 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3693 tln = &lrec->forest_trust_data.top_level_name;
3694 rec->data.name.string =
3695 talloc_strdup(mem_ctx, tln->string);
3696 if (!rec->data.name.string) {
3697 return NT_STATUS_NO_MEMORY;
3699 rec->data.name.size = strlen(rec->data.name.string);
3700 break;
3701 case LSA_FOREST_TRUST_DOMAIN_INFO:
3702 info = &lrec->forest_trust_data.domain_info;
3703 rec->data.info.sid = *info->domain_sid;
3704 rec->data.info.dns_name.string =
3705 talloc_strdup(mem_ctx,
3706 info->dns_domain_name.string);
3707 if (!rec->data.info.dns_name.string) {
3708 return NT_STATUS_NO_MEMORY;
3710 rec->data.info.dns_name.size =
3711 strlen(rec->data.info.dns_name.string);
3712 rec->data.info.netbios_name.string =
3713 talloc_strdup(mem_ctx,
3714 info->netbios_domain_name.string);
3715 if (!rec->data.info.netbios_name.string) {
3716 return NT_STATUS_NO_MEMORY;
3718 rec->data.info.netbios_name.size =
3719 strlen(rec->data.info.netbios_name.string);
3720 break;
3721 default:
3722 return NT_STATUS_INVALID_DOMAIN_STATE;
3726 return NT_STATUS_OK;
3729 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3730 uint32_t index, uint32_t collision_type,
3731 uint32_t conflict_type, const char *tdo_name);
3733 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
3734 const char *tdo_name,
3735 struct ForestTrustInfo *tdo_fti,
3736 struct ForestTrustInfo *new_fti,
3737 struct lsa_ForestTrustCollisionInfo *c_info)
3739 struct ForestTrustInfoRecord *nrec;
3740 struct ForestTrustInfoRecord *trec;
3741 const char *dns_name;
3742 const char *nb_name = NULL;
3743 struct dom_sid *sid = NULL;
3744 const char *tname = NULL;
3745 size_t dns_len = 0;
3746 size_t nb_len;
3747 size_t tlen = 0;
3748 NTSTATUS nt_status;
3749 uint32_t new_fti_idx;
3750 uint32_t i;
3751 /* use always TDO type, until we understand when Xref can be used */
3752 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
3753 bool tln_conflict;
3754 bool sid_conflict;
3755 bool nb_conflict;
3756 bool exclusion;
3757 bool ex_rule = false;
3758 int ret;
3760 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
3762 nrec = &new_fti->records[new_fti_idx].record;
3763 dns_name = NULL;
3764 tln_conflict = false;
3765 sid_conflict = false;
3766 nb_conflict = false;
3767 exclusion = false;
3769 switch (nrec->type) {
3770 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3771 /* exclusions do not conflict by definition */
3772 break;
3774 case FOREST_TRUST_TOP_LEVEL_NAME:
3775 dns_name = nrec->data.name.string;
3776 dns_len = nrec->data.name.size;
3777 break;
3779 case LSA_FOREST_TRUST_DOMAIN_INFO:
3780 dns_name = nrec->data.info.dns_name.string;
3781 dns_len = nrec->data.info.dns_name.size;
3782 nb_name = nrec->data.info.netbios_name.string;
3783 nb_len = nrec->data.info.netbios_name.size;
3784 sid = &nrec->data.info.sid;
3785 break;
3788 if (!dns_name) continue;
3790 /* check if this is already taken and not excluded */
3791 for (i = 0; i < tdo_fti->count; i++) {
3792 trec = &tdo_fti->records[i].record;
3794 switch (trec->type) {
3795 case FOREST_TRUST_TOP_LEVEL_NAME:
3796 ex_rule = false;
3797 tname = trec->data.name.string;
3798 tlen = trec->data.name.size;
3799 break;
3800 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
3801 ex_rule = true;
3802 tname = trec->data.name.string;
3803 tlen = trec->data.name.size;
3804 break;
3805 case FOREST_TRUST_DOMAIN_INFO:
3806 ex_rule = false;
3807 tname = trec->data.info.dns_name.string;
3808 tlen = trec->data.info.dns_name.size;
3809 break;
3810 default:
3811 return NT_STATUS_INVALID_PARAMETER;
3813 ret = dns_cmp(dns_name, dns_len, tname, tlen);
3814 switch (ret) {
3815 case DNS_CMP_MATCH:
3816 /* if it matches exclusion,
3817 * it doesn't conflict */
3818 if (ex_rule) {
3819 exclusion = true;
3820 break;
3822 /* fall through */
3823 case DNS_CMP_FIRST_IS_CHILD:
3824 case DNS_CMP_SECOND_IS_CHILD:
3825 tln_conflict = true;
3826 /* fall through */
3827 default:
3828 break;
3831 /* explicit exclusion, no dns name conflict here */
3832 if (exclusion) {
3833 tln_conflict = false;
3836 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
3837 continue;
3840 /* also test for domain info */
3841 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
3842 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
3843 sid_conflict = true;
3845 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
3846 strcasecmp_m(trec->data.info.netbios_name.string,
3847 nb_name) == 0) {
3848 nb_conflict = true;
3852 if (tln_conflict) {
3853 nt_status = add_collision(c_info, new_fti_idx,
3854 collision_type,
3855 LSA_TLN_DISABLED_CONFLICT,
3856 tdo_name);
3858 if (sid_conflict) {
3859 nt_status = add_collision(c_info, new_fti_idx,
3860 collision_type,
3861 LSA_SID_DISABLED_CONFLICT,
3862 tdo_name);
3864 if (nb_conflict) {
3865 nt_status = add_collision(c_info, new_fti_idx,
3866 collision_type,
3867 LSA_NB_DISABLED_CONFLICT,
3868 tdo_name);
3872 return NT_STATUS_OK;
3875 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3876 uint32_t idx, uint32_t collision_type,
3877 uint32_t conflict_type, const char *tdo_name)
3879 struct lsa_ForestTrustCollisionRecord **es;
3880 uint32_t i = c_info->count;
3882 es = talloc_realloc(c_info, c_info->entries,
3883 struct lsa_ForestTrustCollisionRecord *, i + 1);
3884 if (!es) {
3885 return NT_STATUS_NO_MEMORY;
3887 c_info->entries = es;
3888 c_info->count = i + 1;
3890 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
3891 if (!es[i]) {
3892 return NT_STATUS_NO_MEMORY;
3895 es[i]->index = idx;
3896 es[i]->type = collision_type;
3897 es[i]->flags.flags = conflict_type;
3898 es[i]->name.string = talloc_strdup(es[i], tdo_name);
3899 if (!es[i]->name.string) {
3900 return NT_STATUS_NO_MEMORY;
3902 es[i]->name.size = strlen(es[i]->name.string);
3904 return NT_STATUS_OK;
3907 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3908 struct pdb_trusted_domain *td,
3909 struct ForestTrustInfo *info)
3911 enum ndr_err_code ndr_err;
3913 if (td->trust_forest_trust_info.length == 0 ||
3914 td->trust_forest_trust_info.data == NULL) {
3915 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3917 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
3918 info,
3919 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3920 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3921 return NT_STATUS_INVALID_DOMAIN_STATE;
3924 return NT_STATUS_OK;
3927 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
3928 struct ForestTrustInfo *fti)
3930 struct ForestTrustDataDomainInfo *info;
3931 struct ForestTrustInfoRecord *rec;
3933 fti->version = 1;
3934 fti->count = 2;
3935 fti->records = talloc_array(fti,
3936 struct ForestTrustInfoRecordArmor, 2);
3937 if (!fti->records) {
3938 return NT_STATUS_NO_MEMORY;
3941 /* TLN info */
3942 rec = &fti->records[0].record;
3944 rec->flags = 0;
3945 rec->timestamp = 0;
3946 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3948 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
3949 if (!rec->data.name.string) {
3950 return NT_STATUS_NO_MEMORY;
3952 rec->data.name.size = strlen(rec->data.name.string);
3954 /* DOMAIN info */
3955 rec = &fti->records[1].record;
3957 rec->flags = 0;
3958 rec->timestamp = 0;
3959 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3961 info = &rec->data.info;
3963 info->sid = dom_info->sid;
3964 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
3965 if (!info->dns_name.string) {
3966 return NT_STATUS_NO_MEMORY;
3968 info->dns_name.size = strlen(info->dns_name.string);
3969 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
3970 if (!info->netbios_name.string) {
3971 return NT_STATUS_NO_MEMORY;
3973 info->netbios_name.size = strlen(info->netbios_name.string);
3975 return NT_STATUS_OK;
3978 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
3979 struct lsa_lsaRSetForestTrustInformation *r)
3981 NTSTATUS status;
3982 int i;
3983 int j;
3984 struct lsa_info *handle;
3985 uint32_t num_domains;
3986 struct pdb_trusted_domain **domains;
3987 struct ForestTrustInfo *nfti;
3988 struct ForestTrustInfo *fti;
3989 struct lsa_ForestTrustCollisionInfo *c_info;
3990 struct pdb_domain_info *dom_info;
3991 enum ndr_err_code ndr_err;
3993 if (!IS_DC) {
3994 return NT_STATUS_NOT_SUPPORTED;
3997 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
3998 return NT_STATUS_INVALID_HANDLE;
4001 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
4002 return NT_STATUS_INVALID_HANDLE;
4005 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
4006 return NT_STATUS_ACCESS_DENIED;
4009 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
4010 if (!NT_STATUS_IS_OK(status)) {
4011 return status;
4013 if (num_domains == 0) {
4014 return NT_STATUS_NO_SUCH_DOMAIN;
4017 for (i = 0; i < num_domains; i++) {
4018 if (domains[i]->domain_name == NULL) {
4019 return NT_STATUS_INVALID_DOMAIN_STATE;
4021 if (strcasecmp_m(domains[i]->domain_name,
4022 r->in.trusted_domain_name->string) == 0) {
4023 break;
4026 if (i >= num_domains) {
4027 return NT_STATUS_NO_SUCH_DOMAIN;
4030 if (!(domains[i]->trust_attributes &
4031 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4032 return NT_STATUS_INVALID_PARAMETER;
4035 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4036 return NT_STATUS_INVALID_PARAMETER;
4039 /* The following section until COPY_END is a copy from
4040 * source4/rpmc_server/lsa/scesrc_lsa.c */
4041 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
4042 if (!nfti) {
4043 return NT_STATUS_NO_MEMORY;
4046 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4047 if (!NT_STATUS_IS_OK(status)) {
4048 return status;
4051 c_info = talloc_zero(r->out.collision_info,
4052 struct lsa_ForestTrustCollisionInfo);
4053 if (!c_info) {
4054 return NT_STATUS_NO_MEMORY;
4057 /* first check own info, then other domains */
4058 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4059 if (!fti) {
4060 return NT_STATUS_NO_MEMORY;
4063 dom_info = pdb_get_domain_info(p->mem_ctx);
4065 status = own_ft_info(dom_info, fti);
4066 if (!NT_STATUS_IS_OK(status)) {
4067 return status;
4070 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
4071 if (!NT_STATUS_IS_OK(status)) {
4072 return status;
4075 for (j = 0; j < num_domains; j++) {
4076 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4077 if (!fti) {
4078 return NT_STATUS_NO_MEMORY;
4081 status = get_ft_info(p->mem_ctx, domains[j], fti);
4082 if (!NT_STATUS_IS_OK(status)) {
4083 if (NT_STATUS_EQUAL(status,
4084 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4085 continue;
4087 return status;
4090 if (domains[j]->domain_name == NULL) {
4091 return NT_STATUS_INVALID_DOMAIN_STATE;
4094 status = check_ft_info(c_info, domains[j]->domain_name,
4095 fti, nfti, c_info);
4096 if (!NT_STATUS_IS_OK(status)) {
4097 return status;
4101 *r->out.collision_info = c_info;
4103 if (r->in.check_only != 0) {
4104 return NT_STATUS_OK;
4107 /* COPY_END */
4109 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
4110 p->mem_ctx, nfti,
4111 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4112 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4113 return NT_STATUS_INVALID_PARAMETER;
4116 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
4117 if (!NT_STATUS_IS_OK(status)) {
4118 return status;
4121 return NT_STATUS_OK;
4124 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
4125 struct lsa_CREDRRENAME *r)
4127 p->rng_fault_state = True;
4128 return NT_STATUS_NOT_IMPLEMENTED;
4131 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
4132 struct lsa_LSAROPENPOLICYSCE *r)
4134 p->rng_fault_state = True;
4135 return NT_STATUS_NOT_IMPLEMENTED;
4138 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4139 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4141 p->rng_fault_state = True;
4142 return NT_STATUS_NOT_IMPLEMENTED;
4145 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4146 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4148 p->rng_fault_state = True;
4149 return NT_STATUS_NOT_IMPLEMENTED;
4152 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4153 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4155 p->rng_fault_state = True;
4156 return NT_STATUS_NOT_IMPLEMENTED;