Add a security model to LSA. Similar to the SAMR code - using
[Samba.git] / source3 / rpc_server / srv_lsa_nt.c
blobf187432baffe6f155edef08d297e1d70e6a5cf76
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Jeremy Allison 2001, 2006.
8 * Copyright (C) Rafal Szczesniak 2002,
9 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
10 * Copyright (C) Simo Sorce 2003.
11 * Copyright (C) Gerald (Jerry) Carter 2005.
12 * Copyright (C) Volker Lendecke 2005.
13 * Copyright (C) Guenther Deschner 2008.
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 3 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see <http://www.gnu.org/licenses/>.
29 /* This is the implementation of the lsa server code. */
31 #include "includes.h"
33 #undef DBGC_CLASS
34 #define DBGC_CLASS DBGC_RPC_SRV
36 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
38 extern PRIVS privs[];
40 enum lsa_handle_type { LSA_HANDLE_POLICY_TYPE = 1, LSA_HANDLE_ACCOUNT_TYPE };
42 struct lsa_info {
43 DOM_SID sid;
44 uint32 access;
45 enum lsa_handle_type type;
48 const struct generic_mapping lsa_account_mapping = {
49 LSA_ACCOUNT_READ,
50 LSA_ACCOUNT_WRITE,
51 LSA_ACCOUNT_EXECUTE,
52 LSA_ACCOUNT_ALL_ACCESS
55 const struct generic_mapping lsa_policy_mapping = {
56 LSA_POLICY_READ,
57 LSA_POLICY_WRITE,
58 LSA_POLICY_EXECUTE,
59 LSA_POLICY_ALL_ACCESS
62 /***************************************************************************
63 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
64 ***************************************************************************/
66 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
67 struct lsa_RefDomainList *ref,
68 const char *dom_name,
69 DOM_SID *dom_sid)
71 int num = 0;
73 if (dom_name != NULL) {
74 for (num = 0; num < ref->count; num++) {
75 if (sid_equal(dom_sid, ref->domains[num].sid)) {
76 return num;
79 } else {
80 num = ref->count;
83 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
84 /* index not found, already at maximum domain limit */
85 return -1;
88 ref->count = num + 1;
89 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
91 ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains,
92 struct lsa_DomainInfo, ref->count);
93 if (!ref->domains) {
94 return -1;
97 ZERO_STRUCT(ref->domains[num]);
99 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
100 ref->domains[num].sid = sid_dup_talloc(mem_ctx, dom_sid);
101 if (!ref->domains[num].sid) {
102 return -1;
105 return num;
109 /***************************************************************************
110 initialize a lsa_DomainInfo structure.
111 ***************************************************************************/
113 static void init_dom_query_3(struct lsa_DomainInfo *r,
114 const char *name,
115 DOM_SID *sid)
117 init_lsa_StringLarge(&r->name, name);
118 r->sid = sid;
121 /***************************************************************************
122 initialize a lsa_DomainInfo structure.
123 ***************************************************************************/
125 static void init_dom_query_5(struct lsa_DomainInfo *r,
126 const char *name,
127 DOM_SID *sid)
129 init_lsa_StringLarge(&r->name, name);
130 r->sid = sid;
133 /***************************************************************************
134 lookup_lsa_rids. Must be called as root for lookup_name to work.
135 ***************************************************************************/
137 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
138 struct lsa_RefDomainList *ref,
139 struct lsa_TranslatedSid *prid,
140 uint32_t num_entries,
141 struct lsa_String *name,
142 int flags,
143 uint32_t *pmapped_count)
145 uint32 mapped_count, i;
147 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
149 mapped_count = 0;
150 *pmapped_count = 0;
152 for (i = 0; i < num_entries; i++) {
153 DOM_SID sid;
154 uint32 rid;
155 int dom_idx;
156 const char *full_name;
157 const char *domain;
158 enum lsa_SidType type = SID_NAME_UNKNOWN;
160 /* Split name into domain and user component */
162 full_name = name[i].string;
163 if (full_name == NULL) {
164 return NT_STATUS_NO_MEMORY;
167 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
169 /* We can ignore the result of lookup_name, it will not touch
170 "type" if it's not successful */
172 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
173 &sid, &type);
175 switch (type) {
176 case SID_NAME_USER:
177 case SID_NAME_DOM_GRP:
178 case SID_NAME_DOMAIN:
179 case SID_NAME_ALIAS:
180 case SID_NAME_WKN_GRP:
181 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
182 /* Leave these unchanged */
183 break;
184 default:
185 /* Don't hand out anything but the list above */
186 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
187 type = SID_NAME_UNKNOWN;
188 break;
191 rid = 0;
192 dom_idx = -1;
194 if (type != SID_NAME_UNKNOWN) {
195 sid_split_rid(&sid, &rid);
196 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
197 mapped_count++;
200 prid[i].sid_type = type;
201 prid[i].rid = rid;
202 prid[i].sid_index = dom_idx;
205 *pmapped_count = mapped_count;
206 return NT_STATUS_OK;
209 /***************************************************************************
210 lookup_lsa_sids. Must be called as root for lookup_name to work.
211 ***************************************************************************/
213 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
214 struct lsa_RefDomainList *ref,
215 struct lsa_TranslatedSid3 *trans_sids,
216 uint32_t num_entries,
217 struct lsa_String *name,
218 int flags,
219 uint32 *pmapped_count)
221 uint32 mapped_count, i;
223 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
225 mapped_count = 0;
226 *pmapped_count = 0;
228 for (i = 0; i < num_entries; i++) {
229 DOM_SID sid;
230 uint32 rid;
231 int dom_idx;
232 const char *full_name;
233 const char *domain;
234 enum lsa_SidType type = SID_NAME_UNKNOWN;
236 ZERO_STRUCT(sid);
238 /* Split name into domain and user component */
240 full_name = name[i].string;
241 if (full_name == NULL) {
242 return NT_STATUS_NO_MEMORY;
245 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
247 /* We can ignore the result of lookup_name, it will not touch
248 "type" if it's not successful */
250 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
251 &sid, &type);
253 switch (type) {
254 case SID_NAME_USER:
255 case SID_NAME_DOM_GRP:
256 case SID_NAME_DOMAIN:
257 case SID_NAME_ALIAS:
258 case SID_NAME_WKN_GRP:
259 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
260 /* Leave these unchanged */
261 break;
262 default:
263 /* Don't hand out anything but the list above */
264 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
265 type = SID_NAME_UNKNOWN;
266 break;
269 rid = 0;
270 dom_idx = -1;
272 if (type != SID_NAME_UNKNOWN) {
273 DOM_SID domain_sid;
274 sid_copy(&domain_sid, &sid);
275 sid_split_rid(&domain_sid, &rid);
276 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
277 mapped_count++;
280 /* Initialize the lsa_TranslatedSid3 return. */
281 trans_sids[i].sid_type = type;
282 trans_sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
283 trans_sids[i].sid_index = dom_idx;
286 *pmapped_count = mapped_count;
287 return NT_STATUS_OK;
290 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size,
291 const struct generic_mapping *map,
292 DOM_SID *sid, uint32_t sid_access)
294 DOM_SID adm_sid;
295 SEC_ACE ace[5];
296 size_t i = 0;
298 SEC_ACL *psa = NULL;
300 /* READ|EXECUTE access for Everyone */
302 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
303 map->generic_execute | map->generic_read, 0);
305 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
307 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
308 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
309 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
310 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
312 /* Add Full Access for Domain Admins */
313 sid_copy(&adm_sid, get_global_sam_sid());
314 sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS);
315 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
316 map->generic_all, 0);
318 /* If we have a sid, give it some special access */
320 if (sid) {
321 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
322 sid_access, 0);
325 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
326 return NT_STATUS_NO_MEMORY;
328 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
329 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
330 psa, sd_size)) == NULL)
331 return NT_STATUS_NO_MEMORY;
333 return NT_STATUS_OK;
336 #if 0 /* AD DC work in ongoing in Samba 4 */
338 /***************************************************************************
339 Init_dns_dom_info.
340 ***************************************************************************/
342 static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name,
343 const char *dns_name, const char *forest_name,
344 struct GUID *dom_guid, DOM_SID *dom_sid)
346 if (nb_name && *nb_name) {
347 init_unistr2(&r_l->uni_nb_dom_name, nb_name, UNI_FLAGS_NONE);
348 init_uni_hdr(&r_l->hdr_nb_dom_name, &r_l->uni_nb_dom_name);
349 r_l->hdr_nb_dom_name.uni_max_len += 2;
350 r_l->uni_nb_dom_name.uni_max_len += 1;
353 if (dns_name && *dns_name) {
354 init_unistr2(&r_l->uni_dns_dom_name, dns_name, UNI_FLAGS_NONE);
355 init_uni_hdr(&r_l->hdr_dns_dom_name, &r_l->uni_dns_dom_name);
356 r_l->hdr_dns_dom_name.uni_max_len += 2;
357 r_l->uni_dns_dom_name.uni_max_len += 1;
360 if (forest_name && *forest_name) {
361 init_unistr2(&r_l->uni_forest_name, forest_name, UNI_FLAGS_NONE);
362 init_uni_hdr(&r_l->hdr_forest_name, &r_l->uni_forest_name);
363 r_l->hdr_forest_name.uni_max_len += 2;
364 r_l->uni_forest_name.uni_max_len += 1;
367 /* how do we init the guid ? probably should write an init fn */
368 if (dom_guid) {
369 memcpy(&r_l->dom_guid, dom_guid, sizeof(struct GUID));
372 if (dom_sid) {
373 r_l->ptr_dom_sid = 1;
374 init_dom_sid2(&r_l->dom_sid, dom_sid);
377 #endif /* AD DC work in ongoing in Samba 4 */
380 /***************************************************************************
381 _lsa_OpenPolicy2
382 ***************************************************************************/
384 NTSTATUS _lsa_OpenPolicy2(pipes_struct *p,
385 struct lsa_OpenPolicy2 *r)
387 struct lsa_info *info;
388 SEC_DESC *psd = NULL;
389 size_t sd_size;
390 uint32 des_access = r->in.access_mask;
391 uint32 acc_granted;
392 NTSTATUS status;
394 /* Work out max allowed. */
395 map_max_allowed_access(p->server_info->ptok, &des_access);
397 /* map the generic bits to the lsa policy ones */
398 se_map_generic(&des_access, &lsa_policy_mapping);
400 /* get the generic lsa policy SD until we store it */
401 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
402 NULL, 0);
403 if (!NT_STATUS_IS_OK(status)) {
404 return status;
407 status = access_check_object(psd, p->server_info->ptok,
408 NULL, 0, des_access,
409 &acc_granted, "_lsa_OpenPolicy2" );
411 if (!NT_STATUS_IS_OK(status)) {
412 return status;
415 /* associate the domain SID with the (unique) handle. */
416 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
417 if (info == NULL) {
418 return NT_STATUS_NO_MEMORY;
421 sid_copy(&info->sid,get_global_sam_sid());
422 info->access = acc_granted;
423 info->type = LSA_HANDLE_POLICY_TYPE;
425 /* set up the LSA QUERY INFO response */
426 if (!create_policy_hnd(p, r->out.handle, info))
427 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
429 return NT_STATUS_OK;
432 /***************************************************************************
433 _lsa_OpenPolicy
434 ***************************************************************************/
436 NTSTATUS _lsa_OpenPolicy(pipes_struct *p,
437 struct lsa_OpenPolicy *r)
439 struct lsa_OpenPolicy2 o;
441 o.in.system_name = NULL; /* should be ignored */
442 o.in.attr = r->in.attr;
443 o.in.access_mask = r->in.access_mask;
445 o.out.handle = r->out.handle;
447 return _lsa_OpenPolicy2(p, &o);
450 /***************************************************************************
451 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
452 ufff, done :) mimir
453 ***************************************************************************/
455 NTSTATUS _lsa_EnumTrustDom(pipes_struct *p,
456 struct lsa_EnumTrustDom *r)
458 struct lsa_info *info;
459 uint32 next_idx;
460 struct trustdom_info **domains;
461 struct lsa_DomainInfo *lsa_domains = NULL;
462 int i;
465 * preferred length is set to 5 as a "our" preferred length
466 * nt sets this parameter to 2
467 * update (20.08.2002): it's not preferred length, but preferred size!
468 * it needs further investigation how to optimally choose this value
470 uint32 max_num_domains =
471 r->in.max_size < 5 ? r->in.max_size : 10;
472 uint32 num_domains;
473 NTSTATUS nt_status;
474 uint32 num_thistime;
476 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
477 return NT_STATUS_INVALID_HANDLE;
479 if (info->type != LSA_HANDLE_POLICY_TYPE) {
480 return NT_STATUS_INVALID_HANDLE;
483 /* check if the user has enough rights */
484 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
485 return NT_STATUS_ACCESS_DENIED;
487 become_root();
488 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &num_domains, &domains);
489 unbecome_root();
491 if (!NT_STATUS_IS_OK(nt_status)) {
492 return nt_status;
495 if (*r->in.resume_handle < num_domains) {
496 num_thistime = MIN(num_domains, max_num_domains);
498 nt_status = STATUS_MORE_ENTRIES;
500 if (*r->in.resume_handle + num_thistime > num_domains) {
501 num_thistime = num_domains - *r->in.resume_handle;
502 nt_status = NT_STATUS_OK;
505 next_idx = *r->in.resume_handle + num_thistime;
506 } else {
507 num_thistime = 0;
508 next_idx = 0xffffffff;
509 nt_status = NT_STATUS_NO_MORE_ENTRIES;
512 /* set up the lsa_enum_trust_dom response */
514 lsa_domains = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo,
515 num_thistime);
516 if (!lsa_domains) {
517 return NT_STATUS_NO_MEMORY;
520 for (i=0; i<num_thistime; i++) {
521 init_lsa_StringLarge(&lsa_domains[i].name, domains[i]->name);
522 lsa_domains[i].sid = &domains[i]->sid;
525 *r->out.resume_handle = next_idx;
526 r->out.domains->count = num_thistime;
527 r->out.domains->domains = lsa_domains;
529 return nt_status;
532 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
533 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
534 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
536 /***************************************************************************
537 _lsa_QueryInfoPolicy
538 ***************************************************************************/
540 NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p,
541 struct lsa_QueryInfoPolicy *r)
543 NTSTATUS status = NT_STATUS_OK;
544 struct lsa_info *handle;
545 DOM_SID domain_sid;
546 const char *name;
547 DOM_SID *sid = NULL;
548 union lsa_PolicyInformation *info = NULL;
550 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
551 return NT_STATUS_INVALID_HANDLE;
553 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
554 return NT_STATUS_INVALID_HANDLE;
557 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
558 if (!info) {
559 return NT_STATUS_NO_MEMORY;
562 switch (r->in.level) {
563 case 0x02:
566 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
568 /* check if the user has enough rights */
569 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
570 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
571 return NT_STATUS_ACCESS_DENIED;
574 /* fake info: We audit everything. ;) */
576 info->audit_events.auditing_mode = true;
577 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
578 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
579 enum lsa_PolicyAuditPolicy,
580 info->audit_events.count);
581 if (!info->audit_events.settings) {
582 return NT_STATUS_NO_MEMORY;
585 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
586 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
587 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
588 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
589 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
590 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
591 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
593 break;
595 case 0x03:
596 /* check if the user has enough rights */
597 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
598 return NT_STATUS_ACCESS_DENIED;
600 /* Request PolicyPrimaryDomainInformation. */
601 switch (lp_server_role()) {
602 case ROLE_DOMAIN_PDC:
603 case ROLE_DOMAIN_BDC:
604 name = get_global_sam_name();
605 sid = sid_dup_talloc(p->mem_ctx, get_global_sam_sid());
606 if (!sid) {
607 return NT_STATUS_NO_MEMORY;
609 break;
610 case ROLE_DOMAIN_MEMBER:
611 name = lp_workgroup();
612 /* We need to return the Domain SID here. */
613 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
614 sid = sid_dup_talloc(p->mem_ctx, &domain_sid);
615 if (!sid) {
616 return NT_STATUS_NO_MEMORY;
618 } else {
619 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
621 break;
622 case ROLE_STANDALONE:
623 name = lp_workgroup();
624 sid = NULL;
625 break;
626 default:
627 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
629 init_dom_query_3(&info->domain, name, sid);
630 break;
631 case 0x05:
632 /* check if the user has enough rights */
633 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
634 return NT_STATUS_ACCESS_DENIED;
636 /* Request PolicyAccountDomainInformation. */
637 name = get_global_sam_name();
638 sid = get_global_sam_sid();
640 init_dom_query_5(&info->account_domain, name, sid);
641 break;
642 case 0x06:
643 /* check if the user has enough rights */
644 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
645 return NT_STATUS_ACCESS_DENIED;
647 switch (lp_server_role()) {
648 case ROLE_DOMAIN_BDC:
650 * only a BDC is a backup controller
651 * of the domain, it controls.
653 info->role.role = LSA_ROLE_BACKUP;
654 break;
655 default:
657 * any other role is a primary
658 * of the domain, it controls.
660 info->role.role = LSA_ROLE_PRIMARY;
661 break;
663 break;
664 default:
665 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
666 r->in.level));
667 status = NT_STATUS_INVALID_INFO_CLASS;
668 break;
671 *r->out.info = info;
673 return status;
676 /***************************************************************************
677 _lsa_lookup_sids_internal
678 ***************************************************************************/
680 static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p,
681 TALLOC_CTX *mem_ctx,
682 uint16_t level, /* input */
683 int num_sids, /* input */
684 struct lsa_SidPtr *sid, /* input */
685 struct lsa_RefDomainList **pp_ref, /* input/output */
686 struct lsa_TranslatedName2 **pp_names,/* input/output */
687 uint32_t *pp_mapped_count) /* input/output */
689 NTSTATUS status;
690 int i;
691 const DOM_SID **sids = NULL;
692 struct lsa_RefDomainList *ref = NULL;
693 uint32 mapped_count = 0;
694 struct lsa_dom_info *dom_infos = NULL;
695 struct lsa_name_info *name_infos = NULL;
696 struct lsa_TranslatedName2 *names = NULL;
698 *pp_mapped_count = 0;
699 *pp_names = NULL;
700 *pp_ref = NULL;
702 if (num_sids == 0) {
703 return NT_STATUS_OK;
706 sids = TALLOC_ARRAY(p->mem_ctx, const DOM_SID *, num_sids);
707 ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
709 if (sids == NULL || ref == NULL) {
710 return NT_STATUS_NO_MEMORY;
713 for (i=0; i<num_sids; i++) {
714 sids[i] = sid[i].sid;
717 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
718 &dom_infos, &name_infos);
720 if (!NT_STATUS_IS_OK(status)) {
721 return status;
724 names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
725 if (names == NULL) {
726 return NT_STATUS_NO_MEMORY;
729 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
731 if (!dom_infos[i].valid) {
732 break;
735 if (init_lsa_ref_domain_list(mem_ctx, ref,
736 dom_infos[i].name,
737 &dom_infos[i].sid) != i) {
738 DEBUG(0, ("Domain %s mentioned twice??\n",
739 dom_infos[i].name));
740 return NT_STATUS_INTERNAL_ERROR;
744 for (i=0; i<num_sids; i++) {
745 struct lsa_name_info *name = &name_infos[i];
747 if (name->type == SID_NAME_UNKNOWN) {
748 fstring tmp;
749 name->dom_idx = -1;
750 /* Unknown sids should return the string
751 * representation of the SID. Windows 2003 behaves
752 * rather erratic here, in many cases it returns the
753 * RID as 8 bytes hex, in others it returns the full
754 * SID. We (Jerry/VL) could not figure out which the
755 * hard cases are, so leave it with the SID. */
756 name->name = talloc_asprintf(p->mem_ctx, "%s",
757 sid_to_fstring(tmp,
758 sids[i]));
759 if (name->name == NULL) {
760 return NT_STATUS_NO_MEMORY;
762 } else {
763 mapped_count += 1;
766 names[i].sid_type = name->type;
767 names[i].name.string = name->name;
768 names[i].sid_index = name->dom_idx;
769 names[i].unknown = 0;
772 status = NT_STATUS_NONE_MAPPED;
773 if (mapped_count > 0) {
774 status = (mapped_count < num_sids) ?
775 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
778 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
779 num_sids, mapped_count, nt_errstr(status)));
781 *pp_mapped_count = mapped_count;
782 *pp_names = names;
783 *pp_ref = ref;
785 return status;
788 /***************************************************************************
789 _lsa_LookupSids
790 ***************************************************************************/
792 NTSTATUS _lsa_LookupSids(pipes_struct *p,
793 struct lsa_LookupSids *r)
795 NTSTATUS status;
796 struct lsa_info *handle;
797 int num_sids = r->in.sids->num_sids;
798 uint32 mapped_count = 0;
799 struct lsa_RefDomainList *domains = NULL;
800 struct lsa_TranslatedName *names_out = NULL;
801 struct lsa_TranslatedName2 *names = NULL;
802 int i;
804 if ((r->in.level < 1) || (r->in.level > 6)) {
805 return NT_STATUS_INVALID_PARAMETER;
808 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
809 return NT_STATUS_INVALID_HANDLE;
812 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
813 return NT_STATUS_INVALID_HANDLE;
816 /* check if the user has enough rights */
817 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
818 return NT_STATUS_ACCESS_DENIED;
821 if (num_sids > MAX_LOOKUP_SIDS) {
822 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
823 MAX_LOOKUP_SIDS, num_sids));
824 return NT_STATUS_NONE_MAPPED;
827 status = _lsa_lookup_sids_internal(p,
828 p->mem_ctx,
829 r->in.level,
830 num_sids,
831 r->in.sids->sids,
832 &domains,
833 &names,
834 &mapped_count);
836 /* Only return here when there is a real error.
837 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
838 the requested sids could be resolved. Older versions of XP (pre SP3)
839 rely that we return with the string representations of those SIDs in
840 that case. If we don't, XP crashes - Guenther
843 if (NT_STATUS_IS_ERR(status) &&
844 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
845 return status;
848 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
849 names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
850 num_sids);
851 if (!names_out) {
852 return NT_STATUS_NO_MEMORY;
855 for (i=0; i<num_sids; i++) {
856 names_out[i].sid_type = names[i].sid_type;
857 names_out[i].name = names[i].name;
858 names_out[i].sid_index = names[i].sid_index;
861 *r->out.domains = domains;
862 r->out.names->count = num_sids;
863 r->out.names->names = names_out;
864 *r->out.count = mapped_count;
866 return status;
869 /***************************************************************************
870 _lsa_LookupSids2
871 ***************************************************************************/
873 NTSTATUS _lsa_LookupSids2(pipes_struct *p,
874 struct lsa_LookupSids2 *r)
876 NTSTATUS status;
877 struct lsa_info *handle;
878 int num_sids = r->in.sids->num_sids;
879 uint32 mapped_count = 0;
880 struct lsa_RefDomainList *domains = NULL;
881 struct lsa_TranslatedName2 *names = NULL;
882 bool check_policy = true;
884 switch (p->hdr_req.opnum) {
885 case NDR_LSA_LOOKUPSIDS3:
886 check_policy = false;
887 break;
888 case NDR_LSA_LOOKUPSIDS2:
889 default:
890 check_policy = true;
893 if ((r->in.level < 1) || (r->in.level > 6)) {
894 return NT_STATUS_INVALID_PARAMETER;
897 if (check_policy) {
898 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
899 return NT_STATUS_INVALID_HANDLE;
902 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
903 return NT_STATUS_INVALID_HANDLE;
906 /* check if the user has enough rights */
907 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
908 return NT_STATUS_ACCESS_DENIED;
912 if (num_sids > MAX_LOOKUP_SIDS) {
913 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
914 MAX_LOOKUP_SIDS, num_sids));
915 return NT_STATUS_NONE_MAPPED;
918 status = _lsa_lookup_sids_internal(p,
919 p->mem_ctx,
920 r->in.level,
921 num_sids,
922 r->in.sids->sids,
923 &domains,
924 &names,
925 &mapped_count);
927 *r->out.domains = domains;
928 r->out.names->count = num_sids;
929 r->out.names->names = names;
930 *r->out.count = mapped_count;
932 return status;
935 /***************************************************************************
936 _lsa_LookupSids3
937 ***************************************************************************/
939 NTSTATUS _lsa_LookupSids3(pipes_struct *p,
940 struct lsa_LookupSids3 *r)
942 struct lsa_LookupSids2 q;
944 /* No policy handle on this call. Restrict to crypto connections. */
945 if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
946 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
947 get_remote_machine_name() ));
948 return NT_STATUS_INVALID_PARAMETER;
951 q.in.handle = NULL;
952 q.in.sids = r->in.sids;
953 q.in.level = r->in.level;
954 q.in.unknown1 = r->in.unknown1;
955 q.in.unknown2 = r->in.unknown2;
956 q.in.names = r->in.names;
957 q.in.count = r->in.count;
959 q.out.domains = r->out.domains;
960 q.out.names = r->out.names;
961 q.out.count = r->out.count;
963 return _lsa_LookupSids2(p, &q);
966 /***************************************************************************
967 ***************************************************************************/
969 static int lsa_lookup_level_to_flags(uint16 level)
971 int flags;
973 switch (level) {
974 case 1:
975 flags = LOOKUP_NAME_ALL;
976 break;
977 case 2:
978 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
979 break;
980 case 3:
981 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
982 break;
983 case 4:
984 case 5:
985 case 6:
986 default:
987 flags = LOOKUP_NAME_NONE;
988 break;
991 return flags;
994 /***************************************************************************
995 _lsa_LookupNames
996 ***************************************************************************/
998 NTSTATUS _lsa_LookupNames(pipes_struct *p,
999 struct lsa_LookupNames *r)
1001 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1002 struct lsa_info *handle;
1003 struct lsa_String *names = r->in.names;
1004 uint32 num_entries = r->in.num_names;
1005 struct lsa_RefDomainList *domains = NULL;
1006 struct lsa_TranslatedSid *rids = NULL;
1007 uint32 mapped_count = 0;
1008 int flags = 0;
1010 if (num_entries > MAX_LOOKUP_SIDS) {
1011 num_entries = MAX_LOOKUP_SIDS;
1012 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1013 num_entries));
1016 flags = lsa_lookup_level_to_flags(r->in.level);
1018 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1019 if (!domains) {
1020 return NT_STATUS_NO_MEMORY;
1023 if (num_entries) {
1024 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1025 num_entries);
1026 if (!rids) {
1027 return NT_STATUS_NO_MEMORY;
1029 } else {
1030 rids = NULL;
1033 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1034 status = NT_STATUS_INVALID_HANDLE;
1035 goto done;
1038 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1039 return NT_STATUS_INVALID_HANDLE;
1042 /* check if the user has enough rights */
1043 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1044 status = NT_STATUS_ACCESS_DENIED;
1045 goto done;
1048 /* set up the LSA Lookup RIDs response */
1049 become_root(); /* lookup_name can require root privs */
1050 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1051 names, flags, &mapped_count);
1052 unbecome_root();
1054 done:
1056 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1057 if (mapped_count == 0) {
1058 status = NT_STATUS_NONE_MAPPED;
1059 } else if (mapped_count != num_entries) {
1060 status = STATUS_SOME_UNMAPPED;
1064 *r->out.count = mapped_count;
1065 *r->out.domains = domains;
1066 r->out.sids->sids = rids;
1067 r->out.sids->count = num_entries;
1069 return status;
1072 /***************************************************************************
1073 _lsa_LookupNames2
1074 ***************************************************************************/
1076 NTSTATUS _lsa_LookupNames2(pipes_struct *p,
1077 struct lsa_LookupNames2 *r)
1079 NTSTATUS status;
1080 struct lsa_LookupNames q;
1081 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1082 struct lsa_TransSidArray *sid_array = NULL;
1083 uint32_t i;
1085 sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1086 if (!sid_array) {
1087 return NT_STATUS_NO_MEMORY;
1090 q.in.handle = r->in.handle;
1091 q.in.num_names = r->in.num_names;
1092 q.in.names = r->in.names;
1093 q.in.level = r->in.level;
1094 q.in.sids = sid_array;
1095 q.in.count = r->in.count;
1096 /* we do not know what this is for */
1097 /* = r->in.unknown1; */
1098 /* = r->in.unknown2; */
1100 q.out.domains = r->out.domains;
1101 q.out.sids = sid_array;
1102 q.out.count = r->out.count;
1104 status = _lsa_LookupNames(p, &q);
1106 sid_array2->count = sid_array->count;
1107 sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1108 if (!sid_array2->sids) {
1109 return NT_STATUS_NO_MEMORY;
1112 for (i=0; i<sid_array->count; i++) {
1113 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1114 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1115 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1116 sid_array2->sids[i].unknown = 0;
1119 r->out.sids = sid_array2;
1121 return status;
1124 /***************************************************************************
1125 _lsa_LookupNames3
1126 ***************************************************************************/
1128 NTSTATUS _lsa_LookupNames3(pipes_struct *p,
1129 struct lsa_LookupNames3 *r)
1131 NTSTATUS status;
1132 struct lsa_info *handle;
1133 struct lsa_String *names = r->in.names;
1134 uint32 num_entries = r->in.num_names;
1135 struct lsa_RefDomainList *domains = NULL;
1136 struct lsa_TranslatedSid3 *trans_sids = NULL;
1137 uint32 mapped_count = 0;
1138 int flags = 0;
1139 bool check_policy = true;
1141 switch (p->hdr_req.opnum) {
1142 case NDR_LSA_LOOKUPNAMES4:
1143 check_policy = false;
1144 break;
1145 case NDR_LSA_LOOKUPNAMES3:
1146 default:
1147 check_policy = true;
1150 if (num_entries > MAX_LOOKUP_SIDS) {
1151 num_entries = MAX_LOOKUP_SIDS;
1152 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1155 /* Probably the lookup_level is some sort of bitmask. */
1156 if (r->in.level == 1) {
1157 flags = LOOKUP_NAME_ALL;
1160 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1161 if (!domains) {
1162 return NT_STATUS_NO_MEMORY;
1165 if (num_entries) {
1166 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1167 num_entries);
1168 if (!trans_sids) {
1169 return NT_STATUS_NO_MEMORY;
1171 } else {
1172 trans_sids = NULL;
1175 if (check_policy) {
1177 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1178 status = NT_STATUS_INVALID_HANDLE;
1179 goto done;
1182 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1183 return NT_STATUS_INVALID_HANDLE;
1186 /* check if the user has enough rights */
1187 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1188 status = NT_STATUS_ACCESS_DENIED;
1189 goto done;
1193 /* set up the LSA Lookup SIDs response */
1194 become_root(); /* lookup_name can require root privs */
1195 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1196 names, flags, &mapped_count);
1197 unbecome_root();
1199 done:
1201 if (NT_STATUS_IS_OK(status)) {
1202 if (mapped_count == 0) {
1203 status = NT_STATUS_NONE_MAPPED;
1204 } else if (mapped_count != num_entries) {
1205 status = STATUS_SOME_UNMAPPED;
1209 *r->out.count = mapped_count;
1210 *r->out.domains = domains;
1211 r->out.sids->sids = trans_sids;
1212 r->out.sids->count = num_entries;
1214 return status;
1217 /***************************************************************************
1218 _lsa_LookupNames4
1219 ***************************************************************************/
1221 NTSTATUS _lsa_LookupNames4(pipes_struct *p,
1222 struct lsa_LookupNames4 *r)
1224 struct lsa_LookupNames3 q;
1226 /* No policy handle on this call. Restrict to crypto connections. */
1227 if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
1228 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1229 get_remote_machine_name() ));
1230 return NT_STATUS_INVALID_PARAMETER;
1233 q.in.handle = NULL;
1234 q.in.num_names = r->in.num_names;
1235 q.in.names = r->in.names;
1236 q.in.level = r->in.level;
1237 q.in.lookup_options = r->in.lookup_options;
1238 q.in.client_revision = r->in.client_revision;
1239 q.in.sids = r->in.sids;
1240 q.in.count = r->in.count;
1242 q.out.domains = r->out.domains;
1243 q.out.sids = r->out.sids;
1244 q.out.count = r->out.count;
1246 return _lsa_LookupNames3(p, &q);
1249 /***************************************************************************
1250 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1251 ***************************************************************************/
1253 NTSTATUS _lsa_Close(pipes_struct *p, struct lsa_Close *r)
1255 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1256 return NT_STATUS_INVALID_HANDLE;
1259 close_policy_hnd(p, r->in.handle);
1260 ZERO_STRUCTP(r->out.handle);
1261 return NT_STATUS_OK;
1264 /***************************************************************************
1265 ***************************************************************************/
1267 NTSTATUS _lsa_OpenSecret(pipes_struct *p, struct lsa_OpenSecret *r)
1269 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1272 /***************************************************************************
1273 ***************************************************************************/
1275 NTSTATUS _lsa_OpenTrustedDomain(pipes_struct *p, struct lsa_OpenTrustedDomain *r)
1277 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1280 /***************************************************************************
1281 ***************************************************************************/
1283 NTSTATUS _lsa_CreateTrustedDomain(pipes_struct *p, struct lsa_CreateTrustedDomain *r)
1285 return NT_STATUS_ACCESS_DENIED;
1288 /***************************************************************************
1289 ***************************************************************************/
1291 NTSTATUS _lsa_CreateSecret(pipes_struct *p, struct lsa_CreateSecret *r)
1293 return NT_STATUS_ACCESS_DENIED;
1296 /***************************************************************************
1297 ***************************************************************************/
1299 NTSTATUS _lsa_SetSecret(pipes_struct *p, struct lsa_SetSecret *r)
1301 return NT_STATUS_ACCESS_DENIED;
1304 /***************************************************************************
1305 _lsa_DeleteObject
1306 ***************************************************************************/
1308 NTSTATUS _lsa_DeleteObject(pipes_struct *p,
1309 struct lsa_DeleteObject *r)
1311 NTSTATUS status;
1312 struct lsa_info *info = NULL;
1314 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
1315 return NT_STATUS_INVALID_HANDLE;
1318 if (!(info->access & STD_RIGHT_DELETE_ACCESS)) {
1319 return NT_STATUS_ACCESS_DENIED;
1322 status = privilege_delete_account(&info->sid);
1323 if (!NT_STATUS_IS_OK(status)) {
1324 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
1325 nt_errstr(status)));
1328 return status;
1331 /***************************************************************************
1332 _lsa_EnumPrivs
1333 ***************************************************************************/
1335 NTSTATUS _lsa_EnumPrivs(pipes_struct *p,
1336 struct lsa_EnumPrivs *r)
1338 struct lsa_info *handle;
1339 uint32 i;
1340 uint32 enum_context = *r->in.resume_handle;
1341 int num_privs = count_all_privileges();
1342 struct lsa_PrivEntry *entries = NULL;
1343 LUID_ATTR luid;
1345 /* remember that the enum_context starts at 0 and not 1 */
1347 if ( enum_context >= num_privs )
1348 return NT_STATUS_NO_MORE_ENTRIES;
1350 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
1351 enum_context, num_privs));
1353 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1354 return NT_STATUS_INVALID_HANDLE;
1356 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1357 return NT_STATUS_INVALID_HANDLE;
1360 /* check if the user has enough rights
1361 I don't know if it's the right one. not documented. */
1363 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1364 return NT_STATUS_ACCESS_DENIED;
1366 if (num_privs) {
1367 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
1368 if (!entries) {
1369 return NT_STATUS_NO_MEMORY;
1371 } else {
1372 entries = NULL;
1375 for (i = 0; i < num_privs; i++) {
1376 if( i < enum_context) {
1378 init_lsa_StringLarge(&entries[i].name, NULL);
1380 entries[i].luid.low = 0;
1381 entries[i].luid.high = 0;
1382 } else {
1384 init_lsa_StringLarge(&entries[i].name, privs[i].name);
1386 luid = get_privilege_luid( &privs[i].se_priv );
1388 entries[i].luid.low = luid.luid.low;
1389 entries[i].luid.high = luid.luid.high;
1393 enum_context = num_privs;
1395 *r->out.resume_handle = enum_context;
1396 r->out.privs->count = num_privs;
1397 r->out.privs->privs = entries;
1399 return NT_STATUS_OK;
1402 /***************************************************************************
1403 _lsa_LookupPrivDisplayName
1404 ***************************************************************************/
1406 NTSTATUS _lsa_LookupPrivDisplayName(pipes_struct *p,
1407 struct lsa_LookupPrivDisplayName *r)
1409 struct lsa_info *handle;
1410 const char *description;
1411 struct lsa_StringLarge *lsa_name;
1413 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1414 return NT_STATUS_INVALID_HANDLE;
1416 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1417 return NT_STATUS_INVALID_HANDLE;
1420 /* check if the user has enough rights */
1423 * I don't know if it's the right one. not documented.
1425 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1426 return NT_STATUS_ACCESS_DENIED;
1428 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
1430 description = get_privilege_dispname(r->in.name->string);
1431 if (!description) {
1432 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
1433 return NT_STATUS_NO_SUCH_PRIVILEGE;
1436 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
1438 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
1439 if (!lsa_name) {
1440 return NT_STATUS_NO_MEMORY;
1443 init_lsa_StringLarge(lsa_name, description);
1445 *r->out.returned_language_id = r->in.language_id;
1446 *r->out.disp_name = lsa_name;
1448 return NT_STATUS_OK;
1451 /***************************************************************************
1452 _lsa_EnumAccounts
1453 ***************************************************************************/
1455 NTSTATUS _lsa_EnumAccounts(pipes_struct *p,
1456 struct lsa_EnumAccounts *r)
1458 struct lsa_info *handle;
1459 DOM_SID *sid_list;
1460 int i, j, num_entries;
1461 NTSTATUS status;
1462 struct lsa_SidPtr *sids = NULL;
1464 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1465 return NT_STATUS_INVALID_HANDLE;
1467 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1468 return NT_STATUS_INVALID_HANDLE;
1471 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1472 return NT_STATUS_ACCESS_DENIED;
1474 sid_list = NULL;
1475 num_entries = 0;
1477 /* The only way we can currently find out all the SIDs that have been
1478 privileged is to scan all privileges */
1480 status = privilege_enumerate_accounts(&sid_list, &num_entries);
1481 if (!NT_STATUS_IS_OK(status)) {
1482 return status;
1485 if (*r->in.resume_handle >= num_entries) {
1486 return NT_STATUS_NO_MORE_ENTRIES;
1489 if (num_entries - *r->in.resume_handle) {
1490 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
1491 num_entries - *r->in.resume_handle);
1492 if (!sids) {
1493 talloc_free(sid_list);
1494 return NT_STATUS_NO_MEMORY;
1497 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
1498 sids[j].sid = sid_dup_talloc(p->mem_ctx, &sid_list[i]);
1499 if (!sids[j].sid) {
1500 talloc_free(sid_list);
1501 return NT_STATUS_NO_MEMORY;
1506 talloc_free(sid_list);
1508 *r->out.resume_handle = num_entries;
1509 r->out.sids->num_sids = num_entries;
1510 r->out.sids->sids = sids;
1512 return NT_STATUS_OK;
1515 /***************************************************************************
1516 _lsa_GetUserName
1517 ***************************************************************************/
1519 NTSTATUS _lsa_GetUserName(pipes_struct *p,
1520 struct lsa_GetUserName *r)
1522 const char *username, *domname;
1523 struct lsa_String *account_name = NULL;
1524 struct lsa_String *authority_name = NULL;
1526 if (r->in.account_name &&
1527 *r->in.account_name) {
1528 return NT_STATUS_INVALID_PARAMETER;
1531 if (r->in.authority_name &&
1532 *r->in.authority_name) {
1533 return NT_STATUS_INVALID_PARAMETER;
1536 if (p->server_info->guest) {
1538 * I'm 99% sure this is not the right place to do this,
1539 * global_sid_Anonymous should probably be put into the token
1540 * instead of the guest id -- vl
1542 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
1543 &domname, &username, NULL)) {
1544 return NT_STATUS_NO_MEMORY;
1546 } else {
1547 username = p->server_info->sanitized_username;
1548 domname = pdb_get_domain(p->server_info->sam_account);
1551 account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1552 if (!account_name) {
1553 return NT_STATUS_NO_MEMORY;
1555 init_lsa_String(account_name, username);
1557 if (r->out.authority_name) {
1558 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1559 if (!authority_name) {
1560 return NT_STATUS_NO_MEMORY;
1562 init_lsa_String(authority_name, domname);
1565 *r->out.account_name = account_name;
1566 if (r->out.authority_name) {
1567 *r->out.authority_name = authority_name;
1570 return NT_STATUS_OK;
1573 /***************************************************************************
1574 _lsa_CreateAccount
1575 ***************************************************************************/
1577 NTSTATUS _lsa_CreateAccount(pipes_struct *p,
1578 struct lsa_CreateAccount *r)
1580 struct lsa_info *handle;
1581 struct lsa_info *info;
1583 /* find the connection policy handle. */
1584 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1585 return NT_STATUS_INVALID_HANDLE;
1587 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1588 return NT_STATUS_INVALID_HANDLE;
1591 /* check if the user has enough rights */
1594 * I don't know if it's the right one. not documented.
1595 * but guessed with rpcclient.
1597 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT))
1598 return NT_STATUS_ACCESS_DENIED;
1600 if ( is_privileged_sid( r->in.sid ) )
1601 return NT_STATUS_OBJECT_NAME_COLLISION;
1603 /* associate the user/group SID with the (unique) handle. */
1605 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1606 if (info == NULL) {
1607 return NT_STATUS_NO_MEMORY;
1610 info->sid = *r->in.sid;
1611 info->access = r->in.access_mask;
1612 info->type = LSA_HANDLE_ACCOUNT_TYPE;
1614 /* get a (unique) handle. open a policy on it. */
1615 if (!create_policy_hnd(p, r->out.acct_handle, info))
1616 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1618 return privilege_create_account( &info->sid );
1621 /***************************************************************************
1622 _lsa_OpenAccount
1623 ***************************************************************************/
1625 NTSTATUS _lsa_OpenAccount(pipes_struct *p,
1626 struct lsa_OpenAccount *r)
1628 struct lsa_info *handle;
1629 struct lsa_info *info;
1630 SEC_DESC *psd = NULL;
1631 size_t sd_size;
1632 uint32_t des_access = r->in.access_mask;
1633 uint32_t acc_granted;
1634 NTSTATUS status;
1636 /* find the connection policy handle. */
1637 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1638 return NT_STATUS_INVALID_HANDLE;
1640 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1641 return NT_STATUS_INVALID_HANDLE;
1644 /* des_access is for the account here, not the policy
1645 * handle - so don't check against policy handle. */
1647 /* Work out max allowed. */
1648 map_max_allowed_access(p->server_info->ptok, &des_access);
1650 /* map the generic bits to the lsa account ones */
1651 se_map_generic(&des_access, &lsa_account_mapping);
1653 /* get the generic lsa account SD until we store it */
1654 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1655 &lsa_account_mapping,
1656 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
1657 if (!NT_STATUS_IS_OK(status)) {
1658 return status;
1661 status = access_check_object(psd, p->server_info->ptok,
1662 NULL, 0, des_access,
1663 &acc_granted, "_lsa_OpenAccount" );
1665 if (!NT_STATUS_IS_OK(status)) {
1666 return status;
1669 /* TODO: Fis the parsing routine before reenabling this check! */
1670 #if 0
1671 if (!lookup_sid(&handle->sid, dom_name, name, &type))
1672 return NT_STATUS_ACCESS_DENIED;
1673 #endif
1674 /* associate the user/group SID with the (unique) handle. */
1675 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1676 if (info == NULL) {
1677 return NT_STATUS_NO_MEMORY;
1680 info->sid = *r->in.sid;
1681 info->access = acc_granted;
1682 info->type = LSA_HANDLE_ACCOUNT_TYPE;
1684 /* get a (unique) handle. open a policy on it. */
1685 if (!create_policy_hnd(p, r->out.acct_handle, info))
1686 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1688 return NT_STATUS_OK;
1691 /***************************************************************************
1692 _lsa_EnumPrivsAccount
1693 For a given SID, enumerate all the privilege this account has.
1694 ***************************************************************************/
1696 NTSTATUS _lsa_EnumPrivsAccount(pipes_struct *p,
1697 struct lsa_EnumPrivsAccount *r)
1699 NTSTATUS status = NT_STATUS_OK;
1700 struct lsa_info *info=NULL;
1701 SE_PRIV mask;
1702 PRIVILEGE_SET privileges;
1703 struct lsa_PrivilegeSet *priv_set = NULL;
1704 struct lsa_LUIDAttribute *luid_attrs = NULL;
1705 int i;
1707 /* find the connection policy handle. */
1708 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1709 return NT_STATUS_INVALID_HANDLE;
1711 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1712 return NT_STATUS_INVALID_HANDLE;
1715 if (!(info->access & LSA_ACCOUNT_VIEW))
1716 return NT_STATUS_ACCESS_DENIED;
1718 if ( !get_privileges_for_sids( &mask, &info->sid, 1 ) )
1719 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1721 privilege_set_init( &privileges );
1723 if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
1725 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
1726 sid_string_dbg(&info->sid),
1727 privileges.count));
1729 priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
1730 if (!priv_set) {
1731 status = NT_STATUS_NO_MEMORY;
1732 goto done;
1735 luid_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx,
1736 struct lsa_LUIDAttribute,
1737 privileges.count);
1738 if (!luid_attrs) {
1739 status = NT_STATUS_NO_MEMORY;
1740 goto done;
1743 for (i=0; i<privileges.count; i++) {
1744 luid_attrs[i].luid.low = privileges.set[i].luid.low;
1745 luid_attrs[i].luid.high = privileges.set[i].luid.high;
1746 luid_attrs[i].attribute = privileges.set[i].attr;
1749 priv_set->count = privileges.count;
1750 priv_set->unknown = 0;
1751 priv_set->set = luid_attrs;
1753 *r->out.privs = priv_set;
1754 } else {
1755 status = NT_STATUS_NO_SUCH_PRIVILEGE;
1758 done:
1759 privilege_set_free( &privileges );
1761 return status;
1764 /***************************************************************************
1765 _lsa_GetSystemAccessAccount
1766 ***************************************************************************/
1768 NTSTATUS _lsa_GetSystemAccessAccount(pipes_struct *p,
1769 struct lsa_GetSystemAccessAccount *r)
1771 NTSTATUS status;
1772 struct lsa_info *info = NULL;
1773 struct lsa_EnumPrivsAccount e;
1774 struct lsa_PrivilegeSet *privset;
1776 /* find the connection policy handle. */
1778 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1779 return NT_STATUS_INVALID_HANDLE;
1781 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1782 return NT_STATUS_INVALID_HANDLE;
1785 if (!(info->access & LSA_ACCOUNT_VIEW))
1786 return NT_STATUS_ACCESS_DENIED;
1788 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
1789 if (!privset) {
1790 return NT_STATUS_NO_MEMORY;
1793 e.in.handle = r->in.handle;
1794 e.out.privs = &privset;
1796 status = _lsa_EnumPrivsAccount(p, &e);
1797 if (!NT_STATUS_IS_OK(status)) {
1798 DEBUG(10,("_lsa_GetSystemAccessAccount: "
1799 "failed to call _lsa_EnumPrivsAccount(): %s\n",
1800 nt_errstr(status)));
1801 return status;
1804 /* Samba4 would iterate over the privset to merge the policy mode bits,
1805 * not sure samba3 can do the same here, so just return what we did in
1806 * the past - gd */
1809 0x01 -> Log on locally
1810 0x02 -> Access this computer from network
1811 0x04 -> Log on as a batch job
1812 0x10 -> Log on as a service
1814 they can be ORed together
1817 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
1818 LSA_POLICY_MODE_NETWORK;
1820 return NT_STATUS_OK;
1823 /***************************************************************************
1824 update the systemaccount information
1825 ***************************************************************************/
1827 NTSTATUS _lsa_SetSystemAccessAccount(pipes_struct *p,
1828 struct lsa_SetSystemAccessAccount *r)
1830 struct lsa_info *info=NULL;
1831 GROUP_MAP map;
1833 /* find the connection policy handle. */
1834 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1835 return NT_STATUS_INVALID_HANDLE;
1837 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1838 return NT_STATUS_INVALID_HANDLE;
1841 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
1842 return NT_STATUS_ACCESS_DENIED;
1845 if (!pdb_getgrsid(&map, info->sid))
1846 return NT_STATUS_NO_SUCH_GROUP;
1848 return pdb_update_group_mapping_entry(&map);
1851 /***************************************************************************
1852 _lsa_AddPrivilegesToAccount
1853 For a given SID, add some privileges.
1854 ***************************************************************************/
1856 NTSTATUS _lsa_AddPrivilegesToAccount(pipes_struct *p,
1857 struct lsa_AddPrivilegesToAccount *r)
1859 struct lsa_info *info = NULL;
1860 SE_PRIV mask;
1861 struct lsa_PrivilegeSet *set = NULL;
1863 /* find the connection policy handle. */
1864 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1865 return NT_STATUS_INVALID_HANDLE;
1867 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1868 return NT_STATUS_INVALID_HANDLE;
1871 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
1872 return NT_STATUS_ACCESS_DENIED;
1875 set = r->in.privs;
1876 if ( !privilege_set_to_se_priv( &mask, set ) )
1877 return NT_STATUS_NO_SUCH_PRIVILEGE;
1879 if ( !grant_privilege( &info->sid, &mask ) ) {
1880 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege(%s) failed!\n",
1881 sid_string_dbg(&info->sid) ));
1882 DEBUG(3,("Privilege mask:\n"));
1883 dump_se_priv( DBGC_ALL, 3, &mask );
1884 return NT_STATUS_NO_SUCH_PRIVILEGE;
1887 return NT_STATUS_OK;
1890 /***************************************************************************
1891 _lsa_RemovePrivilegesFromAccount
1892 For a given SID, remove some privileges.
1893 ***************************************************************************/
1895 NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p,
1896 struct lsa_RemovePrivilegesFromAccount *r)
1898 struct lsa_info *info = NULL;
1899 SE_PRIV mask;
1900 struct lsa_PrivilegeSet *set = NULL;
1902 /* find the connection policy handle. */
1903 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1904 return NT_STATUS_INVALID_HANDLE;
1906 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1907 return NT_STATUS_INVALID_HANDLE;
1910 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
1911 return NT_STATUS_ACCESS_DENIED;
1914 set = r->in.privs;
1916 if ( !privilege_set_to_se_priv( &mask, set ) )
1917 return NT_STATUS_NO_SUCH_PRIVILEGE;
1919 if ( !revoke_privilege( &info->sid, &mask ) ) {
1920 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
1921 sid_string_dbg(&info->sid) ));
1922 DEBUG(3,("Privilege mask:\n"));
1923 dump_se_priv( DBGC_ALL, 3, &mask );
1924 return NT_STATUS_NO_SUCH_PRIVILEGE;
1927 return NT_STATUS_OK;
1930 /***************************************************************************
1931 _lsa_QuerySecurity
1932 ***************************************************************************/
1934 NTSTATUS _lsa_QuerySecurity(pipes_struct *p,
1935 struct lsa_QuerySecurity *r)
1937 struct lsa_info *handle=NULL;
1938 SEC_DESC *psd = NULL;
1939 size_t sd_size;
1940 NTSTATUS status;
1942 /* find the connection policy handle. */
1943 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1944 return NT_STATUS_INVALID_HANDLE;
1946 if (handle->type == LSA_HANDLE_POLICY_TYPE) {
1947 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1948 &lsa_policy_mapping, NULL, 0);
1949 } else if (handle->type == LSA_HANDLE_ACCOUNT_TYPE) {
1950 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1951 &lsa_account_mapping,
1952 &handle->sid, LSA_ACCOUNT_ALL_ACCESS);
1953 } else {
1954 status = NT_STATUS_INVALID_HANDLE;
1957 if (!NT_STATUS_IS_OK(status)) {
1958 return status;
1961 switch (r->in.sec_info) {
1962 case 1:
1963 /* SD contains only the owner */
1964 if((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1965 return NT_STATUS_NO_MEMORY;
1966 break;
1967 case 4:
1968 /* SD contains only the ACL */
1969 if((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
1970 return NT_STATUS_NO_MEMORY;
1971 break;
1972 default:
1973 return NT_STATUS_INVALID_LEVEL;
1976 return status;
1979 #if 0 /* AD DC work in ongoing in Samba 4 */
1981 /***************************************************************************
1982 ***************************************************************************/
1984 NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_INFO2 *r_u)
1986 struct lsa_info *handle;
1987 const char *nb_name;
1988 char *dns_name = NULL;
1989 char *forest_name = NULL;
1990 DOM_SID *sid = NULL;
1991 struct GUID guid;
1992 fstring dnsdomname;
1994 ZERO_STRUCT(guid);
1995 r_u->status = NT_STATUS_OK;
1997 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
1998 return NT_STATUS_INVALID_HANDLE;
2000 switch (q_u->info_class) {
2001 case 0x0c:
2002 /* check if the user has enough rights */
2003 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2004 return NT_STATUS_ACCESS_DENIED;
2006 /* Request PolicyPrimaryDomainInformation. */
2007 switch (lp_server_role()) {
2008 case ROLE_DOMAIN_PDC:
2009 case ROLE_DOMAIN_BDC:
2010 nb_name = get_global_sam_name();
2011 /* ugly temp hack for these next two */
2013 /* This should be a 'netbios domain -> DNS domain' mapping */
2014 dnsdomname = get_mydnsdomname(p->mem_ctx);
2015 if (!dnsdomname || !*dnsdomname) {
2016 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2018 strlower_m(dnsdomname);
2020 dns_name = dnsdomname;
2021 forest_name = dnsdomname;
2023 sid = get_global_sam_sid();
2024 secrets_fetch_domain_guid(lp_workgroup(), &guid);
2025 break;
2026 default:
2027 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2029 init_dns_dom_info(&r_u->info.dns_dom_info, nb_name, dns_name,
2030 forest_name,&guid,sid);
2031 break;
2032 default:
2033 DEBUG(0,("_lsa_query_info2: unknown info level in Lsa Query: %d\n", q_u->info_class));
2034 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
2035 break;
2038 if (NT_STATUS_IS_OK(r_u->status)) {
2039 r_u->ptr = 0x1;
2040 r_u->info_class = q_u->info_class;
2043 return r_u->status;
2045 #endif /* AD DC work in ongoing in Samba 4 */
2047 /***************************************************************************
2048 _lsa_AddAccountRights
2049 ***************************************************************************/
2051 NTSTATUS _lsa_AddAccountRights(pipes_struct *p,
2052 struct lsa_AddAccountRights *r)
2054 struct lsa_info *info = NULL;
2055 int i = 0;
2056 uint32_t acc_granted = 0;
2057 SEC_DESC *psd = NULL;
2058 size_t sd_size;
2059 DOM_SID sid;
2060 NTSTATUS status;
2062 /* find the connection policy handle. */
2063 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2064 return NT_STATUS_INVALID_HANDLE;
2066 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2067 return NT_STATUS_INVALID_HANDLE;
2070 /* get the generic lsa account SD for this SID until we store it */
2071 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2072 &lsa_account_mapping,
2073 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2074 if (!NT_STATUS_IS_OK(status)) {
2075 return status;
2079 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2080 * on the policy handle. If it does, ask for
2081 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2082 * on the account sid. We don't check here so just use the latter. JRA.
2085 status = access_check_object(psd, p->server_info->ptok,
2086 NULL, 0, LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2087 &acc_granted, "_lsa_AddAccountRights" );
2089 if (!NT_STATUS_IS_OK(status)) {
2090 return status;
2093 /* according to an NT4 PDC, you can add privileges to SIDs even without
2094 call_lsa_create_account() first. And you can use any arbitrary SID. */
2096 sid_copy( &sid, r->in.sid );
2098 for ( i=0; i < r->in.rights->count; i++ ) {
2100 const char *privname = r->in.rights->names[i].string;
2102 /* only try to add non-null strings */
2104 if ( !privname )
2105 continue;
2107 if ( !grant_privilege_by_name( &sid, privname ) ) {
2108 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2109 privname ));
2110 return NT_STATUS_NO_SUCH_PRIVILEGE;
2114 return NT_STATUS_OK;
2117 /***************************************************************************
2118 _lsa_RemoveAccountRights
2119 ***************************************************************************/
2121 NTSTATUS _lsa_RemoveAccountRights(pipes_struct *p,
2122 struct lsa_RemoveAccountRights *r)
2124 struct lsa_info *info = NULL;
2125 int i = 0;
2126 SEC_DESC *psd = NULL;
2127 size_t sd_size;
2128 DOM_SID sid;
2129 const char *privname = NULL;
2130 uint32_t acc_granted = 0;
2131 NTSTATUS status;
2133 /* find the connection policy handle. */
2134 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2135 return NT_STATUS_INVALID_HANDLE;
2137 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2138 return NT_STATUS_INVALID_HANDLE;
2141 /* get the generic lsa account SD for this SID until we store it */
2142 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2143 &lsa_account_mapping,
2144 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2145 if (!NT_STATUS_IS_OK(status)) {
2146 return status;
2150 * From the MS DOCs. We need
2151 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2152 * and DELETE on the account sid.
2155 status = access_check_object(psd, p->server_info->ptok,
2156 NULL, 0, LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2157 LSA_ACCOUNT_VIEW|STD_RIGHT_DELETE_ACCESS,
2158 &acc_granted, "_lsa_AddAccountRights" );
2160 if (!NT_STATUS_IS_OK(status)) {
2161 return status;
2164 sid_copy( &sid, r->in.sid );
2166 if ( r->in.remove_all ) {
2167 if ( !revoke_all_privileges( &sid ) )
2168 return NT_STATUS_ACCESS_DENIED;
2170 return NT_STATUS_OK;
2173 for ( i=0; i < r->in.rights->count; i++ ) {
2175 privname = r->in.rights->names[i].string;
2177 /* only try to add non-null strings */
2179 if ( !privname )
2180 continue;
2182 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2183 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2184 privname ));
2185 return NT_STATUS_NO_SUCH_PRIVILEGE;
2189 return NT_STATUS_OK;
2192 /*******************************************************************
2193 ********************************************************************/
2195 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
2196 struct lsa_RightSet *r,
2197 PRIVILEGE_SET *privileges)
2199 uint32 i;
2200 const char *privname;
2201 const char **privname_array = NULL;
2202 int num_priv = 0;
2204 for (i=0; i<privileges->count; i++) {
2206 privname = luid_to_privilege_name(&privileges->set[i].luid);
2207 if (privname) {
2208 if (!add_string_to_array(mem_ctx, privname,
2209 &privname_array, &num_priv)) {
2210 return NT_STATUS_NO_MEMORY;
2215 if (num_priv) {
2217 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
2218 num_priv);
2219 if (!r->names) {
2220 return NT_STATUS_NO_MEMORY;
2223 for (i=0; i<num_priv; i++) {
2224 init_lsa_StringLarge(&r->names[i], privname_array[i]);
2227 r->count = num_priv;
2230 return NT_STATUS_OK;
2233 /***************************************************************************
2234 _lsa_EnumAccountRights
2235 ***************************************************************************/
2237 NTSTATUS _lsa_EnumAccountRights(pipes_struct *p,
2238 struct lsa_EnumAccountRights *r)
2240 NTSTATUS status;
2241 struct lsa_info *info = NULL;
2242 DOM_SID sid;
2243 PRIVILEGE_SET privileges;
2244 SE_PRIV mask;
2246 /* find the connection policy handle. */
2248 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2249 return NT_STATUS_INVALID_HANDLE;
2251 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2252 return NT_STATUS_INVALID_HANDLE;
2255 if (!(info->access & LSA_ACCOUNT_VIEW)) {
2256 return NT_STATUS_ACCESS_DENIED;
2259 /* according to an NT4 PDC, you can add privileges to SIDs even without
2260 call_lsa_create_account() first. And you can use any arbitrary SID. */
2262 sid_copy( &sid, r->in.sid );
2264 if ( !get_privileges_for_sids( &mask, &sid, 1 ) )
2265 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2267 privilege_set_init( &privileges );
2269 if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
2271 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
2272 sid_string_dbg(&sid), privileges.count));
2274 status = init_lsa_right_set(p->mem_ctx, r->out.rights, &privileges);
2275 } else {
2276 status = NT_STATUS_NO_SUCH_PRIVILEGE;
2279 privilege_set_free( &privileges );
2281 return status;
2284 /***************************************************************************
2285 _lsa_LookupPrivValue
2286 ***************************************************************************/
2288 NTSTATUS _lsa_LookupPrivValue(pipes_struct *p,
2289 struct lsa_LookupPrivValue *r)
2291 struct lsa_info *info = NULL;
2292 const char *name = NULL;
2293 LUID_ATTR priv_luid;
2294 SE_PRIV mask;
2296 /* find the connection policy handle. */
2298 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2299 return NT_STATUS_INVALID_HANDLE;
2301 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2302 return NT_STATUS_INVALID_HANDLE;
2305 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
2306 return NT_STATUS_ACCESS_DENIED;
2308 name = r->in.name->string;
2310 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
2312 if ( !se_priv_from_name( name, &mask ) )
2313 return NT_STATUS_NO_SUCH_PRIVILEGE;
2315 priv_luid = get_privilege_luid( &mask );
2317 r->out.luid->low = priv_luid.luid.low;
2318 r->out.luid->high = priv_luid.luid.high;
2320 return NT_STATUS_OK;
2324 * From here on the server routines are just dummy ones to make smbd link with
2325 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
2326 * pulling the server stubs across one by one.
2329 NTSTATUS _lsa_Delete(pipes_struct *p, struct lsa_Delete *r)
2331 p->rng_fault_state = True;
2332 return NT_STATUS_NOT_IMPLEMENTED;
2335 NTSTATUS _lsa_SetSecObj(pipes_struct *p, struct lsa_SetSecObj *r)
2337 p->rng_fault_state = True;
2338 return NT_STATUS_NOT_IMPLEMENTED;
2341 NTSTATUS _lsa_ChangePassword(pipes_struct *p, struct lsa_ChangePassword *r)
2343 p->rng_fault_state = True;
2344 return NT_STATUS_NOT_IMPLEMENTED;
2347 NTSTATUS _lsa_SetInfoPolicy(pipes_struct *p, struct lsa_SetInfoPolicy *r)
2349 p->rng_fault_state = True;
2350 return NT_STATUS_NOT_IMPLEMENTED;
2353 NTSTATUS _lsa_ClearAuditLog(pipes_struct *p, struct lsa_ClearAuditLog *r)
2355 p->rng_fault_state = True;
2356 return NT_STATUS_NOT_IMPLEMENTED;
2359 NTSTATUS _lsa_GetQuotasForAccount(pipes_struct *p, struct lsa_GetQuotasForAccount *r)
2361 p->rng_fault_state = True;
2362 return NT_STATUS_NOT_IMPLEMENTED;
2365 NTSTATUS _lsa_SetQuotasForAccount(pipes_struct *p, struct lsa_SetQuotasForAccount *r)
2367 p->rng_fault_state = True;
2368 return NT_STATUS_NOT_IMPLEMENTED;
2371 NTSTATUS _lsa_QueryTrustedDomainInfo(pipes_struct *p, struct lsa_QueryTrustedDomainInfo *r)
2373 p->rng_fault_state = True;
2374 return NT_STATUS_NOT_IMPLEMENTED;
2377 NTSTATUS _lsa_SetInformationTrustedDomain(pipes_struct *p, struct lsa_SetInformationTrustedDomain *r)
2379 p->rng_fault_state = True;
2380 return NT_STATUS_NOT_IMPLEMENTED;
2383 NTSTATUS _lsa_QuerySecret(pipes_struct *p, struct lsa_QuerySecret *r)
2385 p->rng_fault_state = True;
2386 return NT_STATUS_NOT_IMPLEMENTED;
2389 NTSTATUS _lsa_LookupPrivName(pipes_struct *p, struct lsa_LookupPrivName *r)
2391 p->rng_fault_state = True;
2392 return NT_STATUS_NOT_IMPLEMENTED;
2395 NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p, struct lsa_EnumAccountsWithUserRight *r)
2397 p->rng_fault_state = True;
2398 return NT_STATUS_NOT_IMPLEMENTED;
2401 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(pipes_struct *p, struct lsa_QueryTrustedDomainInfoBySid *r)
2403 p->rng_fault_state = True;
2404 return NT_STATUS_NOT_IMPLEMENTED;
2407 NTSTATUS _lsa_SetTrustedDomainInfo(pipes_struct *p, struct lsa_SetTrustedDomainInfo *r)
2409 p->rng_fault_state = True;
2410 return NT_STATUS_NOT_IMPLEMENTED;
2413 NTSTATUS _lsa_DeleteTrustedDomain(pipes_struct *p, struct lsa_DeleteTrustedDomain *r)
2415 p->rng_fault_state = True;
2416 return NT_STATUS_NOT_IMPLEMENTED;
2419 NTSTATUS _lsa_StorePrivateData(pipes_struct *p, struct lsa_StorePrivateData *r)
2421 p->rng_fault_state = True;
2422 return NT_STATUS_NOT_IMPLEMENTED;
2425 NTSTATUS _lsa_RetrievePrivateData(pipes_struct *p, struct lsa_RetrievePrivateData *r)
2427 p->rng_fault_state = True;
2428 return NT_STATUS_NOT_IMPLEMENTED;
2431 NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p, struct lsa_QueryInfoPolicy2 *r)
2433 p->rng_fault_state = True;
2434 return NT_STATUS_NOT_IMPLEMENTED;
2437 NTSTATUS _lsa_SetInfoPolicy2(pipes_struct *p, struct lsa_SetInfoPolicy2 *r)
2439 p->rng_fault_state = True;
2440 return NT_STATUS_NOT_IMPLEMENTED;
2443 NTSTATUS _lsa_QueryTrustedDomainInfoByName(pipes_struct *p, struct lsa_QueryTrustedDomainInfoByName *r)
2445 p->rng_fault_state = True;
2446 return NT_STATUS_NOT_IMPLEMENTED;
2449 NTSTATUS _lsa_SetTrustedDomainInfoByName(pipes_struct *p, struct lsa_SetTrustedDomainInfoByName *r)
2451 p->rng_fault_state = True;
2452 return NT_STATUS_NOT_IMPLEMENTED;
2455 NTSTATUS _lsa_EnumTrustedDomainsEx(pipes_struct *p, struct lsa_EnumTrustedDomainsEx *r)
2457 p->rng_fault_state = True;
2458 return NT_STATUS_NOT_IMPLEMENTED;
2461 NTSTATUS _lsa_CreateTrustedDomainEx(pipes_struct *p, struct lsa_CreateTrustedDomainEx *r)
2463 p->rng_fault_state = True;
2464 return NT_STATUS_NOT_IMPLEMENTED;
2467 NTSTATUS _lsa_CloseTrustedDomainEx(pipes_struct *p, struct lsa_CloseTrustedDomainEx *r)
2469 p->rng_fault_state = True;
2470 return NT_STATUS_NOT_IMPLEMENTED;
2473 NTSTATUS _lsa_QueryDomainInformationPolicy(pipes_struct *p, struct lsa_QueryDomainInformationPolicy *r)
2475 p->rng_fault_state = True;
2476 return NT_STATUS_NOT_IMPLEMENTED;
2479 NTSTATUS _lsa_SetDomainInformationPolicy(pipes_struct *p, struct lsa_SetDomainInformationPolicy *r)
2481 p->rng_fault_state = True;
2482 return NT_STATUS_NOT_IMPLEMENTED;
2485 NTSTATUS _lsa_OpenTrustedDomainByName(pipes_struct *p, struct lsa_OpenTrustedDomainByName *r)
2487 p->rng_fault_state = True;
2488 return NT_STATUS_NOT_IMPLEMENTED;
2491 NTSTATUS _lsa_TestCall(pipes_struct *p, struct lsa_TestCall *r)
2493 p->rng_fault_state = True;
2494 return NT_STATUS_NOT_IMPLEMENTED;
2497 NTSTATUS _lsa_CreateTrustedDomainEx2(pipes_struct *p, struct lsa_CreateTrustedDomainEx2 *r)
2499 p->rng_fault_state = True;
2500 return NT_STATUS_NOT_IMPLEMENTED;
2503 NTSTATUS _lsa_CREDRWRITE(pipes_struct *p, struct lsa_CREDRWRITE *r)
2505 p->rng_fault_state = True;
2506 return NT_STATUS_NOT_IMPLEMENTED;
2509 NTSTATUS _lsa_CREDRREAD(pipes_struct *p, struct lsa_CREDRREAD *r)
2511 p->rng_fault_state = True;
2512 return NT_STATUS_NOT_IMPLEMENTED;
2515 NTSTATUS _lsa_CREDRENUMERATE(pipes_struct *p, struct lsa_CREDRENUMERATE *r)
2517 p->rng_fault_state = True;
2518 return NT_STATUS_NOT_IMPLEMENTED;
2521 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(pipes_struct *p, struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2523 p->rng_fault_state = True;
2524 return NT_STATUS_NOT_IMPLEMENTED;
2527 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(pipes_struct *p, struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2529 p->rng_fault_state = True;
2530 return NT_STATUS_NOT_IMPLEMENTED;
2533 NTSTATUS _lsa_CREDRDELETE(pipes_struct *p, struct lsa_CREDRDELETE *r)
2535 p->rng_fault_state = True;
2536 return NT_STATUS_NOT_IMPLEMENTED;
2539 NTSTATUS _lsa_CREDRGETTARGETINFO(pipes_struct *p, struct lsa_CREDRGETTARGETINFO *r)
2541 p->rng_fault_state = True;
2542 return NT_STATUS_NOT_IMPLEMENTED;
2545 NTSTATUS _lsa_CREDRPROFILELOADED(pipes_struct *p, struct lsa_CREDRPROFILELOADED *r)
2547 p->rng_fault_state = True;
2548 return NT_STATUS_NOT_IMPLEMENTED;
2551 NTSTATUS _lsa_CREDRGETSESSIONTYPES(pipes_struct *p, struct lsa_CREDRGETSESSIONTYPES *r)
2553 p->rng_fault_state = True;
2554 return NT_STATUS_NOT_IMPLEMENTED;
2557 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARREGISTERAUDITEVENT *r)
2559 p->rng_fault_state = True;
2560 return NT_STATUS_NOT_IMPLEMENTED;
2563 NTSTATUS _lsa_LSARGENAUDITEVENT(pipes_struct *p, struct lsa_LSARGENAUDITEVENT *r)
2565 p->rng_fault_state = True;
2566 return NT_STATUS_NOT_IMPLEMENTED;
2569 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARUNREGISTERAUDITEVENT *r)
2571 p->rng_fault_state = True;
2572 return NT_STATUS_NOT_IMPLEMENTED;
2575 NTSTATUS _lsa_lsaRQueryForestTrustInformation(pipes_struct *p, struct lsa_lsaRQueryForestTrustInformation *r)
2577 p->rng_fault_state = True;
2578 return NT_STATUS_NOT_IMPLEMENTED;
2581 NTSTATUS _lsa_LSARSETFORESTTRUSTINFORMATION(pipes_struct *p, struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2583 p->rng_fault_state = True;
2584 return NT_STATUS_NOT_IMPLEMENTED;
2587 NTSTATUS _lsa_CREDRRENAME(pipes_struct *p, struct lsa_CREDRRENAME *r)
2589 p->rng_fault_state = True;
2590 return NT_STATUS_NOT_IMPLEMENTED;
2593 NTSTATUS _lsa_LSAROPENPOLICYSCE(pipes_struct *p, struct lsa_LSAROPENPOLICYSCE *r)
2595 p->rng_fault_state = True;
2596 return NT_STATUS_NOT_IMPLEMENTED;
2599 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(pipes_struct *p, struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2601 p->rng_fault_state = True;
2602 return NT_STATUS_NOT_IMPLEMENTED;
2605 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(pipes_struct *p, struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2607 p->rng_fault_state = True;
2608 return NT_STATUS_NOT_IMPLEMENTED;
2611 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(pipes_struct *p, struct lsa_LSARADTREPORTSECURITYEVENT *r)
2613 p->rng_fault_state = True;
2614 return NT_STATUS_NOT_IMPLEMENTED;