s3: Lift the server_messaging_context from send_spoolss_notify2_msg
[Samba/gbeck.git] / source3 / rpc_server / srv_lsa_nt.c
blob1a0ddb1892927c102e4b1bf23c20a1af7bb689f7
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.
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 3 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see <http://www.gnu.org/licenses/>.
29 /* This is the implementation of the lsa server code. */
31 #include "includes.h"
32 #include "../librpc/gen_ndr/srv_lsa.h"
33 #include "secrets.h"
34 #include "../librpc/gen_ndr/netlogon.h"
36 #undef DBGC_CLASS
37 #define DBGC_CLASS DBGC_RPC_SRV
39 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
41 extern PRIVS privs[];
43 enum lsa_handle_type { LSA_HANDLE_POLICY_TYPE = 1, LSA_HANDLE_ACCOUNT_TYPE };
45 struct lsa_info {
46 struct dom_sid sid;
47 const char *name;
48 uint32 access;
49 enum lsa_handle_type type;
50 struct security_descriptor *sd;
53 const struct generic_mapping lsa_account_mapping = {
54 LSA_ACCOUNT_READ,
55 LSA_ACCOUNT_WRITE,
56 LSA_ACCOUNT_EXECUTE,
57 LSA_ACCOUNT_ALL_ACCESS
60 const struct generic_mapping lsa_policy_mapping = {
61 LSA_POLICY_READ,
62 LSA_POLICY_WRITE,
63 LSA_POLICY_EXECUTE,
64 LSA_POLICY_ALL_ACCESS
67 const struct generic_mapping lsa_secret_mapping = {
68 LSA_SECRET_READ,
69 LSA_SECRET_WRITE,
70 LSA_SECRET_EXECUTE,
71 LSA_SECRET_ALL_ACCESS
74 const struct generic_mapping lsa_trusted_domain_mapping = {
75 LSA_TRUSTED_DOMAIN_READ,
76 LSA_TRUSTED_DOMAIN_WRITE,
77 LSA_TRUSTED_DOMAIN_EXECUTE,
78 LSA_TRUSTED_DOMAIN_ALL_ACCESS
81 /***************************************************************************
82 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
83 ***************************************************************************/
85 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
86 struct lsa_RefDomainList *ref,
87 const char *dom_name,
88 struct dom_sid *dom_sid)
90 int num = 0;
92 if (dom_name != NULL) {
93 for (num = 0; num < ref->count; num++) {
94 if (sid_equal(dom_sid, ref->domains[num].sid)) {
95 return num;
98 } else {
99 num = ref->count;
102 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
103 /* index not found, already at maximum domain limit */
104 return -1;
107 ref->count = num + 1;
108 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
110 ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains,
111 struct lsa_DomainInfo, ref->count);
112 if (!ref->domains) {
113 return -1;
116 ZERO_STRUCT(ref->domains[num]);
118 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
119 ref->domains[num].sid = sid_dup_talloc(mem_ctx, dom_sid);
120 if (!ref->domains[num].sid) {
121 return -1;
124 return num;
128 /***************************************************************************
129 initialize a lsa_DomainInfo structure.
130 ***************************************************************************/
132 static void init_dom_query_3(struct lsa_DomainInfo *r,
133 const char *name,
134 struct dom_sid *sid)
136 init_lsa_StringLarge(&r->name, name);
137 r->sid = sid;
140 /***************************************************************************
141 initialize a lsa_DomainInfo structure.
142 ***************************************************************************/
144 static void init_dom_query_5(struct lsa_DomainInfo *r,
145 const char *name,
146 struct dom_sid *sid)
148 init_lsa_StringLarge(&r->name, name);
149 r->sid = sid;
152 /***************************************************************************
153 lookup_lsa_rids. Must be called as root for lookup_name to work.
154 ***************************************************************************/
156 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
157 struct lsa_RefDomainList *ref,
158 struct lsa_TranslatedSid *prid,
159 uint32_t num_entries,
160 struct lsa_String *name,
161 int flags,
162 uint32_t *pmapped_count)
164 uint32 mapped_count, i;
166 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
168 mapped_count = 0;
169 *pmapped_count = 0;
171 for (i = 0; i < num_entries; i++) {
172 struct dom_sid sid;
173 uint32 rid;
174 int dom_idx;
175 const char *full_name;
176 const char *domain;
177 enum lsa_SidType type = SID_NAME_UNKNOWN;
179 /* Split name into domain and user component */
181 /* follow w2k8 behavior and return the builtin domain when no
182 * input has been passed in */
184 if (name[i].string) {
185 full_name = name[i].string;
186 } else {
187 full_name = "BUILTIN";
190 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
192 /* We can ignore the result of lookup_name, it will not touch
193 "type" if it's not successful */
195 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
196 &sid, &type);
198 switch (type) {
199 case SID_NAME_USER:
200 case SID_NAME_DOM_GRP:
201 case SID_NAME_DOMAIN:
202 case SID_NAME_ALIAS:
203 case SID_NAME_WKN_GRP:
204 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
205 /* Leave these unchanged */
206 break;
207 default:
208 /* Don't hand out anything but the list above */
209 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
210 type = SID_NAME_UNKNOWN;
211 break;
214 rid = 0;
215 dom_idx = -1;
217 if (type != SID_NAME_UNKNOWN) {
218 if (type == SID_NAME_DOMAIN) {
219 rid = (uint32_t)-1;
220 } else {
221 sid_split_rid(&sid, &rid);
223 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
224 mapped_count++;
227 prid[i].sid_type = type;
228 prid[i].rid = rid;
229 prid[i].sid_index = dom_idx;
232 *pmapped_count = mapped_count;
233 return NT_STATUS_OK;
236 /***************************************************************************
237 lookup_lsa_sids. Must be called as root for lookup_name to work.
238 ***************************************************************************/
240 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
241 struct lsa_RefDomainList *ref,
242 struct lsa_TranslatedSid3 *trans_sids,
243 uint32_t num_entries,
244 struct lsa_String *name,
245 int flags,
246 uint32 *pmapped_count)
248 uint32 mapped_count, i;
250 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
252 mapped_count = 0;
253 *pmapped_count = 0;
255 for (i = 0; i < num_entries; i++) {
256 struct dom_sid sid;
257 uint32 rid;
258 int dom_idx;
259 const char *full_name;
260 const char *domain;
261 enum lsa_SidType type = SID_NAME_UNKNOWN;
263 ZERO_STRUCT(sid);
265 /* Split name into domain and user component */
267 full_name = name[i].string;
268 if (full_name == NULL) {
269 return NT_STATUS_NO_MEMORY;
272 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
274 /* We can ignore the result of lookup_name, it will not touch
275 "type" if it's not successful */
277 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
278 &sid, &type);
280 switch (type) {
281 case SID_NAME_USER:
282 case SID_NAME_DOM_GRP:
283 case SID_NAME_DOMAIN:
284 case SID_NAME_ALIAS:
285 case SID_NAME_WKN_GRP:
286 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
287 /* Leave these unchanged */
288 break;
289 default:
290 /* Don't hand out anything but the list above */
291 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
292 type = SID_NAME_UNKNOWN;
293 break;
296 rid = 0;
297 dom_idx = -1;
299 if (type != SID_NAME_UNKNOWN) {
300 struct dom_sid domain_sid;
301 sid_copy(&domain_sid, &sid);
302 sid_split_rid(&domain_sid, &rid);
303 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
304 mapped_count++;
307 /* Initialize the lsa_TranslatedSid3 return. */
308 trans_sids[i].sid_type = type;
309 trans_sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
310 trans_sids[i].sid_index = dom_idx;
313 *pmapped_count = mapped_count;
314 return NT_STATUS_OK;
317 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
318 const struct generic_mapping *map,
319 struct dom_sid *sid, uint32_t sid_access)
321 struct dom_sid adm_sid;
322 struct security_ace ace[5];
323 size_t i = 0;
325 struct security_acl *psa = NULL;
327 /* READ|EXECUTE access for Everyone */
329 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
330 map->generic_execute | map->generic_read, 0);
332 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
334 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
335 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
336 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
337 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
339 /* Add Full Access for Domain Admins */
340 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
341 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
342 map->generic_all, 0);
344 /* If we have a sid, give it some special access */
346 if (sid) {
347 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
348 sid_access, 0);
351 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
352 return NT_STATUS_NO_MEMORY;
354 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
355 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
356 psa, sd_size)) == NULL)
357 return NT_STATUS_NO_MEMORY;
359 return NT_STATUS_OK;
363 /***************************************************************************
364 _lsa_OpenPolicy2
365 ***************************************************************************/
367 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
368 struct lsa_OpenPolicy2 *r)
370 struct lsa_info *info;
371 struct security_descriptor *psd = NULL;
372 size_t sd_size;
373 uint32 des_access = r->in.access_mask;
374 uint32 acc_granted;
375 NTSTATUS status;
377 /* Work out max allowed. */
378 map_max_allowed_access(p->server_info->ptok,
379 &p->server_info->utok,
380 &des_access);
382 /* map the generic bits to the lsa policy ones */
383 se_map_generic(&des_access, &lsa_policy_mapping);
385 /* get the generic lsa policy SD until we store it */
386 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
387 NULL, 0);
388 if (!NT_STATUS_IS_OK(status)) {
389 return status;
392 status = access_check_object(psd, p->server_info->ptok,
393 NULL, 0, des_access,
394 &acc_granted, "_lsa_OpenPolicy2" );
395 if (!NT_STATUS_IS_OK(status)) {
396 return status;
399 /* associate the domain SID with the (unique) handle. */
400 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
401 if (info == NULL) {
402 return NT_STATUS_NO_MEMORY;
405 sid_copy(&info->sid,get_global_sam_sid());
406 info->access = acc_granted;
407 info->type = LSA_HANDLE_POLICY_TYPE;
409 /* set up the LSA QUERY INFO response */
410 if (!create_policy_hnd(p, r->out.handle, info))
411 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
413 return NT_STATUS_OK;
416 /***************************************************************************
417 _lsa_OpenPolicy
418 ***************************************************************************/
420 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
421 struct lsa_OpenPolicy *r)
423 struct lsa_OpenPolicy2 o;
425 o.in.system_name = NULL; /* should be ignored */
426 o.in.attr = r->in.attr;
427 o.in.access_mask = r->in.access_mask;
429 o.out.handle = r->out.handle;
431 return _lsa_OpenPolicy2(p, &o);
434 /***************************************************************************
435 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
436 ufff, done :) mimir
437 ***************************************************************************/
439 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
440 struct lsa_EnumTrustDom *r)
442 struct lsa_info *info;
443 uint32_t count;
444 struct trustdom_info **domains;
445 struct lsa_DomainInfo *entries;
446 int i;
447 NTSTATUS nt_status;
449 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
450 return NT_STATUS_INVALID_HANDLE;
452 if (info->type != LSA_HANDLE_POLICY_TYPE) {
453 return NT_STATUS_INVALID_HANDLE;
456 /* check if the user has enough rights */
457 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
458 return NT_STATUS_ACCESS_DENIED;
460 become_root();
461 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
462 unbecome_root();
464 if (!NT_STATUS_IS_OK(nt_status)) {
465 return nt_status;
468 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo, count);
469 if (!entries) {
470 return NT_STATUS_NO_MEMORY;
473 for (i=0; i<count; i++) {
474 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
475 entries[i].sid = &domains[i]->sid;
478 if (*r->in.resume_handle >= count) {
479 *r->out.resume_handle = -1;
480 TALLOC_FREE(entries);
481 return NT_STATUS_NO_MORE_ENTRIES;
484 /* return the rest, limit by max_size. Note that we
485 use the w2k3 element size value of 60 */
486 r->out.domains->count = count - *r->in.resume_handle;
487 r->out.domains->count = MIN(r->out.domains->count,
488 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
490 r->out.domains->domains = entries + *r->in.resume_handle;
492 if (r->out.domains->count < count - *r->in.resume_handle) {
493 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
494 return STATUS_MORE_ENTRIES;
497 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
498 * always be larger than the previous input resume handle, in
499 * particular when hitting the last query it is vital to set the
500 * resume handle correctly to avoid infinite client loops, as
501 * seen e.g. with Windows XP SP3 when resume handle is 0 and
502 * status is NT_STATUS_OK - gd */
504 *r->out.resume_handle = (uint32_t)-1;
506 return NT_STATUS_OK;
509 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
510 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
511 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
513 /***************************************************************************
514 _lsa_QueryInfoPolicy
515 ***************************************************************************/
517 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
518 struct lsa_QueryInfoPolicy *r)
520 NTSTATUS status = NT_STATUS_OK;
521 struct lsa_info *handle;
522 struct dom_sid domain_sid;
523 const char *name;
524 struct dom_sid *sid = NULL;
525 union lsa_PolicyInformation *info = NULL;
526 uint32_t acc_required = 0;
528 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
529 return NT_STATUS_INVALID_HANDLE;
531 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
532 return NT_STATUS_INVALID_HANDLE;
535 switch (r->in.level) {
536 case LSA_POLICY_INFO_AUDIT_LOG:
537 case LSA_POLICY_INFO_AUDIT_EVENTS:
538 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
539 break;
540 case LSA_POLICY_INFO_DOMAIN:
541 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
542 break;
543 case LSA_POLICY_INFO_PD:
544 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
545 break;
546 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
547 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
548 break;
549 case LSA_POLICY_INFO_ROLE:
550 case LSA_POLICY_INFO_REPLICA:
551 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
552 break;
553 case LSA_POLICY_INFO_QUOTA:
554 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
555 break;
556 case LSA_POLICY_INFO_MOD:
557 case LSA_POLICY_INFO_AUDIT_FULL_SET:
558 /* according to MS-LSAD 3.1.4.4.3 */
559 return NT_STATUS_INVALID_PARAMETER;
560 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
561 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
562 break;
563 case LSA_POLICY_INFO_DNS:
564 case LSA_POLICY_INFO_DNS_INT:
565 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
566 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
567 break;
568 default:
569 break;
572 if (!(handle->access & acc_required)) {
573 /* return NT_STATUS_ACCESS_DENIED; */
576 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
577 if (!info) {
578 return NT_STATUS_NO_MEMORY;
581 switch (r->in.level) {
582 /* according to MS-LSAD 3.1.4.4.3 */
583 case LSA_POLICY_INFO_MOD:
584 case LSA_POLICY_INFO_AUDIT_FULL_SET:
585 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
586 return NT_STATUS_INVALID_PARAMETER;
587 case LSA_POLICY_INFO_AUDIT_LOG:
588 info->audit_log.percent_full = 0;
589 info->audit_log.maximum_log_size = 0;
590 info->audit_log.retention_time = 0;
591 info->audit_log.shutdown_in_progress = 0;
592 info->audit_log.time_to_shutdown = 0;
593 info->audit_log.next_audit_record = 0;
594 status = NT_STATUS_OK;
595 break;
596 case LSA_POLICY_INFO_PD:
597 info->pd.name.string = NULL;
598 status = NT_STATUS_OK;
599 break;
600 case LSA_POLICY_INFO_REPLICA:
601 info->replica.source.string = NULL;
602 info->replica.account.string = NULL;
603 status = NT_STATUS_OK;
604 break;
605 case LSA_POLICY_INFO_QUOTA:
606 info->quota.paged_pool = 0;
607 info->quota.non_paged_pool = 0;
608 info->quota.min_wss = 0;
609 info->quota.max_wss = 0;
610 info->quota.pagefile = 0;
611 info->quota.unknown = 0;
612 status = NT_STATUS_OK;
613 break;
614 case LSA_POLICY_INFO_AUDIT_EVENTS:
617 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
619 /* check if the user has enough rights */
620 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
621 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
622 return NT_STATUS_ACCESS_DENIED;
625 /* fake info: We audit everything. ;) */
627 info->audit_events.auditing_mode = true;
628 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
629 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
630 enum lsa_PolicyAuditPolicy,
631 info->audit_events.count);
632 if (!info->audit_events.settings) {
633 return NT_STATUS_NO_MEMORY;
636 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
637 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
638 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
639 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
640 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
641 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
642 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
644 break;
646 case LSA_POLICY_INFO_DOMAIN:
647 /* check if the user has enough rights */
648 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
649 return NT_STATUS_ACCESS_DENIED;
651 /* Request PolicyPrimaryDomainInformation. */
652 switch (lp_server_role()) {
653 case ROLE_DOMAIN_PDC:
654 case ROLE_DOMAIN_BDC:
655 name = get_global_sam_name();
656 sid = sid_dup_talloc(p->mem_ctx, get_global_sam_sid());
657 if (!sid) {
658 return NT_STATUS_NO_MEMORY;
660 break;
661 case ROLE_DOMAIN_MEMBER:
662 name = lp_workgroup();
663 /* We need to return the Domain SID here. */
664 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
665 sid = sid_dup_talloc(p->mem_ctx, &domain_sid);
666 if (!sid) {
667 return NT_STATUS_NO_MEMORY;
669 } else {
670 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
672 break;
673 case ROLE_STANDALONE:
674 name = lp_workgroup();
675 sid = NULL;
676 break;
677 default:
678 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
680 init_dom_query_3(&info->domain, name, sid);
681 break;
682 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
683 /* check if the user has enough rights */
684 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
685 return NT_STATUS_ACCESS_DENIED;
687 /* Request PolicyAccountDomainInformation. */
688 name = get_global_sam_name();
689 sid = get_global_sam_sid();
691 init_dom_query_5(&info->account_domain, name, sid);
692 break;
693 case LSA_POLICY_INFO_ROLE:
694 /* check if the user has enough rights */
695 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
696 return NT_STATUS_ACCESS_DENIED;
698 switch (lp_server_role()) {
699 case ROLE_DOMAIN_BDC:
701 * only a BDC is a backup controller
702 * of the domain, it controls.
704 info->role.role = LSA_ROLE_BACKUP;
705 break;
706 default:
708 * any other role is a primary
709 * of the domain, it controls.
711 info->role.role = LSA_ROLE_PRIMARY;
712 break;
714 break;
715 case LSA_POLICY_INFO_DNS:
716 case LSA_POLICY_INFO_DNS_INT: {
717 struct pdb_domain_info *dominfo;
719 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
720 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
721 "without ADS passdb backend\n"));
722 status = NT_STATUS_INVALID_INFO_CLASS;
723 break;
726 dominfo = pdb_get_domain_info(info);
727 if (dominfo == NULL) {
728 status = NT_STATUS_NO_MEMORY;
729 break;
732 init_lsa_StringLarge(&info->dns.name,
733 dominfo->name);
734 init_lsa_StringLarge(&info->dns.dns_domain,
735 dominfo->dns_domain);
736 init_lsa_StringLarge(&info->dns.dns_forest,
737 dominfo->dns_forest);
738 info->dns.domain_guid = dominfo->guid;
739 info->dns.sid = &dominfo->sid;
740 break;
742 default:
743 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
744 r->in.level));
745 status = NT_STATUS_INVALID_INFO_CLASS;
746 break;
749 *r->out.info = info;
751 return status;
754 /***************************************************************************
755 _lsa_QueryInfoPolicy2
756 ***************************************************************************/
758 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
759 struct lsa_QueryInfoPolicy2 *r2)
761 struct lsa_QueryInfoPolicy r;
763 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
764 p->rng_fault_state = True;
765 return NT_STATUS_NOT_IMPLEMENTED;
768 ZERO_STRUCT(r);
769 r.in.handle = r2->in.handle;
770 r.in.level = r2->in.level;
771 r.out.info = r2->out.info;
773 return _lsa_QueryInfoPolicy(p, &r);
776 /***************************************************************************
777 _lsa_lookup_sids_internal
778 ***************************************************************************/
780 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
781 TALLOC_CTX *mem_ctx,
782 uint16_t level, /* input */
783 int num_sids, /* input */
784 struct lsa_SidPtr *sid, /* input */
785 struct lsa_RefDomainList **pp_ref, /* input/output */
786 struct lsa_TranslatedName2 **pp_names,/* input/output */
787 uint32_t *pp_mapped_count) /* input/output */
789 NTSTATUS status;
790 int i;
791 const struct dom_sid **sids = NULL;
792 struct lsa_RefDomainList *ref = NULL;
793 uint32 mapped_count = 0;
794 struct lsa_dom_info *dom_infos = NULL;
795 struct lsa_name_info *name_infos = NULL;
796 struct lsa_TranslatedName2 *names = NULL;
798 *pp_mapped_count = 0;
799 *pp_names = NULL;
800 *pp_ref = NULL;
802 if (num_sids == 0) {
803 return NT_STATUS_OK;
806 sids = TALLOC_ARRAY(p->mem_ctx, const struct dom_sid *, num_sids);
807 ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
809 if (sids == NULL || ref == NULL) {
810 return NT_STATUS_NO_MEMORY;
813 for (i=0; i<num_sids; i++) {
814 sids[i] = sid[i].sid;
817 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
818 &dom_infos, &name_infos);
820 if (!NT_STATUS_IS_OK(status)) {
821 return status;
824 names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
825 if (names == NULL) {
826 return NT_STATUS_NO_MEMORY;
829 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
831 if (!dom_infos[i].valid) {
832 break;
835 if (init_lsa_ref_domain_list(mem_ctx, ref,
836 dom_infos[i].name,
837 &dom_infos[i].sid) != i) {
838 DEBUG(0, ("Domain %s mentioned twice??\n",
839 dom_infos[i].name));
840 return NT_STATUS_INTERNAL_ERROR;
844 for (i=0; i<num_sids; i++) {
845 struct lsa_name_info *name = &name_infos[i];
847 if (name->type == SID_NAME_UNKNOWN) {
848 fstring tmp;
849 name->dom_idx = -1;
850 /* Unknown sids should return the string
851 * representation of the SID. Windows 2003 behaves
852 * rather erratic here, in many cases it returns the
853 * RID as 8 bytes hex, in others it returns the full
854 * SID. We (Jerry/VL) could not figure out which the
855 * hard cases are, so leave it with the SID. */
856 name->name = talloc_asprintf(p->mem_ctx, "%s",
857 sid_to_fstring(tmp,
858 sids[i]));
859 if (name->name == NULL) {
860 return NT_STATUS_NO_MEMORY;
862 } else {
863 mapped_count += 1;
866 names[i].sid_type = name->type;
867 names[i].name.string = name->name;
868 names[i].sid_index = name->dom_idx;
869 names[i].unknown = 0;
872 status = NT_STATUS_NONE_MAPPED;
873 if (mapped_count > 0) {
874 status = (mapped_count < num_sids) ?
875 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
878 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
879 num_sids, mapped_count, nt_errstr(status)));
881 *pp_mapped_count = mapped_count;
882 *pp_names = names;
883 *pp_ref = ref;
885 return status;
888 /***************************************************************************
889 _lsa_LookupSids
890 ***************************************************************************/
892 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
893 struct lsa_LookupSids *r)
895 NTSTATUS status;
896 struct lsa_info *handle;
897 int num_sids = r->in.sids->num_sids;
898 uint32 mapped_count = 0;
899 struct lsa_RefDomainList *domains = NULL;
900 struct lsa_TranslatedName *names_out = NULL;
901 struct lsa_TranslatedName2 *names = NULL;
902 int i;
904 if ((r->in.level < 1) || (r->in.level > 6)) {
905 return NT_STATUS_INVALID_PARAMETER;
908 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
909 return NT_STATUS_INVALID_HANDLE;
912 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
913 return NT_STATUS_INVALID_HANDLE;
916 /* check if the user has enough rights */
917 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
918 return NT_STATUS_ACCESS_DENIED;
921 if (num_sids > MAX_LOOKUP_SIDS) {
922 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
923 MAX_LOOKUP_SIDS, num_sids));
924 return NT_STATUS_NONE_MAPPED;
927 status = _lsa_lookup_sids_internal(p,
928 p->mem_ctx,
929 r->in.level,
930 num_sids,
931 r->in.sids->sids,
932 &domains,
933 &names,
934 &mapped_count);
936 /* Only return here when there is a real error.
937 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
938 the requested sids could be resolved. Older versions of XP (pre SP3)
939 rely that we return with the string representations of those SIDs in
940 that case. If we don't, XP crashes - Guenther
943 if (NT_STATUS_IS_ERR(status) &&
944 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
945 return status;
948 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
949 names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
950 num_sids);
951 if (!names_out) {
952 return NT_STATUS_NO_MEMORY;
955 for (i=0; i<num_sids; i++) {
956 names_out[i].sid_type = names[i].sid_type;
957 names_out[i].name = names[i].name;
958 names_out[i].sid_index = names[i].sid_index;
961 *r->out.domains = domains;
962 r->out.names->count = num_sids;
963 r->out.names->names = names_out;
964 *r->out.count = mapped_count;
966 return status;
969 /***************************************************************************
970 _lsa_LookupSids2
971 ***************************************************************************/
973 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
974 struct lsa_LookupSids2 *r)
976 NTSTATUS status;
977 struct lsa_info *handle;
978 int num_sids = r->in.sids->num_sids;
979 uint32 mapped_count = 0;
980 struct lsa_RefDomainList *domains = NULL;
981 struct lsa_TranslatedName2 *names = NULL;
982 bool check_policy = true;
984 switch (p->opnum) {
985 case NDR_LSA_LOOKUPSIDS3:
986 check_policy = false;
987 break;
988 case NDR_LSA_LOOKUPSIDS2:
989 default:
990 check_policy = true;
993 if ((r->in.level < 1) || (r->in.level > 6)) {
994 return NT_STATUS_INVALID_PARAMETER;
997 if (check_policy) {
998 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
999 return NT_STATUS_INVALID_HANDLE;
1002 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1003 return NT_STATUS_INVALID_HANDLE;
1006 /* check if the user has enough rights */
1007 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1008 return NT_STATUS_ACCESS_DENIED;
1012 if (num_sids > MAX_LOOKUP_SIDS) {
1013 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1014 MAX_LOOKUP_SIDS, num_sids));
1015 return NT_STATUS_NONE_MAPPED;
1018 status = _lsa_lookup_sids_internal(p,
1019 p->mem_ctx,
1020 r->in.level,
1021 num_sids,
1022 r->in.sids->sids,
1023 &domains,
1024 &names,
1025 &mapped_count);
1027 *r->out.domains = domains;
1028 r->out.names->count = num_sids;
1029 r->out.names->names = names;
1030 *r->out.count = mapped_count;
1032 return status;
1035 /***************************************************************************
1036 _lsa_LookupSids3
1037 ***************************************************************************/
1039 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1040 struct lsa_LookupSids3 *r)
1042 struct lsa_LookupSids2 q;
1044 /* No policy handle on this call. Restrict to crypto connections. */
1045 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1046 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1047 get_remote_machine_name() ));
1048 return NT_STATUS_INVALID_PARAMETER;
1051 q.in.handle = NULL;
1052 q.in.sids = r->in.sids;
1053 q.in.level = r->in.level;
1054 q.in.lookup_options = r->in.lookup_options;
1055 q.in.client_revision = r->in.client_revision;
1056 q.in.names = r->in.names;
1057 q.in.count = r->in.count;
1059 q.out.domains = r->out.domains;
1060 q.out.names = r->out.names;
1061 q.out.count = r->out.count;
1063 return _lsa_LookupSids2(p, &q);
1066 /***************************************************************************
1067 ***************************************************************************/
1069 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1071 int flags;
1073 switch (level) {
1074 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1075 flags = LOOKUP_NAME_ALL;
1076 break;
1077 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1078 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1079 break;
1080 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1081 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1082 break;
1083 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1084 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1085 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1086 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1087 default:
1088 flags = LOOKUP_NAME_NONE;
1089 break;
1092 return flags;
1095 /***************************************************************************
1096 _lsa_LookupNames
1097 ***************************************************************************/
1099 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1100 struct lsa_LookupNames *r)
1102 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1103 struct lsa_info *handle;
1104 struct lsa_String *names = r->in.names;
1105 uint32 num_entries = r->in.num_names;
1106 struct lsa_RefDomainList *domains = NULL;
1107 struct lsa_TranslatedSid *rids = NULL;
1108 uint32 mapped_count = 0;
1109 int flags = 0;
1111 if (num_entries > MAX_LOOKUP_SIDS) {
1112 num_entries = MAX_LOOKUP_SIDS;
1113 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1114 num_entries));
1117 flags = lsa_lookup_level_to_flags(r->in.level);
1119 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1120 if (!domains) {
1121 return NT_STATUS_NO_MEMORY;
1124 if (num_entries) {
1125 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1126 num_entries);
1127 if (!rids) {
1128 return NT_STATUS_NO_MEMORY;
1130 } else {
1131 rids = NULL;
1134 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1135 status = NT_STATUS_INVALID_HANDLE;
1136 goto done;
1139 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1140 return NT_STATUS_INVALID_HANDLE;
1143 /* check if the user has enough rights */
1144 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1145 status = NT_STATUS_ACCESS_DENIED;
1146 goto done;
1149 /* set up the LSA Lookup RIDs response */
1150 become_root(); /* lookup_name can require root privs */
1151 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1152 names, flags, &mapped_count);
1153 unbecome_root();
1155 done:
1157 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1158 if (mapped_count == 0) {
1159 status = NT_STATUS_NONE_MAPPED;
1160 } else if (mapped_count != num_entries) {
1161 status = STATUS_SOME_UNMAPPED;
1165 *r->out.count = mapped_count;
1166 *r->out.domains = domains;
1167 r->out.sids->sids = rids;
1168 r->out.sids->count = num_entries;
1170 return status;
1173 /***************************************************************************
1174 _lsa_LookupNames2
1175 ***************************************************************************/
1177 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1178 struct lsa_LookupNames2 *r)
1180 NTSTATUS status;
1181 struct lsa_LookupNames q;
1182 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1183 struct lsa_TransSidArray *sid_array = NULL;
1184 uint32_t i;
1186 sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1187 if (!sid_array) {
1188 return NT_STATUS_NO_MEMORY;
1191 q.in.handle = r->in.handle;
1192 q.in.num_names = r->in.num_names;
1193 q.in.names = r->in.names;
1194 q.in.level = r->in.level;
1195 q.in.sids = sid_array;
1196 q.in.count = r->in.count;
1197 /* we do not know what this is for */
1198 /* = r->in.unknown1; */
1199 /* = r->in.unknown2; */
1201 q.out.domains = r->out.domains;
1202 q.out.sids = sid_array;
1203 q.out.count = r->out.count;
1205 status = _lsa_LookupNames(p, &q);
1207 sid_array2->count = sid_array->count;
1208 sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1209 if (!sid_array2->sids) {
1210 return NT_STATUS_NO_MEMORY;
1213 for (i=0; i<sid_array->count; i++) {
1214 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1215 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1216 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1217 sid_array2->sids[i].unknown = 0;
1220 r->out.sids = sid_array2;
1222 return status;
1225 /***************************************************************************
1226 _lsa_LookupNames3
1227 ***************************************************************************/
1229 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1230 struct lsa_LookupNames3 *r)
1232 NTSTATUS status;
1233 struct lsa_info *handle;
1234 struct lsa_String *names = r->in.names;
1235 uint32 num_entries = r->in.num_names;
1236 struct lsa_RefDomainList *domains = NULL;
1237 struct lsa_TranslatedSid3 *trans_sids = NULL;
1238 uint32 mapped_count = 0;
1239 int flags = 0;
1240 bool check_policy = true;
1242 switch (p->opnum) {
1243 case NDR_LSA_LOOKUPNAMES4:
1244 check_policy = false;
1245 break;
1246 case NDR_LSA_LOOKUPNAMES3:
1247 default:
1248 check_policy = true;
1251 if (num_entries > MAX_LOOKUP_SIDS) {
1252 num_entries = MAX_LOOKUP_SIDS;
1253 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1256 /* Probably the lookup_level is some sort of bitmask. */
1257 if (r->in.level == 1) {
1258 flags = LOOKUP_NAME_ALL;
1261 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1262 if (!domains) {
1263 return NT_STATUS_NO_MEMORY;
1266 if (num_entries) {
1267 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1268 num_entries);
1269 if (!trans_sids) {
1270 return NT_STATUS_NO_MEMORY;
1272 } else {
1273 trans_sids = NULL;
1276 if (check_policy) {
1278 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1279 status = NT_STATUS_INVALID_HANDLE;
1280 goto done;
1283 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1284 return NT_STATUS_INVALID_HANDLE;
1287 /* check if the user has enough rights */
1288 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1289 status = NT_STATUS_ACCESS_DENIED;
1290 goto done;
1294 /* set up the LSA Lookup SIDs response */
1295 become_root(); /* lookup_name can require root privs */
1296 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1297 names, flags, &mapped_count);
1298 unbecome_root();
1300 done:
1302 if (NT_STATUS_IS_OK(status)) {
1303 if (mapped_count == 0) {
1304 status = NT_STATUS_NONE_MAPPED;
1305 } else if (mapped_count != num_entries) {
1306 status = STATUS_SOME_UNMAPPED;
1310 *r->out.count = mapped_count;
1311 *r->out.domains = domains;
1312 r->out.sids->sids = trans_sids;
1313 r->out.sids->count = num_entries;
1315 return status;
1318 /***************************************************************************
1319 _lsa_LookupNames4
1320 ***************************************************************************/
1322 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1323 struct lsa_LookupNames4 *r)
1325 struct lsa_LookupNames3 q;
1327 /* No policy handle on this call. Restrict to crypto connections. */
1328 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1329 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1330 get_remote_machine_name() ));
1331 return NT_STATUS_INVALID_PARAMETER;
1334 q.in.handle = NULL;
1335 q.in.num_names = r->in.num_names;
1336 q.in.names = r->in.names;
1337 q.in.level = r->in.level;
1338 q.in.lookup_options = r->in.lookup_options;
1339 q.in.client_revision = r->in.client_revision;
1340 q.in.sids = r->in.sids;
1341 q.in.count = r->in.count;
1343 q.out.domains = r->out.domains;
1344 q.out.sids = r->out.sids;
1345 q.out.count = r->out.count;
1347 return _lsa_LookupNames3(p, &q);
1350 /***************************************************************************
1351 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1352 ***************************************************************************/
1354 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1356 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1357 return NT_STATUS_INVALID_HANDLE;
1360 close_policy_hnd(p, r->in.handle);
1361 ZERO_STRUCTP(r->out.handle);
1362 return NT_STATUS_OK;
1365 /***************************************************************************
1366 ***************************************************************************/
1368 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p, struct lsa_OpenSecret *r)
1370 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1373 /***************************************************************************
1374 ***************************************************************************/
1376 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1377 struct lsa_OpenTrustedDomain *r)
1379 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1382 /***************************************************************************
1383 ***************************************************************************/
1385 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1386 struct lsa_CreateTrustedDomain *r)
1388 return NT_STATUS_ACCESS_DENIED;
1391 /***************************************************************************
1392 ***************************************************************************/
1394 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p, struct lsa_CreateSecret *r)
1396 return NT_STATUS_ACCESS_DENIED;
1399 /***************************************************************************
1400 ***************************************************************************/
1402 NTSTATUS _lsa_SetSecret(struct pipes_struct *p, struct lsa_SetSecret *r)
1404 return NT_STATUS_ACCESS_DENIED;
1407 /***************************************************************************
1408 _lsa_DeleteObject
1409 ***************************************************************************/
1411 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
1412 struct lsa_DeleteObject *r)
1414 NTSTATUS status;
1415 struct lsa_info *info = NULL;
1417 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
1418 return NT_STATUS_INVALID_HANDLE;
1421 if (!(info->access & SEC_STD_DELETE)) {
1422 return NT_STATUS_ACCESS_DENIED;
1425 switch (info->type) {
1426 case LSA_HANDLE_ACCOUNT_TYPE:
1427 status = privilege_delete_account(&info->sid);
1428 if (!NT_STATUS_IS_OK(status)) {
1429 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
1430 nt_errstr(status)));
1431 return status;
1433 break;
1434 default:
1435 return NT_STATUS_INVALID_HANDLE;
1438 close_policy_hnd(p, r->in.handle);
1439 ZERO_STRUCTP(r->out.handle);
1441 return status;
1444 /***************************************************************************
1445 _lsa_EnumPrivs
1446 ***************************************************************************/
1448 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
1449 struct lsa_EnumPrivs *r)
1451 struct lsa_info *handle;
1452 uint32 i;
1453 uint32 enum_context = *r->in.resume_handle;
1454 int num_privs = count_all_privileges();
1455 struct lsa_PrivEntry *entries = NULL;
1456 struct lsa_LUIDAttribute luid;
1458 /* remember that the enum_context starts at 0 and not 1 */
1460 if ( enum_context >= num_privs )
1461 return NT_STATUS_NO_MORE_ENTRIES;
1463 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
1464 enum_context, num_privs));
1466 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1467 return NT_STATUS_INVALID_HANDLE;
1469 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1470 return NT_STATUS_INVALID_HANDLE;
1473 /* check if the user has enough rights
1474 I don't know if it's the right one. not documented. */
1476 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1477 return NT_STATUS_ACCESS_DENIED;
1479 if (num_privs) {
1480 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
1481 if (!entries) {
1482 return NT_STATUS_NO_MEMORY;
1484 } else {
1485 entries = NULL;
1488 for (i = 0; i < num_privs; i++) {
1489 if( i < enum_context) {
1491 init_lsa_StringLarge(&entries[i].name, NULL);
1493 entries[i].luid.low = 0;
1494 entries[i].luid.high = 0;
1495 } else {
1497 init_lsa_StringLarge(&entries[i].name, privs[i].name);
1499 luid = get_privilege_luid( &privs[i].se_priv );
1501 entries[i].luid.low = luid.luid.low;
1502 entries[i].luid.high = luid.luid.high;
1506 enum_context = num_privs;
1508 *r->out.resume_handle = enum_context;
1509 r->out.privs->count = num_privs;
1510 r->out.privs->privs = entries;
1512 return NT_STATUS_OK;
1515 /***************************************************************************
1516 _lsa_LookupPrivDisplayName
1517 ***************************************************************************/
1519 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
1520 struct lsa_LookupPrivDisplayName *r)
1522 struct lsa_info *handle;
1523 const char *description;
1524 struct lsa_StringLarge *lsa_name;
1526 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1527 return NT_STATUS_INVALID_HANDLE;
1529 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1530 return NT_STATUS_INVALID_HANDLE;
1533 /* check if the user has enough rights */
1536 * I don't know if it's the right one. not documented.
1538 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1539 return NT_STATUS_ACCESS_DENIED;
1541 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
1543 description = get_privilege_dispname(r->in.name->string);
1544 if (!description) {
1545 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
1546 return NT_STATUS_NO_SUCH_PRIVILEGE;
1549 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
1551 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
1552 if (!lsa_name) {
1553 return NT_STATUS_NO_MEMORY;
1556 init_lsa_StringLarge(lsa_name, description);
1558 *r->out.returned_language_id = r->in.language_id;
1559 *r->out.disp_name = lsa_name;
1561 return NT_STATUS_OK;
1564 /***************************************************************************
1565 _lsa_EnumAccounts
1566 ***************************************************************************/
1568 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
1569 struct lsa_EnumAccounts *r)
1571 struct lsa_info *handle;
1572 struct dom_sid *sid_list;
1573 int i, j, num_entries;
1574 NTSTATUS status;
1575 struct lsa_SidPtr *sids = NULL;
1577 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1578 return NT_STATUS_INVALID_HANDLE;
1580 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1581 return NT_STATUS_INVALID_HANDLE;
1584 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1585 return NT_STATUS_ACCESS_DENIED;
1587 sid_list = NULL;
1588 num_entries = 0;
1590 /* The only way we can currently find out all the SIDs that have been
1591 privileged is to scan all privileges */
1593 status = privilege_enumerate_accounts(&sid_list, &num_entries);
1594 if (!NT_STATUS_IS_OK(status)) {
1595 return status;
1598 if (*r->in.resume_handle >= num_entries) {
1599 return NT_STATUS_NO_MORE_ENTRIES;
1602 if (num_entries - *r->in.resume_handle) {
1603 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
1604 num_entries - *r->in.resume_handle);
1605 if (!sids) {
1606 talloc_free(sid_list);
1607 return NT_STATUS_NO_MEMORY;
1610 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
1611 sids[j].sid = sid_dup_talloc(p->mem_ctx, &sid_list[i]);
1612 if (!sids[j].sid) {
1613 talloc_free(sid_list);
1614 return NT_STATUS_NO_MEMORY;
1619 talloc_free(sid_list);
1621 *r->out.resume_handle = num_entries;
1622 r->out.sids->num_sids = num_entries;
1623 r->out.sids->sids = sids;
1625 return NT_STATUS_OK;
1628 /***************************************************************************
1629 _lsa_GetUserName
1630 ***************************************************************************/
1632 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
1633 struct lsa_GetUserName *r)
1635 const char *username, *domname;
1636 struct lsa_String *account_name = NULL;
1637 struct lsa_String *authority_name = NULL;
1639 if (r->in.account_name &&
1640 *r->in.account_name) {
1641 return NT_STATUS_INVALID_PARAMETER;
1644 if (r->in.authority_name &&
1645 *r->in.authority_name) {
1646 return NT_STATUS_INVALID_PARAMETER;
1649 if (p->server_info->guest) {
1651 * I'm 99% sure this is not the right place to do this,
1652 * global_sid_Anonymous should probably be put into the token
1653 * instead of the guest id -- vl
1655 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
1656 &domname, &username, NULL)) {
1657 return NT_STATUS_NO_MEMORY;
1659 } else {
1660 username = p->server_info->sanitized_username;
1661 domname = p->server_info->info3->base.domain.string;
1664 account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1665 if (!account_name) {
1666 return NT_STATUS_NO_MEMORY;
1668 init_lsa_String(account_name, username);
1670 if (r->out.authority_name) {
1671 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1672 if (!authority_name) {
1673 return NT_STATUS_NO_MEMORY;
1675 init_lsa_String(authority_name, domname);
1678 *r->out.account_name = account_name;
1679 if (r->out.authority_name) {
1680 *r->out.authority_name = authority_name;
1683 return NT_STATUS_OK;
1686 /***************************************************************************
1687 _lsa_CreateAccount
1688 ***************************************************************************/
1690 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
1691 struct lsa_CreateAccount *r)
1693 NTSTATUS status;
1694 struct lsa_info *handle;
1695 struct lsa_info *info;
1696 uint32_t acc_granted;
1697 struct security_descriptor *psd;
1698 size_t sd_size;
1700 /* find the connection policy handle. */
1701 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1702 return NT_STATUS_INVALID_HANDLE;
1704 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1705 return NT_STATUS_INVALID_HANDLE;
1708 /* check if the user has enough rights */
1710 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
1711 return NT_STATUS_ACCESS_DENIED;
1714 /* Work out max allowed. */
1715 map_max_allowed_access(p->server_info->ptok,
1716 &p->server_info->utok,
1717 &r->in.access_mask);
1719 /* map the generic bits to the lsa policy ones */
1720 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1722 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1723 &lsa_account_mapping,
1724 r->in.sid, LSA_POLICY_ALL_ACCESS);
1725 if (!NT_STATUS_IS_OK(status)) {
1726 return status;
1729 status = access_check_object(psd, p->server_info->ptok,
1730 NULL, 0, r->in.access_mask,
1731 &acc_granted, "_lsa_CreateAccount");
1732 if (!NT_STATUS_IS_OK(status)) {
1733 return status;
1736 if ( is_privileged_sid( r->in.sid ) )
1737 return NT_STATUS_OBJECT_NAME_COLLISION;
1739 /* associate the user/group SID with the (unique) handle. */
1741 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1742 if (info == NULL) {
1743 return NT_STATUS_NO_MEMORY;
1746 info->sid = *r->in.sid;
1747 info->access = acc_granted;
1748 info->type = LSA_HANDLE_ACCOUNT_TYPE;
1750 /* get a (unique) handle. open a policy on it. */
1751 if (!create_policy_hnd(p, r->out.acct_handle, info))
1752 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1754 return privilege_create_account( &info->sid );
1757 /***************************************************************************
1758 _lsa_OpenAccount
1759 ***************************************************************************/
1761 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
1762 struct lsa_OpenAccount *r)
1764 struct lsa_info *handle;
1765 struct lsa_info *info;
1766 struct security_descriptor *psd = NULL;
1767 size_t sd_size;
1768 uint32_t des_access = r->in.access_mask;
1769 uint32_t acc_granted;
1770 NTSTATUS status;
1772 /* find the connection policy handle. */
1773 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1774 return NT_STATUS_INVALID_HANDLE;
1776 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1777 return NT_STATUS_INVALID_HANDLE;
1780 /* des_access is for the account here, not the policy
1781 * handle - so don't check against policy handle. */
1783 /* Work out max allowed. */
1784 map_max_allowed_access(p->server_info->ptok,
1785 &p->server_info->utok,
1786 &des_access);
1788 /* map the generic bits to the lsa account ones */
1789 se_map_generic(&des_access, &lsa_account_mapping);
1791 /* get the generic lsa account SD until we store it */
1792 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1793 &lsa_account_mapping,
1794 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
1795 if (!NT_STATUS_IS_OK(status)) {
1796 return status;
1799 status = access_check_object(psd, p->server_info->ptok,
1800 NULL, 0, des_access,
1801 &acc_granted, "_lsa_OpenAccount" );
1802 if (!NT_STATUS_IS_OK(status)) {
1803 return status;
1806 /* TODO: Fis the parsing routine before reenabling this check! */
1807 #if 0
1808 if (!lookup_sid(&handle->sid, dom_name, name, &type))
1809 return NT_STATUS_ACCESS_DENIED;
1810 #endif
1811 /* associate the user/group SID with the (unique) handle. */
1812 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1813 if (info == NULL) {
1814 return NT_STATUS_NO_MEMORY;
1817 info->sid = *r->in.sid;
1818 info->access = acc_granted;
1819 info->type = LSA_HANDLE_ACCOUNT_TYPE;
1821 /* get a (unique) handle. open a policy on it. */
1822 if (!create_policy_hnd(p, r->out.acct_handle, info))
1823 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1825 return NT_STATUS_OK;
1828 /***************************************************************************
1829 _lsa_EnumPrivsAccount
1830 For a given SID, enumerate all the privilege this account has.
1831 ***************************************************************************/
1833 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
1834 struct lsa_EnumPrivsAccount *r)
1836 NTSTATUS status = NT_STATUS_OK;
1837 struct lsa_info *info=NULL;
1838 SE_PRIV mask;
1839 PRIVILEGE_SET privileges;
1840 struct lsa_PrivilegeSet *priv_set = NULL;
1841 struct lsa_LUIDAttribute *luid_attrs = NULL;
1842 int i;
1844 /* find the connection policy handle. */
1845 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1846 return NT_STATUS_INVALID_HANDLE;
1848 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1849 return NT_STATUS_INVALID_HANDLE;
1852 if (!(info->access & LSA_ACCOUNT_VIEW))
1853 return NT_STATUS_ACCESS_DENIED;
1855 get_privileges_for_sids(&mask, &info->sid, 1);
1857 privilege_set_init( &privileges );
1859 priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
1860 if (!priv_set) {
1861 status = NT_STATUS_NO_MEMORY;
1862 goto done;
1865 if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
1867 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
1868 sid_string_dbg(&info->sid),
1869 privileges.count));
1871 luid_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx,
1872 struct lsa_LUIDAttribute,
1873 privileges.count);
1874 if (!luid_attrs) {
1875 status = NT_STATUS_NO_MEMORY;
1876 goto done;
1879 for (i=0; i<privileges.count; i++) {
1880 luid_attrs[i] = privileges.set[i];
1883 priv_set->count = privileges.count;
1884 priv_set->unknown = 0;
1885 priv_set->set = luid_attrs;
1887 } else {
1888 priv_set->count = 0;
1889 priv_set->unknown = 0;
1890 priv_set->set = NULL;
1893 *r->out.privs = priv_set;
1895 done:
1896 privilege_set_free( &privileges );
1898 return status;
1901 /***************************************************************************
1902 _lsa_GetSystemAccessAccount
1903 ***************************************************************************/
1905 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
1906 struct lsa_GetSystemAccessAccount *r)
1908 NTSTATUS status;
1909 struct lsa_info *info = NULL;
1910 struct lsa_EnumPrivsAccount e;
1911 struct lsa_PrivilegeSet *privset;
1913 /* find the connection policy handle. */
1915 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1916 return NT_STATUS_INVALID_HANDLE;
1918 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1919 return NT_STATUS_INVALID_HANDLE;
1922 if (!(info->access & LSA_ACCOUNT_VIEW))
1923 return NT_STATUS_ACCESS_DENIED;
1925 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
1926 if (!privset) {
1927 return NT_STATUS_NO_MEMORY;
1930 e.in.handle = r->in.handle;
1931 e.out.privs = &privset;
1933 status = _lsa_EnumPrivsAccount(p, &e);
1934 if (!NT_STATUS_IS_OK(status)) {
1935 DEBUG(10,("_lsa_GetSystemAccessAccount: "
1936 "failed to call _lsa_EnumPrivsAccount(): %s\n",
1937 nt_errstr(status)));
1938 return status;
1941 /* Samba4 would iterate over the privset to merge the policy mode bits,
1942 * not sure samba3 can do the same here, so just return what we did in
1943 * the past - gd */
1946 0x01 -> Log on locally
1947 0x02 -> Access this computer from network
1948 0x04 -> Log on as a batch job
1949 0x10 -> Log on as a service
1951 they can be ORed together
1954 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
1955 LSA_POLICY_MODE_NETWORK;
1957 return NT_STATUS_OK;
1960 /***************************************************************************
1961 update the systemaccount information
1962 ***************************************************************************/
1964 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
1965 struct lsa_SetSystemAccessAccount *r)
1967 struct lsa_info *info=NULL;
1968 GROUP_MAP map;
1970 /* find the connection policy handle. */
1971 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1972 return NT_STATUS_INVALID_HANDLE;
1974 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1975 return NT_STATUS_INVALID_HANDLE;
1978 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
1979 return NT_STATUS_ACCESS_DENIED;
1982 if (!pdb_getgrsid(&map, info->sid))
1983 return NT_STATUS_NO_SUCH_GROUP;
1985 return pdb_update_group_mapping_entry(&map);
1988 /***************************************************************************
1989 _lsa_AddPrivilegesToAccount
1990 For a given SID, add some privileges.
1991 ***************************************************************************/
1993 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
1994 struct lsa_AddPrivilegesToAccount *r)
1996 struct lsa_info *info = NULL;
1997 SE_PRIV mask;
1998 struct lsa_PrivilegeSet *set = NULL;
2000 /* find the connection policy handle. */
2001 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2002 return NT_STATUS_INVALID_HANDLE;
2004 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2005 return NT_STATUS_INVALID_HANDLE;
2008 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2009 return NT_STATUS_ACCESS_DENIED;
2012 set = r->in.privs;
2013 if ( !privilege_set_to_se_priv( &mask, set ) )
2014 return NT_STATUS_NO_SUCH_PRIVILEGE;
2016 if ( !grant_privilege( &info->sid, &mask ) ) {
2017 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege(%s) failed!\n",
2018 sid_string_dbg(&info->sid) ));
2019 DEBUG(3,("Privilege mask:\n"));
2020 dump_se_priv( DBGC_ALL, 3, &mask );
2021 return NT_STATUS_NO_SUCH_PRIVILEGE;
2024 return NT_STATUS_OK;
2027 /***************************************************************************
2028 _lsa_RemovePrivilegesFromAccount
2029 For a given SID, remove some privileges.
2030 ***************************************************************************/
2032 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2033 struct lsa_RemovePrivilegesFromAccount *r)
2035 struct lsa_info *info = NULL;
2036 SE_PRIV mask;
2037 struct lsa_PrivilegeSet *set = NULL;
2039 /* find the connection policy handle. */
2040 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2041 return NT_STATUS_INVALID_HANDLE;
2043 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2044 return NT_STATUS_INVALID_HANDLE;
2047 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2048 return NT_STATUS_ACCESS_DENIED;
2051 set = r->in.privs;
2053 if ( !privilege_set_to_se_priv( &mask, set ) )
2054 return NT_STATUS_NO_SUCH_PRIVILEGE;
2056 if ( !revoke_privilege( &info->sid, &mask ) ) {
2057 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2058 sid_string_dbg(&info->sid) ));
2059 DEBUG(3,("Privilege mask:\n"));
2060 dump_se_priv( DBGC_ALL, 3, &mask );
2061 return NT_STATUS_NO_SUCH_PRIVILEGE;
2064 return NT_STATUS_OK;
2067 /***************************************************************************
2068 _lsa_LookupPrivName
2069 ***************************************************************************/
2071 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2072 struct lsa_LookupPrivName *r)
2074 struct lsa_info *info = NULL;
2075 const char *name;
2076 struct lsa_StringLarge *lsa_name;
2078 /* find the connection policy handle. */
2079 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2080 return NT_STATUS_INVALID_HANDLE;
2083 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2084 return NT_STATUS_INVALID_HANDLE;
2087 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2088 return NT_STATUS_ACCESS_DENIED;
2091 name = luid_to_privilege_name(r->in.luid);
2092 if (!name) {
2093 return NT_STATUS_NO_SUCH_PRIVILEGE;
2096 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2097 if (!lsa_name) {
2098 return NT_STATUS_NO_MEMORY;
2101 lsa_name->string = talloc_strdup(lsa_name, name);
2102 if (!lsa_name->string) {
2103 TALLOC_FREE(lsa_name);
2104 return NT_STATUS_NO_MEMORY;
2107 *r->out.name = lsa_name;
2109 return NT_STATUS_OK;
2112 /***************************************************************************
2113 _lsa_QuerySecurity
2114 ***************************************************************************/
2116 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
2117 struct lsa_QuerySecurity *r)
2119 struct lsa_info *handle=NULL;
2120 struct security_descriptor *psd = NULL;
2121 size_t sd_size;
2122 NTSTATUS status;
2124 /* find the connection policy handle. */
2125 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2126 return NT_STATUS_INVALID_HANDLE;
2128 switch (handle->type) {
2129 case LSA_HANDLE_POLICY_TYPE:
2130 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2131 &lsa_policy_mapping, NULL, 0);
2132 break;
2133 case LSA_HANDLE_ACCOUNT_TYPE:
2134 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2135 &lsa_account_mapping,
2136 &handle->sid, LSA_ACCOUNT_ALL_ACCESS);
2137 break;
2138 default:
2139 status = NT_STATUS_INVALID_HANDLE;
2140 break;
2143 if (!NT_STATUS_IS_OK(status)) {
2144 return status;
2147 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2148 if (!*r->out.sdbuf) {
2149 return NT_STATUS_NO_MEMORY;
2152 return status;
2155 /***************************************************************************
2156 _lsa_AddAccountRights
2157 ***************************************************************************/
2159 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
2160 struct lsa_AddAccountRights *r)
2162 struct lsa_info *info = NULL;
2163 int i = 0;
2164 uint32_t acc_granted = 0;
2165 struct security_descriptor *psd = NULL;
2166 size_t sd_size;
2167 struct dom_sid sid;
2168 NTSTATUS status;
2170 /* find the connection policy handle. */
2171 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2172 return NT_STATUS_INVALID_HANDLE;
2174 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2175 return NT_STATUS_INVALID_HANDLE;
2178 /* get the generic lsa account SD for this SID until we store it */
2179 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2180 &lsa_account_mapping,
2181 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2182 if (!NT_STATUS_IS_OK(status)) {
2183 return status;
2187 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2188 * on the policy handle. If it does, ask for
2189 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2190 * on the account sid. We don't check here so just use the latter. JRA.
2193 status = access_check_object(psd, p->server_info->ptok,
2194 NULL, 0,
2195 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2196 &acc_granted, "_lsa_AddAccountRights" );
2197 if (!NT_STATUS_IS_OK(status)) {
2198 return status;
2201 /* according to an NT4 PDC, you can add privileges to SIDs even without
2202 call_lsa_create_account() first. And you can use any arbitrary SID. */
2204 sid_copy( &sid, r->in.sid );
2206 for ( i=0; i < r->in.rights->count; i++ ) {
2208 const char *privname = r->in.rights->names[i].string;
2210 /* only try to add non-null strings */
2212 if ( !privname )
2213 continue;
2215 if ( !grant_privilege_by_name( &sid, privname ) ) {
2216 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2217 privname ));
2218 return NT_STATUS_NO_SUCH_PRIVILEGE;
2222 return NT_STATUS_OK;
2225 /***************************************************************************
2226 _lsa_RemoveAccountRights
2227 ***************************************************************************/
2229 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
2230 struct lsa_RemoveAccountRights *r)
2232 struct lsa_info *info = NULL;
2233 int i = 0;
2234 struct security_descriptor *psd = NULL;
2235 size_t sd_size;
2236 struct dom_sid sid;
2237 const char *privname = NULL;
2238 uint32_t acc_granted = 0;
2239 NTSTATUS status;
2241 /* find the connection policy handle. */
2242 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2243 return NT_STATUS_INVALID_HANDLE;
2245 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2246 return NT_STATUS_INVALID_HANDLE;
2249 /* get the generic lsa account SD for this SID until we store it */
2250 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2251 &lsa_account_mapping,
2252 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2253 if (!NT_STATUS_IS_OK(status)) {
2254 return status;
2258 * From the MS DOCs. We need
2259 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2260 * and DELETE on the account sid.
2263 status = access_check_object(psd, p->server_info->ptok,
2264 NULL, 0,
2265 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2266 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
2267 &acc_granted, "_lsa_RemoveAccountRights");
2268 if (!NT_STATUS_IS_OK(status)) {
2269 return status;
2272 sid_copy( &sid, r->in.sid );
2274 if ( r->in.remove_all ) {
2275 if ( !revoke_all_privileges( &sid ) )
2276 return NT_STATUS_ACCESS_DENIED;
2278 return NT_STATUS_OK;
2281 for ( i=0; i < r->in.rights->count; i++ ) {
2283 privname = r->in.rights->names[i].string;
2285 /* only try to add non-null strings */
2287 if ( !privname )
2288 continue;
2290 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2291 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2292 privname ));
2293 return NT_STATUS_NO_SUCH_PRIVILEGE;
2297 return NT_STATUS_OK;
2300 /*******************************************************************
2301 ********************************************************************/
2303 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
2304 struct lsa_RightSet *r,
2305 PRIVILEGE_SET *privileges)
2307 uint32 i;
2308 const char *privname;
2309 const char **privname_array = NULL;
2310 int num_priv = 0;
2312 for (i=0; i<privileges->count; i++) {
2314 privname = luid_to_privilege_name(&privileges->set[i].luid);
2315 if (privname) {
2316 if (!add_string_to_array(mem_ctx, privname,
2317 &privname_array, &num_priv)) {
2318 return NT_STATUS_NO_MEMORY;
2323 if (num_priv) {
2325 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
2326 num_priv);
2327 if (!r->names) {
2328 return NT_STATUS_NO_MEMORY;
2331 for (i=0; i<num_priv; i++) {
2332 init_lsa_StringLarge(&r->names[i], privname_array[i]);
2335 r->count = num_priv;
2338 return NT_STATUS_OK;
2341 /***************************************************************************
2342 _lsa_EnumAccountRights
2343 ***************************************************************************/
2345 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
2346 struct lsa_EnumAccountRights *r)
2348 NTSTATUS status;
2349 struct lsa_info *info = NULL;
2350 struct dom_sid sid;
2351 PRIVILEGE_SET privileges;
2352 SE_PRIV mask;
2354 /* find the connection policy handle. */
2356 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2357 return NT_STATUS_INVALID_HANDLE;
2359 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2360 return NT_STATUS_INVALID_HANDLE;
2363 if (!(info->access & LSA_ACCOUNT_VIEW)) {
2364 return NT_STATUS_ACCESS_DENIED;
2367 /* according to an NT4 PDC, you can add privileges to SIDs even without
2368 call_lsa_create_account() first. And you can use any arbitrary SID. */
2370 sid_copy( &sid, r->in.sid );
2372 /* according to MS-LSAD 3.1.4.5.10 it is required to return
2373 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
2374 * the lsa database */
2376 if (!get_privileges_for_sids(&mask, &sid, 1)) {
2377 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2380 status = privilege_set_init(&privileges);
2381 if (!NT_STATUS_IS_OK(status)) {
2382 return status;
2385 se_priv_to_privilege_set(&privileges, &mask);
2387 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
2388 sid_string_dbg(&sid), privileges.count));
2390 status = init_lsa_right_set(p->mem_ctx, r->out.rights, &privileges);
2392 privilege_set_free( &privileges );
2394 return status;
2397 /***************************************************************************
2398 _lsa_LookupPrivValue
2399 ***************************************************************************/
2401 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
2402 struct lsa_LookupPrivValue *r)
2404 struct lsa_info *info = NULL;
2405 const char *name = NULL;
2406 struct lsa_LUIDAttribute priv_luid;
2407 SE_PRIV mask;
2409 /* find the connection policy handle. */
2411 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2412 return NT_STATUS_INVALID_HANDLE;
2414 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2415 return NT_STATUS_INVALID_HANDLE;
2418 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
2419 return NT_STATUS_ACCESS_DENIED;
2421 name = r->in.name->string;
2423 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
2425 if ( !se_priv_from_name( name, &mask ) )
2426 return NT_STATUS_NO_SUCH_PRIVILEGE;
2428 priv_luid = get_privilege_luid( &mask );
2430 r->out.luid->low = priv_luid.luid.low;
2431 r->out.luid->high = priv_luid.luid.high;
2433 return NT_STATUS_OK;
2436 /***************************************************************************
2437 _lsa_EnumAccountsWithUserRight
2438 ***************************************************************************/
2440 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
2441 struct lsa_EnumAccountsWithUserRight *r)
2443 NTSTATUS status;
2444 struct lsa_info *info = NULL;
2445 struct dom_sid *sids = NULL;
2446 int num_sids = 0;
2447 uint32_t i;
2448 SE_PRIV mask;
2450 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2451 return NT_STATUS_INVALID_HANDLE;
2454 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2455 return NT_STATUS_INVALID_HANDLE;
2458 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
2459 return NT_STATUS_ACCESS_DENIED;
2462 if (!r->in.name || !r->in.name->string) {
2463 return NT_STATUS_NO_SUCH_PRIVILEGE;
2466 if (!se_priv_from_name(r->in.name->string, &mask)) {
2467 return NT_STATUS_NO_SUCH_PRIVILEGE;
2470 status = privilege_enum_sids(&mask, p->mem_ctx,
2471 &sids, &num_sids);
2472 if (!NT_STATUS_IS_OK(status)) {
2473 return status;
2476 r->out.sids->num_sids = num_sids;
2477 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
2478 r->out.sids->num_sids);
2480 for (i=0; i < r->out.sids->num_sids; i++) {
2481 r->out.sids->sids[i].sid = sid_dup_talloc(r->out.sids->sids,
2482 &sids[i]);
2483 if (!r->out.sids->sids[i].sid) {
2484 TALLOC_FREE(r->out.sids->sids);
2485 r->out.sids->num_sids = 0;
2486 return NT_STATUS_NO_MEMORY;
2490 return NT_STATUS_OK;
2493 /***************************************************************************
2494 _lsa_Delete
2495 ***************************************************************************/
2497 NTSTATUS _lsa_Delete(struct pipes_struct *p,
2498 struct lsa_Delete *r)
2500 return NT_STATUS_NOT_SUPPORTED;
2504 * From here on the server routines are just dummy ones to make smbd link with
2505 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
2506 * pulling the server stubs across one by one.
2509 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
2511 p->rng_fault_state = True;
2512 return NT_STATUS_NOT_IMPLEMENTED;
2515 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
2516 struct lsa_ChangePassword *r)
2518 p->rng_fault_state = True;
2519 return NT_STATUS_NOT_IMPLEMENTED;
2522 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
2524 p->rng_fault_state = True;
2525 return NT_STATUS_NOT_IMPLEMENTED;
2528 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
2530 p->rng_fault_state = True;
2531 return NT_STATUS_NOT_IMPLEMENTED;
2534 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
2535 struct lsa_GetQuotasForAccount *r)
2537 p->rng_fault_state = True;
2538 return NT_STATUS_NOT_IMPLEMENTED;
2541 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
2542 struct lsa_SetQuotasForAccount *r)
2544 p->rng_fault_state = True;
2545 return NT_STATUS_NOT_IMPLEMENTED;
2548 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
2549 struct lsa_QueryTrustedDomainInfo *r)
2551 p->rng_fault_state = True;
2552 return NT_STATUS_NOT_IMPLEMENTED;
2555 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
2556 struct lsa_SetInformationTrustedDomain *r)
2558 p->rng_fault_state = True;
2559 return NT_STATUS_NOT_IMPLEMENTED;
2562 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
2564 p->rng_fault_state = True;
2565 return NT_STATUS_NOT_IMPLEMENTED;
2568 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2569 struct lsa_QueryTrustedDomainInfoBySid *r)
2571 p->rng_fault_state = True;
2572 return NT_STATUS_NOT_IMPLEMENTED;
2575 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
2576 struct lsa_SetTrustedDomainInfo *r)
2578 p->rng_fault_state = True;
2579 return NT_STATUS_NOT_IMPLEMENTED;
2582 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
2583 struct lsa_DeleteTrustedDomain *r)
2585 p->rng_fault_state = True;
2586 return NT_STATUS_NOT_IMPLEMENTED;
2589 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
2590 struct lsa_StorePrivateData *r)
2592 p->rng_fault_state = True;
2593 return NT_STATUS_NOT_IMPLEMENTED;
2596 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
2597 struct lsa_RetrievePrivateData *r)
2599 p->rng_fault_state = True;
2600 return NT_STATUS_NOT_IMPLEMENTED;
2603 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
2604 struct lsa_SetInfoPolicy2 *r)
2606 p->rng_fault_state = True;
2607 return NT_STATUS_NOT_IMPLEMENTED;
2610 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2611 struct lsa_QueryTrustedDomainInfoByName *r)
2613 p->rng_fault_state = True;
2614 return NT_STATUS_NOT_IMPLEMENTED;
2617 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
2618 struct lsa_SetTrustedDomainInfoByName *r)
2620 p->rng_fault_state = True;
2621 return NT_STATUS_NOT_IMPLEMENTED;
2624 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
2625 struct lsa_EnumTrustedDomainsEx *r)
2627 p->rng_fault_state = True;
2628 return NT_STATUS_NOT_IMPLEMENTED;
2631 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
2632 struct lsa_CreateTrustedDomainEx *r)
2634 p->rng_fault_state = True;
2635 return NT_STATUS_NOT_IMPLEMENTED;
2638 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
2639 struct lsa_CloseTrustedDomainEx *r)
2641 p->rng_fault_state = True;
2642 return NT_STATUS_NOT_IMPLEMENTED;
2645 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
2646 struct lsa_QueryDomainInformationPolicy *r)
2648 p->rng_fault_state = True;
2649 return NT_STATUS_NOT_IMPLEMENTED;
2652 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
2653 struct lsa_SetDomainInformationPolicy *r)
2655 p->rng_fault_state = True;
2656 return NT_STATUS_NOT_IMPLEMENTED;
2659 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
2660 struct lsa_OpenTrustedDomainByName *r)
2662 p->rng_fault_state = True;
2663 return NT_STATUS_NOT_IMPLEMENTED;
2666 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
2668 p->rng_fault_state = True;
2669 return NT_STATUS_NOT_IMPLEMENTED;
2672 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
2673 struct lsa_CreateTrustedDomainEx2 *r)
2675 p->rng_fault_state = True;
2676 return NT_STATUS_NOT_IMPLEMENTED;
2679 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
2681 p->rng_fault_state = True;
2682 return NT_STATUS_NOT_IMPLEMENTED;
2685 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
2687 p->rng_fault_state = True;
2688 return NT_STATUS_NOT_IMPLEMENTED;
2691 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
2693 p->rng_fault_state = True;
2694 return NT_STATUS_NOT_IMPLEMENTED;
2697 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
2698 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2700 p->rng_fault_state = True;
2701 return NT_STATUS_NOT_IMPLEMENTED;
2704 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
2705 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2707 p->rng_fault_state = True;
2708 return NT_STATUS_NOT_IMPLEMENTED;
2711 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
2713 p->rng_fault_state = True;
2714 return NT_STATUS_NOT_IMPLEMENTED;
2717 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
2718 struct lsa_CREDRGETTARGETINFO *r)
2720 p->rng_fault_state = True;
2721 return NT_STATUS_NOT_IMPLEMENTED;
2724 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
2725 struct lsa_CREDRPROFILELOADED *r)
2727 p->rng_fault_state = True;
2728 return NT_STATUS_NOT_IMPLEMENTED;
2731 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
2732 struct lsa_CREDRGETSESSIONTYPES *r)
2734 p->rng_fault_state = True;
2735 return NT_STATUS_NOT_IMPLEMENTED;
2738 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
2739 struct lsa_LSARREGISTERAUDITEVENT *r)
2741 p->rng_fault_state = True;
2742 return NT_STATUS_NOT_IMPLEMENTED;
2745 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
2746 struct lsa_LSARGENAUDITEVENT *r)
2748 p->rng_fault_state = True;
2749 return NT_STATUS_NOT_IMPLEMENTED;
2752 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
2753 struct lsa_LSARUNREGISTERAUDITEVENT *r)
2755 p->rng_fault_state = True;
2756 return NT_STATUS_NOT_IMPLEMENTED;
2759 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
2760 struct lsa_lsaRQueryForestTrustInformation *r)
2762 p->rng_fault_state = True;
2763 return NT_STATUS_NOT_IMPLEMENTED;
2766 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
2767 struct lsa_lsaRSetForestTrustInformation *r)
2769 p->rng_fault_state = True;
2770 return NT_STATUS_NOT_IMPLEMENTED;
2773 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
2774 struct lsa_CREDRRENAME *r)
2776 p->rng_fault_state = True;
2777 return NT_STATUS_NOT_IMPLEMENTED;
2780 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
2781 struct lsa_LSAROPENPOLICYSCE *r)
2783 p->rng_fault_state = True;
2784 return NT_STATUS_NOT_IMPLEMENTED;
2787 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
2788 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2790 p->rng_fault_state = True;
2791 return NT_STATUS_NOT_IMPLEMENTED;
2794 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
2795 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2797 p->rng_fault_state = True;
2798 return NT_STATUS_NOT_IMPLEMENTED;
2801 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
2802 struct lsa_LSARADTREPORTSECURITYEVENT *r)
2804 p->rng_fault_state = True;
2805 return NT_STATUS_NOT_IMPLEMENTED;