s3-lsa: When looking up domains in LookupNames, do not strip the sid.
[Samba/ekacnet.git] / source3 / rpc_server / srv_lsa_nt.c
bloba3a1218956efc4fb29334f00e7df706a1dd9ae0c
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 prid[i].sid_type = type;
165 prid[i].rid = 0;
166 prid[i].sid_index = (uint32_t)-1;
167 continue;
170 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
172 /* We can ignore the result of lookup_name, it will not touch
173 "type" if it's not successful */
175 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
176 &sid, &type);
178 switch (type) {
179 case SID_NAME_USER:
180 case SID_NAME_DOM_GRP:
181 case SID_NAME_DOMAIN:
182 case SID_NAME_ALIAS:
183 case SID_NAME_WKN_GRP:
184 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
185 /* Leave these unchanged */
186 break;
187 default:
188 /* Don't hand out anything but the list above */
189 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
190 type = SID_NAME_UNKNOWN;
191 break;
194 rid = 0;
195 dom_idx = -1;
197 if (type != SID_NAME_UNKNOWN) {
198 if (type == SID_NAME_DOMAIN) {
199 rid = (uint32_t)-1;
200 } else {
201 sid_split_rid(&sid, &rid);
203 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
204 mapped_count++;
207 prid[i].sid_type = type;
208 prid[i].rid = rid;
209 prid[i].sid_index = dom_idx;
212 *pmapped_count = mapped_count;
213 return NT_STATUS_OK;
216 /***************************************************************************
217 lookup_lsa_sids. Must be called as root for lookup_name to work.
218 ***************************************************************************/
220 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
221 struct lsa_RefDomainList *ref,
222 struct lsa_TranslatedSid3 *trans_sids,
223 uint32_t num_entries,
224 struct lsa_String *name,
225 int flags,
226 uint32 *pmapped_count)
228 uint32 mapped_count, i;
230 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
232 mapped_count = 0;
233 *pmapped_count = 0;
235 for (i = 0; i < num_entries; i++) {
236 DOM_SID sid;
237 uint32 rid;
238 int dom_idx;
239 const char *full_name;
240 const char *domain;
241 enum lsa_SidType type = SID_NAME_UNKNOWN;
243 ZERO_STRUCT(sid);
245 /* Split name into domain and user component */
247 full_name = name[i].string;
248 if (full_name == NULL) {
249 return NT_STATUS_NO_MEMORY;
252 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
254 /* We can ignore the result of lookup_name, it will not touch
255 "type" if it's not successful */
257 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
258 &sid, &type);
260 switch (type) {
261 case SID_NAME_USER:
262 case SID_NAME_DOM_GRP:
263 case SID_NAME_DOMAIN:
264 case SID_NAME_ALIAS:
265 case SID_NAME_WKN_GRP:
266 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
267 /* Leave these unchanged */
268 break;
269 default:
270 /* Don't hand out anything but the list above */
271 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
272 type = SID_NAME_UNKNOWN;
273 break;
276 rid = 0;
277 dom_idx = -1;
279 if (type != SID_NAME_UNKNOWN) {
280 DOM_SID domain_sid;
281 sid_copy(&domain_sid, &sid);
282 sid_split_rid(&domain_sid, &rid);
283 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
284 mapped_count++;
287 /* Initialize the lsa_TranslatedSid3 return. */
288 trans_sids[i].sid_type = type;
289 trans_sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
290 trans_sids[i].sid_index = dom_idx;
293 *pmapped_count = mapped_count;
294 return NT_STATUS_OK;
297 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size,
298 const struct generic_mapping *map,
299 DOM_SID *sid, uint32_t sid_access)
301 DOM_SID adm_sid;
302 SEC_ACE ace[5];
303 size_t i = 0;
305 SEC_ACL *psa = NULL;
307 /* READ|EXECUTE access for Everyone */
309 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
310 map->generic_execute | map->generic_read, 0);
312 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
314 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
315 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
316 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
317 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
319 /* Add Full Access for Domain Admins */
320 sid_copy(&adm_sid, get_global_sam_sid());
321 sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS);
322 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
323 map->generic_all, 0);
325 /* If we have a sid, give it some special access */
327 if (sid) {
328 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
329 sid_access, 0);
332 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
333 return NT_STATUS_NO_MEMORY;
335 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
336 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
337 psa, sd_size)) == NULL)
338 return NT_STATUS_NO_MEMORY;
340 return NT_STATUS_OK;
344 /***************************************************************************
345 _lsa_OpenPolicy2
346 ***************************************************************************/
348 NTSTATUS _lsa_OpenPolicy2(pipes_struct *p,
349 struct lsa_OpenPolicy2 *r)
351 struct lsa_info *info;
352 SEC_DESC *psd = NULL;
353 size_t sd_size;
354 uint32 des_access = r->in.access_mask;
355 uint32 acc_granted;
356 NTSTATUS status;
358 /* Work out max allowed. */
359 map_max_allowed_access(p->server_info->ptok,
360 &p->server_info->utok,
361 &des_access);
363 /* map the generic bits to the lsa policy ones */
364 se_map_generic(&des_access, &lsa_policy_mapping);
366 /* get the generic lsa policy SD until we store it */
367 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
368 NULL, 0);
369 if (!NT_STATUS_IS_OK(status)) {
370 return status;
373 status = access_check_object(psd, p->server_info->ptok,
374 NULL, 0, des_access,
375 &acc_granted, "_lsa_OpenPolicy2" );
377 if (!NT_STATUS_IS_OK(status)) {
378 return status;
381 /* associate the domain SID with the (unique) handle. */
382 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
383 if (info == NULL) {
384 return NT_STATUS_NO_MEMORY;
387 sid_copy(&info->sid,get_global_sam_sid());
388 info->access = acc_granted;
389 info->type = LSA_HANDLE_POLICY_TYPE;
391 /* set up the LSA QUERY INFO response */
392 if (!create_policy_hnd(p, r->out.handle, info))
393 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
395 return NT_STATUS_OK;
398 /***************************************************************************
399 _lsa_OpenPolicy
400 ***************************************************************************/
402 NTSTATUS _lsa_OpenPolicy(pipes_struct *p,
403 struct lsa_OpenPolicy *r)
405 struct lsa_OpenPolicy2 o;
407 o.in.system_name = NULL; /* should be ignored */
408 o.in.attr = r->in.attr;
409 o.in.access_mask = r->in.access_mask;
411 o.out.handle = r->out.handle;
413 return _lsa_OpenPolicy2(p, &o);
416 /***************************************************************************
417 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
418 ufff, done :) mimir
419 ***************************************************************************/
421 NTSTATUS _lsa_EnumTrustDom(pipes_struct *p,
422 struct lsa_EnumTrustDom *r)
424 struct lsa_info *info;
425 uint32 next_idx;
426 struct trustdom_info **domains;
427 struct lsa_DomainInfo *lsa_domains = NULL;
428 int i;
431 * preferred length is set to 5 as a "our" preferred length
432 * nt sets this parameter to 2
433 * update (20.08.2002): it's not preferred length, but preferred size!
434 * it needs further investigation how to optimally choose this value
436 uint32 max_num_domains =
437 r->in.max_size < 5 ? r->in.max_size : 10;
438 uint32 num_domains;
439 NTSTATUS nt_status;
440 uint32 num_thistime;
442 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
443 return NT_STATUS_INVALID_HANDLE;
445 if (info->type != LSA_HANDLE_POLICY_TYPE) {
446 return NT_STATUS_INVALID_HANDLE;
449 /* check if the user has enough rights */
450 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
451 return NT_STATUS_ACCESS_DENIED;
453 become_root();
454 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &num_domains, &domains);
455 unbecome_root();
457 if (!NT_STATUS_IS_OK(nt_status)) {
458 return nt_status;
461 if (*r->in.resume_handle < num_domains) {
462 num_thistime = MIN(num_domains, max_num_domains);
464 nt_status = STATUS_MORE_ENTRIES;
466 if (*r->in.resume_handle + num_thistime > num_domains) {
467 num_thistime = num_domains - *r->in.resume_handle;
468 nt_status = NT_STATUS_OK;
471 next_idx = *r->in.resume_handle + num_thistime;
472 } else {
473 num_thistime = 0;
474 next_idx = 0xffffffff;
475 nt_status = NT_STATUS_NO_MORE_ENTRIES;
478 /* set up the lsa_enum_trust_dom response */
480 lsa_domains = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo,
481 num_thistime);
482 if (!lsa_domains) {
483 return NT_STATUS_NO_MEMORY;
486 for (i=0; i<num_thistime; i++) {
487 init_lsa_StringLarge(&lsa_domains[i].name, domains[i]->name);
488 lsa_domains[i].sid = &domains[i]->sid;
491 *r->out.resume_handle = next_idx;
492 r->out.domains->count = num_thistime;
493 r->out.domains->domains = lsa_domains;
495 return nt_status;
498 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
499 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
500 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
502 /***************************************************************************
503 _lsa_QueryInfoPolicy
504 ***************************************************************************/
506 NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p,
507 struct lsa_QueryInfoPolicy *r)
509 NTSTATUS status = NT_STATUS_OK;
510 struct lsa_info *handle;
511 DOM_SID domain_sid;
512 const char *name;
513 DOM_SID *sid = NULL;
514 union lsa_PolicyInformation *info = NULL;
515 uint32_t acc_required = 0;
517 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
518 return NT_STATUS_INVALID_HANDLE;
520 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
521 return NT_STATUS_INVALID_HANDLE;
524 switch (r->in.level) {
525 case LSA_POLICY_INFO_AUDIT_LOG:
526 case LSA_POLICY_INFO_AUDIT_EVENTS:
527 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
528 break;
529 case LSA_POLICY_INFO_DOMAIN:
530 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
531 break;
532 case LSA_POLICY_INFO_PD:
533 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
534 break;
535 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
536 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
537 break;
538 case LSA_POLICY_INFO_ROLE:
539 case LSA_POLICY_INFO_REPLICA:
540 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
541 break;
542 case LSA_POLICY_INFO_QUOTA:
543 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
544 break;
545 case LSA_POLICY_INFO_MOD:
546 case LSA_POLICY_INFO_AUDIT_FULL_SET:
547 /* according to MS-LSAD 3.1.4.4.3 */
548 return NT_STATUS_INVALID_PARAMETER;
549 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
550 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
551 break;
552 case LSA_POLICY_INFO_DNS:
553 case LSA_POLICY_INFO_DNS_INT:
554 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
555 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
556 break;
557 default:
558 break;
561 if (!(handle->access & acc_required)) {
562 /* return NT_STATUS_ACCESS_DENIED; */
565 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
566 if (!info) {
567 return NT_STATUS_NO_MEMORY;
570 switch (r->in.level) {
571 case LSA_POLICY_INFO_AUDIT_EVENTS:
574 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
576 /* check if the user has enough rights */
577 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
578 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
579 return NT_STATUS_ACCESS_DENIED;
582 /* fake info: We audit everything. ;) */
584 info->audit_events.auditing_mode = true;
585 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
586 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
587 enum lsa_PolicyAuditPolicy,
588 info->audit_events.count);
589 if (!info->audit_events.settings) {
590 return NT_STATUS_NO_MEMORY;
593 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
594 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
595 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
596 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
597 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
598 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
599 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
601 break;
603 case LSA_POLICY_INFO_DOMAIN:
604 /* check if the user has enough rights */
605 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
606 return NT_STATUS_ACCESS_DENIED;
608 /* Request PolicyPrimaryDomainInformation. */
609 switch (lp_server_role()) {
610 case ROLE_DOMAIN_PDC:
611 case ROLE_DOMAIN_BDC:
612 name = get_global_sam_name();
613 sid = sid_dup_talloc(p->mem_ctx, get_global_sam_sid());
614 if (!sid) {
615 return NT_STATUS_NO_MEMORY;
617 break;
618 case ROLE_DOMAIN_MEMBER:
619 name = lp_workgroup();
620 /* We need to return the Domain SID here. */
621 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
622 sid = sid_dup_talloc(p->mem_ctx, &domain_sid);
623 if (!sid) {
624 return NT_STATUS_NO_MEMORY;
626 } else {
627 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
629 break;
630 case ROLE_STANDALONE:
631 name = lp_workgroup();
632 sid = NULL;
633 break;
634 default:
635 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
637 init_dom_query_3(&info->domain, name, sid);
638 break;
639 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
640 /* check if the user has enough rights */
641 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
642 return NT_STATUS_ACCESS_DENIED;
644 /* Request PolicyAccountDomainInformation. */
645 name = get_global_sam_name();
646 sid = get_global_sam_sid();
648 init_dom_query_5(&info->account_domain, name, sid);
649 break;
650 case LSA_POLICY_INFO_ROLE:
651 /* check if the user has enough rights */
652 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
653 return NT_STATUS_ACCESS_DENIED;
655 switch (lp_server_role()) {
656 case ROLE_DOMAIN_BDC:
658 * only a BDC is a backup controller
659 * of the domain, it controls.
661 info->role.role = LSA_ROLE_BACKUP;
662 break;
663 default:
665 * any other role is a primary
666 * of the domain, it controls.
668 info->role.role = LSA_ROLE_PRIMARY;
669 break;
671 break;
672 case LSA_POLICY_INFO_DNS:
673 case LSA_POLICY_INFO_DNS_INT: {
674 struct pdb_domain_info *dominfo;
676 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
677 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
678 "without ADS passdb backend\n"));
679 status = NT_STATUS_INVALID_INFO_CLASS;
680 break;
683 dominfo = pdb_get_domain_info(info);
684 if (dominfo == NULL) {
685 status = NT_STATUS_NO_MEMORY;
686 break;
689 init_lsa_StringLarge(&info->dns.name,
690 dominfo->name);
691 init_lsa_StringLarge(&info->dns.dns_domain,
692 dominfo->dns_domain);
693 init_lsa_StringLarge(&info->dns.dns_forest,
694 dominfo->dns_forest);
695 info->dns.domain_guid = dominfo->guid;
696 info->dns.sid = &dominfo->sid;
697 break;
699 default:
700 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
701 r->in.level));
702 status = NT_STATUS_INVALID_INFO_CLASS;
703 break;
706 *r->out.info = info;
708 return status;
711 /***************************************************************************
712 _lsa_QueryInfoPolicy2
713 ***************************************************************************/
715 NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p,
716 struct lsa_QueryInfoPolicy2 *r2)
718 struct lsa_QueryInfoPolicy r;
720 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
721 p->rng_fault_state = True;
722 return NT_STATUS_NOT_IMPLEMENTED;
725 ZERO_STRUCT(r);
726 r.in.handle = r2->in.handle;
727 r.in.level = r2->in.level;
728 r.out.info = r2->out.info;
730 return _lsa_QueryInfoPolicy(p, &r);
733 /***************************************************************************
734 _lsa_lookup_sids_internal
735 ***************************************************************************/
737 static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p,
738 TALLOC_CTX *mem_ctx,
739 uint16_t level, /* input */
740 int num_sids, /* input */
741 struct lsa_SidPtr *sid, /* input */
742 struct lsa_RefDomainList **pp_ref, /* input/output */
743 struct lsa_TranslatedName2 **pp_names,/* input/output */
744 uint32_t *pp_mapped_count) /* input/output */
746 NTSTATUS status;
747 int i;
748 const DOM_SID **sids = NULL;
749 struct lsa_RefDomainList *ref = NULL;
750 uint32 mapped_count = 0;
751 struct lsa_dom_info *dom_infos = NULL;
752 struct lsa_name_info *name_infos = NULL;
753 struct lsa_TranslatedName2 *names = NULL;
755 *pp_mapped_count = 0;
756 *pp_names = NULL;
757 *pp_ref = NULL;
759 if (num_sids == 0) {
760 return NT_STATUS_OK;
763 sids = TALLOC_ARRAY(p->mem_ctx, const DOM_SID *, num_sids);
764 ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
766 if (sids == NULL || ref == NULL) {
767 return NT_STATUS_NO_MEMORY;
770 for (i=0; i<num_sids; i++) {
771 sids[i] = sid[i].sid;
774 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
775 &dom_infos, &name_infos);
777 if (!NT_STATUS_IS_OK(status)) {
778 return status;
781 names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
782 if (names == NULL) {
783 return NT_STATUS_NO_MEMORY;
786 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
788 if (!dom_infos[i].valid) {
789 break;
792 if (init_lsa_ref_domain_list(mem_ctx, ref,
793 dom_infos[i].name,
794 &dom_infos[i].sid) != i) {
795 DEBUG(0, ("Domain %s mentioned twice??\n",
796 dom_infos[i].name));
797 return NT_STATUS_INTERNAL_ERROR;
801 for (i=0; i<num_sids; i++) {
802 struct lsa_name_info *name = &name_infos[i];
804 if (name->type == SID_NAME_UNKNOWN) {
805 fstring tmp;
806 name->dom_idx = -1;
807 /* Unknown sids should return the string
808 * representation of the SID. Windows 2003 behaves
809 * rather erratic here, in many cases it returns the
810 * RID as 8 bytes hex, in others it returns the full
811 * SID. We (Jerry/VL) could not figure out which the
812 * hard cases are, so leave it with the SID. */
813 name->name = talloc_asprintf(p->mem_ctx, "%s",
814 sid_to_fstring(tmp,
815 sids[i]));
816 if (name->name == NULL) {
817 return NT_STATUS_NO_MEMORY;
819 } else {
820 mapped_count += 1;
823 names[i].sid_type = name->type;
824 names[i].name.string = name->name;
825 names[i].sid_index = name->dom_idx;
826 names[i].unknown = 0;
829 status = NT_STATUS_NONE_MAPPED;
830 if (mapped_count > 0) {
831 status = (mapped_count < num_sids) ?
832 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
835 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
836 num_sids, mapped_count, nt_errstr(status)));
838 *pp_mapped_count = mapped_count;
839 *pp_names = names;
840 *pp_ref = ref;
842 return status;
845 /***************************************************************************
846 _lsa_LookupSids
847 ***************************************************************************/
849 NTSTATUS _lsa_LookupSids(pipes_struct *p,
850 struct lsa_LookupSids *r)
852 NTSTATUS status;
853 struct lsa_info *handle;
854 int num_sids = r->in.sids->num_sids;
855 uint32 mapped_count = 0;
856 struct lsa_RefDomainList *domains = NULL;
857 struct lsa_TranslatedName *names_out = NULL;
858 struct lsa_TranslatedName2 *names = NULL;
859 int i;
861 if ((r->in.level < 1) || (r->in.level > 6)) {
862 return NT_STATUS_INVALID_PARAMETER;
865 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
866 return NT_STATUS_INVALID_HANDLE;
869 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
870 return NT_STATUS_INVALID_HANDLE;
873 /* check if the user has enough rights */
874 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
875 return NT_STATUS_ACCESS_DENIED;
878 if (num_sids > MAX_LOOKUP_SIDS) {
879 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
880 MAX_LOOKUP_SIDS, num_sids));
881 return NT_STATUS_NONE_MAPPED;
884 status = _lsa_lookup_sids_internal(p,
885 p->mem_ctx,
886 r->in.level,
887 num_sids,
888 r->in.sids->sids,
889 &domains,
890 &names,
891 &mapped_count);
893 /* Only return here when there is a real error.
894 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
895 the requested sids could be resolved. Older versions of XP (pre SP3)
896 rely that we return with the string representations of those SIDs in
897 that case. If we don't, XP crashes - Guenther
900 if (NT_STATUS_IS_ERR(status) &&
901 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
902 return status;
905 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
906 names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
907 num_sids);
908 if (!names_out) {
909 return NT_STATUS_NO_MEMORY;
912 for (i=0; i<num_sids; i++) {
913 names_out[i].sid_type = names[i].sid_type;
914 names_out[i].name = names[i].name;
915 names_out[i].sid_index = names[i].sid_index;
918 *r->out.domains = domains;
919 r->out.names->count = num_sids;
920 r->out.names->names = names_out;
921 *r->out.count = mapped_count;
923 return status;
926 /***************************************************************************
927 _lsa_LookupSids2
928 ***************************************************************************/
930 NTSTATUS _lsa_LookupSids2(pipes_struct *p,
931 struct lsa_LookupSids2 *r)
933 NTSTATUS status;
934 struct lsa_info *handle;
935 int num_sids = r->in.sids->num_sids;
936 uint32 mapped_count = 0;
937 struct lsa_RefDomainList *domains = NULL;
938 struct lsa_TranslatedName2 *names = NULL;
939 bool check_policy = true;
941 switch (p->hdr_req.opnum) {
942 case NDR_LSA_LOOKUPSIDS3:
943 check_policy = false;
944 break;
945 case NDR_LSA_LOOKUPSIDS2:
946 default:
947 check_policy = true;
950 if ((r->in.level < 1) || (r->in.level > 6)) {
951 return NT_STATUS_INVALID_PARAMETER;
954 if (check_policy) {
955 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
956 return NT_STATUS_INVALID_HANDLE;
959 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
960 return NT_STATUS_INVALID_HANDLE;
963 /* check if the user has enough rights */
964 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
965 return NT_STATUS_ACCESS_DENIED;
969 if (num_sids > MAX_LOOKUP_SIDS) {
970 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
971 MAX_LOOKUP_SIDS, num_sids));
972 return NT_STATUS_NONE_MAPPED;
975 status = _lsa_lookup_sids_internal(p,
976 p->mem_ctx,
977 r->in.level,
978 num_sids,
979 r->in.sids->sids,
980 &domains,
981 &names,
982 &mapped_count);
984 *r->out.domains = domains;
985 r->out.names->count = num_sids;
986 r->out.names->names = names;
987 *r->out.count = mapped_count;
989 return status;
992 /***************************************************************************
993 _lsa_LookupSids3
994 ***************************************************************************/
996 NTSTATUS _lsa_LookupSids3(pipes_struct *p,
997 struct lsa_LookupSids3 *r)
999 struct lsa_LookupSids2 q;
1001 /* No policy handle on this call. Restrict to crypto connections. */
1002 if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
1003 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1004 get_remote_machine_name() ));
1005 return NT_STATUS_INVALID_PARAMETER;
1008 q.in.handle = NULL;
1009 q.in.sids = r->in.sids;
1010 q.in.level = r->in.level;
1011 q.in.lookup_options = r->in.lookup_options;
1012 q.in.client_revision = r->in.client_revision;
1013 q.in.names = r->in.names;
1014 q.in.count = r->in.count;
1016 q.out.domains = r->out.domains;
1017 q.out.names = r->out.names;
1018 q.out.count = r->out.count;
1020 return _lsa_LookupSids2(p, &q);
1023 /***************************************************************************
1024 ***************************************************************************/
1026 static int lsa_lookup_level_to_flags(uint16 level)
1028 int flags;
1030 switch (level) {
1031 case 1:
1032 flags = LOOKUP_NAME_ALL;
1033 break;
1034 case 2:
1035 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1036 break;
1037 case 3:
1038 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1039 break;
1040 case 4:
1041 case 5:
1042 case 6:
1043 default:
1044 flags = LOOKUP_NAME_NONE;
1045 break;
1048 return flags;
1051 /***************************************************************************
1052 _lsa_LookupNames
1053 ***************************************************************************/
1055 NTSTATUS _lsa_LookupNames(pipes_struct *p,
1056 struct lsa_LookupNames *r)
1058 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1059 struct lsa_info *handle;
1060 struct lsa_String *names = r->in.names;
1061 uint32 num_entries = r->in.num_names;
1062 struct lsa_RefDomainList *domains = NULL;
1063 struct lsa_TranslatedSid *rids = NULL;
1064 uint32 mapped_count = 0;
1065 int flags = 0;
1067 if (num_entries > MAX_LOOKUP_SIDS) {
1068 num_entries = MAX_LOOKUP_SIDS;
1069 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1070 num_entries));
1073 flags = lsa_lookup_level_to_flags(r->in.level);
1075 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1076 if (!domains) {
1077 return NT_STATUS_NO_MEMORY;
1080 if (num_entries) {
1081 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1082 num_entries);
1083 if (!rids) {
1084 return NT_STATUS_NO_MEMORY;
1086 } else {
1087 rids = NULL;
1090 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1091 status = NT_STATUS_INVALID_HANDLE;
1092 goto done;
1095 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1096 return NT_STATUS_INVALID_HANDLE;
1099 /* check if the user has enough rights */
1100 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1101 status = NT_STATUS_ACCESS_DENIED;
1102 goto done;
1105 /* set up the LSA Lookup RIDs response */
1106 become_root(); /* lookup_name can require root privs */
1107 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1108 names, flags, &mapped_count);
1109 unbecome_root();
1111 done:
1113 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1114 if (mapped_count == 0) {
1115 status = NT_STATUS_NONE_MAPPED;
1116 } else if (mapped_count != num_entries) {
1117 status = STATUS_SOME_UNMAPPED;
1121 *r->out.count = mapped_count;
1122 *r->out.domains = domains;
1123 r->out.sids->sids = rids;
1124 r->out.sids->count = num_entries;
1126 return status;
1129 /***************************************************************************
1130 _lsa_LookupNames2
1131 ***************************************************************************/
1133 NTSTATUS _lsa_LookupNames2(pipes_struct *p,
1134 struct lsa_LookupNames2 *r)
1136 NTSTATUS status;
1137 struct lsa_LookupNames q;
1138 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1139 struct lsa_TransSidArray *sid_array = NULL;
1140 uint32_t i;
1142 sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1143 if (!sid_array) {
1144 return NT_STATUS_NO_MEMORY;
1147 q.in.handle = r->in.handle;
1148 q.in.num_names = r->in.num_names;
1149 q.in.names = r->in.names;
1150 q.in.level = r->in.level;
1151 q.in.sids = sid_array;
1152 q.in.count = r->in.count;
1153 /* we do not know what this is for */
1154 /* = r->in.unknown1; */
1155 /* = r->in.unknown2; */
1157 q.out.domains = r->out.domains;
1158 q.out.sids = sid_array;
1159 q.out.count = r->out.count;
1161 status = _lsa_LookupNames(p, &q);
1163 sid_array2->count = sid_array->count;
1164 sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1165 if (!sid_array2->sids) {
1166 return NT_STATUS_NO_MEMORY;
1169 for (i=0; i<sid_array->count; i++) {
1170 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1171 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1172 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1173 sid_array2->sids[i].unknown = 0;
1176 r->out.sids = sid_array2;
1178 return status;
1181 /***************************************************************************
1182 _lsa_LookupNames3
1183 ***************************************************************************/
1185 NTSTATUS _lsa_LookupNames3(pipes_struct *p,
1186 struct lsa_LookupNames3 *r)
1188 NTSTATUS status;
1189 struct lsa_info *handle;
1190 struct lsa_String *names = r->in.names;
1191 uint32 num_entries = r->in.num_names;
1192 struct lsa_RefDomainList *domains = NULL;
1193 struct lsa_TranslatedSid3 *trans_sids = NULL;
1194 uint32 mapped_count = 0;
1195 int flags = 0;
1196 bool check_policy = true;
1198 switch (p->hdr_req.opnum) {
1199 case NDR_LSA_LOOKUPNAMES4:
1200 check_policy = false;
1201 break;
1202 case NDR_LSA_LOOKUPNAMES3:
1203 default:
1204 check_policy = true;
1207 if (num_entries > MAX_LOOKUP_SIDS) {
1208 num_entries = MAX_LOOKUP_SIDS;
1209 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1212 /* Probably the lookup_level is some sort of bitmask. */
1213 if (r->in.level == 1) {
1214 flags = LOOKUP_NAME_ALL;
1217 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1218 if (!domains) {
1219 return NT_STATUS_NO_MEMORY;
1222 if (num_entries) {
1223 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1224 num_entries);
1225 if (!trans_sids) {
1226 return NT_STATUS_NO_MEMORY;
1228 } else {
1229 trans_sids = NULL;
1232 if (check_policy) {
1234 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1235 status = NT_STATUS_INVALID_HANDLE;
1236 goto done;
1239 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1240 return NT_STATUS_INVALID_HANDLE;
1243 /* check if the user has enough rights */
1244 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1245 status = NT_STATUS_ACCESS_DENIED;
1246 goto done;
1250 /* set up the LSA Lookup SIDs response */
1251 become_root(); /* lookup_name can require root privs */
1252 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1253 names, flags, &mapped_count);
1254 unbecome_root();
1256 done:
1258 if (NT_STATUS_IS_OK(status)) {
1259 if (mapped_count == 0) {
1260 status = NT_STATUS_NONE_MAPPED;
1261 } else if (mapped_count != num_entries) {
1262 status = STATUS_SOME_UNMAPPED;
1266 *r->out.count = mapped_count;
1267 *r->out.domains = domains;
1268 r->out.sids->sids = trans_sids;
1269 r->out.sids->count = num_entries;
1271 return status;
1274 /***************************************************************************
1275 _lsa_LookupNames4
1276 ***************************************************************************/
1278 NTSTATUS _lsa_LookupNames4(pipes_struct *p,
1279 struct lsa_LookupNames4 *r)
1281 struct lsa_LookupNames3 q;
1283 /* No policy handle on this call. Restrict to crypto connections. */
1284 if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
1285 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1286 get_remote_machine_name() ));
1287 return NT_STATUS_INVALID_PARAMETER;
1290 q.in.handle = NULL;
1291 q.in.num_names = r->in.num_names;
1292 q.in.names = r->in.names;
1293 q.in.level = r->in.level;
1294 q.in.lookup_options = r->in.lookup_options;
1295 q.in.client_revision = r->in.client_revision;
1296 q.in.sids = r->in.sids;
1297 q.in.count = r->in.count;
1299 q.out.domains = r->out.domains;
1300 q.out.sids = r->out.sids;
1301 q.out.count = r->out.count;
1303 return _lsa_LookupNames3(p, &q);
1306 /***************************************************************************
1307 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1308 ***************************************************************************/
1310 NTSTATUS _lsa_Close(pipes_struct *p, struct lsa_Close *r)
1312 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1313 return NT_STATUS_INVALID_HANDLE;
1316 close_policy_hnd(p, r->in.handle);
1317 ZERO_STRUCTP(r->out.handle);
1318 return NT_STATUS_OK;
1321 /***************************************************************************
1322 ***************************************************************************/
1324 NTSTATUS _lsa_OpenSecret(pipes_struct *p, struct lsa_OpenSecret *r)
1326 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1329 /***************************************************************************
1330 ***************************************************************************/
1332 NTSTATUS _lsa_OpenTrustedDomain(pipes_struct *p, struct lsa_OpenTrustedDomain *r)
1334 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1337 /***************************************************************************
1338 ***************************************************************************/
1340 NTSTATUS _lsa_CreateTrustedDomain(pipes_struct *p, struct lsa_CreateTrustedDomain *r)
1342 return NT_STATUS_ACCESS_DENIED;
1345 /***************************************************************************
1346 ***************************************************************************/
1348 NTSTATUS _lsa_CreateSecret(pipes_struct *p, struct lsa_CreateSecret *r)
1350 return NT_STATUS_ACCESS_DENIED;
1353 /***************************************************************************
1354 ***************************************************************************/
1356 NTSTATUS _lsa_SetSecret(pipes_struct *p, struct lsa_SetSecret *r)
1358 return NT_STATUS_ACCESS_DENIED;
1361 /***************************************************************************
1362 _lsa_DeleteObject
1363 ***************************************************************************/
1365 NTSTATUS _lsa_DeleteObject(pipes_struct *p,
1366 struct lsa_DeleteObject *r)
1368 NTSTATUS status;
1369 struct lsa_info *info = NULL;
1371 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
1372 return NT_STATUS_INVALID_HANDLE;
1375 if (!(info->access & STD_RIGHT_DELETE_ACCESS)) {
1376 return NT_STATUS_ACCESS_DENIED;
1379 switch (info->type) {
1380 case LSA_HANDLE_ACCOUNT_TYPE:
1381 status = privilege_delete_account(&info->sid);
1382 if (!NT_STATUS_IS_OK(status)) {
1383 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
1384 nt_errstr(status)));
1385 return status;
1387 break;
1388 default:
1389 return NT_STATUS_INVALID_HANDLE;
1392 close_policy_hnd(p, r->in.handle);
1393 ZERO_STRUCTP(r->out.handle);
1395 return status;
1398 /***************************************************************************
1399 _lsa_EnumPrivs
1400 ***************************************************************************/
1402 NTSTATUS _lsa_EnumPrivs(pipes_struct *p,
1403 struct lsa_EnumPrivs *r)
1405 struct lsa_info *handle;
1406 uint32 i;
1407 uint32 enum_context = *r->in.resume_handle;
1408 int num_privs = count_all_privileges();
1409 struct lsa_PrivEntry *entries = NULL;
1410 LUID_ATTR luid;
1412 /* remember that the enum_context starts at 0 and not 1 */
1414 if ( enum_context >= num_privs )
1415 return NT_STATUS_NO_MORE_ENTRIES;
1417 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
1418 enum_context, num_privs));
1420 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1421 return NT_STATUS_INVALID_HANDLE;
1423 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1424 return NT_STATUS_INVALID_HANDLE;
1427 /* check if the user has enough rights
1428 I don't know if it's the right one. not documented. */
1430 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1431 return NT_STATUS_ACCESS_DENIED;
1433 if (num_privs) {
1434 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
1435 if (!entries) {
1436 return NT_STATUS_NO_MEMORY;
1438 } else {
1439 entries = NULL;
1442 for (i = 0; i < num_privs; i++) {
1443 if( i < enum_context) {
1445 init_lsa_StringLarge(&entries[i].name, NULL);
1447 entries[i].luid.low = 0;
1448 entries[i].luid.high = 0;
1449 } else {
1451 init_lsa_StringLarge(&entries[i].name, privs[i].name);
1453 luid = get_privilege_luid( &privs[i].se_priv );
1455 entries[i].luid.low = luid.luid.low;
1456 entries[i].luid.high = luid.luid.high;
1460 enum_context = num_privs;
1462 *r->out.resume_handle = enum_context;
1463 r->out.privs->count = num_privs;
1464 r->out.privs->privs = entries;
1466 return NT_STATUS_OK;
1469 /***************************************************************************
1470 _lsa_LookupPrivDisplayName
1471 ***************************************************************************/
1473 NTSTATUS _lsa_LookupPrivDisplayName(pipes_struct *p,
1474 struct lsa_LookupPrivDisplayName *r)
1476 struct lsa_info *handle;
1477 const char *description;
1478 struct lsa_StringLarge *lsa_name;
1480 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1481 return NT_STATUS_INVALID_HANDLE;
1483 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1484 return NT_STATUS_INVALID_HANDLE;
1487 /* check if the user has enough rights */
1490 * I don't know if it's the right one. not documented.
1492 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1493 return NT_STATUS_ACCESS_DENIED;
1495 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
1497 description = get_privilege_dispname(r->in.name->string);
1498 if (!description) {
1499 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
1500 return NT_STATUS_NO_SUCH_PRIVILEGE;
1503 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
1505 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
1506 if (!lsa_name) {
1507 return NT_STATUS_NO_MEMORY;
1510 init_lsa_StringLarge(lsa_name, description);
1512 *r->out.returned_language_id = r->in.language_id;
1513 *r->out.disp_name = lsa_name;
1515 return NT_STATUS_OK;
1518 /***************************************************************************
1519 _lsa_EnumAccounts
1520 ***************************************************************************/
1522 NTSTATUS _lsa_EnumAccounts(pipes_struct *p,
1523 struct lsa_EnumAccounts *r)
1525 struct lsa_info *handle;
1526 DOM_SID *sid_list;
1527 int i, j, num_entries;
1528 NTSTATUS status;
1529 struct lsa_SidPtr *sids = NULL;
1531 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1532 return NT_STATUS_INVALID_HANDLE;
1534 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1535 return NT_STATUS_INVALID_HANDLE;
1538 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1539 return NT_STATUS_ACCESS_DENIED;
1541 sid_list = NULL;
1542 num_entries = 0;
1544 /* The only way we can currently find out all the SIDs that have been
1545 privileged is to scan all privileges */
1547 status = privilege_enumerate_accounts(&sid_list, &num_entries);
1548 if (!NT_STATUS_IS_OK(status)) {
1549 return status;
1552 if (*r->in.resume_handle >= num_entries) {
1553 return NT_STATUS_NO_MORE_ENTRIES;
1556 if (num_entries - *r->in.resume_handle) {
1557 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
1558 num_entries - *r->in.resume_handle);
1559 if (!sids) {
1560 talloc_free(sid_list);
1561 return NT_STATUS_NO_MEMORY;
1564 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
1565 sids[j].sid = sid_dup_talloc(p->mem_ctx, &sid_list[i]);
1566 if (!sids[j].sid) {
1567 talloc_free(sid_list);
1568 return NT_STATUS_NO_MEMORY;
1573 talloc_free(sid_list);
1575 *r->out.resume_handle = num_entries;
1576 r->out.sids->num_sids = num_entries;
1577 r->out.sids->sids = sids;
1579 return NT_STATUS_OK;
1582 /***************************************************************************
1583 _lsa_GetUserName
1584 ***************************************************************************/
1586 NTSTATUS _lsa_GetUserName(pipes_struct *p,
1587 struct lsa_GetUserName *r)
1589 const char *username, *domname;
1590 struct lsa_String *account_name = NULL;
1591 struct lsa_String *authority_name = NULL;
1593 if (r->in.account_name &&
1594 *r->in.account_name) {
1595 return NT_STATUS_INVALID_PARAMETER;
1598 if (r->in.authority_name &&
1599 *r->in.authority_name) {
1600 return NT_STATUS_INVALID_PARAMETER;
1603 if (p->server_info->guest) {
1605 * I'm 99% sure this is not the right place to do this,
1606 * global_sid_Anonymous should probably be put into the token
1607 * instead of the guest id -- vl
1609 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
1610 &domname, &username, NULL)) {
1611 return NT_STATUS_NO_MEMORY;
1613 } else {
1614 username = p->server_info->sanitized_username;
1615 domname = pdb_get_domain(p->server_info->sam_account);
1618 account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1619 if (!account_name) {
1620 return NT_STATUS_NO_MEMORY;
1622 init_lsa_String(account_name, username);
1624 if (r->out.authority_name) {
1625 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1626 if (!authority_name) {
1627 return NT_STATUS_NO_MEMORY;
1629 init_lsa_String(authority_name, domname);
1632 *r->out.account_name = account_name;
1633 if (r->out.authority_name) {
1634 *r->out.authority_name = authority_name;
1637 return NT_STATUS_OK;
1640 /***************************************************************************
1641 _lsa_CreateAccount
1642 ***************************************************************************/
1644 NTSTATUS _lsa_CreateAccount(pipes_struct *p,
1645 struct lsa_CreateAccount *r)
1647 NTSTATUS status;
1648 struct lsa_info *handle;
1649 struct lsa_info *info;
1650 uint32_t acc_granted;
1651 struct security_descriptor *psd;
1652 size_t sd_size;
1654 /* find the connection policy handle. */
1655 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1656 return NT_STATUS_INVALID_HANDLE;
1658 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1659 return NT_STATUS_INVALID_HANDLE;
1662 /* check if the user has enough rights */
1664 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
1665 return NT_STATUS_ACCESS_DENIED;
1668 /* map the generic bits to the lsa policy ones */
1669 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1671 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1672 &lsa_account_mapping,
1673 r->in.sid, LSA_POLICY_ALL_ACCESS);
1674 if (!NT_STATUS_IS_OK(status)) {
1675 return status;
1678 status = access_check_object(psd, p->server_info->ptok,
1679 NULL, 0, r->in.access_mask,
1680 &acc_granted, "_lsa_CreateAccount");
1681 if (!NT_STATUS_IS_OK(status)) {
1682 return status;
1685 if ( is_privileged_sid( r->in.sid ) )
1686 return NT_STATUS_OBJECT_NAME_COLLISION;
1688 /* associate the user/group SID with the (unique) handle. */
1690 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1691 if (info == NULL) {
1692 return NT_STATUS_NO_MEMORY;
1695 info->sid = *r->in.sid;
1696 info->access = acc_granted;
1697 info->type = LSA_HANDLE_ACCOUNT_TYPE;
1699 /* get a (unique) handle. open a policy on it. */
1700 if (!create_policy_hnd(p, r->out.acct_handle, info))
1701 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1703 return privilege_create_account( &info->sid );
1706 /***************************************************************************
1707 _lsa_OpenAccount
1708 ***************************************************************************/
1710 NTSTATUS _lsa_OpenAccount(pipes_struct *p,
1711 struct lsa_OpenAccount *r)
1713 struct lsa_info *handle;
1714 struct lsa_info *info;
1715 SEC_DESC *psd = NULL;
1716 size_t sd_size;
1717 uint32_t des_access = r->in.access_mask;
1718 uint32_t acc_granted;
1719 NTSTATUS status;
1721 /* find the connection policy handle. */
1722 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1723 return NT_STATUS_INVALID_HANDLE;
1725 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1726 return NT_STATUS_INVALID_HANDLE;
1729 /* des_access is for the account here, not the policy
1730 * handle - so don't check against policy handle. */
1732 /* Work out max allowed. */
1733 map_max_allowed_access(p->server_info->ptok,
1734 &p->server_info->utok,
1735 &des_access);
1737 /* map the generic bits to the lsa account ones */
1738 se_map_generic(&des_access, &lsa_account_mapping);
1740 /* get the generic lsa account SD until we store it */
1741 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1742 &lsa_account_mapping,
1743 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
1744 if (!NT_STATUS_IS_OK(status)) {
1745 return status;
1748 status = access_check_object(psd, p->server_info->ptok,
1749 NULL, 0, des_access,
1750 &acc_granted, "_lsa_OpenAccount" );
1752 if (!NT_STATUS_IS_OK(status)) {
1753 return status;
1756 /* TODO: Fis the parsing routine before reenabling this check! */
1757 #if 0
1758 if (!lookup_sid(&handle->sid, dom_name, name, &type))
1759 return NT_STATUS_ACCESS_DENIED;
1760 #endif
1761 /* associate the user/group SID with the (unique) handle. */
1762 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1763 if (info == NULL) {
1764 return NT_STATUS_NO_MEMORY;
1767 info->sid = *r->in.sid;
1768 info->access = acc_granted;
1769 info->type = LSA_HANDLE_ACCOUNT_TYPE;
1771 /* get a (unique) handle. open a policy on it. */
1772 if (!create_policy_hnd(p, r->out.acct_handle, info))
1773 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1775 return NT_STATUS_OK;
1778 /***************************************************************************
1779 _lsa_EnumPrivsAccount
1780 For a given SID, enumerate all the privilege this account has.
1781 ***************************************************************************/
1783 NTSTATUS _lsa_EnumPrivsAccount(pipes_struct *p,
1784 struct lsa_EnumPrivsAccount *r)
1786 NTSTATUS status = NT_STATUS_OK;
1787 struct lsa_info *info=NULL;
1788 SE_PRIV mask;
1789 PRIVILEGE_SET privileges;
1790 struct lsa_PrivilegeSet *priv_set = NULL;
1791 struct lsa_LUIDAttribute *luid_attrs = NULL;
1792 int i;
1794 /* find the connection policy handle. */
1795 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1796 return NT_STATUS_INVALID_HANDLE;
1798 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1799 return NT_STATUS_INVALID_HANDLE;
1802 if (!(info->access & LSA_ACCOUNT_VIEW))
1803 return NT_STATUS_ACCESS_DENIED;
1805 get_privileges_for_sids(&mask, &info->sid, 1);
1807 privilege_set_init( &privileges );
1809 priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
1810 if (!priv_set) {
1811 status = NT_STATUS_NO_MEMORY;
1812 goto done;
1815 if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
1817 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
1818 sid_string_dbg(&info->sid),
1819 privileges.count));
1821 luid_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx,
1822 struct lsa_LUIDAttribute,
1823 privileges.count);
1824 if (!luid_attrs) {
1825 status = NT_STATUS_NO_MEMORY;
1826 goto done;
1829 for (i=0; i<privileges.count; i++) {
1830 luid_attrs[i].luid.low = privileges.set[i].luid.low;
1831 luid_attrs[i].luid.high = privileges.set[i].luid.high;
1832 luid_attrs[i].attribute = privileges.set[i].attr;
1835 priv_set->count = privileges.count;
1836 priv_set->unknown = 0;
1837 priv_set->set = luid_attrs;
1839 } else {
1840 priv_set->count = 0;
1841 priv_set->unknown = 0;
1842 priv_set->set = NULL;
1845 *r->out.privs = priv_set;
1847 done:
1848 privilege_set_free( &privileges );
1850 return status;
1853 /***************************************************************************
1854 _lsa_GetSystemAccessAccount
1855 ***************************************************************************/
1857 NTSTATUS _lsa_GetSystemAccessAccount(pipes_struct *p,
1858 struct lsa_GetSystemAccessAccount *r)
1860 NTSTATUS status;
1861 struct lsa_info *info = NULL;
1862 struct lsa_EnumPrivsAccount e;
1863 struct lsa_PrivilegeSet *privset;
1865 /* find the connection policy handle. */
1867 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1868 return NT_STATUS_INVALID_HANDLE;
1870 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1871 return NT_STATUS_INVALID_HANDLE;
1874 if (!(info->access & LSA_ACCOUNT_VIEW))
1875 return NT_STATUS_ACCESS_DENIED;
1877 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
1878 if (!privset) {
1879 return NT_STATUS_NO_MEMORY;
1882 e.in.handle = r->in.handle;
1883 e.out.privs = &privset;
1885 status = _lsa_EnumPrivsAccount(p, &e);
1886 if (!NT_STATUS_IS_OK(status)) {
1887 DEBUG(10,("_lsa_GetSystemAccessAccount: "
1888 "failed to call _lsa_EnumPrivsAccount(): %s\n",
1889 nt_errstr(status)));
1890 return status;
1893 /* Samba4 would iterate over the privset to merge the policy mode bits,
1894 * not sure samba3 can do the same here, so just return what we did in
1895 * the past - gd */
1898 0x01 -> Log on locally
1899 0x02 -> Access this computer from network
1900 0x04 -> Log on as a batch job
1901 0x10 -> Log on as a service
1903 they can be ORed together
1906 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
1907 LSA_POLICY_MODE_NETWORK;
1909 return NT_STATUS_OK;
1912 /***************************************************************************
1913 update the systemaccount information
1914 ***************************************************************************/
1916 NTSTATUS _lsa_SetSystemAccessAccount(pipes_struct *p,
1917 struct lsa_SetSystemAccessAccount *r)
1919 struct lsa_info *info=NULL;
1920 GROUP_MAP map;
1922 /* find the connection policy handle. */
1923 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1924 return NT_STATUS_INVALID_HANDLE;
1926 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1927 return NT_STATUS_INVALID_HANDLE;
1930 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
1931 return NT_STATUS_ACCESS_DENIED;
1934 if (!pdb_getgrsid(&map, info->sid))
1935 return NT_STATUS_NO_SUCH_GROUP;
1937 return pdb_update_group_mapping_entry(&map);
1940 /***************************************************************************
1941 _lsa_AddPrivilegesToAccount
1942 For a given SID, add some privileges.
1943 ***************************************************************************/
1945 NTSTATUS _lsa_AddPrivilegesToAccount(pipes_struct *p,
1946 struct lsa_AddPrivilegesToAccount *r)
1948 struct lsa_info *info = NULL;
1949 SE_PRIV mask;
1950 struct lsa_PrivilegeSet *set = NULL;
1952 /* find the connection policy handle. */
1953 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1954 return NT_STATUS_INVALID_HANDLE;
1956 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1957 return NT_STATUS_INVALID_HANDLE;
1960 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
1961 return NT_STATUS_ACCESS_DENIED;
1964 set = r->in.privs;
1965 if ( !privilege_set_to_se_priv( &mask, set ) )
1966 return NT_STATUS_NO_SUCH_PRIVILEGE;
1968 if ( !grant_privilege( &info->sid, &mask ) ) {
1969 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege(%s) failed!\n",
1970 sid_string_dbg(&info->sid) ));
1971 DEBUG(3,("Privilege mask:\n"));
1972 dump_se_priv( DBGC_ALL, 3, &mask );
1973 return NT_STATUS_NO_SUCH_PRIVILEGE;
1976 return NT_STATUS_OK;
1979 /***************************************************************************
1980 _lsa_RemovePrivilegesFromAccount
1981 For a given SID, remove some privileges.
1982 ***************************************************************************/
1984 NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p,
1985 struct lsa_RemovePrivilegesFromAccount *r)
1987 struct lsa_info *info = NULL;
1988 SE_PRIV mask;
1989 struct lsa_PrivilegeSet *set = NULL;
1991 /* find the connection policy handle. */
1992 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1993 return NT_STATUS_INVALID_HANDLE;
1995 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1996 return NT_STATUS_INVALID_HANDLE;
1999 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2000 return NT_STATUS_ACCESS_DENIED;
2003 set = r->in.privs;
2005 if ( !privilege_set_to_se_priv( &mask, set ) )
2006 return NT_STATUS_NO_SUCH_PRIVILEGE;
2008 if ( !revoke_privilege( &info->sid, &mask ) ) {
2009 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2010 sid_string_dbg(&info->sid) ));
2011 DEBUG(3,("Privilege mask:\n"));
2012 dump_se_priv( DBGC_ALL, 3, &mask );
2013 return NT_STATUS_NO_SUCH_PRIVILEGE;
2016 return NT_STATUS_OK;
2019 /***************************************************************************
2020 _lsa_LookupPrivName
2021 ***************************************************************************/
2023 NTSTATUS _lsa_LookupPrivName(pipes_struct *p,
2024 struct lsa_LookupPrivName *r)
2026 struct lsa_info *info = NULL;
2027 const char *name;
2028 struct lsa_StringLarge *lsa_name;
2030 /* find the connection policy handle. */
2031 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2032 return NT_STATUS_INVALID_HANDLE;
2035 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2036 return NT_STATUS_INVALID_HANDLE;
2039 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2040 return NT_STATUS_ACCESS_DENIED;
2043 name = luid_to_privilege_name((LUID *)r->in.luid);
2044 if (!name) {
2045 return NT_STATUS_NO_SUCH_PRIVILEGE;
2048 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2049 if (!lsa_name) {
2050 return NT_STATUS_NO_MEMORY;
2053 lsa_name->string = talloc_strdup(lsa_name, name);
2054 if (!lsa_name->string) {
2055 TALLOC_FREE(lsa_name);
2056 return NT_STATUS_NO_MEMORY;
2059 *r->out.name = lsa_name;
2061 return NT_STATUS_OK;
2064 /***************************************************************************
2065 _lsa_QuerySecurity
2066 ***************************************************************************/
2068 NTSTATUS _lsa_QuerySecurity(pipes_struct *p,
2069 struct lsa_QuerySecurity *r)
2071 struct lsa_info *handle=NULL;
2072 SEC_DESC *psd = NULL;
2073 size_t sd_size;
2074 NTSTATUS status;
2076 /* find the connection policy handle. */
2077 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2078 return NT_STATUS_INVALID_HANDLE;
2080 if (handle->type == LSA_HANDLE_POLICY_TYPE) {
2081 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2082 &lsa_policy_mapping, NULL, 0);
2083 } else if (handle->type == LSA_HANDLE_ACCOUNT_TYPE) {
2084 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2085 &lsa_account_mapping,
2086 &handle->sid, LSA_ACCOUNT_ALL_ACCESS);
2087 } else {
2088 status = NT_STATUS_INVALID_HANDLE;
2091 if (!NT_STATUS_IS_OK(status)) {
2092 return status;
2095 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2096 if (!*r->out.sdbuf) {
2097 return NT_STATUS_NO_MEMORY;
2100 return status;
2103 /***************************************************************************
2104 _lsa_AddAccountRights
2105 ***************************************************************************/
2107 NTSTATUS _lsa_AddAccountRights(pipes_struct *p,
2108 struct lsa_AddAccountRights *r)
2110 struct lsa_info *info = NULL;
2111 int i = 0;
2112 uint32_t acc_granted = 0;
2113 SEC_DESC *psd = NULL;
2114 size_t sd_size;
2115 DOM_SID sid;
2116 NTSTATUS status;
2118 /* find the connection policy handle. */
2119 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2120 return NT_STATUS_INVALID_HANDLE;
2122 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2123 return NT_STATUS_INVALID_HANDLE;
2126 /* get the generic lsa account SD for this SID until we store it */
2127 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2128 &lsa_account_mapping,
2129 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2130 if (!NT_STATUS_IS_OK(status)) {
2131 return status;
2135 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2136 * on the policy handle. If it does, ask for
2137 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2138 * on the account sid. We don't check here so just use the latter. JRA.
2141 status = access_check_object(psd, p->server_info->ptok,
2142 NULL, 0, LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2143 &acc_granted, "_lsa_AddAccountRights" );
2145 if (!NT_STATUS_IS_OK(status)) {
2146 return status;
2149 /* according to an NT4 PDC, you can add privileges to SIDs even without
2150 call_lsa_create_account() first. And you can use any arbitrary SID. */
2152 sid_copy( &sid, r->in.sid );
2154 for ( i=0; i < r->in.rights->count; i++ ) {
2156 const char *privname = r->in.rights->names[i].string;
2158 /* only try to add non-null strings */
2160 if ( !privname )
2161 continue;
2163 if ( !grant_privilege_by_name( &sid, privname ) ) {
2164 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2165 privname ));
2166 return NT_STATUS_NO_SUCH_PRIVILEGE;
2170 return NT_STATUS_OK;
2173 /***************************************************************************
2174 _lsa_RemoveAccountRights
2175 ***************************************************************************/
2177 NTSTATUS _lsa_RemoveAccountRights(pipes_struct *p,
2178 struct lsa_RemoveAccountRights *r)
2180 struct lsa_info *info = NULL;
2181 int i = 0;
2182 SEC_DESC *psd = NULL;
2183 size_t sd_size;
2184 DOM_SID sid;
2185 const char *privname = NULL;
2186 uint32_t acc_granted = 0;
2187 NTSTATUS status;
2189 /* find the connection policy handle. */
2190 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2191 return NT_STATUS_INVALID_HANDLE;
2193 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2194 return NT_STATUS_INVALID_HANDLE;
2197 /* get the generic lsa account SD for this SID until we store it */
2198 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2199 &lsa_account_mapping,
2200 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2201 if (!NT_STATUS_IS_OK(status)) {
2202 return status;
2206 * From the MS DOCs. We need
2207 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2208 * and DELETE on the account sid.
2211 status = access_check_object(psd, p->server_info->ptok,
2212 NULL, 0, LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2213 LSA_ACCOUNT_VIEW|STD_RIGHT_DELETE_ACCESS,
2214 &acc_granted, "_lsa_AddAccountRights" );
2216 if (!NT_STATUS_IS_OK(status)) {
2217 return status;
2220 sid_copy( &sid, r->in.sid );
2222 if ( r->in.remove_all ) {
2223 if ( !revoke_all_privileges( &sid ) )
2224 return NT_STATUS_ACCESS_DENIED;
2226 return NT_STATUS_OK;
2229 for ( i=0; i < r->in.rights->count; i++ ) {
2231 privname = r->in.rights->names[i].string;
2233 /* only try to add non-null strings */
2235 if ( !privname )
2236 continue;
2238 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2239 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2240 privname ));
2241 return NT_STATUS_NO_SUCH_PRIVILEGE;
2245 return NT_STATUS_OK;
2248 /*******************************************************************
2249 ********************************************************************/
2251 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
2252 struct lsa_RightSet *r,
2253 PRIVILEGE_SET *privileges)
2255 uint32 i;
2256 const char *privname;
2257 const char **privname_array = NULL;
2258 int num_priv = 0;
2260 for (i=0; i<privileges->count; i++) {
2262 privname = luid_to_privilege_name(&privileges->set[i].luid);
2263 if (privname) {
2264 if (!add_string_to_array(mem_ctx, privname,
2265 &privname_array, &num_priv)) {
2266 return NT_STATUS_NO_MEMORY;
2271 if (num_priv) {
2273 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
2274 num_priv);
2275 if (!r->names) {
2276 return NT_STATUS_NO_MEMORY;
2279 for (i=0; i<num_priv; i++) {
2280 init_lsa_StringLarge(&r->names[i], privname_array[i]);
2283 r->count = num_priv;
2286 return NT_STATUS_OK;
2289 /***************************************************************************
2290 _lsa_EnumAccountRights
2291 ***************************************************************************/
2293 NTSTATUS _lsa_EnumAccountRights(pipes_struct *p,
2294 struct lsa_EnumAccountRights *r)
2296 NTSTATUS status;
2297 struct lsa_info *info = NULL;
2298 DOM_SID sid;
2299 PRIVILEGE_SET privileges;
2300 SE_PRIV mask;
2302 /* find the connection policy handle. */
2304 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2305 return NT_STATUS_INVALID_HANDLE;
2307 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2308 return NT_STATUS_INVALID_HANDLE;
2311 if (!(info->access & LSA_ACCOUNT_VIEW)) {
2312 return NT_STATUS_ACCESS_DENIED;
2315 /* according to an NT4 PDC, you can add privileges to SIDs even without
2316 call_lsa_create_account() first. And you can use any arbitrary SID. */
2318 sid_copy( &sid, r->in.sid );
2320 /* according to MS-LSAD 3.1.4.5.10 it is required to return
2321 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
2322 * the lsa database */
2324 if (!get_privileges_for_sids(&mask, &sid, 1)) {
2325 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2328 status = privilege_set_init(&privileges);
2329 if (!NT_STATUS_IS_OK(status)) {
2330 return status;
2333 se_priv_to_privilege_set(&privileges, &mask);
2335 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
2336 sid_string_dbg(&sid), privileges.count));
2338 status = init_lsa_right_set(p->mem_ctx, r->out.rights, &privileges);
2340 privilege_set_free( &privileges );
2342 return status;
2345 /***************************************************************************
2346 _lsa_LookupPrivValue
2347 ***************************************************************************/
2349 NTSTATUS _lsa_LookupPrivValue(pipes_struct *p,
2350 struct lsa_LookupPrivValue *r)
2352 struct lsa_info *info = NULL;
2353 const char *name = NULL;
2354 LUID_ATTR priv_luid;
2355 SE_PRIV mask;
2357 /* find the connection policy handle. */
2359 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2360 return NT_STATUS_INVALID_HANDLE;
2362 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2363 return NT_STATUS_INVALID_HANDLE;
2366 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
2367 return NT_STATUS_ACCESS_DENIED;
2369 name = r->in.name->string;
2371 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
2373 if ( !se_priv_from_name( name, &mask ) )
2374 return NT_STATUS_NO_SUCH_PRIVILEGE;
2376 priv_luid = get_privilege_luid( &mask );
2378 r->out.luid->low = priv_luid.luid.low;
2379 r->out.luid->high = priv_luid.luid.high;
2381 return NT_STATUS_OK;
2384 /***************************************************************************
2385 _lsa_EnumAccountsWithUserRight
2386 ***************************************************************************/
2388 NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p,
2389 struct lsa_EnumAccountsWithUserRight *r)
2391 NTSTATUS status;
2392 struct lsa_info *info = NULL;
2393 struct dom_sid *sids = NULL;
2394 int num_sids = 0;
2395 uint32_t i;
2396 SE_PRIV mask;
2398 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2399 return NT_STATUS_INVALID_HANDLE;
2402 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2403 return NT_STATUS_INVALID_HANDLE;
2406 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
2407 return NT_STATUS_ACCESS_DENIED;
2410 if (!r->in.name || !r->in.name->string) {
2411 return NT_STATUS_NO_SUCH_PRIVILEGE;
2414 if (!se_priv_from_name(r->in.name->string, &mask)) {
2415 return NT_STATUS_NO_SUCH_PRIVILEGE;
2418 status = privilege_enum_sids(&mask, p->mem_ctx,
2419 &sids, &num_sids);
2420 if (!NT_STATUS_IS_OK(status)) {
2421 return status;
2424 r->out.sids->num_sids = num_sids;
2425 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
2426 r->out.sids->num_sids);
2428 for (i=0; i < r->out.sids->num_sids; i++) {
2429 r->out.sids->sids[i].sid = sid_dup_talloc(r->out.sids->sids,
2430 &sids[i]);
2431 if (!r->out.sids->sids[i].sid) {
2432 TALLOC_FREE(r->out.sids->sids);
2433 r->out.sids->num_sids = 0;
2434 return NT_STATUS_NO_MEMORY;
2438 return NT_STATUS_OK;
2441 /***************************************************************************
2442 _lsa_Delete
2443 ***************************************************************************/
2445 NTSTATUS _lsa_Delete(pipes_struct *p,
2446 struct lsa_Delete *r)
2448 return NT_STATUS_NOT_SUPPORTED;
2452 * From here on the server routines are just dummy ones to make smbd link with
2453 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
2454 * pulling the server stubs across one by one.
2457 NTSTATUS _lsa_SetSecObj(pipes_struct *p, struct lsa_SetSecObj *r)
2459 p->rng_fault_state = True;
2460 return NT_STATUS_NOT_IMPLEMENTED;
2463 NTSTATUS _lsa_ChangePassword(pipes_struct *p, struct lsa_ChangePassword *r)
2465 p->rng_fault_state = True;
2466 return NT_STATUS_NOT_IMPLEMENTED;
2469 NTSTATUS _lsa_SetInfoPolicy(pipes_struct *p, struct lsa_SetInfoPolicy *r)
2471 p->rng_fault_state = True;
2472 return NT_STATUS_NOT_IMPLEMENTED;
2475 NTSTATUS _lsa_ClearAuditLog(pipes_struct *p, struct lsa_ClearAuditLog *r)
2477 p->rng_fault_state = True;
2478 return NT_STATUS_NOT_IMPLEMENTED;
2481 NTSTATUS _lsa_GetQuotasForAccount(pipes_struct *p, struct lsa_GetQuotasForAccount *r)
2483 p->rng_fault_state = True;
2484 return NT_STATUS_NOT_IMPLEMENTED;
2487 NTSTATUS _lsa_SetQuotasForAccount(pipes_struct *p, struct lsa_SetQuotasForAccount *r)
2489 p->rng_fault_state = True;
2490 return NT_STATUS_NOT_IMPLEMENTED;
2493 NTSTATUS _lsa_QueryTrustedDomainInfo(pipes_struct *p, struct lsa_QueryTrustedDomainInfo *r)
2495 p->rng_fault_state = True;
2496 return NT_STATUS_NOT_IMPLEMENTED;
2499 NTSTATUS _lsa_SetInformationTrustedDomain(pipes_struct *p, struct lsa_SetInformationTrustedDomain *r)
2501 p->rng_fault_state = True;
2502 return NT_STATUS_NOT_IMPLEMENTED;
2505 NTSTATUS _lsa_QuerySecret(pipes_struct *p, struct lsa_QuerySecret *r)
2507 p->rng_fault_state = True;
2508 return NT_STATUS_NOT_IMPLEMENTED;
2511 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(pipes_struct *p, struct lsa_QueryTrustedDomainInfoBySid *r)
2513 p->rng_fault_state = True;
2514 return NT_STATUS_NOT_IMPLEMENTED;
2517 NTSTATUS _lsa_SetTrustedDomainInfo(pipes_struct *p, struct lsa_SetTrustedDomainInfo *r)
2519 p->rng_fault_state = True;
2520 return NT_STATUS_NOT_IMPLEMENTED;
2523 NTSTATUS _lsa_DeleteTrustedDomain(pipes_struct *p, struct lsa_DeleteTrustedDomain *r)
2525 p->rng_fault_state = True;
2526 return NT_STATUS_NOT_IMPLEMENTED;
2529 NTSTATUS _lsa_StorePrivateData(pipes_struct *p, struct lsa_StorePrivateData *r)
2531 p->rng_fault_state = True;
2532 return NT_STATUS_NOT_IMPLEMENTED;
2535 NTSTATUS _lsa_RetrievePrivateData(pipes_struct *p, struct lsa_RetrievePrivateData *r)
2537 p->rng_fault_state = True;
2538 return NT_STATUS_NOT_IMPLEMENTED;
2541 NTSTATUS _lsa_SetInfoPolicy2(pipes_struct *p, struct lsa_SetInfoPolicy2 *r)
2543 p->rng_fault_state = True;
2544 return NT_STATUS_NOT_IMPLEMENTED;
2547 NTSTATUS _lsa_QueryTrustedDomainInfoByName(pipes_struct *p, struct lsa_QueryTrustedDomainInfoByName *r)
2549 p->rng_fault_state = True;
2550 return NT_STATUS_NOT_IMPLEMENTED;
2553 NTSTATUS _lsa_SetTrustedDomainInfoByName(pipes_struct *p, struct lsa_SetTrustedDomainInfoByName *r)
2555 p->rng_fault_state = True;
2556 return NT_STATUS_NOT_IMPLEMENTED;
2559 NTSTATUS _lsa_EnumTrustedDomainsEx(pipes_struct *p, struct lsa_EnumTrustedDomainsEx *r)
2561 p->rng_fault_state = True;
2562 return NT_STATUS_NOT_IMPLEMENTED;
2565 NTSTATUS _lsa_CreateTrustedDomainEx(pipes_struct *p, struct lsa_CreateTrustedDomainEx *r)
2567 p->rng_fault_state = True;
2568 return NT_STATUS_NOT_IMPLEMENTED;
2571 NTSTATUS _lsa_CloseTrustedDomainEx(pipes_struct *p, struct lsa_CloseTrustedDomainEx *r)
2573 p->rng_fault_state = True;
2574 return NT_STATUS_NOT_IMPLEMENTED;
2577 NTSTATUS _lsa_QueryDomainInformationPolicy(pipes_struct *p, struct lsa_QueryDomainInformationPolicy *r)
2579 p->rng_fault_state = True;
2580 return NT_STATUS_NOT_IMPLEMENTED;
2583 NTSTATUS _lsa_SetDomainInformationPolicy(pipes_struct *p, struct lsa_SetDomainInformationPolicy *r)
2585 p->rng_fault_state = True;
2586 return NT_STATUS_NOT_IMPLEMENTED;
2589 NTSTATUS _lsa_OpenTrustedDomainByName(pipes_struct *p, struct lsa_OpenTrustedDomainByName *r)
2591 p->rng_fault_state = True;
2592 return NT_STATUS_NOT_IMPLEMENTED;
2595 NTSTATUS _lsa_TestCall(pipes_struct *p, struct lsa_TestCall *r)
2597 p->rng_fault_state = True;
2598 return NT_STATUS_NOT_IMPLEMENTED;
2601 NTSTATUS _lsa_CreateTrustedDomainEx2(pipes_struct *p, struct lsa_CreateTrustedDomainEx2 *r)
2603 p->rng_fault_state = True;
2604 return NT_STATUS_NOT_IMPLEMENTED;
2607 NTSTATUS _lsa_CREDRWRITE(pipes_struct *p, struct lsa_CREDRWRITE *r)
2609 p->rng_fault_state = True;
2610 return NT_STATUS_NOT_IMPLEMENTED;
2613 NTSTATUS _lsa_CREDRREAD(pipes_struct *p, struct lsa_CREDRREAD *r)
2615 p->rng_fault_state = True;
2616 return NT_STATUS_NOT_IMPLEMENTED;
2619 NTSTATUS _lsa_CREDRENUMERATE(pipes_struct *p, struct lsa_CREDRENUMERATE *r)
2621 p->rng_fault_state = True;
2622 return NT_STATUS_NOT_IMPLEMENTED;
2625 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(pipes_struct *p, struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2627 p->rng_fault_state = True;
2628 return NT_STATUS_NOT_IMPLEMENTED;
2631 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(pipes_struct *p, struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2633 p->rng_fault_state = True;
2634 return NT_STATUS_NOT_IMPLEMENTED;
2637 NTSTATUS _lsa_CREDRDELETE(pipes_struct *p, struct lsa_CREDRDELETE *r)
2639 p->rng_fault_state = True;
2640 return NT_STATUS_NOT_IMPLEMENTED;
2643 NTSTATUS _lsa_CREDRGETTARGETINFO(pipes_struct *p, struct lsa_CREDRGETTARGETINFO *r)
2645 p->rng_fault_state = True;
2646 return NT_STATUS_NOT_IMPLEMENTED;
2649 NTSTATUS _lsa_CREDRPROFILELOADED(pipes_struct *p, struct lsa_CREDRPROFILELOADED *r)
2651 p->rng_fault_state = True;
2652 return NT_STATUS_NOT_IMPLEMENTED;
2655 NTSTATUS _lsa_CREDRGETSESSIONTYPES(pipes_struct *p, struct lsa_CREDRGETSESSIONTYPES *r)
2657 p->rng_fault_state = True;
2658 return NT_STATUS_NOT_IMPLEMENTED;
2661 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARREGISTERAUDITEVENT *r)
2663 p->rng_fault_state = True;
2664 return NT_STATUS_NOT_IMPLEMENTED;
2667 NTSTATUS _lsa_LSARGENAUDITEVENT(pipes_struct *p, struct lsa_LSARGENAUDITEVENT *r)
2669 p->rng_fault_state = True;
2670 return NT_STATUS_NOT_IMPLEMENTED;
2673 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARUNREGISTERAUDITEVENT *r)
2675 p->rng_fault_state = True;
2676 return NT_STATUS_NOT_IMPLEMENTED;
2679 NTSTATUS _lsa_lsaRQueryForestTrustInformation(pipes_struct *p, struct lsa_lsaRQueryForestTrustInformation *r)
2681 p->rng_fault_state = True;
2682 return NT_STATUS_NOT_IMPLEMENTED;
2685 NTSTATUS _lsa_LSARSETFORESTTRUSTINFORMATION(pipes_struct *p, struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2687 p->rng_fault_state = True;
2688 return NT_STATUS_NOT_IMPLEMENTED;
2691 NTSTATUS _lsa_CREDRRENAME(pipes_struct *p, struct lsa_CREDRRENAME *r)
2693 p->rng_fault_state = True;
2694 return NT_STATUS_NOT_IMPLEMENTED;
2697 NTSTATUS _lsa_LSAROPENPOLICYSCE(pipes_struct *p, struct lsa_LSAROPENPOLICYSCE *r)
2699 p->rng_fault_state = True;
2700 return NT_STATUS_NOT_IMPLEMENTED;
2703 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(pipes_struct *p, struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2705 p->rng_fault_state = True;
2706 return NT_STATUS_NOT_IMPLEMENTED;
2709 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(pipes_struct *p, struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2711 p->rng_fault_state = True;
2712 return NT_STATUS_NOT_IMPLEMENTED;
2715 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(pipes_struct *p, struct lsa_LSARADTREPORTSECURITYEVENT *r)
2717 p->rng_fault_state = True;
2718 return NT_STATUS_NOT_IMPLEMENTED;