s4:repl_meta_data: increment the attribute version with each change
[Samba.git] / source3 / rpc_server / srv_lsa_nt.c
blobcc5d23ce71fc3e3f3682ed3b0040637ce1f83fae
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"
33 #undef DBGC_CLASS
34 #define DBGC_CLASS DBGC_RPC_SRV
36 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
38 extern PRIVS privs[];
40 enum lsa_handle_type { LSA_HANDLE_POLICY_TYPE = 1, LSA_HANDLE_ACCOUNT_TYPE };
42 struct lsa_info {
43 DOM_SID sid;
44 uint32 access;
45 enum lsa_handle_type type;
48 const struct generic_mapping lsa_account_mapping = {
49 LSA_ACCOUNT_READ,
50 LSA_ACCOUNT_WRITE,
51 LSA_ACCOUNT_EXECUTE,
52 LSA_ACCOUNT_ALL_ACCESS
55 const struct generic_mapping lsa_policy_mapping = {
56 LSA_POLICY_READ,
57 LSA_POLICY_WRITE,
58 LSA_POLICY_EXECUTE,
59 LSA_POLICY_ALL_ACCESS
62 /***************************************************************************
63 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
64 ***************************************************************************/
66 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
67 struct lsa_RefDomainList *ref,
68 const char *dom_name,
69 DOM_SID *dom_sid)
71 int num = 0;
73 if (dom_name != NULL) {
74 for (num = 0; num < ref->count; num++) {
75 if (sid_equal(dom_sid, ref->domains[num].sid)) {
76 return num;
79 } else {
80 num = ref->count;
83 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
84 /* index not found, already at maximum domain limit */
85 return -1;
88 ref->count = num + 1;
89 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
91 ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains,
92 struct lsa_DomainInfo, ref->count);
93 if (!ref->domains) {
94 return -1;
97 ZERO_STRUCT(ref->domains[num]);
99 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
100 ref->domains[num].sid = sid_dup_talloc(mem_ctx, dom_sid);
101 if (!ref->domains[num].sid) {
102 return -1;
105 return num;
109 /***************************************************************************
110 initialize a lsa_DomainInfo structure.
111 ***************************************************************************/
113 static void init_dom_query_3(struct lsa_DomainInfo *r,
114 const char *name,
115 DOM_SID *sid)
117 init_lsa_StringLarge(&r->name, name);
118 r->sid = sid;
121 /***************************************************************************
122 initialize a lsa_DomainInfo structure.
123 ***************************************************************************/
125 static void init_dom_query_5(struct lsa_DomainInfo *r,
126 const char *name,
127 DOM_SID *sid)
129 init_lsa_StringLarge(&r->name, name);
130 r->sid = sid;
133 /***************************************************************************
134 lookup_lsa_rids. Must be called as root for lookup_name to work.
135 ***************************************************************************/
137 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
138 struct lsa_RefDomainList *ref,
139 struct lsa_TranslatedSid *prid,
140 uint32_t num_entries,
141 struct lsa_String *name,
142 int flags,
143 uint32_t *pmapped_count)
145 uint32 mapped_count, i;
147 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
149 mapped_count = 0;
150 *pmapped_count = 0;
152 for (i = 0; i < num_entries; i++) {
153 DOM_SID sid;
154 uint32 rid;
155 int dom_idx;
156 const char *full_name;
157 const char *domain;
158 enum lsa_SidType type = SID_NAME_UNKNOWN;
160 /* Split name into domain and user component */
162 full_name = name[i].string;
163 if (full_name == NULL) {
164 return NT_STATUS_NO_MEMORY;
167 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
169 /* We can ignore the result of lookup_name, it will not touch
170 "type" if it's not successful */
172 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
173 &sid, &type);
175 switch (type) {
176 case SID_NAME_USER:
177 case SID_NAME_DOM_GRP:
178 case SID_NAME_DOMAIN:
179 case SID_NAME_ALIAS:
180 case SID_NAME_WKN_GRP:
181 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
182 /* Leave these unchanged */
183 break;
184 default:
185 /* Don't hand out anything but the list above */
186 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
187 type = SID_NAME_UNKNOWN;
188 break;
191 rid = 0;
192 dom_idx = -1;
194 if (type != SID_NAME_UNKNOWN) {
195 sid_split_rid(&sid, &rid);
196 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
197 mapped_count++;
200 prid[i].sid_type = type;
201 prid[i].rid = rid;
202 prid[i].sid_index = dom_idx;
205 *pmapped_count = mapped_count;
206 return NT_STATUS_OK;
209 /***************************************************************************
210 lookup_lsa_sids. Must be called as root for lookup_name to work.
211 ***************************************************************************/
213 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
214 struct lsa_RefDomainList *ref,
215 struct lsa_TranslatedSid3 *trans_sids,
216 uint32_t num_entries,
217 struct lsa_String *name,
218 int flags,
219 uint32 *pmapped_count)
221 uint32 mapped_count, i;
223 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
225 mapped_count = 0;
226 *pmapped_count = 0;
228 for (i = 0; i < num_entries; i++) {
229 DOM_SID sid;
230 uint32 rid;
231 int dom_idx;
232 const char *full_name;
233 const char *domain;
234 enum lsa_SidType type = SID_NAME_UNKNOWN;
236 ZERO_STRUCT(sid);
238 /* Split name into domain and user component */
240 full_name = name[i].string;
241 if (full_name == NULL) {
242 return NT_STATUS_NO_MEMORY;
245 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
247 /* We can ignore the result of lookup_name, it will not touch
248 "type" if it's not successful */
250 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
251 &sid, &type);
253 switch (type) {
254 case SID_NAME_USER:
255 case SID_NAME_DOM_GRP:
256 case SID_NAME_DOMAIN:
257 case SID_NAME_ALIAS:
258 case SID_NAME_WKN_GRP:
259 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
260 /* Leave these unchanged */
261 break;
262 default:
263 /* Don't hand out anything but the list above */
264 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
265 type = SID_NAME_UNKNOWN;
266 break;
269 rid = 0;
270 dom_idx = -1;
272 if (type != SID_NAME_UNKNOWN) {
273 DOM_SID domain_sid;
274 sid_copy(&domain_sid, &sid);
275 sid_split_rid(&domain_sid, &rid);
276 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
277 mapped_count++;
280 /* Initialize the lsa_TranslatedSid3 return. */
281 trans_sids[i].sid_type = type;
282 trans_sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
283 trans_sids[i].sid_index = dom_idx;
286 *pmapped_count = mapped_count;
287 return NT_STATUS_OK;
290 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size,
291 const struct generic_mapping *map,
292 DOM_SID *sid, uint32_t sid_access)
294 DOM_SID adm_sid;
295 SEC_ACE ace[5];
296 size_t i = 0;
298 SEC_ACL *psa = NULL;
300 /* READ|EXECUTE access for Everyone */
302 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
303 map->generic_execute | map->generic_read, 0);
305 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
307 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
308 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
309 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
310 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
312 /* Add Full Access for Domain Admins */
313 sid_copy(&adm_sid, get_global_sam_sid());
314 sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS);
315 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
316 map->generic_all, 0);
318 /* If we have a sid, give it some special access */
320 if (sid) {
321 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
322 sid_access, 0);
325 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
326 return NT_STATUS_NO_MEMORY;
328 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
329 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
330 psa, sd_size)) == NULL)
331 return NT_STATUS_NO_MEMORY;
333 return NT_STATUS_OK;
337 /***************************************************************************
338 _lsa_OpenPolicy2
339 ***************************************************************************/
341 NTSTATUS _lsa_OpenPolicy2(pipes_struct *p,
342 struct lsa_OpenPolicy2 *r)
344 struct lsa_info *info;
345 SEC_DESC *psd = NULL;
346 size_t sd_size;
347 uint32 des_access = r->in.access_mask;
348 uint32 acc_granted;
349 NTSTATUS status;
351 /* Work out max allowed. */
352 map_max_allowed_access(p->server_info->ptok,
353 &p->server_info->utok,
354 &des_access);
356 /* map the generic bits to the lsa policy ones */
357 se_map_generic(&des_access, &lsa_policy_mapping);
359 /* get the generic lsa policy SD until we store it */
360 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
361 NULL, 0);
362 if (!NT_STATUS_IS_OK(status)) {
363 return status;
366 status = access_check_object(psd, p->server_info->ptok,
367 NULL, 0, des_access,
368 &acc_granted, "_lsa_OpenPolicy2" );
370 if (!NT_STATUS_IS_OK(status)) {
371 return status;
374 /* associate the domain SID with the (unique) handle. */
375 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
376 if (info == NULL) {
377 return NT_STATUS_NO_MEMORY;
380 sid_copy(&info->sid,get_global_sam_sid());
381 info->access = acc_granted;
382 info->type = LSA_HANDLE_POLICY_TYPE;
384 /* set up the LSA QUERY INFO response */
385 if (!create_policy_hnd(p, r->out.handle, info))
386 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
388 return NT_STATUS_OK;
391 /***************************************************************************
392 _lsa_OpenPolicy
393 ***************************************************************************/
395 NTSTATUS _lsa_OpenPolicy(pipes_struct *p,
396 struct lsa_OpenPolicy *r)
398 struct lsa_OpenPolicy2 o;
400 o.in.system_name = NULL; /* should be ignored */
401 o.in.attr = r->in.attr;
402 o.in.access_mask = r->in.access_mask;
404 o.out.handle = r->out.handle;
406 return _lsa_OpenPolicy2(p, &o);
409 /***************************************************************************
410 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
411 ufff, done :) mimir
412 ***************************************************************************/
414 NTSTATUS _lsa_EnumTrustDom(pipes_struct *p,
415 struct lsa_EnumTrustDom *r)
417 struct lsa_info *info;
418 uint32 next_idx;
419 struct trustdom_info **domains;
420 struct lsa_DomainInfo *lsa_domains = NULL;
421 int i;
424 * preferred length is set to 5 as a "our" preferred length
425 * nt sets this parameter to 2
426 * update (20.08.2002): it's not preferred length, but preferred size!
427 * it needs further investigation how to optimally choose this value
429 uint32 max_num_domains =
430 r->in.max_size < 5 ? r->in.max_size : 10;
431 uint32 num_domains;
432 NTSTATUS nt_status;
433 uint32 num_thistime;
435 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
436 return NT_STATUS_INVALID_HANDLE;
438 if (info->type != LSA_HANDLE_POLICY_TYPE) {
439 return NT_STATUS_INVALID_HANDLE;
442 /* check if the user has enough rights */
443 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
444 return NT_STATUS_ACCESS_DENIED;
446 become_root();
447 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &num_domains, &domains);
448 unbecome_root();
450 if (!NT_STATUS_IS_OK(nt_status)) {
451 return nt_status;
454 if (*r->in.resume_handle < num_domains) {
455 num_thistime = MIN(num_domains, max_num_domains);
457 nt_status = STATUS_MORE_ENTRIES;
459 if (*r->in.resume_handle + num_thistime > num_domains) {
460 num_thistime = num_domains - *r->in.resume_handle;
461 nt_status = NT_STATUS_OK;
464 next_idx = *r->in.resume_handle + num_thistime;
465 } else {
466 num_thistime = 0;
467 next_idx = 0xffffffff;
468 nt_status = NT_STATUS_NO_MORE_ENTRIES;
471 /* set up the lsa_enum_trust_dom response */
473 lsa_domains = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo,
474 num_thistime);
475 if (!lsa_domains) {
476 return NT_STATUS_NO_MEMORY;
479 for (i=0; i<num_thistime; i++) {
480 init_lsa_StringLarge(&lsa_domains[i].name, domains[i]->name);
481 lsa_domains[i].sid = &domains[i]->sid;
484 *r->out.resume_handle = next_idx;
485 r->out.domains->count = num_thistime;
486 r->out.domains->domains = lsa_domains;
488 return nt_status;
491 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
492 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
493 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
495 /***************************************************************************
496 _lsa_QueryInfoPolicy
497 ***************************************************************************/
499 NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p,
500 struct lsa_QueryInfoPolicy *r)
502 NTSTATUS status = NT_STATUS_OK;
503 struct lsa_info *handle;
504 DOM_SID domain_sid;
505 const char *name;
506 DOM_SID *sid = NULL;
507 union lsa_PolicyInformation *info = NULL;
508 uint32_t acc_required = 0;
510 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
511 return NT_STATUS_INVALID_HANDLE;
513 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
514 return NT_STATUS_INVALID_HANDLE;
517 switch (r->in.level) {
518 case LSA_POLICY_INFO_AUDIT_LOG:
519 case LSA_POLICY_INFO_AUDIT_EVENTS:
520 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
521 break;
522 case LSA_POLICY_INFO_DOMAIN:
523 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
524 break;
525 case LSA_POLICY_INFO_PD:
526 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
527 break;
528 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
529 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
530 break;
531 case LSA_POLICY_INFO_ROLE:
532 case LSA_POLICY_INFO_REPLICA:
533 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
534 break;
535 case LSA_POLICY_INFO_QUOTA:
536 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
537 break;
538 case LSA_POLICY_INFO_MOD:
539 case LSA_POLICY_INFO_AUDIT_FULL_SET:
540 /* according to MS-LSAD 3.1.4.4.3 */
541 return NT_STATUS_INVALID_PARAMETER;
542 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
543 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
544 break;
545 case LSA_POLICY_INFO_DNS:
546 case LSA_POLICY_INFO_DNS_INT:
547 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
548 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
549 break;
550 default:
551 break;
554 if (!(handle->access & acc_required)) {
555 /* return NT_STATUS_ACCESS_DENIED; */
558 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
559 if (!info) {
560 return NT_STATUS_NO_MEMORY;
563 switch (r->in.level) {
564 case LSA_POLICY_INFO_AUDIT_EVENTS:
567 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
569 /* check if the user has enough rights */
570 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
571 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
572 return NT_STATUS_ACCESS_DENIED;
575 /* fake info: We audit everything. ;) */
577 info->audit_events.auditing_mode = true;
578 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
579 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
580 enum lsa_PolicyAuditPolicy,
581 info->audit_events.count);
582 if (!info->audit_events.settings) {
583 return NT_STATUS_NO_MEMORY;
586 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
587 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
588 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
589 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
590 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
591 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
592 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
594 break;
596 case LSA_POLICY_INFO_DOMAIN:
597 /* check if the user has enough rights */
598 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
599 return NT_STATUS_ACCESS_DENIED;
601 /* Request PolicyPrimaryDomainInformation. */
602 switch (lp_server_role()) {
603 case ROLE_DOMAIN_PDC:
604 case ROLE_DOMAIN_BDC:
605 name = get_global_sam_name();
606 sid = sid_dup_talloc(p->mem_ctx, get_global_sam_sid());
607 if (!sid) {
608 return NT_STATUS_NO_MEMORY;
610 break;
611 case ROLE_DOMAIN_MEMBER:
612 name = lp_workgroup();
613 /* We need to return the Domain SID here. */
614 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
615 sid = sid_dup_talloc(p->mem_ctx, &domain_sid);
616 if (!sid) {
617 return NT_STATUS_NO_MEMORY;
619 } else {
620 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
622 break;
623 case ROLE_STANDALONE:
624 name = lp_workgroup();
625 sid = NULL;
626 break;
627 default:
628 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
630 init_dom_query_3(&info->domain, name, sid);
631 break;
632 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
633 /* check if the user has enough rights */
634 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
635 return NT_STATUS_ACCESS_DENIED;
637 /* Request PolicyAccountDomainInformation. */
638 name = get_global_sam_name();
639 sid = get_global_sam_sid();
641 init_dom_query_5(&info->account_domain, name, sid);
642 break;
643 case LSA_POLICY_INFO_ROLE:
644 /* check if the user has enough rights */
645 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
646 return NT_STATUS_ACCESS_DENIED;
648 switch (lp_server_role()) {
649 case ROLE_DOMAIN_BDC:
651 * only a BDC is a backup controller
652 * of the domain, it controls.
654 info->role.role = LSA_ROLE_BACKUP;
655 break;
656 default:
658 * any other role is a primary
659 * of the domain, it controls.
661 info->role.role = LSA_ROLE_PRIMARY;
662 break;
664 break;
665 case LSA_POLICY_INFO_DNS:
666 case LSA_POLICY_INFO_DNS_INT: {
667 struct pdb_domain_info *dominfo;
669 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
670 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
671 "without ADS passdb backend\n"));
672 status = NT_STATUS_INVALID_INFO_CLASS;
673 break;
676 dominfo = pdb_get_domain_info(info);
677 if (dominfo == NULL) {
678 status = NT_STATUS_NO_MEMORY;
679 break;
682 init_lsa_StringLarge(&info->dns.name,
683 dominfo->name);
684 init_lsa_StringLarge(&info->dns.dns_domain,
685 dominfo->dns_domain);
686 init_lsa_StringLarge(&info->dns.dns_forest,
687 dominfo->dns_forest);
688 info->dns.domain_guid = dominfo->guid;
689 info->dns.sid = &dominfo->sid;
690 break;
692 default:
693 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
694 r->in.level));
695 status = NT_STATUS_INVALID_INFO_CLASS;
696 break;
699 *r->out.info = info;
701 return status;
704 /***************************************************************************
705 _lsa_QueryInfoPolicy2
706 ***************************************************************************/
708 NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p,
709 struct lsa_QueryInfoPolicy2 *r2)
711 struct lsa_QueryInfoPolicy r;
713 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
714 p->rng_fault_state = True;
715 return NT_STATUS_NOT_IMPLEMENTED;
718 ZERO_STRUCT(r);
719 r.in.handle = r2->in.handle;
720 r.in.level = r2->in.level;
721 r.out.info = r2->out.info;
723 return _lsa_QueryInfoPolicy(p, &r);
726 /***************************************************************************
727 _lsa_lookup_sids_internal
728 ***************************************************************************/
730 static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p,
731 TALLOC_CTX *mem_ctx,
732 uint16_t level, /* input */
733 int num_sids, /* input */
734 struct lsa_SidPtr *sid, /* input */
735 struct lsa_RefDomainList **pp_ref, /* input/output */
736 struct lsa_TranslatedName2 **pp_names,/* input/output */
737 uint32_t *pp_mapped_count) /* input/output */
739 NTSTATUS status;
740 int i;
741 const DOM_SID **sids = NULL;
742 struct lsa_RefDomainList *ref = NULL;
743 uint32 mapped_count = 0;
744 struct lsa_dom_info *dom_infos = NULL;
745 struct lsa_name_info *name_infos = NULL;
746 struct lsa_TranslatedName2 *names = NULL;
748 *pp_mapped_count = 0;
749 *pp_names = NULL;
750 *pp_ref = NULL;
752 if (num_sids == 0) {
753 return NT_STATUS_OK;
756 sids = TALLOC_ARRAY(p->mem_ctx, const DOM_SID *, num_sids);
757 ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
759 if (sids == NULL || ref == NULL) {
760 return NT_STATUS_NO_MEMORY;
763 for (i=0; i<num_sids; i++) {
764 sids[i] = sid[i].sid;
767 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
768 &dom_infos, &name_infos);
770 if (!NT_STATUS_IS_OK(status)) {
771 return status;
774 names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
775 if (names == NULL) {
776 return NT_STATUS_NO_MEMORY;
779 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
781 if (!dom_infos[i].valid) {
782 break;
785 if (init_lsa_ref_domain_list(mem_ctx, ref,
786 dom_infos[i].name,
787 &dom_infos[i].sid) != i) {
788 DEBUG(0, ("Domain %s mentioned twice??\n",
789 dom_infos[i].name));
790 return NT_STATUS_INTERNAL_ERROR;
794 for (i=0; i<num_sids; i++) {
795 struct lsa_name_info *name = &name_infos[i];
797 if (name->type == SID_NAME_UNKNOWN) {
798 fstring tmp;
799 name->dom_idx = -1;
800 /* Unknown sids should return the string
801 * representation of the SID. Windows 2003 behaves
802 * rather erratic here, in many cases it returns the
803 * RID as 8 bytes hex, in others it returns the full
804 * SID. We (Jerry/VL) could not figure out which the
805 * hard cases are, so leave it with the SID. */
806 name->name = talloc_asprintf(p->mem_ctx, "%s",
807 sid_to_fstring(tmp,
808 sids[i]));
809 if (name->name == NULL) {
810 return NT_STATUS_NO_MEMORY;
812 } else {
813 mapped_count += 1;
816 names[i].sid_type = name->type;
817 names[i].name.string = name->name;
818 names[i].sid_index = name->dom_idx;
819 names[i].unknown = 0;
822 status = NT_STATUS_NONE_MAPPED;
823 if (mapped_count > 0) {
824 status = (mapped_count < num_sids) ?
825 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
828 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
829 num_sids, mapped_count, nt_errstr(status)));
831 *pp_mapped_count = mapped_count;
832 *pp_names = names;
833 *pp_ref = ref;
835 return status;
838 /***************************************************************************
839 _lsa_LookupSids
840 ***************************************************************************/
842 NTSTATUS _lsa_LookupSids(pipes_struct *p,
843 struct lsa_LookupSids *r)
845 NTSTATUS status;
846 struct lsa_info *handle;
847 int num_sids = r->in.sids->num_sids;
848 uint32 mapped_count = 0;
849 struct lsa_RefDomainList *domains = NULL;
850 struct lsa_TranslatedName *names_out = NULL;
851 struct lsa_TranslatedName2 *names = NULL;
852 int i;
854 if ((r->in.level < 1) || (r->in.level > 6)) {
855 return NT_STATUS_INVALID_PARAMETER;
858 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
859 return NT_STATUS_INVALID_HANDLE;
862 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
863 return NT_STATUS_INVALID_HANDLE;
866 /* check if the user has enough rights */
867 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
868 return NT_STATUS_ACCESS_DENIED;
871 if (num_sids > MAX_LOOKUP_SIDS) {
872 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
873 MAX_LOOKUP_SIDS, num_sids));
874 return NT_STATUS_NONE_MAPPED;
877 status = _lsa_lookup_sids_internal(p,
878 p->mem_ctx,
879 r->in.level,
880 num_sids,
881 r->in.sids->sids,
882 &domains,
883 &names,
884 &mapped_count);
886 /* Only return here when there is a real error.
887 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
888 the requested sids could be resolved. Older versions of XP (pre SP3)
889 rely that we return with the string representations of those SIDs in
890 that case. If we don't, XP crashes - Guenther
893 if (NT_STATUS_IS_ERR(status) &&
894 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
895 return status;
898 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
899 names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
900 num_sids);
901 if (!names_out) {
902 return NT_STATUS_NO_MEMORY;
905 for (i=0; i<num_sids; i++) {
906 names_out[i].sid_type = names[i].sid_type;
907 names_out[i].name = names[i].name;
908 names_out[i].sid_index = names[i].sid_index;
911 *r->out.domains = domains;
912 r->out.names->count = num_sids;
913 r->out.names->names = names_out;
914 *r->out.count = mapped_count;
916 return status;
919 /***************************************************************************
920 _lsa_LookupSids2
921 ***************************************************************************/
923 NTSTATUS _lsa_LookupSids2(pipes_struct *p,
924 struct lsa_LookupSids2 *r)
926 NTSTATUS status;
927 struct lsa_info *handle;
928 int num_sids = r->in.sids->num_sids;
929 uint32 mapped_count = 0;
930 struct lsa_RefDomainList *domains = NULL;
931 struct lsa_TranslatedName2 *names = NULL;
932 bool check_policy = true;
934 switch (p->hdr_req.opnum) {
935 case NDR_LSA_LOOKUPSIDS3:
936 check_policy = false;
937 break;
938 case NDR_LSA_LOOKUPSIDS2:
939 default:
940 check_policy = true;
943 if ((r->in.level < 1) || (r->in.level > 6)) {
944 return NT_STATUS_INVALID_PARAMETER;
947 if (check_policy) {
948 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
949 return NT_STATUS_INVALID_HANDLE;
952 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
953 return NT_STATUS_INVALID_HANDLE;
956 /* check if the user has enough rights */
957 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
958 return NT_STATUS_ACCESS_DENIED;
962 if (num_sids > MAX_LOOKUP_SIDS) {
963 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
964 MAX_LOOKUP_SIDS, num_sids));
965 return NT_STATUS_NONE_MAPPED;
968 status = _lsa_lookup_sids_internal(p,
969 p->mem_ctx,
970 r->in.level,
971 num_sids,
972 r->in.sids->sids,
973 &domains,
974 &names,
975 &mapped_count);
977 *r->out.domains = domains;
978 r->out.names->count = num_sids;
979 r->out.names->names = names;
980 *r->out.count = mapped_count;
982 return status;
985 /***************************************************************************
986 _lsa_LookupSids3
987 ***************************************************************************/
989 NTSTATUS _lsa_LookupSids3(pipes_struct *p,
990 struct lsa_LookupSids3 *r)
992 struct lsa_LookupSids2 q;
994 /* No policy handle on this call. Restrict to crypto connections. */
995 if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
996 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
997 get_remote_machine_name() ));
998 return NT_STATUS_INVALID_PARAMETER;
1001 q.in.handle = NULL;
1002 q.in.sids = r->in.sids;
1003 q.in.level = r->in.level;
1004 q.in.lookup_options = r->in.lookup_options;
1005 q.in.client_revision = r->in.client_revision;
1006 q.in.names = r->in.names;
1007 q.in.count = r->in.count;
1009 q.out.domains = r->out.domains;
1010 q.out.names = r->out.names;
1011 q.out.count = r->out.count;
1013 return _lsa_LookupSids2(p, &q);
1016 /***************************************************************************
1017 ***************************************************************************/
1019 static int lsa_lookup_level_to_flags(uint16 level)
1021 int flags;
1023 switch (level) {
1024 case 1:
1025 flags = LOOKUP_NAME_ALL;
1026 break;
1027 case 2:
1028 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1029 break;
1030 case 3:
1031 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1032 break;
1033 case 4:
1034 case 5:
1035 case 6:
1036 default:
1037 flags = LOOKUP_NAME_NONE;
1038 break;
1041 return flags;
1044 /***************************************************************************
1045 _lsa_LookupNames
1046 ***************************************************************************/
1048 NTSTATUS _lsa_LookupNames(pipes_struct *p,
1049 struct lsa_LookupNames *r)
1051 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1052 struct lsa_info *handle;
1053 struct lsa_String *names = r->in.names;
1054 uint32 num_entries = r->in.num_names;
1055 struct lsa_RefDomainList *domains = NULL;
1056 struct lsa_TranslatedSid *rids = NULL;
1057 uint32 mapped_count = 0;
1058 int flags = 0;
1060 if (num_entries > MAX_LOOKUP_SIDS) {
1061 num_entries = MAX_LOOKUP_SIDS;
1062 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1063 num_entries));
1066 flags = lsa_lookup_level_to_flags(r->in.level);
1068 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1069 if (!domains) {
1070 return NT_STATUS_NO_MEMORY;
1073 if (num_entries) {
1074 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1075 num_entries);
1076 if (!rids) {
1077 return NT_STATUS_NO_MEMORY;
1079 } else {
1080 rids = NULL;
1083 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1084 status = NT_STATUS_INVALID_HANDLE;
1085 goto done;
1088 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1089 return NT_STATUS_INVALID_HANDLE;
1092 /* check if the user has enough rights */
1093 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1094 status = NT_STATUS_ACCESS_DENIED;
1095 goto done;
1098 /* set up the LSA Lookup RIDs response */
1099 become_root(); /* lookup_name can require root privs */
1100 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1101 names, flags, &mapped_count);
1102 unbecome_root();
1104 done:
1106 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1107 if (mapped_count == 0) {
1108 status = NT_STATUS_NONE_MAPPED;
1109 } else if (mapped_count != num_entries) {
1110 status = STATUS_SOME_UNMAPPED;
1114 *r->out.count = mapped_count;
1115 *r->out.domains = domains;
1116 r->out.sids->sids = rids;
1117 r->out.sids->count = num_entries;
1119 return status;
1122 /***************************************************************************
1123 _lsa_LookupNames2
1124 ***************************************************************************/
1126 NTSTATUS _lsa_LookupNames2(pipes_struct *p,
1127 struct lsa_LookupNames2 *r)
1129 NTSTATUS status;
1130 struct lsa_LookupNames q;
1131 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1132 struct lsa_TransSidArray *sid_array = NULL;
1133 uint32_t i;
1135 sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1136 if (!sid_array) {
1137 return NT_STATUS_NO_MEMORY;
1140 q.in.handle = r->in.handle;
1141 q.in.num_names = r->in.num_names;
1142 q.in.names = r->in.names;
1143 q.in.level = r->in.level;
1144 q.in.sids = sid_array;
1145 q.in.count = r->in.count;
1146 /* we do not know what this is for */
1147 /* = r->in.unknown1; */
1148 /* = r->in.unknown2; */
1150 q.out.domains = r->out.domains;
1151 q.out.sids = sid_array;
1152 q.out.count = r->out.count;
1154 status = _lsa_LookupNames(p, &q);
1156 sid_array2->count = sid_array->count;
1157 sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1158 if (!sid_array2->sids) {
1159 return NT_STATUS_NO_MEMORY;
1162 for (i=0; i<sid_array->count; i++) {
1163 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1164 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1165 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1166 sid_array2->sids[i].unknown = 0;
1169 r->out.sids = sid_array2;
1171 return status;
1174 /***************************************************************************
1175 _lsa_LookupNames3
1176 ***************************************************************************/
1178 NTSTATUS _lsa_LookupNames3(pipes_struct *p,
1179 struct lsa_LookupNames3 *r)
1181 NTSTATUS status;
1182 struct lsa_info *handle;
1183 struct lsa_String *names = r->in.names;
1184 uint32 num_entries = r->in.num_names;
1185 struct lsa_RefDomainList *domains = NULL;
1186 struct lsa_TranslatedSid3 *trans_sids = NULL;
1187 uint32 mapped_count = 0;
1188 int flags = 0;
1189 bool check_policy = true;
1191 switch (p->hdr_req.opnum) {
1192 case NDR_LSA_LOOKUPNAMES4:
1193 check_policy = false;
1194 break;
1195 case NDR_LSA_LOOKUPNAMES3:
1196 default:
1197 check_policy = true;
1200 if (num_entries > MAX_LOOKUP_SIDS) {
1201 num_entries = MAX_LOOKUP_SIDS;
1202 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1205 /* Probably the lookup_level is some sort of bitmask. */
1206 if (r->in.level == 1) {
1207 flags = LOOKUP_NAME_ALL;
1210 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1211 if (!domains) {
1212 return NT_STATUS_NO_MEMORY;
1215 if (num_entries) {
1216 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1217 num_entries);
1218 if (!trans_sids) {
1219 return NT_STATUS_NO_MEMORY;
1221 } else {
1222 trans_sids = NULL;
1225 if (check_policy) {
1227 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1228 status = NT_STATUS_INVALID_HANDLE;
1229 goto done;
1232 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1233 return NT_STATUS_INVALID_HANDLE;
1236 /* check if the user has enough rights */
1237 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1238 status = NT_STATUS_ACCESS_DENIED;
1239 goto done;
1243 /* set up the LSA Lookup SIDs response */
1244 become_root(); /* lookup_name can require root privs */
1245 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1246 names, flags, &mapped_count);
1247 unbecome_root();
1249 done:
1251 if (NT_STATUS_IS_OK(status)) {
1252 if (mapped_count == 0) {
1253 status = NT_STATUS_NONE_MAPPED;
1254 } else if (mapped_count != num_entries) {
1255 status = STATUS_SOME_UNMAPPED;
1259 *r->out.count = mapped_count;
1260 *r->out.domains = domains;
1261 r->out.sids->sids = trans_sids;
1262 r->out.sids->count = num_entries;
1264 return status;
1267 /***************************************************************************
1268 _lsa_LookupNames4
1269 ***************************************************************************/
1271 NTSTATUS _lsa_LookupNames4(pipes_struct *p,
1272 struct lsa_LookupNames4 *r)
1274 struct lsa_LookupNames3 q;
1276 /* No policy handle on this call. Restrict to crypto connections. */
1277 if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
1278 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1279 get_remote_machine_name() ));
1280 return NT_STATUS_INVALID_PARAMETER;
1283 q.in.handle = NULL;
1284 q.in.num_names = r->in.num_names;
1285 q.in.names = r->in.names;
1286 q.in.level = r->in.level;
1287 q.in.lookup_options = r->in.lookup_options;
1288 q.in.client_revision = r->in.client_revision;
1289 q.in.sids = r->in.sids;
1290 q.in.count = r->in.count;
1292 q.out.domains = r->out.domains;
1293 q.out.sids = r->out.sids;
1294 q.out.count = r->out.count;
1296 return _lsa_LookupNames3(p, &q);
1299 /***************************************************************************
1300 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1301 ***************************************************************************/
1303 NTSTATUS _lsa_Close(pipes_struct *p, struct lsa_Close *r)
1305 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1306 return NT_STATUS_INVALID_HANDLE;
1309 close_policy_hnd(p, r->in.handle);
1310 ZERO_STRUCTP(r->out.handle);
1311 return NT_STATUS_OK;
1314 /***************************************************************************
1315 ***************************************************************************/
1317 NTSTATUS _lsa_OpenSecret(pipes_struct *p, struct lsa_OpenSecret *r)
1319 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1322 /***************************************************************************
1323 ***************************************************************************/
1325 NTSTATUS _lsa_OpenTrustedDomain(pipes_struct *p, struct lsa_OpenTrustedDomain *r)
1327 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1330 /***************************************************************************
1331 ***************************************************************************/
1333 NTSTATUS _lsa_CreateTrustedDomain(pipes_struct *p, struct lsa_CreateTrustedDomain *r)
1335 return NT_STATUS_ACCESS_DENIED;
1338 /***************************************************************************
1339 ***************************************************************************/
1341 NTSTATUS _lsa_CreateSecret(pipes_struct *p, struct lsa_CreateSecret *r)
1343 return NT_STATUS_ACCESS_DENIED;
1346 /***************************************************************************
1347 ***************************************************************************/
1349 NTSTATUS _lsa_SetSecret(pipes_struct *p, struct lsa_SetSecret *r)
1351 return NT_STATUS_ACCESS_DENIED;
1354 /***************************************************************************
1355 _lsa_DeleteObject
1356 ***************************************************************************/
1358 NTSTATUS _lsa_DeleteObject(pipes_struct *p,
1359 struct lsa_DeleteObject *r)
1361 NTSTATUS status;
1362 struct lsa_info *info = NULL;
1364 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
1365 return NT_STATUS_INVALID_HANDLE;
1368 if (!(info->access & STD_RIGHT_DELETE_ACCESS)) {
1369 return NT_STATUS_ACCESS_DENIED;
1372 switch (info->type) {
1373 case LSA_HANDLE_ACCOUNT_TYPE:
1374 status = privilege_delete_account(&info->sid);
1375 if (!NT_STATUS_IS_OK(status)) {
1376 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
1377 nt_errstr(status)));
1378 return status;
1380 break;
1381 default:
1382 return NT_STATUS_INVALID_HANDLE;
1385 close_policy_hnd(p, r->in.handle);
1386 ZERO_STRUCTP(r->out.handle);
1388 return status;
1391 /***************************************************************************
1392 _lsa_EnumPrivs
1393 ***************************************************************************/
1395 NTSTATUS _lsa_EnumPrivs(pipes_struct *p,
1396 struct lsa_EnumPrivs *r)
1398 struct lsa_info *handle;
1399 uint32 i;
1400 uint32 enum_context = *r->in.resume_handle;
1401 int num_privs = count_all_privileges();
1402 struct lsa_PrivEntry *entries = NULL;
1403 LUID_ATTR luid;
1405 /* remember that the enum_context starts at 0 and not 1 */
1407 if ( enum_context >= num_privs )
1408 return NT_STATUS_NO_MORE_ENTRIES;
1410 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
1411 enum_context, num_privs));
1413 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1414 return NT_STATUS_INVALID_HANDLE;
1416 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1417 return NT_STATUS_INVALID_HANDLE;
1420 /* check if the user has enough rights
1421 I don't know if it's the right one. not documented. */
1423 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1424 return NT_STATUS_ACCESS_DENIED;
1426 if (num_privs) {
1427 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
1428 if (!entries) {
1429 return NT_STATUS_NO_MEMORY;
1431 } else {
1432 entries = NULL;
1435 for (i = 0; i < num_privs; i++) {
1436 if( i < enum_context) {
1438 init_lsa_StringLarge(&entries[i].name, NULL);
1440 entries[i].luid.low = 0;
1441 entries[i].luid.high = 0;
1442 } else {
1444 init_lsa_StringLarge(&entries[i].name, privs[i].name);
1446 luid = get_privilege_luid( &privs[i].se_priv );
1448 entries[i].luid.low = luid.luid.low;
1449 entries[i].luid.high = luid.luid.high;
1453 enum_context = num_privs;
1455 *r->out.resume_handle = enum_context;
1456 r->out.privs->count = num_privs;
1457 r->out.privs->privs = entries;
1459 return NT_STATUS_OK;
1462 /***************************************************************************
1463 _lsa_LookupPrivDisplayName
1464 ***************************************************************************/
1466 NTSTATUS _lsa_LookupPrivDisplayName(pipes_struct *p,
1467 struct lsa_LookupPrivDisplayName *r)
1469 struct lsa_info *handle;
1470 const char *description;
1471 struct lsa_StringLarge *lsa_name;
1473 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1474 return NT_STATUS_INVALID_HANDLE;
1476 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1477 return NT_STATUS_INVALID_HANDLE;
1480 /* check if the user has enough rights */
1483 * I don't know if it's the right one. not documented.
1485 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1486 return NT_STATUS_ACCESS_DENIED;
1488 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
1490 description = get_privilege_dispname(r->in.name->string);
1491 if (!description) {
1492 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
1493 return NT_STATUS_NO_SUCH_PRIVILEGE;
1496 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
1498 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
1499 if (!lsa_name) {
1500 return NT_STATUS_NO_MEMORY;
1503 init_lsa_StringLarge(lsa_name, description);
1505 *r->out.returned_language_id = r->in.language_id;
1506 *r->out.disp_name = lsa_name;
1508 return NT_STATUS_OK;
1511 /***************************************************************************
1512 _lsa_EnumAccounts
1513 ***************************************************************************/
1515 NTSTATUS _lsa_EnumAccounts(pipes_struct *p,
1516 struct lsa_EnumAccounts *r)
1518 struct lsa_info *handle;
1519 DOM_SID *sid_list;
1520 int i, j, num_entries;
1521 NTSTATUS status;
1522 struct lsa_SidPtr *sids = NULL;
1524 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1525 return NT_STATUS_INVALID_HANDLE;
1527 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1528 return NT_STATUS_INVALID_HANDLE;
1531 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1532 return NT_STATUS_ACCESS_DENIED;
1534 sid_list = NULL;
1535 num_entries = 0;
1537 /* The only way we can currently find out all the SIDs that have been
1538 privileged is to scan all privileges */
1540 status = privilege_enumerate_accounts(&sid_list, &num_entries);
1541 if (!NT_STATUS_IS_OK(status)) {
1542 return status;
1545 if (*r->in.resume_handle >= num_entries) {
1546 return NT_STATUS_NO_MORE_ENTRIES;
1549 if (num_entries - *r->in.resume_handle) {
1550 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
1551 num_entries - *r->in.resume_handle);
1552 if (!sids) {
1553 talloc_free(sid_list);
1554 return NT_STATUS_NO_MEMORY;
1557 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
1558 sids[j].sid = sid_dup_talloc(p->mem_ctx, &sid_list[i]);
1559 if (!sids[j].sid) {
1560 talloc_free(sid_list);
1561 return NT_STATUS_NO_MEMORY;
1566 talloc_free(sid_list);
1568 *r->out.resume_handle = num_entries;
1569 r->out.sids->num_sids = num_entries;
1570 r->out.sids->sids = sids;
1572 return NT_STATUS_OK;
1575 /***************************************************************************
1576 _lsa_GetUserName
1577 ***************************************************************************/
1579 NTSTATUS _lsa_GetUserName(pipes_struct *p,
1580 struct lsa_GetUserName *r)
1582 const char *username, *domname;
1583 struct lsa_String *account_name = NULL;
1584 struct lsa_String *authority_name = NULL;
1586 if (r->in.account_name &&
1587 *r->in.account_name) {
1588 return NT_STATUS_INVALID_PARAMETER;
1591 if (r->in.authority_name &&
1592 *r->in.authority_name) {
1593 return NT_STATUS_INVALID_PARAMETER;
1596 if (p->server_info->guest) {
1598 * I'm 99% sure this is not the right place to do this,
1599 * global_sid_Anonymous should probably be put into the token
1600 * instead of the guest id -- vl
1602 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
1603 &domname, &username, NULL)) {
1604 return NT_STATUS_NO_MEMORY;
1606 } else {
1607 username = p->server_info->sanitized_username;
1608 domname = pdb_get_domain(p->server_info->sam_account);
1611 account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1612 if (!account_name) {
1613 return NT_STATUS_NO_MEMORY;
1615 init_lsa_String(account_name, username);
1617 if (r->out.authority_name) {
1618 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1619 if (!authority_name) {
1620 return NT_STATUS_NO_MEMORY;
1622 init_lsa_String(authority_name, domname);
1625 *r->out.account_name = account_name;
1626 if (r->out.authority_name) {
1627 *r->out.authority_name = authority_name;
1630 return NT_STATUS_OK;
1633 /***************************************************************************
1634 _lsa_CreateAccount
1635 ***************************************************************************/
1637 NTSTATUS _lsa_CreateAccount(pipes_struct *p,
1638 struct lsa_CreateAccount *r)
1640 NTSTATUS status;
1641 struct lsa_info *handle;
1642 struct lsa_info *info;
1643 uint32_t acc_granted;
1644 struct security_descriptor *psd;
1645 size_t sd_size;
1647 /* find the connection policy handle. */
1648 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1649 return NT_STATUS_INVALID_HANDLE;
1651 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1652 return NT_STATUS_INVALID_HANDLE;
1655 /* check if the user has enough rights */
1657 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
1658 return NT_STATUS_ACCESS_DENIED;
1661 /* map the generic bits to the lsa policy ones */
1662 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1664 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1665 &lsa_account_mapping,
1666 r->in.sid, LSA_POLICY_ALL_ACCESS);
1667 if (!NT_STATUS_IS_OK(status)) {
1668 return status;
1671 status = access_check_object(psd, p->server_info->ptok,
1672 NULL, 0, r->in.access_mask,
1673 &acc_granted, "_lsa_CreateAccount");
1674 if (!NT_STATUS_IS_OK(status)) {
1675 return status;
1678 if ( is_privileged_sid( r->in.sid ) )
1679 return NT_STATUS_OBJECT_NAME_COLLISION;
1681 /* associate the user/group SID with the (unique) handle. */
1683 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1684 if (info == NULL) {
1685 return NT_STATUS_NO_MEMORY;
1688 info->sid = *r->in.sid;
1689 info->access = acc_granted;
1690 info->type = LSA_HANDLE_ACCOUNT_TYPE;
1692 /* get a (unique) handle. open a policy on it. */
1693 if (!create_policy_hnd(p, r->out.acct_handle, info))
1694 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1696 return privilege_create_account( &info->sid );
1699 /***************************************************************************
1700 _lsa_OpenAccount
1701 ***************************************************************************/
1703 NTSTATUS _lsa_OpenAccount(pipes_struct *p,
1704 struct lsa_OpenAccount *r)
1706 struct lsa_info *handle;
1707 struct lsa_info *info;
1708 SEC_DESC *psd = NULL;
1709 size_t sd_size;
1710 uint32_t des_access = r->in.access_mask;
1711 uint32_t acc_granted;
1712 NTSTATUS status;
1714 /* find the connection policy handle. */
1715 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1716 return NT_STATUS_INVALID_HANDLE;
1718 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1719 return NT_STATUS_INVALID_HANDLE;
1722 /* des_access is for the account here, not the policy
1723 * handle - so don't check against policy handle. */
1725 /* Work out max allowed. */
1726 map_max_allowed_access(p->server_info->ptok,
1727 &p->server_info->utok,
1728 &des_access);
1730 /* map the generic bits to the lsa account ones */
1731 se_map_generic(&des_access, &lsa_account_mapping);
1733 /* get the generic lsa account SD until we store it */
1734 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1735 &lsa_account_mapping,
1736 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
1737 if (!NT_STATUS_IS_OK(status)) {
1738 return status;
1741 status = access_check_object(psd, p->server_info->ptok,
1742 NULL, 0, des_access,
1743 &acc_granted, "_lsa_OpenAccount" );
1745 if (!NT_STATUS_IS_OK(status)) {
1746 return status;
1749 /* TODO: Fis the parsing routine before reenabling this check! */
1750 #if 0
1751 if (!lookup_sid(&handle->sid, dom_name, name, &type))
1752 return NT_STATUS_ACCESS_DENIED;
1753 #endif
1754 /* associate the user/group SID with the (unique) handle. */
1755 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1756 if (info == NULL) {
1757 return NT_STATUS_NO_MEMORY;
1760 info->sid = *r->in.sid;
1761 info->access = acc_granted;
1762 info->type = LSA_HANDLE_ACCOUNT_TYPE;
1764 /* get a (unique) handle. open a policy on it. */
1765 if (!create_policy_hnd(p, r->out.acct_handle, info))
1766 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1768 return NT_STATUS_OK;
1771 /***************************************************************************
1772 _lsa_EnumPrivsAccount
1773 For a given SID, enumerate all the privilege this account has.
1774 ***************************************************************************/
1776 NTSTATUS _lsa_EnumPrivsAccount(pipes_struct *p,
1777 struct lsa_EnumPrivsAccount *r)
1779 NTSTATUS status = NT_STATUS_OK;
1780 struct lsa_info *info=NULL;
1781 SE_PRIV mask;
1782 PRIVILEGE_SET privileges;
1783 struct lsa_PrivilegeSet *priv_set = NULL;
1784 struct lsa_LUIDAttribute *luid_attrs = NULL;
1785 int i;
1787 /* find the connection policy handle. */
1788 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1789 return NT_STATUS_INVALID_HANDLE;
1791 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1792 return NT_STATUS_INVALID_HANDLE;
1795 if (!(info->access & LSA_ACCOUNT_VIEW))
1796 return NT_STATUS_ACCESS_DENIED;
1798 get_privileges_for_sids(&mask, &info->sid, 1);
1800 privilege_set_init( &privileges );
1802 priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
1803 if (!priv_set) {
1804 status = NT_STATUS_NO_MEMORY;
1805 goto done;
1808 if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
1810 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
1811 sid_string_dbg(&info->sid),
1812 privileges.count));
1814 luid_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx,
1815 struct lsa_LUIDAttribute,
1816 privileges.count);
1817 if (!luid_attrs) {
1818 status = NT_STATUS_NO_MEMORY;
1819 goto done;
1822 for (i=0; i<privileges.count; i++) {
1823 luid_attrs[i].luid.low = privileges.set[i].luid.low;
1824 luid_attrs[i].luid.high = privileges.set[i].luid.high;
1825 luid_attrs[i].attribute = privileges.set[i].attr;
1828 priv_set->count = privileges.count;
1829 priv_set->unknown = 0;
1830 priv_set->set = luid_attrs;
1832 } else {
1833 priv_set->count = 0;
1834 priv_set->unknown = 0;
1835 priv_set->set = NULL;
1838 *r->out.privs = priv_set;
1840 done:
1841 privilege_set_free( &privileges );
1843 return status;
1846 /***************************************************************************
1847 _lsa_GetSystemAccessAccount
1848 ***************************************************************************/
1850 NTSTATUS _lsa_GetSystemAccessAccount(pipes_struct *p,
1851 struct lsa_GetSystemAccessAccount *r)
1853 NTSTATUS status;
1854 struct lsa_info *info = NULL;
1855 struct lsa_EnumPrivsAccount e;
1856 struct lsa_PrivilegeSet *privset;
1858 /* find the connection policy handle. */
1860 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1861 return NT_STATUS_INVALID_HANDLE;
1863 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1864 return NT_STATUS_INVALID_HANDLE;
1867 if (!(info->access & LSA_ACCOUNT_VIEW))
1868 return NT_STATUS_ACCESS_DENIED;
1870 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
1871 if (!privset) {
1872 return NT_STATUS_NO_MEMORY;
1875 e.in.handle = r->in.handle;
1876 e.out.privs = &privset;
1878 status = _lsa_EnumPrivsAccount(p, &e);
1879 if (!NT_STATUS_IS_OK(status)) {
1880 DEBUG(10,("_lsa_GetSystemAccessAccount: "
1881 "failed to call _lsa_EnumPrivsAccount(): %s\n",
1882 nt_errstr(status)));
1883 return status;
1886 /* Samba4 would iterate over the privset to merge the policy mode bits,
1887 * not sure samba3 can do the same here, so just return what we did in
1888 * the past - gd */
1891 0x01 -> Log on locally
1892 0x02 -> Access this computer from network
1893 0x04 -> Log on as a batch job
1894 0x10 -> Log on as a service
1896 they can be ORed together
1899 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
1900 LSA_POLICY_MODE_NETWORK;
1902 return NT_STATUS_OK;
1905 /***************************************************************************
1906 update the systemaccount information
1907 ***************************************************************************/
1909 NTSTATUS _lsa_SetSystemAccessAccount(pipes_struct *p,
1910 struct lsa_SetSystemAccessAccount *r)
1912 struct lsa_info *info=NULL;
1913 GROUP_MAP map;
1915 /* find the connection policy handle. */
1916 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1917 return NT_STATUS_INVALID_HANDLE;
1919 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1920 return NT_STATUS_INVALID_HANDLE;
1923 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
1924 return NT_STATUS_ACCESS_DENIED;
1927 if (!pdb_getgrsid(&map, info->sid))
1928 return NT_STATUS_NO_SUCH_GROUP;
1930 return pdb_update_group_mapping_entry(&map);
1933 /***************************************************************************
1934 _lsa_AddPrivilegesToAccount
1935 For a given SID, add some privileges.
1936 ***************************************************************************/
1938 NTSTATUS _lsa_AddPrivilegesToAccount(pipes_struct *p,
1939 struct lsa_AddPrivilegesToAccount *r)
1941 struct lsa_info *info = NULL;
1942 SE_PRIV mask;
1943 struct lsa_PrivilegeSet *set = NULL;
1945 /* find the connection policy handle. */
1946 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1947 return NT_STATUS_INVALID_HANDLE;
1949 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1950 return NT_STATUS_INVALID_HANDLE;
1953 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
1954 return NT_STATUS_ACCESS_DENIED;
1957 set = r->in.privs;
1958 if ( !privilege_set_to_se_priv( &mask, set ) )
1959 return NT_STATUS_NO_SUCH_PRIVILEGE;
1961 if ( !grant_privilege( &info->sid, &mask ) ) {
1962 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege(%s) failed!\n",
1963 sid_string_dbg(&info->sid) ));
1964 DEBUG(3,("Privilege mask:\n"));
1965 dump_se_priv( DBGC_ALL, 3, &mask );
1966 return NT_STATUS_NO_SUCH_PRIVILEGE;
1969 return NT_STATUS_OK;
1972 /***************************************************************************
1973 _lsa_RemovePrivilegesFromAccount
1974 For a given SID, remove some privileges.
1975 ***************************************************************************/
1977 NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p,
1978 struct lsa_RemovePrivilegesFromAccount *r)
1980 struct lsa_info *info = NULL;
1981 SE_PRIV mask;
1982 struct lsa_PrivilegeSet *set = NULL;
1984 /* find the connection policy handle. */
1985 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1986 return NT_STATUS_INVALID_HANDLE;
1988 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1989 return NT_STATUS_INVALID_HANDLE;
1992 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
1993 return NT_STATUS_ACCESS_DENIED;
1996 set = r->in.privs;
1998 if ( !privilege_set_to_se_priv( &mask, set ) )
1999 return NT_STATUS_NO_SUCH_PRIVILEGE;
2001 if ( !revoke_privilege( &info->sid, &mask ) ) {
2002 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2003 sid_string_dbg(&info->sid) ));
2004 DEBUG(3,("Privilege mask:\n"));
2005 dump_se_priv( DBGC_ALL, 3, &mask );
2006 return NT_STATUS_NO_SUCH_PRIVILEGE;
2009 return NT_STATUS_OK;
2012 /***************************************************************************
2013 _lsa_LookupPrivName
2014 ***************************************************************************/
2016 NTSTATUS _lsa_LookupPrivName(pipes_struct *p,
2017 struct lsa_LookupPrivName *r)
2019 struct lsa_info *info = NULL;
2020 const char *name;
2021 struct lsa_StringLarge *lsa_name;
2023 /* find the connection policy handle. */
2024 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2025 return NT_STATUS_INVALID_HANDLE;
2028 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2029 return NT_STATUS_INVALID_HANDLE;
2032 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2033 return NT_STATUS_ACCESS_DENIED;
2036 name = luid_to_privilege_name((LUID *)r->in.luid);
2037 if (!name) {
2038 return NT_STATUS_NO_SUCH_PRIVILEGE;
2041 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2042 if (!lsa_name) {
2043 return NT_STATUS_NO_MEMORY;
2046 lsa_name->string = talloc_strdup(lsa_name, name);
2047 if (!lsa_name->string) {
2048 TALLOC_FREE(lsa_name);
2049 return NT_STATUS_NO_MEMORY;
2052 *r->out.name = lsa_name;
2054 return NT_STATUS_OK;
2057 /***************************************************************************
2058 _lsa_QuerySecurity
2059 ***************************************************************************/
2061 NTSTATUS _lsa_QuerySecurity(pipes_struct *p,
2062 struct lsa_QuerySecurity *r)
2064 struct lsa_info *handle=NULL;
2065 SEC_DESC *psd = NULL;
2066 size_t sd_size;
2067 NTSTATUS status;
2069 /* find the connection policy handle. */
2070 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2071 return NT_STATUS_INVALID_HANDLE;
2073 if (handle->type == LSA_HANDLE_POLICY_TYPE) {
2074 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2075 &lsa_policy_mapping, NULL, 0);
2076 } else if (handle->type == LSA_HANDLE_ACCOUNT_TYPE) {
2077 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2078 &lsa_account_mapping,
2079 &handle->sid, LSA_ACCOUNT_ALL_ACCESS);
2080 } else {
2081 status = NT_STATUS_INVALID_HANDLE;
2084 if (!NT_STATUS_IS_OK(status)) {
2085 return status;
2088 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2089 if (!*r->out.sdbuf) {
2090 return NT_STATUS_NO_MEMORY;
2093 return status;
2096 /***************************************************************************
2097 _lsa_AddAccountRights
2098 ***************************************************************************/
2100 NTSTATUS _lsa_AddAccountRights(pipes_struct *p,
2101 struct lsa_AddAccountRights *r)
2103 struct lsa_info *info = NULL;
2104 int i = 0;
2105 uint32_t acc_granted = 0;
2106 SEC_DESC *psd = NULL;
2107 size_t sd_size;
2108 DOM_SID sid;
2109 NTSTATUS status;
2111 /* find the connection policy handle. */
2112 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2113 return NT_STATUS_INVALID_HANDLE;
2115 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2116 return NT_STATUS_INVALID_HANDLE;
2119 /* get the generic lsa account SD for this SID until we store it */
2120 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2121 &lsa_account_mapping,
2122 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2123 if (!NT_STATUS_IS_OK(status)) {
2124 return status;
2128 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2129 * on the policy handle. If it does, ask for
2130 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2131 * on the account sid. We don't check here so just use the latter. JRA.
2134 status = access_check_object(psd, p->server_info->ptok,
2135 NULL, 0, LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2136 &acc_granted, "_lsa_AddAccountRights" );
2138 if (!NT_STATUS_IS_OK(status)) {
2139 return status;
2142 /* according to an NT4 PDC, you can add privileges to SIDs even without
2143 call_lsa_create_account() first. And you can use any arbitrary SID. */
2145 sid_copy( &sid, r->in.sid );
2147 for ( i=0; i < r->in.rights->count; i++ ) {
2149 const char *privname = r->in.rights->names[i].string;
2151 /* only try to add non-null strings */
2153 if ( !privname )
2154 continue;
2156 if ( !grant_privilege_by_name( &sid, privname ) ) {
2157 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2158 privname ));
2159 return NT_STATUS_NO_SUCH_PRIVILEGE;
2163 return NT_STATUS_OK;
2166 /***************************************************************************
2167 _lsa_RemoveAccountRights
2168 ***************************************************************************/
2170 NTSTATUS _lsa_RemoveAccountRights(pipes_struct *p,
2171 struct lsa_RemoveAccountRights *r)
2173 struct lsa_info *info = NULL;
2174 int i = 0;
2175 SEC_DESC *psd = NULL;
2176 size_t sd_size;
2177 DOM_SID sid;
2178 const char *privname = NULL;
2179 uint32_t acc_granted = 0;
2180 NTSTATUS status;
2182 /* find the connection policy handle. */
2183 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2184 return NT_STATUS_INVALID_HANDLE;
2186 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2187 return NT_STATUS_INVALID_HANDLE;
2190 /* get the generic lsa account SD for this SID until we store it */
2191 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2192 &lsa_account_mapping,
2193 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2194 if (!NT_STATUS_IS_OK(status)) {
2195 return status;
2199 * From the MS DOCs. We need
2200 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2201 * and DELETE on the account sid.
2204 status = access_check_object(psd, p->server_info->ptok,
2205 NULL, 0, LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2206 LSA_ACCOUNT_VIEW|STD_RIGHT_DELETE_ACCESS,
2207 &acc_granted, "_lsa_AddAccountRights" );
2209 if (!NT_STATUS_IS_OK(status)) {
2210 return status;
2213 sid_copy( &sid, r->in.sid );
2215 if ( r->in.remove_all ) {
2216 if ( !revoke_all_privileges( &sid ) )
2217 return NT_STATUS_ACCESS_DENIED;
2219 return NT_STATUS_OK;
2222 for ( i=0; i < r->in.rights->count; i++ ) {
2224 privname = r->in.rights->names[i].string;
2226 /* only try to add non-null strings */
2228 if ( !privname )
2229 continue;
2231 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2232 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2233 privname ));
2234 return NT_STATUS_NO_SUCH_PRIVILEGE;
2238 return NT_STATUS_OK;
2241 /*******************************************************************
2242 ********************************************************************/
2244 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
2245 struct lsa_RightSet *r,
2246 PRIVILEGE_SET *privileges)
2248 uint32 i;
2249 const char *privname;
2250 const char **privname_array = NULL;
2251 int num_priv = 0;
2253 for (i=0; i<privileges->count; i++) {
2255 privname = luid_to_privilege_name(&privileges->set[i].luid);
2256 if (privname) {
2257 if (!add_string_to_array(mem_ctx, privname,
2258 &privname_array, &num_priv)) {
2259 return NT_STATUS_NO_MEMORY;
2264 if (num_priv) {
2266 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
2267 num_priv);
2268 if (!r->names) {
2269 return NT_STATUS_NO_MEMORY;
2272 for (i=0; i<num_priv; i++) {
2273 init_lsa_StringLarge(&r->names[i], privname_array[i]);
2276 r->count = num_priv;
2279 return NT_STATUS_OK;
2282 /***************************************************************************
2283 _lsa_EnumAccountRights
2284 ***************************************************************************/
2286 NTSTATUS _lsa_EnumAccountRights(pipes_struct *p,
2287 struct lsa_EnumAccountRights *r)
2289 NTSTATUS status;
2290 struct lsa_info *info = NULL;
2291 DOM_SID sid;
2292 PRIVILEGE_SET privileges;
2293 SE_PRIV mask;
2295 /* find the connection policy handle. */
2297 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2298 return NT_STATUS_INVALID_HANDLE;
2300 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2301 return NT_STATUS_INVALID_HANDLE;
2304 if (!(info->access & LSA_ACCOUNT_VIEW)) {
2305 return NT_STATUS_ACCESS_DENIED;
2308 /* according to an NT4 PDC, you can add privileges to SIDs even without
2309 call_lsa_create_account() first. And you can use any arbitrary SID. */
2311 sid_copy( &sid, r->in.sid );
2313 /* according to MS-LSAD 3.1.4.5.10 it is required to return
2314 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
2315 * the lsa database */
2317 if (!get_privileges_for_sids(&mask, &sid, 1)) {
2318 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2321 status = privilege_set_init(&privileges);
2322 if (!NT_STATUS_IS_OK(status)) {
2323 return status;
2326 se_priv_to_privilege_set(&privileges, &mask);
2328 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
2329 sid_string_dbg(&sid), privileges.count));
2331 status = init_lsa_right_set(p->mem_ctx, r->out.rights, &privileges);
2333 privilege_set_free( &privileges );
2335 return status;
2338 /***************************************************************************
2339 _lsa_LookupPrivValue
2340 ***************************************************************************/
2342 NTSTATUS _lsa_LookupPrivValue(pipes_struct *p,
2343 struct lsa_LookupPrivValue *r)
2345 struct lsa_info *info = NULL;
2346 const char *name = NULL;
2347 LUID_ATTR priv_luid;
2348 SE_PRIV mask;
2350 /* find the connection policy handle. */
2352 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2353 return NT_STATUS_INVALID_HANDLE;
2355 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2356 return NT_STATUS_INVALID_HANDLE;
2359 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
2360 return NT_STATUS_ACCESS_DENIED;
2362 name = r->in.name->string;
2364 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
2366 if ( !se_priv_from_name( name, &mask ) )
2367 return NT_STATUS_NO_SUCH_PRIVILEGE;
2369 priv_luid = get_privilege_luid( &mask );
2371 r->out.luid->low = priv_luid.luid.low;
2372 r->out.luid->high = priv_luid.luid.high;
2374 return NT_STATUS_OK;
2377 /***************************************************************************
2378 _lsa_EnumAccountsWithUserRight
2379 ***************************************************************************/
2381 NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p,
2382 struct lsa_EnumAccountsWithUserRight *r)
2384 NTSTATUS status;
2385 struct lsa_info *info = NULL;
2386 struct dom_sid *sids = NULL;
2387 int num_sids = 0;
2388 uint32_t i;
2389 SE_PRIV mask;
2391 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2392 return NT_STATUS_INVALID_HANDLE;
2395 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2396 return NT_STATUS_INVALID_HANDLE;
2399 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
2400 return NT_STATUS_ACCESS_DENIED;
2403 if (!r->in.name || !r->in.name->string) {
2404 return NT_STATUS_NO_SUCH_PRIVILEGE;
2407 if (!se_priv_from_name(r->in.name->string, &mask)) {
2408 return NT_STATUS_NO_SUCH_PRIVILEGE;
2411 status = privilege_enum_sids(&mask, p->mem_ctx,
2412 &sids, &num_sids);
2413 if (!NT_STATUS_IS_OK(status)) {
2414 return status;
2417 r->out.sids->num_sids = num_sids;
2418 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
2419 r->out.sids->num_sids);
2421 for (i=0; i < r->out.sids->num_sids; i++) {
2422 r->out.sids->sids[i].sid = sid_dup_talloc(r->out.sids->sids,
2423 &sids[i]);
2424 if (!r->out.sids->sids[i].sid) {
2425 TALLOC_FREE(r->out.sids->sids);
2426 r->out.sids->num_sids = 0;
2427 return NT_STATUS_NO_MEMORY;
2431 return NT_STATUS_OK;
2434 /***************************************************************************
2435 _lsa_Delete
2436 ***************************************************************************/
2438 NTSTATUS _lsa_Delete(pipes_struct *p,
2439 struct lsa_Delete *r)
2441 return NT_STATUS_NOT_SUPPORTED;
2445 * From here on the server routines are just dummy ones to make smbd link with
2446 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
2447 * pulling the server stubs across one by one.
2450 NTSTATUS _lsa_SetSecObj(pipes_struct *p, struct lsa_SetSecObj *r)
2452 p->rng_fault_state = True;
2453 return NT_STATUS_NOT_IMPLEMENTED;
2456 NTSTATUS _lsa_ChangePassword(pipes_struct *p, struct lsa_ChangePassword *r)
2458 p->rng_fault_state = True;
2459 return NT_STATUS_NOT_IMPLEMENTED;
2462 NTSTATUS _lsa_SetInfoPolicy(pipes_struct *p, struct lsa_SetInfoPolicy *r)
2464 p->rng_fault_state = True;
2465 return NT_STATUS_NOT_IMPLEMENTED;
2468 NTSTATUS _lsa_ClearAuditLog(pipes_struct *p, struct lsa_ClearAuditLog *r)
2470 p->rng_fault_state = True;
2471 return NT_STATUS_NOT_IMPLEMENTED;
2474 NTSTATUS _lsa_GetQuotasForAccount(pipes_struct *p, struct lsa_GetQuotasForAccount *r)
2476 p->rng_fault_state = True;
2477 return NT_STATUS_NOT_IMPLEMENTED;
2480 NTSTATUS _lsa_SetQuotasForAccount(pipes_struct *p, struct lsa_SetQuotasForAccount *r)
2482 p->rng_fault_state = True;
2483 return NT_STATUS_NOT_IMPLEMENTED;
2486 NTSTATUS _lsa_QueryTrustedDomainInfo(pipes_struct *p, struct lsa_QueryTrustedDomainInfo *r)
2488 p->rng_fault_state = True;
2489 return NT_STATUS_NOT_IMPLEMENTED;
2492 NTSTATUS _lsa_SetInformationTrustedDomain(pipes_struct *p, struct lsa_SetInformationTrustedDomain *r)
2494 p->rng_fault_state = True;
2495 return NT_STATUS_NOT_IMPLEMENTED;
2498 NTSTATUS _lsa_QuerySecret(pipes_struct *p, struct lsa_QuerySecret *r)
2500 p->rng_fault_state = True;
2501 return NT_STATUS_NOT_IMPLEMENTED;
2504 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(pipes_struct *p, struct lsa_QueryTrustedDomainInfoBySid *r)
2506 p->rng_fault_state = True;
2507 return NT_STATUS_NOT_IMPLEMENTED;
2510 NTSTATUS _lsa_SetTrustedDomainInfo(pipes_struct *p, struct lsa_SetTrustedDomainInfo *r)
2512 p->rng_fault_state = True;
2513 return NT_STATUS_NOT_IMPLEMENTED;
2516 NTSTATUS _lsa_DeleteTrustedDomain(pipes_struct *p, struct lsa_DeleteTrustedDomain *r)
2518 p->rng_fault_state = True;
2519 return NT_STATUS_NOT_IMPLEMENTED;
2522 NTSTATUS _lsa_StorePrivateData(pipes_struct *p, struct lsa_StorePrivateData *r)
2524 p->rng_fault_state = True;
2525 return NT_STATUS_NOT_IMPLEMENTED;
2528 NTSTATUS _lsa_RetrievePrivateData(pipes_struct *p, struct lsa_RetrievePrivateData *r)
2530 p->rng_fault_state = True;
2531 return NT_STATUS_NOT_IMPLEMENTED;
2534 NTSTATUS _lsa_SetInfoPolicy2(pipes_struct *p, struct lsa_SetInfoPolicy2 *r)
2536 p->rng_fault_state = True;
2537 return NT_STATUS_NOT_IMPLEMENTED;
2540 NTSTATUS _lsa_QueryTrustedDomainInfoByName(pipes_struct *p, struct lsa_QueryTrustedDomainInfoByName *r)
2542 p->rng_fault_state = True;
2543 return NT_STATUS_NOT_IMPLEMENTED;
2546 NTSTATUS _lsa_SetTrustedDomainInfoByName(pipes_struct *p, struct lsa_SetTrustedDomainInfoByName *r)
2548 p->rng_fault_state = True;
2549 return NT_STATUS_NOT_IMPLEMENTED;
2552 NTSTATUS _lsa_EnumTrustedDomainsEx(pipes_struct *p, struct lsa_EnumTrustedDomainsEx *r)
2554 p->rng_fault_state = True;
2555 return NT_STATUS_NOT_IMPLEMENTED;
2558 NTSTATUS _lsa_CreateTrustedDomainEx(pipes_struct *p, struct lsa_CreateTrustedDomainEx *r)
2560 p->rng_fault_state = True;
2561 return NT_STATUS_NOT_IMPLEMENTED;
2564 NTSTATUS _lsa_CloseTrustedDomainEx(pipes_struct *p, struct lsa_CloseTrustedDomainEx *r)
2566 p->rng_fault_state = True;
2567 return NT_STATUS_NOT_IMPLEMENTED;
2570 NTSTATUS _lsa_QueryDomainInformationPolicy(pipes_struct *p, struct lsa_QueryDomainInformationPolicy *r)
2572 p->rng_fault_state = True;
2573 return NT_STATUS_NOT_IMPLEMENTED;
2576 NTSTATUS _lsa_SetDomainInformationPolicy(pipes_struct *p, struct lsa_SetDomainInformationPolicy *r)
2578 p->rng_fault_state = True;
2579 return NT_STATUS_NOT_IMPLEMENTED;
2582 NTSTATUS _lsa_OpenTrustedDomainByName(pipes_struct *p, struct lsa_OpenTrustedDomainByName *r)
2584 p->rng_fault_state = True;
2585 return NT_STATUS_NOT_IMPLEMENTED;
2588 NTSTATUS _lsa_TestCall(pipes_struct *p, struct lsa_TestCall *r)
2590 p->rng_fault_state = True;
2591 return NT_STATUS_NOT_IMPLEMENTED;
2594 NTSTATUS _lsa_CreateTrustedDomainEx2(pipes_struct *p, struct lsa_CreateTrustedDomainEx2 *r)
2596 p->rng_fault_state = True;
2597 return NT_STATUS_NOT_IMPLEMENTED;
2600 NTSTATUS _lsa_CREDRWRITE(pipes_struct *p, struct lsa_CREDRWRITE *r)
2602 p->rng_fault_state = True;
2603 return NT_STATUS_NOT_IMPLEMENTED;
2606 NTSTATUS _lsa_CREDRREAD(pipes_struct *p, struct lsa_CREDRREAD *r)
2608 p->rng_fault_state = True;
2609 return NT_STATUS_NOT_IMPLEMENTED;
2612 NTSTATUS _lsa_CREDRENUMERATE(pipes_struct *p, struct lsa_CREDRENUMERATE *r)
2614 p->rng_fault_state = True;
2615 return NT_STATUS_NOT_IMPLEMENTED;
2618 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(pipes_struct *p, struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2620 p->rng_fault_state = True;
2621 return NT_STATUS_NOT_IMPLEMENTED;
2624 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(pipes_struct *p, struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2626 p->rng_fault_state = True;
2627 return NT_STATUS_NOT_IMPLEMENTED;
2630 NTSTATUS _lsa_CREDRDELETE(pipes_struct *p, struct lsa_CREDRDELETE *r)
2632 p->rng_fault_state = True;
2633 return NT_STATUS_NOT_IMPLEMENTED;
2636 NTSTATUS _lsa_CREDRGETTARGETINFO(pipes_struct *p, struct lsa_CREDRGETTARGETINFO *r)
2638 p->rng_fault_state = True;
2639 return NT_STATUS_NOT_IMPLEMENTED;
2642 NTSTATUS _lsa_CREDRPROFILELOADED(pipes_struct *p, struct lsa_CREDRPROFILELOADED *r)
2644 p->rng_fault_state = True;
2645 return NT_STATUS_NOT_IMPLEMENTED;
2648 NTSTATUS _lsa_CREDRGETSESSIONTYPES(pipes_struct *p, struct lsa_CREDRGETSESSIONTYPES *r)
2650 p->rng_fault_state = True;
2651 return NT_STATUS_NOT_IMPLEMENTED;
2654 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARREGISTERAUDITEVENT *r)
2656 p->rng_fault_state = True;
2657 return NT_STATUS_NOT_IMPLEMENTED;
2660 NTSTATUS _lsa_LSARGENAUDITEVENT(pipes_struct *p, struct lsa_LSARGENAUDITEVENT *r)
2662 p->rng_fault_state = True;
2663 return NT_STATUS_NOT_IMPLEMENTED;
2666 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARUNREGISTERAUDITEVENT *r)
2668 p->rng_fault_state = True;
2669 return NT_STATUS_NOT_IMPLEMENTED;
2672 NTSTATUS _lsa_lsaRQueryForestTrustInformation(pipes_struct *p, struct lsa_lsaRQueryForestTrustInformation *r)
2674 p->rng_fault_state = True;
2675 return NT_STATUS_NOT_IMPLEMENTED;
2678 NTSTATUS _lsa_LSARSETFORESTTRUSTINFORMATION(pipes_struct *p, struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2680 p->rng_fault_state = True;
2681 return NT_STATUS_NOT_IMPLEMENTED;
2684 NTSTATUS _lsa_CREDRRENAME(pipes_struct *p, struct lsa_CREDRRENAME *r)
2686 p->rng_fault_state = True;
2687 return NT_STATUS_NOT_IMPLEMENTED;
2690 NTSTATUS _lsa_LSAROPENPOLICYSCE(pipes_struct *p, struct lsa_LSAROPENPOLICYSCE *r)
2692 p->rng_fault_state = True;
2693 return NT_STATUS_NOT_IMPLEMENTED;
2696 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(pipes_struct *p, struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2698 p->rng_fault_state = True;
2699 return NT_STATUS_NOT_IMPLEMENTED;
2702 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(pipes_struct *p, struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2704 p->rng_fault_state = True;
2705 return NT_STATUS_NOT_IMPLEMENTED;
2708 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(pipes_struct *p, struct lsa_LSARADTREPORTSECURITYEVENT *r)
2710 p->rng_fault_state = True;
2711 return NT_STATUS_NOT_IMPLEMENTED;