s3-lsa: allow to have NULL strings in lsa LookupName queries.
[Samba.git] / source3 / rpc_server / srv_lsa_nt.c
blobc5805ef3d4b78222fde0d1f7346023ba1d922e80
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 sid_split_rid(&sid, &rid);
199 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
200 mapped_count++;
203 prid[i].sid_type = type;
204 prid[i].rid = rid;
205 prid[i].sid_index = dom_idx;
208 *pmapped_count = mapped_count;
209 return NT_STATUS_OK;
212 /***************************************************************************
213 lookup_lsa_sids. Must be called as root for lookup_name to work.
214 ***************************************************************************/
216 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
217 struct lsa_RefDomainList *ref,
218 struct lsa_TranslatedSid3 *trans_sids,
219 uint32_t num_entries,
220 struct lsa_String *name,
221 int flags,
222 uint32 *pmapped_count)
224 uint32 mapped_count, i;
226 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
228 mapped_count = 0;
229 *pmapped_count = 0;
231 for (i = 0; i < num_entries; i++) {
232 DOM_SID sid;
233 uint32 rid;
234 int dom_idx;
235 const char *full_name;
236 const char *domain;
237 enum lsa_SidType type = SID_NAME_UNKNOWN;
239 ZERO_STRUCT(sid);
241 /* Split name into domain and user component */
243 full_name = name[i].string;
244 if (full_name == NULL) {
245 return NT_STATUS_NO_MEMORY;
248 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
250 /* We can ignore the result of lookup_name, it will not touch
251 "type" if it's not successful */
253 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
254 &sid, &type);
256 switch (type) {
257 case SID_NAME_USER:
258 case SID_NAME_DOM_GRP:
259 case SID_NAME_DOMAIN:
260 case SID_NAME_ALIAS:
261 case SID_NAME_WKN_GRP:
262 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
263 /* Leave these unchanged */
264 break;
265 default:
266 /* Don't hand out anything but the list above */
267 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
268 type = SID_NAME_UNKNOWN;
269 break;
272 rid = 0;
273 dom_idx = -1;
275 if (type != SID_NAME_UNKNOWN) {
276 DOM_SID domain_sid;
277 sid_copy(&domain_sid, &sid);
278 sid_split_rid(&domain_sid, &rid);
279 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
280 mapped_count++;
283 /* Initialize the lsa_TranslatedSid3 return. */
284 trans_sids[i].sid_type = type;
285 trans_sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
286 trans_sids[i].sid_index = dom_idx;
289 *pmapped_count = mapped_count;
290 return NT_STATUS_OK;
293 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size,
294 const struct generic_mapping *map,
295 DOM_SID *sid, uint32_t sid_access)
297 DOM_SID adm_sid;
298 SEC_ACE ace[5];
299 size_t i = 0;
301 SEC_ACL *psa = NULL;
303 /* READ|EXECUTE access for Everyone */
305 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
306 map->generic_execute | map->generic_read, 0);
308 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
310 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
311 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
312 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
313 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
315 /* Add Full Access for Domain Admins */
316 sid_copy(&adm_sid, get_global_sam_sid());
317 sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS);
318 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
319 map->generic_all, 0);
321 /* If we have a sid, give it some special access */
323 if (sid) {
324 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
325 sid_access, 0);
328 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
329 return NT_STATUS_NO_MEMORY;
331 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
332 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
333 psa, sd_size)) == NULL)
334 return NT_STATUS_NO_MEMORY;
336 return NT_STATUS_OK;
340 /***************************************************************************
341 _lsa_OpenPolicy2
342 ***************************************************************************/
344 NTSTATUS _lsa_OpenPolicy2(pipes_struct *p,
345 struct lsa_OpenPolicy2 *r)
347 struct lsa_info *info;
348 SEC_DESC *psd = NULL;
349 size_t sd_size;
350 uint32 des_access = r->in.access_mask;
351 uint32 acc_granted;
352 NTSTATUS status;
354 /* Work out max allowed. */
355 map_max_allowed_access(p->server_info->ptok,
356 &p->server_info->utok,
357 &des_access);
359 /* map the generic bits to the lsa policy ones */
360 se_map_generic(&des_access, &lsa_policy_mapping);
362 /* get the generic lsa policy SD until we store it */
363 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
364 NULL, 0);
365 if (!NT_STATUS_IS_OK(status)) {
366 return status;
369 status = access_check_object(psd, p->server_info->ptok,
370 NULL, 0, des_access,
371 &acc_granted, "_lsa_OpenPolicy2" );
373 if (!NT_STATUS_IS_OK(status)) {
374 return status;
377 /* associate the domain SID with the (unique) handle. */
378 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
379 if (info == NULL) {
380 return NT_STATUS_NO_MEMORY;
383 sid_copy(&info->sid,get_global_sam_sid());
384 info->access = acc_granted;
385 info->type = LSA_HANDLE_POLICY_TYPE;
387 /* set up the LSA QUERY INFO response */
388 if (!create_policy_hnd(p, r->out.handle, info))
389 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
391 return NT_STATUS_OK;
394 /***************************************************************************
395 _lsa_OpenPolicy
396 ***************************************************************************/
398 NTSTATUS _lsa_OpenPolicy(pipes_struct *p,
399 struct lsa_OpenPolicy *r)
401 struct lsa_OpenPolicy2 o;
403 o.in.system_name = NULL; /* should be ignored */
404 o.in.attr = r->in.attr;
405 o.in.access_mask = r->in.access_mask;
407 o.out.handle = r->out.handle;
409 return _lsa_OpenPolicy2(p, &o);
412 /***************************************************************************
413 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
414 ufff, done :) mimir
415 ***************************************************************************/
417 NTSTATUS _lsa_EnumTrustDom(pipes_struct *p,
418 struct lsa_EnumTrustDom *r)
420 struct lsa_info *info;
421 uint32 next_idx;
422 struct trustdom_info **domains;
423 struct lsa_DomainInfo *lsa_domains = NULL;
424 int i;
427 * preferred length is set to 5 as a "our" preferred length
428 * nt sets this parameter to 2
429 * update (20.08.2002): it's not preferred length, but preferred size!
430 * it needs further investigation how to optimally choose this value
432 uint32 max_num_domains =
433 r->in.max_size < 5 ? r->in.max_size : 10;
434 uint32 num_domains;
435 NTSTATUS nt_status;
436 uint32 num_thistime;
438 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
439 return NT_STATUS_INVALID_HANDLE;
441 if (info->type != LSA_HANDLE_POLICY_TYPE) {
442 return NT_STATUS_INVALID_HANDLE;
445 /* check if the user has enough rights */
446 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
447 return NT_STATUS_ACCESS_DENIED;
449 become_root();
450 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &num_domains, &domains);
451 unbecome_root();
453 if (!NT_STATUS_IS_OK(nt_status)) {
454 return nt_status;
457 if (*r->in.resume_handle < num_domains) {
458 num_thistime = MIN(num_domains, max_num_domains);
460 nt_status = STATUS_MORE_ENTRIES;
462 if (*r->in.resume_handle + num_thistime > num_domains) {
463 num_thistime = num_domains - *r->in.resume_handle;
464 nt_status = NT_STATUS_OK;
467 next_idx = *r->in.resume_handle + num_thistime;
468 } else {
469 num_thistime = 0;
470 next_idx = 0xffffffff;
471 nt_status = NT_STATUS_NO_MORE_ENTRIES;
474 /* set up the lsa_enum_trust_dom response */
476 lsa_domains = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo,
477 num_thistime);
478 if (!lsa_domains) {
479 return NT_STATUS_NO_MEMORY;
482 for (i=0; i<num_thistime; i++) {
483 init_lsa_StringLarge(&lsa_domains[i].name, domains[i]->name);
484 lsa_domains[i].sid = &domains[i]->sid;
487 *r->out.resume_handle = next_idx;
488 r->out.domains->count = num_thistime;
489 r->out.domains->domains = lsa_domains;
491 return nt_status;
494 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
495 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
496 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
498 /***************************************************************************
499 _lsa_QueryInfoPolicy
500 ***************************************************************************/
502 NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p,
503 struct lsa_QueryInfoPolicy *r)
505 NTSTATUS status = NT_STATUS_OK;
506 struct lsa_info *handle;
507 DOM_SID domain_sid;
508 const char *name;
509 DOM_SID *sid = NULL;
510 union lsa_PolicyInformation *info = NULL;
511 uint32_t acc_required = 0;
513 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
514 return NT_STATUS_INVALID_HANDLE;
516 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
517 return NT_STATUS_INVALID_HANDLE;
520 switch (r->in.level) {
521 case LSA_POLICY_INFO_AUDIT_LOG:
522 case LSA_POLICY_INFO_AUDIT_EVENTS:
523 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
524 break;
525 case LSA_POLICY_INFO_DOMAIN:
526 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
527 break;
528 case LSA_POLICY_INFO_PD:
529 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
530 break;
531 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
532 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
533 break;
534 case LSA_POLICY_INFO_ROLE:
535 case LSA_POLICY_INFO_REPLICA:
536 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
537 break;
538 case LSA_POLICY_INFO_QUOTA:
539 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
540 break;
541 case LSA_POLICY_INFO_MOD:
542 case LSA_POLICY_INFO_AUDIT_FULL_SET:
543 /* according to MS-LSAD 3.1.4.4.3 */
544 return NT_STATUS_INVALID_PARAMETER;
545 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
546 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
547 break;
548 case LSA_POLICY_INFO_DNS:
549 case LSA_POLICY_INFO_DNS_INT:
550 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
551 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
552 break;
553 default:
554 break;
557 if (!(handle->access & acc_required)) {
558 /* return NT_STATUS_ACCESS_DENIED; */
561 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
562 if (!info) {
563 return NT_STATUS_NO_MEMORY;
566 switch (r->in.level) {
567 case LSA_POLICY_INFO_AUDIT_EVENTS:
570 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
572 /* check if the user has enough rights */
573 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
574 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
575 return NT_STATUS_ACCESS_DENIED;
578 /* fake info: We audit everything. ;) */
580 info->audit_events.auditing_mode = true;
581 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
582 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
583 enum lsa_PolicyAuditPolicy,
584 info->audit_events.count);
585 if (!info->audit_events.settings) {
586 return NT_STATUS_NO_MEMORY;
589 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
590 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
591 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
592 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
593 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
594 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
595 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
597 break;
599 case LSA_POLICY_INFO_DOMAIN:
600 /* check if the user has enough rights */
601 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
602 return NT_STATUS_ACCESS_DENIED;
604 /* Request PolicyPrimaryDomainInformation. */
605 switch (lp_server_role()) {
606 case ROLE_DOMAIN_PDC:
607 case ROLE_DOMAIN_BDC:
608 name = get_global_sam_name();
609 sid = sid_dup_talloc(p->mem_ctx, get_global_sam_sid());
610 if (!sid) {
611 return NT_STATUS_NO_MEMORY;
613 break;
614 case ROLE_DOMAIN_MEMBER:
615 name = lp_workgroup();
616 /* We need to return the Domain SID here. */
617 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
618 sid = sid_dup_talloc(p->mem_ctx, &domain_sid);
619 if (!sid) {
620 return NT_STATUS_NO_MEMORY;
622 } else {
623 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
625 break;
626 case ROLE_STANDALONE:
627 name = lp_workgroup();
628 sid = NULL;
629 break;
630 default:
631 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
633 init_dom_query_3(&info->domain, name, sid);
634 break;
635 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
636 /* check if the user has enough rights */
637 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
638 return NT_STATUS_ACCESS_DENIED;
640 /* Request PolicyAccountDomainInformation. */
641 name = get_global_sam_name();
642 sid = get_global_sam_sid();
644 init_dom_query_5(&info->account_domain, name, sid);
645 break;
646 case LSA_POLICY_INFO_ROLE:
647 /* check if the user has enough rights */
648 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
649 return NT_STATUS_ACCESS_DENIED;
651 switch (lp_server_role()) {
652 case ROLE_DOMAIN_BDC:
654 * only a BDC is a backup controller
655 * of the domain, it controls.
657 info->role.role = LSA_ROLE_BACKUP;
658 break;
659 default:
661 * any other role is a primary
662 * of the domain, it controls.
664 info->role.role = LSA_ROLE_PRIMARY;
665 break;
667 break;
668 case LSA_POLICY_INFO_DNS:
669 case LSA_POLICY_INFO_DNS_INT: {
670 struct pdb_domain_info *dominfo;
672 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
673 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
674 "without ADS passdb backend\n"));
675 status = NT_STATUS_INVALID_INFO_CLASS;
676 break;
679 dominfo = pdb_get_domain_info(info);
680 if (dominfo == NULL) {
681 status = NT_STATUS_NO_MEMORY;
682 break;
685 init_lsa_StringLarge(&info->dns.name,
686 dominfo->name);
687 init_lsa_StringLarge(&info->dns.dns_domain,
688 dominfo->dns_domain);
689 init_lsa_StringLarge(&info->dns.dns_forest,
690 dominfo->dns_forest);
691 info->dns.domain_guid = dominfo->guid;
692 info->dns.sid = &dominfo->sid;
693 break;
695 default:
696 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
697 r->in.level));
698 status = NT_STATUS_INVALID_INFO_CLASS;
699 break;
702 *r->out.info = info;
704 return status;
707 /***************************************************************************
708 _lsa_QueryInfoPolicy2
709 ***************************************************************************/
711 NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p,
712 struct lsa_QueryInfoPolicy2 *r2)
714 struct lsa_QueryInfoPolicy r;
716 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
717 p->rng_fault_state = True;
718 return NT_STATUS_NOT_IMPLEMENTED;
721 ZERO_STRUCT(r);
722 r.in.handle = r2->in.handle;
723 r.in.level = r2->in.level;
724 r.out.info = r2->out.info;
726 return _lsa_QueryInfoPolicy(p, &r);
729 /***************************************************************************
730 _lsa_lookup_sids_internal
731 ***************************************************************************/
733 static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p,
734 TALLOC_CTX *mem_ctx,
735 uint16_t level, /* input */
736 int num_sids, /* input */
737 struct lsa_SidPtr *sid, /* input */
738 struct lsa_RefDomainList **pp_ref, /* input/output */
739 struct lsa_TranslatedName2 **pp_names,/* input/output */
740 uint32_t *pp_mapped_count) /* input/output */
742 NTSTATUS status;
743 int i;
744 const DOM_SID **sids = NULL;
745 struct lsa_RefDomainList *ref = NULL;
746 uint32 mapped_count = 0;
747 struct lsa_dom_info *dom_infos = NULL;
748 struct lsa_name_info *name_infos = NULL;
749 struct lsa_TranslatedName2 *names = NULL;
751 *pp_mapped_count = 0;
752 *pp_names = NULL;
753 *pp_ref = NULL;
755 if (num_sids == 0) {
756 return NT_STATUS_OK;
759 sids = TALLOC_ARRAY(p->mem_ctx, const DOM_SID *, num_sids);
760 ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
762 if (sids == NULL || ref == NULL) {
763 return NT_STATUS_NO_MEMORY;
766 for (i=0; i<num_sids; i++) {
767 sids[i] = sid[i].sid;
770 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
771 &dom_infos, &name_infos);
773 if (!NT_STATUS_IS_OK(status)) {
774 return status;
777 names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
778 if (names == NULL) {
779 return NT_STATUS_NO_MEMORY;
782 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
784 if (!dom_infos[i].valid) {
785 break;
788 if (init_lsa_ref_domain_list(mem_ctx, ref,
789 dom_infos[i].name,
790 &dom_infos[i].sid) != i) {
791 DEBUG(0, ("Domain %s mentioned twice??\n",
792 dom_infos[i].name));
793 return NT_STATUS_INTERNAL_ERROR;
797 for (i=0; i<num_sids; i++) {
798 struct lsa_name_info *name = &name_infos[i];
800 if (name->type == SID_NAME_UNKNOWN) {
801 fstring tmp;
802 name->dom_idx = -1;
803 /* Unknown sids should return the string
804 * representation of the SID. Windows 2003 behaves
805 * rather erratic here, in many cases it returns the
806 * RID as 8 bytes hex, in others it returns the full
807 * SID. We (Jerry/VL) could not figure out which the
808 * hard cases are, so leave it with the SID. */
809 name->name = talloc_asprintf(p->mem_ctx, "%s",
810 sid_to_fstring(tmp,
811 sids[i]));
812 if (name->name == NULL) {
813 return NT_STATUS_NO_MEMORY;
815 } else {
816 mapped_count += 1;
819 names[i].sid_type = name->type;
820 names[i].name.string = name->name;
821 names[i].sid_index = name->dom_idx;
822 names[i].unknown = 0;
825 status = NT_STATUS_NONE_MAPPED;
826 if (mapped_count > 0) {
827 status = (mapped_count < num_sids) ?
828 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
831 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
832 num_sids, mapped_count, nt_errstr(status)));
834 *pp_mapped_count = mapped_count;
835 *pp_names = names;
836 *pp_ref = ref;
838 return status;
841 /***************************************************************************
842 _lsa_LookupSids
843 ***************************************************************************/
845 NTSTATUS _lsa_LookupSids(pipes_struct *p,
846 struct lsa_LookupSids *r)
848 NTSTATUS status;
849 struct lsa_info *handle;
850 int num_sids = r->in.sids->num_sids;
851 uint32 mapped_count = 0;
852 struct lsa_RefDomainList *domains = NULL;
853 struct lsa_TranslatedName *names_out = NULL;
854 struct lsa_TranslatedName2 *names = NULL;
855 int i;
857 if ((r->in.level < 1) || (r->in.level > 6)) {
858 return NT_STATUS_INVALID_PARAMETER;
861 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
862 return NT_STATUS_INVALID_HANDLE;
865 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
866 return NT_STATUS_INVALID_HANDLE;
869 /* check if the user has enough rights */
870 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
871 return NT_STATUS_ACCESS_DENIED;
874 if (num_sids > MAX_LOOKUP_SIDS) {
875 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
876 MAX_LOOKUP_SIDS, num_sids));
877 return NT_STATUS_NONE_MAPPED;
880 status = _lsa_lookup_sids_internal(p,
881 p->mem_ctx,
882 r->in.level,
883 num_sids,
884 r->in.sids->sids,
885 &domains,
886 &names,
887 &mapped_count);
889 /* Only return here when there is a real error.
890 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
891 the requested sids could be resolved. Older versions of XP (pre SP3)
892 rely that we return with the string representations of those SIDs in
893 that case. If we don't, XP crashes - Guenther
896 if (NT_STATUS_IS_ERR(status) &&
897 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
898 return status;
901 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
902 names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
903 num_sids);
904 if (!names_out) {
905 return NT_STATUS_NO_MEMORY;
908 for (i=0; i<num_sids; i++) {
909 names_out[i].sid_type = names[i].sid_type;
910 names_out[i].name = names[i].name;
911 names_out[i].sid_index = names[i].sid_index;
914 *r->out.domains = domains;
915 r->out.names->count = num_sids;
916 r->out.names->names = names_out;
917 *r->out.count = mapped_count;
919 return status;
922 /***************************************************************************
923 _lsa_LookupSids2
924 ***************************************************************************/
926 NTSTATUS _lsa_LookupSids2(pipes_struct *p,
927 struct lsa_LookupSids2 *r)
929 NTSTATUS status;
930 struct lsa_info *handle;
931 int num_sids = r->in.sids->num_sids;
932 uint32 mapped_count = 0;
933 struct lsa_RefDomainList *domains = NULL;
934 struct lsa_TranslatedName2 *names = NULL;
935 bool check_policy = true;
937 switch (p->hdr_req.opnum) {
938 case NDR_LSA_LOOKUPSIDS3:
939 check_policy = false;
940 break;
941 case NDR_LSA_LOOKUPSIDS2:
942 default:
943 check_policy = true;
946 if ((r->in.level < 1) || (r->in.level > 6)) {
947 return NT_STATUS_INVALID_PARAMETER;
950 if (check_policy) {
951 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
952 return NT_STATUS_INVALID_HANDLE;
955 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
956 return NT_STATUS_INVALID_HANDLE;
959 /* check if the user has enough rights */
960 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
961 return NT_STATUS_ACCESS_DENIED;
965 if (num_sids > MAX_LOOKUP_SIDS) {
966 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
967 MAX_LOOKUP_SIDS, num_sids));
968 return NT_STATUS_NONE_MAPPED;
971 status = _lsa_lookup_sids_internal(p,
972 p->mem_ctx,
973 r->in.level,
974 num_sids,
975 r->in.sids->sids,
976 &domains,
977 &names,
978 &mapped_count);
980 *r->out.domains = domains;
981 r->out.names->count = num_sids;
982 r->out.names->names = names;
983 *r->out.count = mapped_count;
985 return status;
988 /***************************************************************************
989 _lsa_LookupSids3
990 ***************************************************************************/
992 NTSTATUS _lsa_LookupSids3(pipes_struct *p,
993 struct lsa_LookupSids3 *r)
995 struct lsa_LookupSids2 q;
997 /* No policy handle on this call. Restrict to crypto connections. */
998 if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
999 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1000 get_remote_machine_name() ));
1001 return NT_STATUS_INVALID_PARAMETER;
1004 q.in.handle = NULL;
1005 q.in.sids = r->in.sids;
1006 q.in.level = r->in.level;
1007 q.in.lookup_options = r->in.lookup_options;
1008 q.in.client_revision = r->in.client_revision;
1009 q.in.names = r->in.names;
1010 q.in.count = r->in.count;
1012 q.out.domains = r->out.domains;
1013 q.out.names = r->out.names;
1014 q.out.count = r->out.count;
1016 return _lsa_LookupSids2(p, &q);
1019 /***************************************************************************
1020 ***************************************************************************/
1022 static int lsa_lookup_level_to_flags(uint16 level)
1024 int flags;
1026 switch (level) {
1027 case 1:
1028 flags = LOOKUP_NAME_ALL;
1029 break;
1030 case 2:
1031 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1032 break;
1033 case 3:
1034 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1035 break;
1036 case 4:
1037 case 5:
1038 case 6:
1039 default:
1040 flags = LOOKUP_NAME_NONE;
1041 break;
1044 return flags;
1047 /***************************************************************************
1048 _lsa_LookupNames
1049 ***************************************************************************/
1051 NTSTATUS _lsa_LookupNames(pipes_struct *p,
1052 struct lsa_LookupNames *r)
1054 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1055 struct lsa_info *handle;
1056 struct lsa_String *names = r->in.names;
1057 uint32 num_entries = r->in.num_names;
1058 struct lsa_RefDomainList *domains = NULL;
1059 struct lsa_TranslatedSid *rids = NULL;
1060 uint32 mapped_count = 0;
1061 int flags = 0;
1063 if (num_entries > MAX_LOOKUP_SIDS) {
1064 num_entries = MAX_LOOKUP_SIDS;
1065 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1066 num_entries));
1069 flags = lsa_lookup_level_to_flags(r->in.level);
1071 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1072 if (!domains) {
1073 return NT_STATUS_NO_MEMORY;
1076 if (num_entries) {
1077 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1078 num_entries);
1079 if (!rids) {
1080 return NT_STATUS_NO_MEMORY;
1082 } else {
1083 rids = NULL;
1086 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1087 status = NT_STATUS_INVALID_HANDLE;
1088 goto done;
1091 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1092 return NT_STATUS_INVALID_HANDLE;
1095 /* check if the user has enough rights */
1096 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1097 status = NT_STATUS_ACCESS_DENIED;
1098 goto done;
1101 /* set up the LSA Lookup RIDs response */
1102 become_root(); /* lookup_name can require root privs */
1103 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1104 names, flags, &mapped_count);
1105 unbecome_root();
1107 done:
1109 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1110 if (mapped_count == 0) {
1111 status = NT_STATUS_NONE_MAPPED;
1112 } else if (mapped_count != num_entries) {
1113 status = STATUS_SOME_UNMAPPED;
1117 *r->out.count = mapped_count;
1118 *r->out.domains = domains;
1119 r->out.sids->sids = rids;
1120 r->out.sids->count = num_entries;
1122 return status;
1125 /***************************************************************************
1126 _lsa_LookupNames2
1127 ***************************************************************************/
1129 NTSTATUS _lsa_LookupNames2(pipes_struct *p,
1130 struct lsa_LookupNames2 *r)
1132 NTSTATUS status;
1133 struct lsa_LookupNames q;
1134 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1135 struct lsa_TransSidArray *sid_array = NULL;
1136 uint32_t i;
1138 sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1139 if (!sid_array) {
1140 return NT_STATUS_NO_MEMORY;
1143 q.in.handle = r->in.handle;
1144 q.in.num_names = r->in.num_names;
1145 q.in.names = r->in.names;
1146 q.in.level = r->in.level;
1147 q.in.sids = sid_array;
1148 q.in.count = r->in.count;
1149 /* we do not know what this is for */
1150 /* = r->in.unknown1; */
1151 /* = r->in.unknown2; */
1153 q.out.domains = r->out.domains;
1154 q.out.sids = sid_array;
1155 q.out.count = r->out.count;
1157 status = _lsa_LookupNames(p, &q);
1159 sid_array2->count = sid_array->count;
1160 sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1161 if (!sid_array2->sids) {
1162 return NT_STATUS_NO_MEMORY;
1165 for (i=0; i<sid_array->count; i++) {
1166 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1167 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1168 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1169 sid_array2->sids[i].unknown = 0;
1172 r->out.sids = sid_array2;
1174 return status;
1177 /***************************************************************************
1178 _lsa_LookupNames3
1179 ***************************************************************************/
1181 NTSTATUS _lsa_LookupNames3(pipes_struct *p,
1182 struct lsa_LookupNames3 *r)
1184 NTSTATUS status;
1185 struct lsa_info *handle;
1186 struct lsa_String *names = r->in.names;
1187 uint32 num_entries = r->in.num_names;
1188 struct lsa_RefDomainList *domains = NULL;
1189 struct lsa_TranslatedSid3 *trans_sids = NULL;
1190 uint32 mapped_count = 0;
1191 int flags = 0;
1192 bool check_policy = true;
1194 switch (p->hdr_req.opnum) {
1195 case NDR_LSA_LOOKUPNAMES4:
1196 check_policy = false;
1197 break;
1198 case NDR_LSA_LOOKUPNAMES3:
1199 default:
1200 check_policy = true;
1203 if (num_entries > MAX_LOOKUP_SIDS) {
1204 num_entries = MAX_LOOKUP_SIDS;
1205 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1208 /* Probably the lookup_level is some sort of bitmask. */
1209 if (r->in.level == 1) {
1210 flags = LOOKUP_NAME_ALL;
1213 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1214 if (!domains) {
1215 return NT_STATUS_NO_MEMORY;
1218 if (num_entries) {
1219 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1220 num_entries);
1221 if (!trans_sids) {
1222 return NT_STATUS_NO_MEMORY;
1224 } else {
1225 trans_sids = NULL;
1228 if (check_policy) {
1230 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1231 status = NT_STATUS_INVALID_HANDLE;
1232 goto done;
1235 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1236 return NT_STATUS_INVALID_HANDLE;
1239 /* check if the user has enough rights */
1240 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1241 status = NT_STATUS_ACCESS_DENIED;
1242 goto done;
1246 /* set up the LSA Lookup SIDs response */
1247 become_root(); /* lookup_name can require root privs */
1248 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1249 names, flags, &mapped_count);
1250 unbecome_root();
1252 done:
1254 if (NT_STATUS_IS_OK(status)) {
1255 if (mapped_count == 0) {
1256 status = NT_STATUS_NONE_MAPPED;
1257 } else if (mapped_count != num_entries) {
1258 status = STATUS_SOME_UNMAPPED;
1262 *r->out.count = mapped_count;
1263 *r->out.domains = domains;
1264 r->out.sids->sids = trans_sids;
1265 r->out.sids->count = num_entries;
1267 return status;
1270 /***************************************************************************
1271 _lsa_LookupNames4
1272 ***************************************************************************/
1274 NTSTATUS _lsa_LookupNames4(pipes_struct *p,
1275 struct lsa_LookupNames4 *r)
1277 struct lsa_LookupNames3 q;
1279 /* No policy handle on this call. Restrict to crypto connections. */
1280 if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
1281 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1282 get_remote_machine_name() ));
1283 return NT_STATUS_INVALID_PARAMETER;
1286 q.in.handle = NULL;
1287 q.in.num_names = r->in.num_names;
1288 q.in.names = r->in.names;
1289 q.in.level = r->in.level;
1290 q.in.lookup_options = r->in.lookup_options;
1291 q.in.client_revision = r->in.client_revision;
1292 q.in.sids = r->in.sids;
1293 q.in.count = r->in.count;
1295 q.out.domains = r->out.domains;
1296 q.out.sids = r->out.sids;
1297 q.out.count = r->out.count;
1299 return _lsa_LookupNames3(p, &q);
1302 /***************************************************************************
1303 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1304 ***************************************************************************/
1306 NTSTATUS _lsa_Close(pipes_struct *p, struct lsa_Close *r)
1308 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1309 return NT_STATUS_INVALID_HANDLE;
1312 close_policy_hnd(p, r->in.handle);
1313 ZERO_STRUCTP(r->out.handle);
1314 return NT_STATUS_OK;
1317 /***************************************************************************
1318 ***************************************************************************/
1320 NTSTATUS _lsa_OpenSecret(pipes_struct *p, struct lsa_OpenSecret *r)
1322 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1325 /***************************************************************************
1326 ***************************************************************************/
1328 NTSTATUS _lsa_OpenTrustedDomain(pipes_struct *p, struct lsa_OpenTrustedDomain *r)
1330 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1333 /***************************************************************************
1334 ***************************************************************************/
1336 NTSTATUS _lsa_CreateTrustedDomain(pipes_struct *p, struct lsa_CreateTrustedDomain *r)
1338 return NT_STATUS_ACCESS_DENIED;
1341 /***************************************************************************
1342 ***************************************************************************/
1344 NTSTATUS _lsa_CreateSecret(pipes_struct *p, struct lsa_CreateSecret *r)
1346 return NT_STATUS_ACCESS_DENIED;
1349 /***************************************************************************
1350 ***************************************************************************/
1352 NTSTATUS _lsa_SetSecret(pipes_struct *p, struct lsa_SetSecret *r)
1354 return NT_STATUS_ACCESS_DENIED;
1357 /***************************************************************************
1358 _lsa_DeleteObject
1359 ***************************************************************************/
1361 NTSTATUS _lsa_DeleteObject(pipes_struct *p,
1362 struct lsa_DeleteObject *r)
1364 NTSTATUS status;
1365 struct lsa_info *info = NULL;
1367 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
1368 return NT_STATUS_INVALID_HANDLE;
1371 if (!(info->access & STD_RIGHT_DELETE_ACCESS)) {
1372 return NT_STATUS_ACCESS_DENIED;
1375 switch (info->type) {
1376 case LSA_HANDLE_ACCOUNT_TYPE:
1377 status = privilege_delete_account(&info->sid);
1378 if (!NT_STATUS_IS_OK(status)) {
1379 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
1380 nt_errstr(status)));
1381 return status;
1383 break;
1384 default:
1385 return NT_STATUS_INVALID_HANDLE;
1388 close_policy_hnd(p, r->in.handle);
1389 ZERO_STRUCTP(r->out.handle);
1391 return status;
1394 /***************************************************************************
1395 _lsa_EnumPrivs
1396 ***************************************************************************/
1398 NTSTATUS _lsa_EnumPrivs(pipes_struct *p,
1399 struct lsa_EnumPrivs *r)
1401 struct lsa_info *handle;
1402 uint32 i;
1403 uint32 enum_context = *r->in.resume_handle;
1404 int num_privs = count_all_privileges();
1405 struct lsa_PrivEntry *entries = NULL;
1406 LUID_ATTR luid;
1408 /* remember that the enum_context starts at 0 and not 1 */
1410 if ( enum_context >= num_privs )
1411 return NT_STATUS_NO_MORE_ENTRIES;
1413 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
1414 enum_context, num_privs));
1416 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1417 return NT_STATUS_INVALID_HANDLE;
1419 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1420 return NT_STATUS_INVALID_HANDLE;
1423 /* check if the user has enough rights
1424 I don't know if it's the right one. not documented. */
1426 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1427 return NT_STATUS_ACCESS_DENIED;
1429 if (num_privs) {
1430 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
1431 if (!entries) {
1432 return NT_STATUS_NO_MEMORY;
1434 } else {
1435 entries = NULL;
1438 for (i = 0; i < num_privs; i++) {
1439 if( i < enum_context) {
1441 init_lsa_StringLarge(&entries[i].name, NULL);
1443 entries[i].luid.low = 0;
1444 entries[i].luid.high = 0;
1445 } else {
1447 init_lsa_StringLarge(&entries[i].name, privs[i].name);
1449 luid = get_privilege_luid( &privs[i].se_priv );
1451 entries[i].luid.low = luid.luid.low;
1452 entries[i].luid.high = luid.luid.high;
1456 enum_context = num_privs;
1458 *r->out.resume_handle = enum_context;
1459 r->out.privs->count = num_privs;
1460 r->out.privs->privs = entries;
1462 return NT_STATUS_OK;
1465 /***************************************************************************
1466 _lsa_LookupPrivDisplayName
1467 ***************************************************************************/
1469 NTSTATUS _lsa_LookupPrivDisplayName(pipes_struct *p,
1470 struct lsa_LookupPrivDisplayName *r)
1472 struct lsa_info *handle;
1473 const char *description;
1474 struct lsa_StringLarge *lsa_name;
1476 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1477 return NT_STATUS_INVALID_HANDLE;
1479 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1480 return NT_STATUS_INVALID_HANDLE;
1483 /* check if the user has enough rights */
1486 * I don't know if it's the right one. not documented.
1488 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1489 return NT_STATUS_ACCESS_DENIED;
1491 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
1493 description = get_privilege_dispname(r->in.name->string);
1494 if (!description) {
1495 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
1496 return NT_STATUS_NO_SUCH_PRIVILEGE;
1499 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
1501 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
1502 if (!lsa_name) {
1503 return NT_STATUS_NO_MEMORY;
1506 init_lsa_StringLarge(lsa_name, description);
1508 *r->out.returned_language_id = r->in.language_id;
1509 *r->out.disp_name = lsa_name;
1511 return NT_STATUS_OK;
1514 /***************************************************************************
1515 _lsa_EnumAccounts
1516 ***************************************************************************/
1518 NTSTATUS _lsa_EnumAccounts(pipes_struct *p,
1519 struct lsa_EnumAccounts *r)
1521 struct lsa_info *handle;
1522 DOM_SID *sid_list;
1523 int i, j, num_entries;
1524 NTSTATUS status;
1525 struct lsa_SidPtr *sids = NULL;
1527 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1528 return NT_STATUS_INVALID_HANDLE;
1530 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1531 return NT_STATUS_INVALID_HANDLE;
1534 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1535 return NT_STATUS_ACCESS_DENIED;
1537 sid_list = NULL;
1538 num_entries = 0;
1540 /* The only way we can currently find out all the SIDs that have been
1541 privileged is to scan all privileges */
1543 status = privilege_enumerate_accounts(&sid_list, &num_entries);
1544 if (!NT_STATUS_IS_OK(status)) {
1545 return status;
1548 if (*r->in.resume_handle >= num_entries) {
1549 return NT_STATUS_NO_MORE_ENTRIES;
1552 if (num_entries - *r->in.resume_handle) {
1553 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
1554 num_entries - *r->in.resume_handle);
1555 if (!sids) {
1556 talloc_free(sid_list);
1557 return NT_STATUS_NO_MEMORY;
1560 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
1561 sids[j].sid = sid_dup_talloc(p->mem_ctx, &sid_list[i]);
1562 if (!sids[j].sid) {
1563 talloc_free(sid_list);
1564 return NT_STATUS_NO_MEMORY;
1569 talloc_free(sid_list);
1571 *r->out.resume_handle = num_entries;
1572 r->out.sids->num_sids = num_entries;
1573 r->out.sids->sids = sids;
1575 return NT_STATUS_OK;
1578 /***************************************************************************
1579 _lsa_GetUserName
1580 ***************************************************************************/
1582 NTSTATUS _lsa_GetUserName(pipes_struct *p,
1583 struct lsa_GetUserName *r)
1585 const char *username, *domname;
1586 struct lsa_String *account_name = NULL;
1587 struct lsa_String *authority_name = NULL;
1589 if (r->in.account_name &&
1590 *r->in.account_name) {
1591 return NT_STATUS_INVALID_PARAMETER;
1594 if (r->in.authority_name &&
1595 *r->in.authority_name) {
1596 return NT_STATUS_INVALID_PARAMETER;
1599 if (p->server_info->guest) {
1601 * I'm 99% sure this is not the right place to do this,
1602 * global_sid_Anonymous should probably be put into the token
1603 * instead of the guest id -- vl
1605 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
1606 &domname, &username, NULL)) {
1607 return NT_STATUS_NO_MEMORY;
1609 } else {
1610 username = p->server_info->sanitized_username;
1611 domname = pdb_get_domain(p->server_info->sam_account);
1614 account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1615 if (!account_name) {
1616 return NT_STATUS_NO_MEMORY;
1618 init_lsa_String(account_name, username);
1620 if (r->out.authority_name) {
1621 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1622 if (!authority_name) {
1623 return NT_STATUS_NO_MEMORY;
1625 init_lsa_String(authority_name, domname);
1628 *r->out.account_name = account_name;
1629 if (r->out.authority_name) {
1630 *r->out.authority_name = authority_name;
1633 return NT_STATUS_OK;
1636 /***************************************************************************
1637 _lsa_CreateAccount
1638 ***************************************************************************/
1640 NTSTATUS _lsa_CreateAccount(pipes_struct *p,
1641 struct lsa_CreateAccount *r)
1643 NTSTATUS status;
1644 struct lsa_info *handle;
1645 struct lsa_info *info;
1646 uint32_t acc_granted;
1647 struct security_descriptor *psd;
1648 size_t sd_size;
1650 /* find the connection policy handle. */
1651 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1652 return NT_STATUS_INVALID_HANDLE;
1654 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1655 return NT_STATUS_INVALID_HANDLE;
1658 /* check if the user has enough rights */
1660 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
1661 return NT_STATUS_ACCESS_DENIED;
1664 /* map the generic bits to the lsa policy ones */
1665 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1667 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1668 &lsa_account_mapping,
1669 r->in.sid, LSA_POLICY_ALL_ACCESS);
1670 if (!NT_STATUS_IS_OK(status)) {
1671 return status;
1674 status = access_check_object(psd, p->server_info->ptok,
1675 NULL, 0, r->in.access_mask,
1676 &acc_granted, "_lsa_CreateAccount");
1677 if (!NT_STATUS_IS_OK(status)) {
1678 return status;
1681 if ( is_privileged_sid( r->in.sid ) )
1682 return NT_STATUS_OBJECT_NAME_COLLISION;
1684 /* associate the user/group SID with the (unique) handle. */
1686 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1687 if (info == NULL) {
1688 return NT_STATUS_NO_MEMORY;
1691 info->sid = *r->in.sid;
1692 info->access = acc_granted;
1693 info->type = LSA_HANDLE_ACCOUNT_TYPE;
1695 /* get a (unique) handle. open a policy on it. */
1696 if (!create_policy_hnd(p, r->out.acct_handle, info))
1697 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1699 return privilege_create_account( &info->sid );
1702 /***************************************************************************
1703 _lsa_OpenAccount
1704 ***************************************************************************/
1706 NTSTATUS _lsa_OpenAccount(pipes_struct *p,
1707 struct lsa_OpenAccount *r)
1709 struct lsa_info *handle;
1710 struct lsa_info *info;
1711 SEC_DESC *psd = NULL;
1712 size_t sd_size;
1713 uint32_t des_access = r->in.access_mask;
1714 uint32_t acc_granted;
1715 NTSTATUS status;
1717 /* find the connection policy handle. */
1718 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1719 return NT_STATUS_INVALID_HANDLE;
1721 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1722 return NT_STATUS_INVALID_HANDLE;
1725 /* des_access is for the account here, not the policy
1726 * handle - so don't check against policy handle. */
1728 /* Work out max allowed. */
1729 map_max_allowed_access(p->server_info->ptok,
1730 &p->server_info->utok,
1731 &des_access);
1733 /* map the generic bits to the lsa account ones */
1734 se_map_generic(&des_access, &lsa_account_mapping);
1736 /* get the generic lsa account SD until we store it */
1737 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1738 &lsa_account_mapping,
1739 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
1740 if (!NT_STATUS_IS_OK(status)) {
1741 return status;
1744 status = access_check_object(psd, p->server_info->ptok,
1745 NULL, 0, des_access,
1746 &acc_granted, "_lsa_OpenAccount" );
1748 if (!NT_STATUS_IS_OK(status)) {
1749 return status;
1752 /* TODO: Fis the parsing routine before reenabling this check! */
1753 #if 0
1754 if (!lookup_sid(&handle->sid, dom_name, name, &type))
1755 return NT_STATUS_ACCESS_DENIED;
1756 #endif
1757 /* associate the user/group SID with the (unique) handle. */
1758 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1759 if (info == NULL) {
1760 return NT_STATUS_NO_MEMORY;
1763 info->sid = *r->in.sid;
1764 info->access = acc_granted;
1765 info->type = LSA_HANDLE_ACCOUNT_TYPE;
1767 /* get a (unique) handle. open a policy on it. */
1768 if (!create_policy_hnd(p, r->out.acct_handle, info))
1769 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1771 return NT_STATUS_OK;
1774 /***************************************************************************
1775 _lsa_EnumPrivsAccount
1776 For a given SID, enumerate all the privilege this account has.
1777 ***************************************************************************/
1779 NTSTATUS _lsa_EnumPrivsAccount(pipes_struct *p,
1780 struct lsa_EnumPrivsAccount *r)
1782 NTSTATUS status = NT_STATUS_OK;
1783 struct lsa_info *info=NULL;
1784 SE_PRIV mask;
1785 PRIVILEGE_SET privileges;
1786 struct lsa_PrivilegeSet *priv_set = NULL;
1787 struct lsa_LUIDAttribute *luid_attrs = NULL;
1788 int i;
1790 /* find the connection policy handle. */
1791 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1792 return NT_STATUS_INVALID_HANDLE;
1794 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1795 return NT_STATUS_INVALID_HANDLE;
1798 if (!(info->access & LSA_ACCOUNT_VIEW))
1799 return NT_STATUS_ACCESS_DENIED;
1801 get_privileges_for_sids(&mask, &info->sid, 1);
1803 privilege_set_init( &privileges );
1805 priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
1806 if (!priv_set) {
1807 status = NT_STATUS_NO_MEMORY;
1808 goto done;
1811 if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
1813 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
1814 sid_string_dbg(&info->sid),
1815 privileges.count));
1817 luid_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx,
1818 struct lsa_LUIDAttribute,
1819 privileges.count);
1820 if (!luid_attrs) {
1821 status = NT_STATUS_NO_MEMORY;
1822 goto done;
1825 for (i=0; i<privileges.count; i++) {
1826 luid_attrs[i].luid.low = privileges.set[i].luid.low;
1827 luid_attrs[i].luid.high = privileges.set[i].luid.high;
1828 luid_attrs[i].attribute = privileges.set[i].attr;
1831 priv_set->count = privileges.count;
1832 priv_set->unknown = 0;
1833 priv_set->set = luid_attrs;
1835 } else {
1836 priv_set->count = 0;
1837 priv_set->unknown = 0;
1838 priv_set->set = NULL;
1841 *r->out.privs = priv_set;
1843 done:
1844 privilege_set_free( &privileges );
1846 return status;
1849 /***************************************************************************
1850 _lsa_GetSystemAccessAccount
1851 ***************************************************************************/
1853 NTSTATUS _lsa_GetSystemAccessAccount(pipes_struct *p,
1854 struct lsa_GetSystemAccessAccount *r)
1856 NTSTATUS status;
1857 struct lsa_info *info = NULL;
1858 struct lsa_EnumPrivsAccount e;
1859 struct lsa_PrivilegeSet *privset;
1861 /* find the connection policy handle. */
1863 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1864 return NT_STATUS_INVALID_HANDLE;
1866 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1867 return NT_STATUS_INVALID_HANDLE;
1870 if (!(info->access & LSA_ACCOUNT_VIEW))
1871 return NT_STATUS_ACCESS_DENIED;
1873 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
1874 if (!privset) {
1875 return NT_STATUS_NO_MEMORY;
1878 e.in.handle = r->in.handle;
1879 e.out.privs = &privset;
1881 status = _lsa_EnumPrivsAccount(p, &e);
1882 if (!NT_STATUS_IS_OK(status)) {
1883 DEBUG(10,("_lsa_GetSystemAccessAccount: "
1884 "failed to call _lsa_EnumPrivsAccount(): %s\n",
1885 nt_errstr(status)));
1886 return status;
1889 /* Samba4 would iterate over the privset to merge the policy mode bits,
1890 * not sure samba3 can do the same here, so just return what we did in
1891 * the past - gd */
1894 0x01 -> Log on locally
1895 0x02 -> Access this computer from network
1896 0x04 -> Log on as a batch job
1897 0x10 -> Log on as a service
1899 they can be ORed together
1902 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
1903 LSA_POLICY_MODE_NETWORK;
1905 return NT_STATUS_OK;
1908 /***************************************************************************
1909 update the systemaccount information
1910 ***************************************************************************/
1912 NTSTATUS _lsa_SetSystemAccessAccount(pipes_struct *p,
1913 struct lsa_SetSystemAccessAccount *r)
1915 struct lsa_info *info=NULL;
1916 GROUP_MAP map;
1918 /* find the connection policy handle. */
1919 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1920 return NT_STATUS_INVALID_HANDLE;
1922 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1923 return NT_STATUS_INVALID_HANDLE;
1926 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
1927 return NT_STATUS_ACCESS_DENIED;
1930 if (!pdb_getgrsid(&map, info->sid))
1931 return NT_STATUS_NO_SUCH_GROUP;
1933 return pdb_update_group_mapping_entry(&map);
1936 /***************************************************************************
1937 _lsa_AddPrivilegesToAccount
1938 For a given SID, add some privileges.
1939 ***************************************************************************/
1941 NTSTATUS _lsa_AddPrivilegesToAccount(pipes_struct *p,
1942 struct lsa_AddPrivilegesToAccount *r)
1944 struct lsa_info *info = NULL;
1945 SE_PRIV mask;
1946 struct lsa_PrivilegeSet *set = NULL;
1948 /* find the connection policy handle. */
1949 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1950 return NT_STATUS_INVALID_HANDLE;
1952 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1953 return NT_STATUS_INVALID_HANDLE;
1956 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
1957 return NT_STATUS_ACCESS_DENIED;
1960 set = r->in.privs;
1961 if ( !privilege_set_to_se_priv( &mask, set ) )
1962 return NT_STATUS_NO_SUCH_PRIVILEGE;
1964 if ( !grant_privilege( &info->sid, &mask ) ) {
1965 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege(%s) failed!\n",
1966 sid_string_dbg(&info->sid) ));
1967 DEBUG(3,("Privilege mask:\n"));
1968 dump_se_priv( DBGC_ALL, 3, &mask );
1969 return NT_STATUS_NO_SUCH_PRIVILEGE;
1972 return NT_STATUS_OK;
1975 /***************************************************************************
1976 _lsa_RemovePrivilegesFromAccount
1977 For a given SID, remove some privileges.
1978 ***************************************************************************/
1980 NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p,
1981 struct lsa_RemovePrivilegesFromAccount *r)
1983 struct lsa_info *info = NULL;
1984 SE_PRIV mask;
1985 struct lsa_PrivilegeSet *set = NULL;
1987 /* find the connection policy handle. */
1988 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1989 return NT_STATUS_INVALID_HANDLE;
1991 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1992 return NT_STATUS_INVALID_HANDLE;
1995 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
1996 return NT_STATUS_ACCESS_DENIED;
1999 set = r->in.privs;
2001 if ( !privilege_set_to_se_priv( &mask, set ) )
2002 return NT_STATUS_NO_SUCH_PRIVILEGE;
2004 if ( !revoke_privilege( &info->sid, &mask ) ) {
2005 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2006 sid_string_dbg(&info->sid) ));
2007 DEBUG(3,("Privilege mask:\n"));
2008 dump_se_priv( DBGC_ALL, 3, &mask );
2009 return NT_STATUS_NO_SUCH_PRIVILEGE;
2012 return NT_STATUS_OK;
2015 /***************************************************************************
2016 _lsa_LookupPrivName
2017 ***************************************************************************/
2019 NTSTATUS _lsa_LookupPrivName(pipes_struct *p,
2020 struct lsa_LookupPrivName *r)
2022 struct lsa_info *info = NULL;
2023 const char *name;
2024 struct lsa_StringLarge *lsa_name;
2026 /* find the connection policy handle. */
2027 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2028 return NT_STATUS_INVALID_HANDLE;
2031 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2032 return NT_STATUS_INVALID_HANDLE;
2035 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2036 return NT_STATUS_ACCESS_DENIED;
2039 name = luid_to_privilege_name((LUID *)r->in.luid);
2040 if (!name) {
2041 return NT_STATUS_NO_SUCH_PRIVILEGE;
2044 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2045 if (!lsa_name) {
2046 return NT_STATUS_NO_MEMORY;
2049 lsa_name->string = talloc_strdup(lsa_name, name);
2050 if (!lsa_name->string) {
2051 TALLOC_FREE(lsa_name);
2052 return NT_STATUS_NO_MEMORY;
2055 *r->out.name = lsa_name;
2057 return NT_STATUS_OK;
2060 /***************************************************************************
2061 _lsa_QuerySecurity
2062 ***************************************************************************/
2064 NTSTATUS _lsa_QuerySecurity(pipes_struct *p,
2065 struct lsa_QuerySecurity *r)
2067 struct lsa_info *handle=NULL;
2068 SEC_DESC *psd = NULL;
2069 size_t sd_size;
2070 NTSTATUS status;
2072 /* find the connection policy handle. */
2073 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2074 return NT_STATUS_INVALID_HANDLE;
2076 if (handle->type == LSA_HANDLE_POLICY_TYPE) {
2077 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2078 &lsa_policy_mapping, NULL, 0);
2079 } else if (handle->type == LSA_HANDLE_ACCOUNT_TYPE) {
2080 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2081 &lsa_account_mapping,
2082 &handle->sid, LSA_ACCOUNT_ALL_ACCESS);
2083 } else {
2084 status = NT_STATUS_INVALID_HANDLE;
2087 if (!NT_STATUS_IS_OK(status)) {
2088 return status;
2091 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2092 if (!*r->out.sdbuf) {
2093 return NT_STATUS_NO_MEMORY;
2096 return status;
2099 /***************************************************************************
2100 _lsa_AddAccountRights
2101 ***************************************************************************/
2103 NTSTATUS _lsa_AddAccountRights(pipes_struct *p,
2104 struct lsa_AddAccountRights *r)
2106 struct lsa_info *info = NULL;
2107 int i = 0;
2108 uint32_t acc_granted = 0;
2109 SEC_DESC *psd = NULL;
2110 size_t sd_size;
2111 DOM_SID sid;
2112 NTSTATUS status;
2114 /* find the connection policy handle. */
2115 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2116 return NT_STATUS_INVALID_HANDLE;
2118 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2119 return NT_STATUS_INVALID_HANDLE;
2122 /* get the generic lsa account SD for this SID until we store it */
2123 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2124 &lsa_account_mapping,
2125 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2126 if (!NT_STATUS_IS_OK(status)) {
2127 return status;
2131 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2132 * on the policy handle. If it does, ask for
2133 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2134 * on the account sid. We don't check here so just use the latter. JRA.
2137 status = access_check_object(psd, p->server_info->ptok,
2138 NULL, 0, LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2139 &acc_granted, "_lsa_AddAccountRights" );
2141 if (!NT_STATUS_IS_OK(status)) {
2142 return status;
2145 /* according to an NT4 PDC, you can add privileges to SIDs even without
2146 call_lsa_create_account() first. And you can use any arbitrary SID. */
2148 sid_copy( &sid, r->in.sid );
2150 for ( i=0; i < r->in.rights->count; i++ ) {
2152 const char *privname = r->in.rights->names[i].string;
2154 /* only try to add non-null strings */
2156 if ( !privname )
2157 continue;
2159 if ( !grant_privilege_by_name( &sid, privname ) ) {
2160 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2161 privname ));
2162 return NT_STATUS_NO_SUCH_PRIVILEGE;
2166 return NT_STATUS_OK;
2169 /***************************************************************************
2170 _lsa_RemoveAccountRights
2171 ***************************************************************************/
2173 NTSTATUS _lsa_RemoveAccountRights(pipes_struct *p,
2174 struct lsa_RemoveAccountRights *r)
2176 struct lsa_info *info = NULL;
2177 int i = 0;
2178 SEC_DESC *psd = NULL;
2179 size_t sd_size;
2180 DOM_SID sid;
2181 const char *privname = NULL;
2182 uint32_t acc_granted = 0;
2183 NTSTATUS status;
2185 /* find the connection policy handle. */
2186 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2187 return NT_STATUS_INVALID_HANDLE;
2189 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2190 return NT_STATUS_INVALID_HANDLE;
2193 /* get the generic lsa account SD for this SID until we store it */
2194 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2195 &lsa_account_mapping,
2196 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2197 if (!NT_STATUS_IS_OK(status)) {
2198 return status;
2202 * From the MS DOCs. We need
2203 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2204 * and DELETE on the account sid.
2207 status = access_check_object(psd, p->server_info->ptok,
2208 NULL, 0, LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2209 LSA_ACCOUNT_VIEW|STD_RIGHT_DELETE_ACCESS,
2210 &acc_granted, "_lsa_AddAccountRights" );
2212 if (!NT_STATUS_IS_OK(status)) {
2213 return status;
2216 sid_copy( &sid, r->in.sid );
2218 if ( r->in.remove_all ) {
2219 if ( !revoke_all_privileges( &sid ) )
2220 return NT_STATUS_ACCESS_DENIED;
2222 return NT_STATUS_OK;
2225 for ( i=0; i < r->in.rights->count; i++ ) {
2227 privname = r->in.rights->names[i].string;
2229 /* only try to add non-null strings */
2231 if ( !privname )
2232 continue;
2234 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2235 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2236 privname ));
2237 return NT_STATUS_NO_SUCH_PRIVILEGE;
2241 return NT_STATUS_OK;
2244 /*******************************************************************
2245 ********************************************************************/
2247 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
2248 struct lsa_RightSet *r,
2249 PRIVILEGE_SET *privileges)
2251 uint32 i;
2252 const char *privname;
2253 const char **privname_array = NULL;
2254 int num_priv = 0;
2256 for (i=0; i<privileges->count; i++) {
2258 privname = luid_to_privilege_name(&privileges->set[i].luid);
2259 if (privname) {
2260 if (!add_string_to_array(mem_ctx, privname,
2261 &privname_array, &num_priv)) {
2262 return NT_STATUS_NO_MEMORY;
2267 if (num_priv) {
2269 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
2270 num_priv);
2271 if (!r->names) {
2272 return NT_STATUS_NO_MEMORY;
2275 for (i=0; i<num_priv; i++) {
2276 init_lsa_StringLarge(&r->names[i], privname_array[i]);
2279 r->count = num_priv;
2282 return NT_STATUS_OK;
2285 /***************************************************************************
2286 _lsa_EnumAccountRights
2287 ***************************************************************************/
2289 NTSTATUS _lsa_EnumAccountRights(pipes_struct *p,
2290 struct lsa_EnumAccountRights *r)
2292 NTSTATUS status;
2293 struct lsa_info *info = NULL;
2294 DOM_SID sid;
2295 PRIVILEGE_SET privileges;
2296 SE_PRIV mask;
2298 /* find the connection policy handle. */
2300 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2301 return NT_STATUS_INVALID_HANDLE;
2303 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2304 return NT_STATUS_INVALID_HANDLE;
2307 if (!(info->access & LSA_ACCOUNT_VIEW)) {
2308 return NT_STATUS_ACCESS_DENIED;
2311 /* according to an NT4 PDC, you can add privileges to SIDs even without
2312 call_lsa_create_account() first. And you can use any arbitrary SID. */
2314 sid_copy( &sid, r->in.sid );
2316 /* according to MS-LSAD 3.1.4.5.10 it is required to return
2317 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
2318 * the lsa database */
2320 if (!get_privileges_for_sids(&mask, &sid, 1)) {
2321 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2324 status = privilege_set_init(&privileges);
2325 if (!NT_STATUS_IS_OK(status)) {
2326 return status;
2329 se_priv_to_privilege_set(&privileges, &mask);
2331 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
2332 sid_string_dbg(&sid), privileges.count));
2334 status = init_lsa_right_set(p->mem_ctx, r->out.rights, &privileges);
2336 privilege_set_free( &privileges );
2338 return status;
2341 /***************************************************************************
2342 _lsa_LookupPrivValue
2343 ***************************************************************************/
2345 NTSTATUS _lsa_LookupPrivValue(pipes_struct *p,
2346 struct lsa_LookupPrivValue *r)
2348 struct lsa_info *info = NULL;
2349 const char *name = NULL;
2350 LUID_ATTR priv_luid;
2351 SE_PRIV mask;
2353 /* find the connection policy handle. */
2355 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2356 return NT_STATUS_INVALID_HANDLE;
2358 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2359 return NT_STATUS_INVALID_HANDLE;
2362 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
2363 return NT_STATUS_ACCESS_DENIED;
2365 name = r->in.name->string;
2367 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
2369 if ( !se_priv_from_name( name, &mask ) )
2370 return NT_STATUS_NO_SUCH_PRIVILEGE;
2372 priv_luid = get_privilege_luid( &mask );
2374 r->out.luid->low = priv_luid.luid.low;
2375 r->out.luid->high = priv_luid.luid.high;
2377 return NT_STATUS_OK;
2380 /***************************************************************************
2381 _lsa_EnumAccountsWithUserRight
2382 ***************************************************************************/
2384 NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p,
2385 struct lsa_EnumAccountsWithUserRight *r)
2387 NTSTATUS status;
2388 struct lsa_info *info = NULL;
2389 struct dom_sid *sids = NULL;
2390 int num_sids = 0;
2391 uint32_t i;
2392 SE_PRIV mask;
2394 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2395 return NT_STATUS_INVALID_HANDLE;
2398 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2399 return NT_STATUS_INVALID_HANDLE;
2402 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
2403 return NT_STATUS_ACCESS_DENIED;
2406 if (!r->in.name || !r->in.name->string) {
2407 return NT_STATUS_NO_SUCH_PRIVILEGE;
2410 if (!se_priv_from_name(r->in.name->string, &mask)) {
2411 return NT_STATUS_NO_SUCH_PRIVILEGE;
2414 status = privilege_enum_sids(&mask, p->mem_ctx,
2415 &sids, &num_sids);
2416 if (!NT_STATUS_IS_OK(status)) {
2417 return status;
2420 r->out.sids->num_sids = num_sids;
2421 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
2422 r->out.sids->num_sids);
2424 for (i=0; i < r->out.sids->num_sids; i++) {
2425 r->out.sids->sids[i].sid = sid_dup_talloc(r->out.sids->sids,
2426 &sids[i]);
2427 if (!r->out.sids->sids[i].sid) {
2428 TALLOC_FREE(r->out.sids->sids);
2429 r->out.sids->num_sids = 0;
2430 return NT_STATUS_NO_MEMORY;
2434 return NT_STATUS_OK;
2437 /***************************************************************************
2438 _lsa_Delete
2439 ***************************************************************************/
2441 NTSTATUS _lsa_Delete(pipes_struct *p,
2442 struct lsa_Delete *r)
2444 return NT_STATUS_NOT_SUPPORTED;
2448 * From here on the server routines are just dummy ones to make smbd link with
2449 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
2450 * pulling the server stubs across one by one.
2453 NTSTATUS _lsa_SetSecObj(pipes_struct *p, struct lsa_SetSecObj *r)
2455 p->rng_fault_state = True;
2456 return NT_STATUS_NOT_IMPLEMENTED;
2459 NTSTATUS _lsa_ChangePassword(pipes_struct *p, struct lsa_ChangePassword *r)
2461 p->rng_fault_state = True;
2462 return NT_STATUS_NOT_IMPLEMENTED;
2465 NTSTATUS _lsa_SetInfoPolicy(pipes_struct *p, struct lsa_SetInfoPolicy *r)
2467 p->rng_fault_state = True;
2468 return NT_STATUS_NOT_IMPLEMENTED;
2471 NTSTATUS _lsa_ClearAuditLog(pipes_struct *p, struct lsa_ClearAuditLog *r)
2473 p->rng_fault_state = True;
2474 return NT_STATUS_NOT_IMPLEMENTED;
2477 NTSTATUS _lsa_GetQuotasForAccount(pipes_struct *p, struct lsa_GetQuotasForAccount *r)
2479 p->rng_fault_state = True;
2480 return NT_STATUS_NOT_IMPLEMENTED;
2483 NTSTATUS _lsa_SetQuotasForAccount(pipes_struct *p, struct lsa_SetQuotasForAccount *r)
2485 p->rng_fault_state = True;
2486 return NT_STATUS_NOT_IMPLEMENTED;
2489 NTSTATUS _lsa_QueryTrustedDomainInfo(pipes_struct *p, struct lsa_QueryTrustedDomainInfo *r)
2491 p->rng_fault_state = True;
2492 return NT_STATUS_NOT_IMPLEMENTED;
2495 NTSTATUS _lsa_SetInformationTrustedDomain(pipes_struct *p, struct lsa_SetInformationTrustedDomain *r)
2497 p->rng_fault_state = True;
2498 return NT_STATUS_NOT_IMPLEMENTED;
2501 NTSTATUS _lsa_QuerySecret(pipes_struct *p, struct lsa_QuerySecret *r)
2503 p->rng_fault_state = True;
2504 return NT_STATUS_NOT_IMPLEMENTED;
2507 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(pipes_struct *p, struct lsa_QueryTrustedDomainInfoBySid *r)
2509 p->rng_fault_state = True;
2510 return NT_STATUS_NOT_IMPLEMENTED;
2513 NTSTATUS _lsa_SetTrustedDomainInfo(pipes_struct *p, struct lsa_SetTrustedDomainInfo *r)
2515 p->rng_fault_state = True;
2516 return NT_STATUS_NOT_IMPLEMENTED;
2519 NTSTATUS _lsa_DeleteTrustedDomain(pipes_struct *p, struct lsa_DeleteTrustedDomain *r)
2521 p->rng_fault_state = True;
2522 return NT_STATUS_NOT_IMPLEMENTED;
2525 NTSTATUS _lsa_StorePrivateData(pipes_struct *p, struct lsa_StorePrivateData *r)
2527 p->rng_fault_state = True;
2528 return NT_STATUS_NOT_IMPLEMENTED;
2531 NTSTATUS _lsa_RetrievePrivateData(pipes_struct *p, struct lsa_RetrievePrivateData *r)
2533 p->rng_fault_state = True;
2534 return NT_STATUS_NOT_IMPLEMENTED;
2537 NTSTATUS _lsa_SetInfoPolicy2(pipes_struct *p, struct lsa_SetInfoPolicy2 *r)
2539 p->rng_fault_state = True;
2540 return NT_STATUS_NOT_IMPLEMENTED;
2543 NTSTATUS _lsa_QueryTrustedDomainInfoByName(pipes_struct *p, struct lsa_QueryTrustedDomainInfoByName *r)
2545 p->rng_fault_state = True;
2546 return NT_STATUS_NOT_IMPLEMENTED;
2549 NTSTATUS _lsa_SetTrustedDomainInfoByName(pipes_struct *p, struct lsa_SetTrustedDomainInfoByName *r)
2551 p->rng_fault_state = True;
2552 return NT_STATUS_NOT_IMPLEMENTED;
2555 NTSTATUS _lsa_EnumTrustedDomainsEx(pipes_struct *p, struct lsa_EnumTrustedDomainsEx *r)
2557 p->rng_fault_state = True;
2558 return NT_STATUS_NOT_IMPLEMENTED;
2561 NTSTATUS _lsa_CreateTrustedDomainEx(pipes_struct *p, struct lsa_CreateTrustedDomainEx *r)
2563 p->rng_fault_state = True;
2564 return NT_STATUS_NOT_IMPLEMENTED;
2567 NTSTATUS _lsa_CloseTrustedDomainEx(pipes_struct *p, struct lsa_CloseTrustedDomainEx *r)
2569 p->rng_fault_state = True;
2570 return NT_STATUS_NOT_IMPLEMENTED;
2573 NTSTATUS _lsa_QueryDomainInformationPolicy(pipes_struct *p, struct lsa_QueryDomainInformationPolicy *r)
2575 p->rng_fault_state = True;
2576 return NT_STATUS_NOT_IMPLEMENTED;
2579 NTSTATUS _lsa_SetDomainInformationPolicy(pipes_struct *p, struct lsa_SetDomainInformationPolicy *r)
2581 p->rng_fault_state = True;
2582 return NT_STATUS_NOT_IMPLEMENTED;
2585 NTSTATUS _lsa_OpenTrustedDomainByName(pipes_struct *p, struct lsa_OpenTrustedDomainByName *r)
2587 p->rng_fault_state = True;
2588 return NT_STATUS_NOT_IMPLEMENTED;
2591 NTSTATUS _lsa_TestCall(pipes_struct *p, struct lsa_TestCall *r)
2593 p->rng_fault_state = True;
2594 return NT_STATUS_NOT_IMPLEMENTED;
2597 NTSTATUS _lsa_CreateTrustedDomainEx2(pipes_struct *p, struct lsa_CreateTrustedDomainEx2 *r)
2599 p->rng_fault_state = True;
2600 return NT_STATUS_NOT_IMPLEMENTED;
2603 NTSTATUS _lsa_CREDRWRITE(pipes_struct *p, struct lsa_CREDRWRITE *r)
2605 p->rng_fault_state = True;
2606 return NT_STATUS_NOT_IMPLEMENTED;
2609 NTSTATUS _lsa_CREDRREAD(pipes_struct *p, struct lsa_CREDRREAD *r)
2611 p->rng_fault_state = True;
2612 return NT_STATUS_NOT_IMPLEMENTED;
2615 NTSTATUS _lsa_CREDRENUMERATE(pipes_struct *p, struct lsa_CREDRENUMERATE *r)
2617 p->rng_fault_state = True;
2618 return NT_STATUS_NOT_IMPLEMENTED;
2621 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(pipes_struct *p, struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2623 p->rng_fault_state = True;
2624 return NT_STATUS_NOT_IMPLEMENTED;
2627 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(pipes_struct *p, struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2629 p->rng_fault_state = True;
2630 return NT_STATUS_NOT_IMPLEMENTED;
2633 NTSTATUS _lsa_CREDRDELETE(pipes_struct *p, struct lsa_CREDRDELETE *r)
2635 p->rng_fault_state = True;
2636 return NT_STATUS_NOT_IMPLEMENTED;
2639 NTSTATUS _lsa_CREDRGETTARGETINFO(pipes_struct *p, struct lsa_CREDRGETTARGETINFO *r)
2641 p->rng_fault_state = True;
2642 return NT_STATUS_NOT_IMPLEMENTED;
2645 NTSTATUS _lsa_CREDRPROFILELOADED(pipes_struct *p, struct lsa_CREDRPROFILELOADED *r)
2647 p->rng_fault_state = True;
2648 return NT_STATUS_NOT_IMPLEMENTED;
2651 NTSTATUS _lsa_CREDRGETSESSIONTYPES(pipes_struct *p, struct lsa_CREDRGETSESSIONTYPES *r)
2653 p->rng_fault_state = True;
2654 return NT_STATUS_NOT_IMPLEMENTED;
2657 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARREGISTERAUDITEVENT *r)
2659 p->rng_fault_state = True;
2660 return NT_STATUS_NOT_IMPLEMENTED;
2663 NTSTATUS _lsa_LSARGENAUDITEVENT(pipes_struct *p, struct lsa_LSARGENAUDITEVENT *r)
2665 p->rng_fault_state = True;
2666 return NT_STATUS_NOT_IMPLEMENTED;
2669 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARUNREGISTERAUDITEVENT *r)
2671 p->rng_fault_state = True;
2672 return NT_STATUS_NOT_IMPLEMENTED;
2675 NTSTATUS _lsa_lsaRQueryForestTrustInformation(pipes_struct *p, struct lsa_lsaRQueryForestTrustInformation *r)
2677 p->rng_fault_state = True;
2678 return NT_STATUS_NOT_IMPLEMENTED;
2681 NTSTATUS _lsa_LSARSETFORESTTRUSTINFORMATION(pipes_struct *p, struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2683 p->rng_fault_state = True;
2684 return NT_STATUS_NOT_IMPLEMENTED;
2687 NTSTATUS _lsa_CREDRRENAME(pipes_struct *p, struct lsa_CREDRRENAME *r)
2689 p->rng_fault_state = True;
2690 return NT_STATUS_NOT_IMPLEMENTED;
2693 NTSTATUS _lsa_LSAROPENPOLICYSCE(pipes_struct *p, struct lsa_LSAROPENPOLICYSCE *r)
2695 p->rng_fault_state = True;
2696 return NT_STATUS_NOT_IMPLEMENTED;
2699 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(pipes_struct *p, struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2701 p->rng_fault_state = True;
2702 return NT_STATUS_NOT_IMPLEMENTED;
2705 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(pipes_struct *p, struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2707 p->rng_fault_state = True;
2708 return NT_STATUS_NOT_IMPLEMENTED;
2711 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(pipes_struct *p, struct lsa_LSARADTREPORTSECURITYEVENT *r)
2713 p->rng_fault_state = True;
2714 return NT_STATUS_NOT_IMPLEMENTED;