s3-lsa: pure cosmetic indentation fixes.
[Samba.git] / source3 / rpc_server / srv_lsa_nt.c
blob986b12685a5ea6163a9001beb40d3592bc8f753b
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 /* follow w2k8 behavior and return the builtin domain when no
163 * input has been passed in */
165 if (name[i].string) {
166 full_name = name[i].string;
167 } else {
168 full_name = "BUILTIN";
171 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
173 /* We can ignore the result of lookup_name, it will not touch
174 "type" if it's not successful */
176 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
177 &sid, &type);
179 switch (type) {
180 case SID_NAME_USER:
181 case SID_NAME_DOM_GRP:
182 case SID_NAME_DOMAIN:
183 case SID_NAME_ALIAS:
184 case SID_NAME_WKN_GRP:
185 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
186 /* Leave these unchanged */
187 break;
188 default:
189 /* Don't hand out anything but the list above */
190 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
191 type = SID_NAME_UNKNOWN;
192 break;
195 rid = 0;
196 dom_idx = -1;
198 if (type != SID_NAME_UNKNOWN) {
199 if (type == SID_NAME_DOMAIN) {
200 rid = (uint32_t)-1;
201 } else {
202 sid_split_rid(&sid, &rid);
204 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
205 mapped_count++;
208 prid[i].sid_type = type;
209 prid[i].rid = rid;
210 prid[i].sid_index = dom_idx;
213 *pmapped_count = mapped_count;
214 return NT_STATUS_OK;
217 /***************************************************************************
218 lookup_lsa_sids. Must be called as root for lookup_name to work.
219 ***************************************************************************/
221 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
222 struct lsa_RefDomainList *ref,
223 struct lsa_TranslatedSid3 *trans_sids,
224 uint32_t num_entries,
225 struct lsa_String *name,
226 int flags,
227 uint32 *pmapped_count)
229 uint32 mapped_count, i;
231 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
233 mapped_count = 0;
234 *pmapped_count = 0;
236 for (i = 0; i < num_entries; i++) {
237 DOM_SID sid;
238 uint32 rid;
239 int dom_idx;
240 const char *full_name;
241 const char *domain;
242 enum lsa_SidType type = SID_NAME_UNKNOWN;
244 ZERO_STRUCT(sid);
246 /* Split name into domain and user component */
248 full_name = name[i].string;
249 if (full_name == NULL) {
250 return NT_STATUS_NO_MEMORY;
253 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
255 /* We can ignore the result of lookup_name, it will not touch
256 "type" if it's not successful */
258 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
259 &sid, &type);
261 switch (type) {
262 case SID_NAME_USER:
263 case SID_NAME_DOM_GRP:
264 case SID_NAME_DOMAIN:
265 case SID_NAME_ALIAS:
266 case SID_NAME_WKN_GRP:
267 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
268 /* Leave these unchanged */
269 break;
270 default:
271 /* Don't hand out anything but the list above */
272 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
273 type = SID_NAME_UNKNOWN;
274 break;
277 rid = 0;
278 dom_idx = -1;
280 if (type != SID_NAME_UNKNOWN) {
281 DOM_SID domain_sid;
282 sid_copy(&domain_sid, &sid);
283 sid_split_rid(&domain_sid, &rid);
284 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
285 mapped_count++;
288 /* Initialize the lsa_TranslatedSid3 return. */
289 trans_sids[i].sid_type = type;
290 trans_sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
291 trans_sids[i].sid_index = dom_idx;
294 *pmapped_count = mapped_count;
295 return NT_STATUS_OK;
298 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size,
299 const struct generic_mapping *map,
300 DOM_SID *sid, uint32_t sid_access)
302 DOM_SID adm_sid;
303 SEC_ACE ace[5];
304 size_t i = 0;
306 SEC_ACL *psa = NULL;
308 /* READ|EXECUTE access for Everyone */
310 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
311 map->generic_execute | map->generic_read, 0);
313 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
315 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
316 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
317 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
318 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
320 /* Add Full Access for Domain Admins */
321 sid_copy(&adm_sid, get_global_sam_sid());
322 sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS);
323 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
324 map->generic_all, 0);
326 /* If we have a sid, give it some special access */
328 if (sid) {
329 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
330 sid_access, 0);
333 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
334 return NT_STATUS_NO_MEMORY;
336 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
337 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
338 psa, sd_size)) == NULL)
339 return NT_STATUS_NO_MEMORY;
341 return NT_STATUS_OK;
345 /***************************************************************************
346 _lsa_OpenPolicy2
347 ***************************************************************************/
349 NTSTATUS _lsa_OpenPolicy2(pipes_struct *p,
350 struct lsa_OpenPolicy2 *r)
352 struct lsa_info *info;
353 SEC_DESC *psd = NULL;
354 size_t sd_size;
355 uint32 des_access = r->in.access_mask;
356 uint32 acc_granted;
357 NTSTATUS status;
359 /* Work out max allowed. */
360 map_max_allowed_access(p->server_info->ptok,
361 &p->server_info->utok,
362 &des_access);
364 /* map the generic bits to the lsa policy ones */
365 se_map_generic(&des_access, &lsa_policy_mapping);
367 /* get the generic lsa policy SD until we store it */
368 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
369 NULL, 0);
370 if (!NT_STATUS_IS_OK(status)) {
371 return status;
374 status = access_check_object(psd, p->server_info->ptok,
375 NULL, 0, des_access,
376 &acc_granted, "_lsa_OpenPolicy2" );
377 if (!NT_STATUS_IS_OK(status)) {
378 return status;
381 /* associate the domain SID with the (unique) handle. */
382 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
383 if (info == NULL) {
384 return NT_STATUS_NO_MEMORY;
387 sid_copy(&info->sid,get_global_sam_sid());
388 info->access = acc_granted;
389 info->type = LSA_HANDLE_POLICY_TYPE;
391 /* set up the LSA QUERY INFO response */
392 if (!create_policy_hnd(p, r->out.handle, info))
393 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
395 return NT_STATUS_OK;
398 /***************************************************************************
399 _lsa_OpenPolicy
400 ***************************************************************************/
402 NTSTATUS _lsa_OpenPolicy(pipes_struct *p,
403 struct lsa_OpenPolicy *r)
405 struct lsa_OpenPolicy2 o;
407 o.in.system_name = NULL; /* should be ignored */
408 o.in.attr = r->in.attr;
409 o.in.access_mask = r->in.access_mask;
411 o.out.handle = r->out.handle;
413 return _lsa_OpenPolicy2(p, &o);
416 /***************************************************************************
417 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
418 ufff, done :) mimir
419 ***************************************************************************/
421 NTSTATUS _lsa_EnumTrustDom(pipes_struct *p,
422 struct lsa_EnumTrustDom *r)
424 struct lsa_info *info;
425 uint32_t count;
426 struct trustdom_info **domains;
427 struct lsa_DomainInfo *entries;
428 int i;
429 NTSTATUS nt_status;
431 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
432 return NT_STATUS_INVALID_HANDLE;
434 if (info->type != LSA_HANDLE_POLICY_TYPE) {
435 return NT_STATUS_INVALID_HANDLE;
438 /* check if the user has enough rights */
439 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
440 return NT_STATUS_ACCESS_DENIED;
442 become_root();
443 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
444 unbecome_root();
446 if (!NT_STATUS_IS_OK(nt_status)) {
447 return nt_status;
450 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo, count);
451 if (!entries) {
452 return NT_STATUS_NO_MEMORY;
455 for (i=0; i<count; i++) {
456 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
457 entries[i].sid = &domains[i]->sid;
460 if (*r->in.resume_handle >= count) {
461 *r->out.resume_handle = -1;
462 TALLOC_FREE(entries);
463 return NT_STATUS_NO_MORE_ENTRIES;
466 /* return the rest, limit by max_size. Note that we
467 use the w2k3 element size value of 60 */
468 r->out.domains->count = count - *r->in.resume_handle;
469 r->out.domains->count = MIN(r->out.domains->count,
470 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
472 r->out.domains->domains = entries + *r->in.resume_handle;
474 if (r->out.domains->count < count - *r->in.resume_handle) {
475 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
476 return STATUS_MORE_ENTRIES;
479 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
480 * always be larger than the previous input resume handle, in
481 * particular when hitting the last query it is vital to set the
482 * resume handle correctly to avoid infinite client loops, as
483 * seen e.g. with Windows XP SP3 when resume handle is 0 and
484 * status is NT_STATUS_OK - gd */
486 *r->out.resume_handle = (uint32_t)-1;
488 return NT_STATUS_OK;
491 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
492 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
493 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
495 /***************************************************************************
496 _lsa_QueryInfoPolicy
497 ***************************************************************************/
499 NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p,
500 struct lsa_QueryInfoPolicy *r)
502 NTSTATUS status = NT_STATUS_OK;
503 struct lsa_info *handle;
504 DOM_SID domain_sid;
505 const char *name;
506 DOM_SID *sid = NULL;
507 union lsa_PolicyInformation *info = NULL;
508 uint32_t acc_required = 0;
510 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
511 return NT_STATUS_INVALID_HANDLE;
513 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
514 return NT_STATUS_INVALID_HANDLE;
517 switch (r->in.level) {
518 case LSA_POLICY_INFO_AUDIT_LOG:
519 case LSA_POLICY_INFO_AUDIT_EVENTS:
520 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
521 break;
522 case LSA_POLICY_INFO_DOMAIN:
523 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
524 break;
525 case LSA_POLICY_INFO_PD:
526 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
527 break;
528 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
529 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
530 break;
531 case LSA_POLICY_INFO_ROLE:
532 case LSA_POLICY_INFO_REPLICA:
533 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
534 break;
535 case LSA_POLICY_INFO_QUOTA:
536 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
537 break;
538 case LSA_POLICY_INFO_MOD:
539 case LSA_POLICY_INFO_AUDIT_FULL_SET:
540 /* according to MS-LSAD 3.1.4.4.3 */
541 return NT_STATUS_INVALID_PARAMETER;
542 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
543 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
544 break;
545 case LSA_POLICY_INFO_DNS:
546 case LSA_POLICY_INFO_DNS_INT:
547 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
548 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
549 break;
550 default:
551 break;
554 if (!(handle->access & acc_required)) {
555 /* return NT_STATUS_ACCESS_DENIED; */
558 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
559 if (!info) {
560 return NT_STATUS_NO_MEMORY;
563 switch (r->in.level) {
564 case LSA_POLICY_INFO_AUDIT_EVENTS:
567 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
569 /* check if the user has enough rights */
570 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
571 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
572 return NT_STATUS_ACCESS_DENIED;
575 /* fake info: We audit everything. ;) */
577 info->audit_events.auditing_mode = true;
578 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
579 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
580 enum lsa_PolicyAuditPolicy,
581 info->audit_events.count);
582 if (!info->audit_events.settings) {
583 return NT_STATUS_NO_MEMORY;
586 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
587 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
588 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
589 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
590 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
591 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
592 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
594 break;
596 case LSA_POLICY_INFO_DOMAIN:
597 /* check if the user has enough rights */
598 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
599 return NT_STATUS_ACCESS_DENIED;
601 /* Request PolicyPrimaryDomainInformation. */
602 switch (lp_server_role()) {
603 case ROLE_DOMAIN_PDC:
604 case ROLE_DOMAIN_BDC:
605 name = get_global_sam_name();
606 sid = sid_dup_talloc(p->mem_ctx, get_global_sam_sid());
607 if (!sid) {
608 return NT_STATUS_NO_MEMORY;
610 break;
611 case ROLE_DOMAIN_MEMBER:
612 name = lp_workgroup();
613 /* We need to return the Domain SID here. */
614 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
615 sid = sid_dup_talloc(p->mem_ctx, &domain_sid);
616 if (!sid) {
617 return NT_STATUS_NO_MEMORY;
619 } else {
620 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
622 break;
623 case ROLE_STANDALONE:
624 name = lp_workgroup();
625 sid = NULL;
626 break;
627 default:
628 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
630 init_dom_query_3(&info->domain, name, sid);
631 break;
632 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
633 /* check if the user has enough rights */
634 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
635 return NT_STATUS_ACCESS_DENIED;
637 /* Request PolicyAccountDomainInformation. */
638 name = get_global_sam_name();
639 sid = get_global_sam_sid();
641 init_dom_query_5(&info->account_domain, name, sid);
642 break;
643 case LSA_POLICY_INFO_ROLE:
644 /* check if the user has enough rights */
645 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
646 return NT_STATUS_ACCESS_DENIED;
648 switch (lp_server_role()) {
649 case ROLE_DOMAIN_BDC:
651 * only a BDC is a backup controller
652 * of the domain, it controls.
654 info->role.role = LSA_ROLE_BACKUP;
655 break;
656 default:
658 * any other role is a primary
659 * of the domain, it controls.
661 info->role.role = LSA_ROLE_PRIMARY;
662 break;
664 break;
665 case LSA_POLICY_INFO_DNS:
666 case LSA_POLICY_INFO_DNS_INT: {
667 struct pdb_domain_info *dominfo;
669 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
670 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
671 "without ADS passdb backend\n"));
672 status = NT_STATUS_INVALID_INFO_CLASS;
673 break;
676 dominfo = pdb_get_domain_info(info);
677 if (dominfo == NULL) {
678 status = NT_STATUS_NO_MEMORY;
679 break;
682 init_lsa_StringLarge(&info->dns.name,
683 dominfo->name);
684 init_lsa_StringLarge(&info->dns.dns_domain,
685 dominfo->dns_domain);
686 init_lsa_StringLarge(&info->dns.dns_forest,
687 dominfo->dns_forest);
688 info->dns.domain_guid = dominfo->guid;
689 info->dns.sid = &dominfo->sid;
690 break;
692 default:
693 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
694 r->in.level));
695 status = NT_STATUS_INVALID_INFO_CLASS;
696 break;
699 *r->out.info = info;
701 return status;
704 /***************************************************************************
705 _lsa_QueryInfoPolicy2
706 ***************************************************************************/
708 NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p,
709 struct lsa_QueryInfoPolicy2 *r2)
711 struct lsa_QueryInfoPolicy r;
713 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
714 p->rng_fault_state = True;
715 return NT_STATUS_NOT_IMPLEMENTED;
718 ZERO_STRUCT(r);
719 r.in.handle = r2->in.handle;
720 r.in.level = r2->in.level;
721 r.out.info = r2->out.info;
723 return _lsa_QueryInfoPolicy(p, &r);
726 /***************************************************************************
727 _lsa_lookup_sids_internal
728 ***************************************************************************/
730 static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p,
731 TALLOC_CTX *mem_ctx,
732 uint16_t level, /* input */
733 int num_sids, /* input */
734 struct lsa_SidPtr *sid, /* input */
735 struct lsa_RefDomainList **pp_ref, /* input/output */
736 struct lsa_TranslatedName2 **pp_names,/* input/output */
737 uint32_t *pp_mapped_count) /* input/output */
739 NTSTATUS status;
740 int i;
741 const DOM_SID **sids = NULL;
742 struct lsa_RefDomainList *ref = NULL;
743 uint32 mapped_count = 0;
744 struct lsa_dom_info *dom_infos = NULL;
745 struct lsa_name_info *name_infos = NULL;
746 struct lsa_TranslatedName2 *names = NULL;
748 *pp_mapped_count = 0;
749 *pp_names = NULL;
750 *pp_ref = NULL;
752 if (num_sids == 0) {
753 return NT_STATUS_OK;
756 sids = TALLOC_ARRAY(p->mem_ctx, const DOM_SID *, num_sids);
757 ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
759 if (sids == NULL || ref == NULL) {
760 return NT_STATUS_NO_MEMORY;
763 for (i=0; i<num_sids; i++) {
764 sids[i] = sid[i].sid;
767 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
768 &dom_infos, &name_infos);
770 if (!NT_STATUS_IS_OK(status)) {
771 return status;
774 names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
775 if (names == NULL) {
776 return NT_STATUS_NO_MEMORY;
779 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
781 if (!dom_infos[i].valid) {
782 break;
785 if (init_lsa_ref_domain_list(mem_ctx, ref,
786 dom_infos[i].name,
787 &dom_infos[i].sid) != i) {
788 DEBUG(0, ("Domain %s mentioned twice??\n",
789 dom_infos[i].name));
790 return NT_STATUS_INTERNAL_ERROR;
794 for (i=0; i<num_sids; i++) {
795 struct lsa_name_info *name = &name_infos[i];
797 if (name->type == SID_NAME_UNKNOWN) {
798 fstring tmp;
799 name->dom_idx = -1;
800 /* Unknown sids should return the string
801 * representation of the SID. Windows 2003 behaves
802 * rather erratic here, in many cases it returns the
803 * RID as 8 bytes hex, in others it returns the full
804 * SID. We (Jerry/VL) could not figure out which the
805 * hard cases are, so leave it with the SID. */
806 name->name = talloc_asprintf(p->mem_ctx, "%s",
807 sid_to_fstring(tmp,
808 sids[i]));
809 if (name->name == NULL) {
810 return NT_STATUS_NO_MEMORY;
812 } else {
813 mapped_count += 1;
816 names[i].sid_type = name->type;
817 names[i].name.string = name->name;
818 names[i].sid_index = name->dom_idx;
819 names[i].unknown = 0;
822 status = NT_STATUS_NONE_MAPPED;
823 if (mapped_count > 0) {
824 status = (mapped_count < num_sids) ?
825 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
828 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
829 num_sids, mapped_count, nt_errstr(status)));
831 *pp_mapped_count = mapped_count;
832 *pp_names = names;
833 *pp_ref = ref;
835 return status;
838 /***************************************************************************
839 _lsa_LookupSids
840 ***************************************************************************/
842 NTSTATUS _lsa_LookupSids(pipes_struct *p,
843 struct lsa_LookupSids *r)
845 NTSTATUS status;
846 struct lsa_info *handle;
847 int num_sids = r->in.sids->num_sids;
848 uint32 mapped_count = 0;
849 struct lsa_RefDomainList *domains = NULL;
850 struct lsa_TranslatedName *names_out = NULL;
851 struct lsa_TranslatedName2 *names = NULL;
852 int i;
854 if ((r->in.level < 1) || (r->in.level > 6)) {
855 return NT_STATUS_INVALID_PARAMETER;
858 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
859 return NT_STATUS_INVALID_HANDLE;
862 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
863 return NT_STATUS_INVALID_HANDLE;
866 /* check if the user has enough rights */
867 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
868 return NT_STATUS_ACCESS_DENIED;
871 if (num_sids > MAX_LOOKUP_SIDS) {
872 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
873 MAX_LOOKUP_SIDS, num_sids));
874 return NT_STATUS_NONE_MAPPED;
877 status = _lsa_lookup_sids_internal(p,
878 p->mem_ctx,
879 r->in.level,
880 num_sids,
881 r->in.sids->sids,
882 &domains,
883 &names,
884 &mapped_count);
886 /* Only return here when there is a real error.
887 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
888 the requested sids could be resolved. Older versions of XP (pre SP3)
889 rely that we return with the string representations of those SIDs in
890 that case. If we don't, XP crashes - Guenther
893 if (NT_STATUS_IS_ERR(status) &&
894 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
895 return status;
898 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
899 names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
900 num_sids);
901 if (!names_out) {
902 return NT_STATUS_NO_MEMORY;
905 for (i=0; i<num_sids; i++) {
906 names_out[i].sid_type = names[i].sid_type;
907 names_out[i].name = names[i].name;
908 names_out[i].sid_index = names[i].sid_index;
911 *r->out.domains = domains;
912 r->out.names->count = num_sids;
913 r->out.names->names = names_out;
914 *r->out.count = mapped_count;
916 return status;
919 /***************************************************************************
920 _lsa_LookupSids2
921 ***************************************************************************/
923 NTSTATUS _lsa_LookupSids2(pipes_struct *p,
924 struct lsa_LookupSids2 *r)
926 NTSTATUS status;
927 struct lsa_info *handle;
928 int num_sids = r->in.sids->num_sids;
929 uint32 mapped_count = 0;
930 struct lsa_RefDomainList *domains = NULL;
931 struct lsa_TranslatedName2 *names = NULL;
932 bool check_policy = true;
934 switch (p->hdr_req.opnum) {
935 case NDR_LSA_LOOKUPSIDS3:
936 check_policy = false;
937 break;
938 case NDR_LSA_LOOKUPSIDS2:
939 default:
940 check_policy = true;
943 if ((r->in.level < 1) || (r->in.level > 6)) {
944 return NT_STATUS_INVALID_PARAMETER;
947 if (check_policy) {
948 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
949 return NT_STATUS_INVALID_HANDLE;
952 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
953 return NT_STATUS_INVALID_HANDLE;
956 /* check if the user has enough rights */
957 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
958 return NT_STATUS_ACCESS_DENIED;
962 if (num_sids > MAX_LOOKUP_SIDS) {
963 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
964 MAX_LOOKUP_SIDS, num_sids));
965 return NT_STATUS_NONE_MAPPED;
968 status = _lsa_lookup_sids_internal(p,
969 p->mem_ctx,
970 r->in.level,
971 num_sids,
972 r->in.sids->sids,
973 &domains,
974 &names,
975 &mapped_count);
977 *r->out.domains = domains;
978 r->out.names->count = num_sids;
979 r->out.names->names = names;
980 *r->out.count = mapped_count;
982 return status;
985 /***************************************************************************
986 _lsa_LookupSids3
987 ***************************************************************************/
989 NTSTATUS _lsa_LookupSids3(pipes_struct *p,
990 struct lsa_LookupSids3 *r)
992 struct lsa_LookupSids2 q;
994 /* No policy handle on this call. Restrict to crypto connections. */
995 if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
996 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
997 get_remote_machine_name() ));
998 return NT_STATUS_INVALID_PARAMETER;
1001 q.in.handle = NULL;
1002 q.in.sids = r->in.sids;
1003 q.in.level = r->in.level;
1004 q.in.lookup_options = r->in.lookup_options;
1005 q.in.client_revision = r->in.client_revision;
1006 q.in.names = r->in.names;
1007 q.in.count = r->in.count;
1009 q.out.domains = r->out.domains;
1010 q.out.names = r->out.names;
1011 q.out.count = r->out.count;
1013 return _lsa_LookupSids2(p, &q);
1016 /***************************************************************************
1017 ***************************************************************************/
1019 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1021 int flags;
1023 switch (level) {
1024 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1025 flags = LOOKUP_NAME_ALL;
1026 break;
1027 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1028 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1029 break;
1030 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1031 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1032 break;
1033 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1034 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1035 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1036 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1037 default:
1038 flags = LOOKUP_NAME_NONE;
1039 break;
1042 return flags;
1045 /***************************************************************************
1046 _lsa_LookupNames
1047 ***************************************************************************/
1049 NTSTATUS _lsa_LookupNames(pipes_struct *p,
1050 struct lsa_LookupNames *r)
1052 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1053 struct lsa_info *handle;
1054 struct lsa_String *names = r->in.names;
1055 uint32 num_entries = r->in.num_names;
1056 struct lsa_RefDomainList *domains = NULL;
1057 struct lsa_TranslatedSid *rids = NULL;
1058 uint32 mapped_count = 0;
1059 int flags = 0;
1061 if (num_entries > MAX_LOOKUP_SIDS) {
1062 num_entries = MAX_LOOKUP_SIDS;
1063 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1064 num_entries));
1067 flags = lsa_lookup_level_to_flags(r->in.level);
1069 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1070 if (!domains) {
1071 return NT_STATUS_NO_MEMORY;
1074 if (num_entries) {
1075 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1076 num_entries);
1077 if (!rids) {
1078 return NT_STATUS_NO_MEMORY;
1080 } else {
1081 rids = NULL;
1084 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1085 status = NT_STATUS_INVALID_HANDLE;
1086 goto done;
1089 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1090 return NT_STATUS_INVALID_HANDLE;
1093 /* check if the user has enough rights */
1094 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1095 status = NT_STATUS_ACCESS_DENIED;
1096 goto done;
1099 /* set up the LSA Lookup RIDs response */
1100 become_root(); /* lookup_name can require root privs */
1101 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1102 names, flags, &mapped_count);
1103 unbecome_root();
1105 done:
1107 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1108 if (mapped_count == 0) {
1109 status = NT_STATUS_NONE_MAPPED;
1110 } else if (mapped_count != num_entries) {
1111 status = STATUS_SOME_UNMAPPED;
1115 *r->out.count = mapped_count;
1116 *r->out.domains = domains;
1117 r->out.sids->sids = rids;
1118 r->out.sids->count = num_entries;
1120 return status;
1123 /***************************************************************************
1124 _lsa_LookupNames2
1125 ***************************************************************************/
1127 NTSTATUS _lsa_LookupNames2(pipes_struct *p,
1128 struct lsa_LookupNames2 *r)
1130 NTSTATUS status;
1131 struct lsa_LookupNames q;
1132 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1133 struct lsa_TransSidArray *sid_array = NULL;
1134 uint32_t i;
1136 sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1137 if (!sid_array) {
1138 return NT_STATUS_NO_MEMORY;
1141 q.in.handle = r->in.handle;
1142 q.in.num_names = r->in.num_names;
1143 q.in.names = r->in.names;
1144 q.in.level = r->in.level;
1145 q.in.sids = sid_array;
1146 q.in.count = r->in.count;
1147 /* we do not know what this is for */
1148 /* = r->in.unknown1; */
1149 /* = r->in.unknown2; */
1151 q.out.domains = r->out.domains;
1152 q.out.sids = sid_array;
1153 q.out.count = r->out.count;
1155 status = _lsa_LookupNames(p, &q);
1157 sid_array2->count = sid_array->count;
1158 sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1159 if (!sid_array2->sids) {
1160 return NT_STATUS_NO_MEMORY;
1163 for (i=0; i<sid_array->count; i++) {
1164 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1165 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1166 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1167 sid_array2->sids[i].unknown = 0;
1170 r->out.sids = sid_array2;
1172 return status;
1175 /***************************************************************************
1176 _lsa_LookupNames3
1177 ***************************************************************************/
1179 NTSTATUS _lsa_LookupNames3(pipes_struct *p,
1180 struct lsa_LookupNames3 *r)
1182 NTSTATUS status;
1183 struct lsa_info *handle;
1184 struct lsa_String *names = r->in.names;
1185 uint32 num_entries = r->in.num_names;
1186 struct lsa_RefDomainList *domains = NULL;
1187 struct lsa_TranslatedSid3 *trans_sids = NULL;
1188 uint32 mapped_count = 0;
1189 int flags = 0;
1190 bool check_policy = true;
1192 switch (p->hdr_req.opnum) {
1193 case NDR_LSA_LOOKUPNAMES4:
1194 check_policy = false;
1195 break;
1196 case NDR_LSA_LOOKUPNAMES3:
1197 default:
1198 check_policy = true;
1201 if (num_entries > MAX_LOOKUP_SIDS) {
1202 num_entries = MAX_LOOKUP_SIDS;
1203 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1206 /* Probably the lookup_level is some sort of bitmask. */
1207 if (r->in.level == 1) {
1208 flags = LOOKUP_NAME_ALL;
1211 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1212 if (!domains) {
1213 return NT_STATUS_NO_MEMORY;
1216 if (num_entries) {
1217 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1218 num_entries);
1219 if (!trans_sids) {
1220 return NT_STATUS_NO_MEMORY;
1222 } else {
1223 trans_sids = NULL;
1226 if (check_policy) {
1228 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1229 status = NT_STATUS_INVALID_HANDLE;
1230 goto done;
1233 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1234 return NT_STATUS_INVALID_HANDLE;
1237 /* check if the user has enough rights */
1238 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1239 status = NT_STATUS_ACCESS_DENIED;
1240 goto done;
1244 /* set up the LSA Lookup SIDs response */
1245 become_root(); /* lookup_name can require root privs */
1246 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1247 names, flags, &mapped_count);
1248 unbecome_root();
1250 done:
1252 if (NT_STATUS_IS_OK(status)) {
1253 if (mapped_count == 0) {
1254 status = NT_STATUS_NONE_MAPPED;
1255 } else if (mapped_count != num_entries) {
1256 status = STATUS_SOME_UNMAPPED;
1260 *r->out.count = mapped_count;
1261 *r->out.domains = domains;
1262 r->out.sids->sids = trans_sids;
1263 r->out.sids->count = num_entries;
1265 return status;
1268 /***************************************************************************
1269 _lsa_LookupNames4
1270 ***************************************************************************/
1272 NTSTATUS _lsa_LookupNames4(pipes_struct *p,
1273 struct lsa_LookupNames4 *r)
1275 struct lsa_LookupNames3 q;
1277 /* No policy handle on this call. Restrict to crypto connections. */
1278 if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
1279 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1280 get_remote_machine_name() ));
1281 return NT_STATUS_INVALID_PARAMETER;
1284 q.in.handle = NULL;
1285 q.in.num_names = r->in.num_names;
1286 q.in.names = r->in.names;
1287 q.in.level = r->in.level;
1288 q.in.lookup_options = r->in.lookup_options;
1289 q.in.client_revision = r->in.client_revision;
1290 q.in.sids = r->in.sids;
1291 q.in.count = r->in.count;
1293 q.out.domains = r->out.domains;
1294 q.out.sids = r->out.sids;
1295 q.out.count = r->out.count;
1297 return _lsa_LookupNames3(p, &q);
1300 /***************************************************************************
1301 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1302 ***************************************************************************/
1304 NTSTATUS _lsa_Close(pipes_struct *p, struct lsa_Close *r)
1306 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1307 return NT_STATUS_INVALID_HANDLE;
1310 close_policy_hnd(p, r->in.handle);
1311 ZERO_STRUCTP(r->out.handle);
1312 return NT_STATUS_OK;
1315 /***************************************************************************
1316 ***************************************************************************/
1318 NTSTATUS _lsa_OpenSecret(pipes_struct *p, struct lsa_OpenSecret *r)
1320 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1323 /***************************************************************************
1324 ***************************************************************************/
1326 NTSTATUS _lsa_OpenTrustedDomain(pipes_struct *p, struct lsa_OpenTrustedDomain *r)
1328 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1331 /***************************************************************************
1332 ***************************************************************************/
1334 NTSTATUS _lsa_CreateTrustedDomain(pipes_struct *p, struct lsa_CreateTrustedDomain *r)
1336 return NT_STATUS_ACCESS_DENIED;
1339 /***************************************************************************
1340 ***************************************************************************/
1342 NTSTATUS _lsa_CreateSecret(pipes_struct *p, struct lsa_CreateSecret *r)
1344 return NT_STATUS_ACCESS_DENIED;
1347 /***************************************************************************
1348 ***************************************************************************/
1350 NTSTATUS _lsa_SetSecret(pipes_struct *p, struct lsa_SetSecret *r)
1352 return NT_STATUS_ACCESS_DENIED;
1355 /***************************************************************************
1356 _lsa_DeleteObject
1357 ***************************************************************************/
1359 NTSTATUS _lsa_DeleteObject(pipes_struct *p,
1360 struct lsa_DeleteObject *r)
1362 NTSTATUS status;
1363 struct lsa_info *info = NULL;
1365 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
1366 return NT_STATUS_INVALID_HANDLE;
1369 if (!(info->access & STD_RIGHT_DELETE_ACCESS)) {
1370 return NT_STATUS_ACCESS_DENIED;
1373 switch (info->type) {
1374 case LSA_HANDLE_ACCOUNT_TYPE:
1375 status = privilege_delete_account(&info->sid);
1376 if (!NT_STATUS_IS_OK(status)) {
1377 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
1378 nt_errstr(status)));
1379 return status;
1381 break;
1382 default:
1383 return NT_STATUS_INVALID_HANDLE;
1386 close_policy_hnd(p, r->in.handle);
1387 ZERO_STRUCTP(r->out.handle);
1389 return status;
1392 /***************************************************************************
1393 _lsa_EnumPrivs
1394 ***************************************************************************/
1396 NTSTATUS _lsa_EnumPrivs(pipes_struct *p,
1397 struct lsa_EnumPrivs *r)
1399 struct lsa_info *handle;
1400 uint32 i;
1401 uint32 enum_context = *r->in.resume_handle;
1402 int num_privs = count_all_privileges();
1403 struct lsa_PrivEntry *entries = NULL;
1404 LUID_ATTR luid;
1406 /* remember that the enum_context starts at 0 and not 1 */
1408 if ( enum_context >= num_privs )
1409 return NT_STATUS_NO_MORE_ENTRIES;
1411 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
1412 enum_context, num_privs));
1414 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1415 return NT_STATUS_INVALID_HANDLE;
1417 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1418 return NT_STATUS_INVALID_HANDLE;
1421 /* check if the user has enough rights
1422 I don't know if it's the right one. not documented. */
1424 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1425 return NT_STATUS_ACCESS_DENIED;
1427 if (num_privs) {
1428 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
1429 if (!entries) {
1430 return NT_STATUS_NO_MEMORY;
1432 } else {
1433 entries = NULL;
1436 for (i = 0; i < num_privs; i++) {
1437 if( i < enum_context) {
1439 init_lsa_StringLarge(&entries[i].name, NULL);
1441 entries[i].luid.low = 0;
1442 entries[i].luid.high = 0;
1443 } else {
1445 init_lsa_StringLarge(&entries[i].name, privs[i].name);
1447 luid = get_privilege_luid( &privs[i].se_priv );
1449 entries[i].luid.low = luid.luid.low;
1450 entries[i].luid.high = luid.luid.high;
1454 enum_context = num_privs;
1456 *r->out.resume_handle = enum_context;
1457 r->out.privs->count = num_privs;
1458 r->out.privs->privs = entries;
1460 return NT_STATUS_OK;
1463 /***************************************************************************
1464 _lsa_LookupPrivDisplayName
1465 ***************************************************************************/
1467 NTSTATUS _lsa_LookupPrivDisplayName(pipes_struct *p,
1468 struct lsa_LookupPrivDisplayName *r)
1470 struct lsa_info *handle;
1471 const char *description;
1472 struct lsa_StringLarge *lsa_name;
1474 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1475 return NT_STATUS_INVALID_HANDLE;
1477 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1478 return NT_STATUS_INVALID_HANDLE;
1481 /* check if the user has enough rights */
1484 * I don't know if it's the right one. not documented.
1486 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1487 return NT_STATUS_ACCESS_DENIED;
1489 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
1491 description = get_privilege_dispname(r->in.name->string);
1492 if (!description) {
1493 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
1494 return NT_STATUS_NO_SUCH_PRIVILEGE;
1497 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
1499 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
1500 if (!lsa_name) {
1501 return NT_STATUS_NO_MEMORY;
1504 init_lsa_StringLarge(lsa_name, description);
1506 *r->out.returned_language_id = r->in.language_id;
1507 *r->out.disp_name = lsa_name;
1509 return NT_STATUS_OK;
1512 /***************************************************************************
1513 _lsa_EnumAccounts
1514 ***************************************************************************/
1516 NTSTATUS _lsa_EnumAccounts(pipes_struct *p,
1517 struct lsa_EnumAccounts *r)
1519 struct lsa_info *handle;
1520 DOM_SID *sid_list;
1521 int i, j, num_entries;
1522 NTSTATUS status;
1523 struct lsa_SidPtr *sids = NULL;
1525 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1526 return NT_STATUS_INVALID_HANDLE;
1528 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1529 return NT_STATUS_INVALID_HANDLE;
1532 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1533 return NT_STATUS_ACCESS_DENIED;
1535 sid_list = NULL;
1536 num_entries = 0;
1538 /* The only way we can currently find out all the SIDs that have been
1539 privileged is to scan all privileges */
1541 status = privilege_enumerate_accounts(&sid_list, &num_entries);
1542 if (!NT_STATUS_IS_OK(status)) {
1543 return status;
1546 if (*r->in.resume_handle >= num_entries) {
1547 return NT_STATUS_NO_MORE_ENTRIES;
1550 if (num_entries - *r->in.resume_handle) {
1551 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
1552 num_entries - *r->in.resume_handle);
1553 if (!sids) {
1554 talloc_free(sid_list);
1555 return NT_STATUS_NO_MEMORY;
1558 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
1559 sids[j].sid = sid_dup_talloc(p->mem_ctx, &sid_list[i]);
1560 if (!sids[j].sid) {
1561 talloc_free(sid_list);
1562 return NT_STATUS_NO_MEMORY;
1567 talloc_free(sid_list);
1569 *r->out.resume_handle = num_entries;
1570 r->out.sids->num_sids = num_entries;
1571 r->out.sids->sids = sids;
1573 return NT_STATUS_OK;
1576 /***************************************************************************
1577 _lsa_GetUserName
1578 ***************************************************************************/
1580 NTSTATUS _lsa_GetUserName(pipes_struct *p,
1581 struct lsa_GetUserName *r)
1583 const char *username, *domname;
1584 struct lsa_String *account_name = NULL;
1585 struct lsa_String *authority_name = NULL;
1587 if (r->in.account_name &&
1588 *r->in.account_name) {
1589 return NT_STATUS_INVALID_PARAMETER;
1592 if (r->in.authority_name &&
1593 *r->in.authority_name) {
1594 return NT_STATUS_INVALID_PARAMETER;
1597 if (p->server_info->guest) {
1599 * I'm 99% sure this is not the right place to do this,
1600 * global_sid_Anonymous should probably be put into the token
1601 * instead of the guest id -- vl
1603 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
1604 &domname, &username, NULL)) {
1605 return NT_STATUS_NO_MEMORY;
1607 } else {
1608 username = p->server_info->sanitized_username;
1609 domname = pdb_get_domain(p->server_info->sam_account);
1612 account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1613 if (!account_name) {
1614 return NT_STATUS_NO_MEMORY;
1616 init_lsa_String(account_name, username);
1618 if (r->out.authority_name) {
1619 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1620 if (!authority_name) {
1621 return NT_STATUS_NO_MEMORY;
1623 init_lsa_String(authority_name, domname);
1626 *r->out.account_name = account_name;
1627 if (r->out.authority_name) {
1628 *r->out.authority_name = authority_name;
1631 return NT_STATUS_OK;
1634 /***************************************************************************
1635 _lsa_CreateAccount
1636 ***************************************************************************/
1638 NTSTATUS _lsa_CreateAccount(pipes_struct *p,
1639 struct lsa_CreateAccount *r)
1641 NTSTATUS status;
1642 struct lsa_info *handle;
1643 struct lsa_info *info;
1644 uint32_t acc_granted;
1645 struct security_descriptor *psd;
1646 size_t sd_size;
1648 /* find the connection policy handle. */
1649 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1650 return NT_STATUS_INVALID_HANDLE;
1652 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1653 return NT_STATUS_INVALID_HANDLE;
1656 /* check if the user has enough rights */
1658 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
1659 return NT_STATUS_ACCESS_DENIED;
1662 /* Work out max allowed. */
1663 map_max_allowed_access(p->server_info->ptok,
1664 &p->server_info->utok,
1665 &r->in.access_mask);
1667 /* map the generic bits to the lsa policy ones */
1668 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1670 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1671 &lsa_account_mapping,
1672 r->in.sid, LSA_POLICY_ALL_ACCESS);
1673 if (!NT_STATUS_IS_OK(status)) {
1674 return status;
1677 status = access_check_object(psd, p->server_info->ptok,
1678 NULL, 0, r->in.access_mask,
1679 &acc_granted, "_lsa_CreateAccount");
1680 if (!NT_STATUS_IS_OK(status)) {
1681 return status;
1684 if ( is_privileged_sid( r->in.sid ) )
1685 return NT_STATUS_OBJECT_NAME_COLLISION;
1687 /* associate the user/group SID with the (unique) handle. */
1689 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1690 if (info == NULL) {
1691 return NT_STATUS_NO_MEMORY;
1694 info->sid = *r->in.sid;
1695 info->access = acc_granted;
1696 info->type = LSA_HANDLE_ACCOUNT_TYPE;
1698 /* get a (unique) handle. open a policy on it. */
1699 if (!create_policy_hnd(p, r->out.acct_handle, info))
1700 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1702 return privilege_create_account( &info->sid );
1705 /***************************************************************************
1706 _lsa_OpenAccount
1707 ***************************************************************************/
1709 NTSTATUS _lsa_OpenAccount(pipes_struct *p,
1710 struct lsa_OpenAccount *r)
1712 struct lsa_info *handle;
1713 struct lsa_info *info;
1714 SEC_DESC *psd = NULL;
1715 size_t sd_size;
1716 uint32_t des_access = r->in.access_mask;
1717 uint32_t acc_granted;
1718 NTSTATUS status;
1720 /* find the connection policy handle. */
1721 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1722 return NT_STATUS_INVALID_HANDLE;
1724 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1725 return NT_STATUS_INVALID_HANDLE;
1728 /* des_access is for the account here, not the policy
1729 * handle - so don't check against policy handle. */
1731 /* Work out max allowed. */
1732 map_max_allowed_access(p->server_info->ptok,
1733 &p->server_info->utok,
1734 &des_access);
1736 /* map the generic bits to the lsa account ones */
1737 se_map_generic(&des_access, &lsa_account_mapping);
1739 /* get the generic lsa account SD until we store it */
1740 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1741 &lsa_account_mapping,
1742 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
1743 if (!NT_STATUS_IS_OK(status)) {
1744 return status;
1747 status = access_check_object(psd, p->server_info->ptok,
1748 NULL, 0, des_access,
1749 &acc_granted, "_lsa_OpenAccount" );
1750 if (!NT_STATUS_IS_OK(status)) {
1751 return status;
1754 /* TODO: Fis the parsing routine before reenabling this check! */
1755 #if 0
1756 if (!lookup_sid(&handle->sid, dom_name, name, &type))
1757 return NT_STATUS_ACCESS_DENIED;
1758 #endif
1759 /* associate the user/group SID with the (unique) handle. */
1760 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1761 if (info == NULL) {
1762 return NT_STATUS_NO_MEMORY;
1765 info->sid = *r->in.sid;
1766 info->access = acc_granted;
1767 info->type = LSA_HANDLE_ACCOUNT_TYPE;
1769 /* get a (unique) handle. open a policy on it. */
1770 if (!create_policy_hnd(p, r->out.acct_handle, info))
1771 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1773 return NT_STATUS_OK;
1776 /***************************************************************************
1777 _lsa_EnumPrivsAccount
1778 For a given SID, enumerate all the privilege this account has.
1779 ***************************************************************************/
1781 NTSTATUS _lsa_EnumPrivsAccount(pipes_struct *p,
1782 struct lsa_EnumPrivsAccount *r)
1784 NTSTATUS status = NT_STATUS_OK;
1785 struct lsa_info *info=NULL;
1786 SE_PRIV mask;
1787 PRIVILEGE_SET privileges;
1788 struct lsa_PrivilegeSet *priv_set = NULL;
1789 struct lsa_LUIDAttribute *luid_attrs = NULL;
1790 int i;
1792 /* find the connection policy handle. */
1793 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1794 return NT_STATUS_INVALID_HANDLE;
1796 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1797 return NT_STATUS_INVALID_HANDLE;
1800 if (!(info->access & LSA_ACCOUNT_VIEW))
1801 return NT_STATUS_ACCESS_DENIED;
1803 get_privileges_for_sids(&mask, &info->sid, 1);
1805 privilege_set_init( &privileges );
1807 priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
1808 if (!priv_set) {
1809 status = NT_STATUS_NO_MEMORY;
1810 goto done;
1813 if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
1815 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
1816 sid_string_dbg(&info->sid),
1817 privileges.count));
1819 luid_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx,
1820 struct lsa_LUIDAttribute,
1821 privileges.count);
1822 if (!luid_attrs) {
1823 status = NT_STATUS_NO_MEMORY;
1824 goto done;
1827 for (i=0; i<privileges.count; i++) {
1828 luid_attrs[i].luid.low = privileges.set[i].luid.low;
1829 luid_attrs[i].luid.high = privileges.set[i].luid.high;
1830 luid_attrs[i].attribute = privileges.set[i].attr;
1833 priv_set->count = privileges.count;
1834 priv_set->unknown = 0;
1835 priv_set->set = luid_attrs;
1837 } else {
1838 priv_set->count = 0;
1839 priv_set->unknown = 0;
1840 priv_set->set = NULL;
1843 *r->out.privs = priv_set;
1845 done:
1846 privilege_set_free( &privileges );
1848 return status;
1851 /***************************************************************************
1852 _lsa_GetSystemAccessAccount
1853 ***************************************************************************/
1855 NTSTATUS _lsa_GetSystemAccessAccount(pipes_struct *p,
1856 struct lsa_GetSystemAccessAccount *r)
1858 NTSTATUS status;
1859 struct lsa_info *info = NULL;
1860 struct lsa_EnumPrivsAccount e;
1861 struct lsa_PrivilegeSet *privset;
1863 /* find the connection policy handle. */
1865 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1866 return NT_STATUS_INVALID_HANDLE;
1868 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1869 return NT_STATUS_INVALID_HANDLE;
1872 if (!(info->access & LSA_ACCOUNT_VIEW))
1873 return NT_STATUS_ACCESS_DENIED;
1875 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
1876 if (!privset) {
1877 return NT_STATUS_NO_MEMORY;
1880 e.in.handle = r->in.handle;
1881 e.out.privs = &privset;
1883 status = _lsa_EnumPrivsAccount(p, &e);
1884 if (!NT_STATUS_IS_OK(status)) {
1885 DEBUG(10,("_lsa_GetSystemAccessAccount: "
1886 "failed to call _lsa_EnumPrivsAccount(): %s\n",
1887 nt_errstr(status)));
1888 return status;
1891 /* Samba4 would iterate over the privset to merge the policy mode bits,
1892 * not sure samba3 can do the same here, so just return what we did in
1893 * the past - gd */
1896 0x01 -> Log on locally
1897 0x02 -> Access this computer from network
1898 0x04 -> Log on as a batch job
1899 0x10 -> Log on as a service
1901 they can be ORed together
1904 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
1905 LSA_POLICY_MODE_NETWORK;
1907 return NT_STATUS_OK;
1910 /***************************************************************************
1911 update the systemaccount information
1912 ***************************************************************************/
1914 NTSTATUS _lsa_SetSystemAccessAccount(pipes_struct *p,
1915 struct lsa_SetSystemAccessAccount *r)
1917 struct lsa_info *info=NULL;
1918 GROUP_MAP map;
1920 /* find the connection policy handle. */
1921 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1922 return NT_STATUS_INVALID_HANDLE;
1924 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1925 return NT_STATUS_INVALID_HANDLE;
1928 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
1929 return NT_STATUS_ACCESS_DENIED;
1932 if (!pdb_getgrsid(&map, info->sid))
1933 return NT_STATUS_NO_SUCH_GROUP;
1935 return pdb_update_group_mapping_entry(&map);
1938 /***************************************************************************
1939 _lsa_AddPrivilegesToAccount
1940 For a given SID, add some privileges.
1941 ***************************************************************************/
1943 NTSTATUS _lsa_AddPrivilegesToAccount(pipes_struct *p,
1944 struct lsa_AddPrivilegesToAccount *r)
1946 struct lsa_info *info = NULL;
1947 SE_PRIV mask;
1948 struct lsa_PrivilegeSet *set = NULL;
1950 /* find the connection policy handle. */
1951 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1952 return NT_STATUS_INVALID_HANDLE;
1954 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1955 return NT_STATUS_INVALID_HANDLE;
1958 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
1959 return NT_STATUS_ACCESS_DENIED;
1962 set = r->in.privs;
1963 if ( !privilege_set_to_se_priv( &mask, set ) )
1964 return NT_STATUS_NO_SUCH_PRIVILEGE;
1966 if ( !grant_privilege( &info->sid, &mask ) ) {
1967 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege(%s) failed!\n",
1968 sid_string_dbg(&info->sid) ));
1969 DEBUG(3,("Privilege mask:\n"));
1970 dump_se_priv( DBGC_ALL, 3, &mask );
1971 return NT_STATUS_NO_SUCH_PRIVILEGE;
1974 return NT_STATUS_OK;
1977 /***************************************************************************
1978 _lsa_RemovePrivilegesFromAccount
1979 For a given SID, remove some privileges.
1980 ***************************************************************************/
1982 NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p,
1983 struct lsa_RemovePrivilegesFromAccount *r)
1985 struct lsa_info *info = NULL;
1986 SE_PRIV mask;
1987 struct lsa_PrivilegeSet *set = NULL;
1989 /* find the connection policy handle. */
1990 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1991 return NT_STATUS_INVALID_HANDLE;
1993 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1994 return NT_STATUS_INVALID_HANDLE;
1997 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
1998 return NT_STATUS_ACCESS_DENIED;
2001 set = r->in.privs;
2003 if ( !privilege_set_to_se_priv( &mask, set ) )
2004 return NT_STATUS_NO_SUCH_PRIVILEGE;
2006 if ( !revoke_privilege( &info->sid, &mask ) ) {
2007 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2008 sid_string_dbg(&info->sid) ));
2009 DEBUG(3,("Privilege mask:\n"));
2010 dump_se_priv( DBGC_ALL, 3, &mask );
2011 return NT_STATUS_NO_SUCH_PRIVILEGE;
2014 return NT_STATUS_OK;
2017 /***************************************************************************
2018 _lsa_LookupPrivName
2019 ***************************************************************************/
2021 NTSTATUS _lsa_LookupPrivName(pipes_struct *p,
2022 struct lsa_LookupPrivName *r)
2024 struct lsa_info *info = NULL;
2025 const char *name;
2026 struct lsa_StringLarge *lsa_name;
2028 /* find the connection policy handle. */
2029 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2030 return NT_STATUS_INVALID_HANDLE;
2033 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2034 return NT_STATUS_INVALID_HANDLE;
2037 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2038 return NT_STATUS_ACCESS_DENIED;
2041 name = luid_to_privilege_name((LUID *)r->in.luid);
2042 if (!name) {
2043 return NT_STATUS_NO_SUCH_PRIVILEGE;
2046 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2047 if (!lsa_name) {
2048 return NT_STATUS_NO_MEMORY;
2051 lsa_name->string = talloc_strdup(lsa_name, name);
2052 if (!lsa_name->string) {
2053 TALLOC_FREE(lsa_name);
2054 return NT_STATUS_NO_MEMORY;
2057 *r->out.name = lsa_name;
2059 return NT_STATUS_OK;
2062 /***************************************************************************
2063 _lsa_QuerySecurity
2064 ***************************************************************************/
2066 NTSTATUS _lsa_QuerySecurity(pipes_struct *p,
2067 struct lsa_QuerySecurity *r)
2069 struct lsa_info *handle=NULL;
2070 SEC_DESC *psd = NULL;
2071 size_t sd_size;
2072 NTSTATUS status;
2074 /* find the connection policy handle. */
2075 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2076 return NT_STATUS_INVALID_HANDLE;
2078 if (handle->type == LSA_HANDLE_POLICY_TYPE) {
2079 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2080 &lsa_policy_mapping, NULL, 0);
2081 } else if (handle->type == LSA_HANDLE_ACCOUNT_TYPE) {
2082 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2083 &lsa_account_mapping,
2084 &handle->sid, LSA_ACCOUNT_ALL_ACCESS);
2085 } else {
2086 status = NT_STATUS_INVALID_HANDLE;
2089 if (!NT_STATUS_IS_OK(status)) {
2090 return status;
2093 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2094 if (!*r->out.sdbuf) {
2095 return NT_STATUS_NO_MEMORY;
2098 return status;
2101 /***************************************************************************
2102 _lsa_AddAccountRights
2103 ***************************************************************************/
2105 NTSTATUS _lsa_AddAccountRights(pipes_struct *p,
2106 struct lsa_AddAccountRights *r)
2108 struct lsa_info *info = NULL;
2109 int i = 0;
2110 uint32_t acc_granted = 0;
2111 SEC_DESC *psd = NULL;
2112 size_t sd_size;
2113 DOM_SID sid;
2114 NTSTATUS status;
2116 /* find the connection policy handle. */
2117 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2118 return NT_STATUS_INVALID_HANDLE;
2120 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2121 return NT_STATUS_INVALID_HANDLE;
2124 /* get the generic lsa account SD for this SID until we store it */
2125 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2126 &lsa_account_mapping,
2127 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2128 if (!NT_STATUS_IS_OK(status)) {
2129 return status;
2133 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2134 * on the policy handle. If it does, ask for
2135 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2136 * on the account sid. We don't check here so just use the latter. JRA.
2139 status = access_check_object(psd, p->server_info->ptok,
2140 NULL, 0,
2141 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2142 &acc_granted, "_lsa_AddAccountRights" );
2143 if (!NT_STATUS_IS_OK(status)) {
2144 return status;
2147 /* according to an NT4 PDC, you can add privileges to SIDs even without
2148 call_lsa_create_account() first. And you can use any arbitrary SID. */
2150 sid_copy( &sid, r->in.sid );
2152 for ( i=0; i < r->in.rights->count; i++ ) {
2154 const char *privname = r->in.rights->names[i].string;
2156 /* only try to add non-null strings */
2158 if ( !privname )
2159 continue;
2161 if ( !grant_privilege_by_name( &sid, privname ) ) {
2162 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2163 privname ));
2164 return NT_STATUS_NO_SUCH_PRIVILEGE;
2168 return NT_STATUS_OK;
2171 /***************************************************************************
2172 _lsa_RemoveAccountRights
2173 ***************************************************************************/
2175 NTSTATUS _lsa_RemoveAccountRights(pipes_struct *p,
2176 struct lsa_RemoveAccountRights *r)
2178 struct lsa_info *info = NULL;
2179 int i = 0;
2180 SEC_DESC *psd = NULL;
2181 size_t sd_size;
2182 DOM_SID sid;
2183 const char *privname = NULL;
2184 uint32_t acc_granted = 0;
2185 NTSTATUS status;
2187 /* find the connection policy handle. */
2188 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2189 return NT_STATUS_INVALID_HANDLE;
2191 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2192 return NT_STATUS_INVALID_HANDLE;
2195 /* get the generic lsa account SD for this SID until we store it */
2196 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2197 &lsa_account_mapping,
2198 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2199 if (!NT_STATUS_IS_OK(status)) {
2200 return status;
2204 * From the MS DOCs. We need
2205 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2206 * and DELETE on the account sid.
2209 status = access_check_object(psd, p->server_info->ptok,
2210 NULL, 0,
2211 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2212 LSA_ACCOUNT_VIEW|STD_RIGHT_DELETE_ACCESS,
2213 &acc_granted, "_lsa_AddAccountRights" );
2214 if (!NT_STATUS_IS_OK(status)) {
2215 return status;
2218 sid_copy( &sid, r->in.sid );
2220 if ( r->in.remove_all ) {
2221 if ( !revoke_all_privileges( &sid ) )
2222 return NT_STATUS_ACCESS_DENIED;
2224 return NT_STATUS_OK;
2227 for ( i=0; i < r->in.rights->count; i++ ) {
2229 privname = r->in.rights->names[i].string;
2231 /* only try to add non-null strings */
2233 if ( !privname )
2234 continue;
2236 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2237 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2238 privname ));
2239 return NT_STATUS_NO_SUCH_PRIVILEGE;
2243 return NT_STATUS_OK;
2246 /*******************************************************************
2247 ********************************************************************/
2249 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
2250 struct lsa_RightSet *r,
2251 PRIVILEGE_SET *privileges)
2253 uint32 i;
2254 const char *privname;
2255 const char **privname_array = NULL;
2256 int num_priv = 0;
2258 for (i=0; i<privileges->count; i++) {
2260 privname = luid_to_privilege_name(&privileges->set[i].luid);
2261 if (privname) {
2262 if (!add_string_to_array(mem_ctx, privname,
2263 &privname_array, &num_priv)) {
2264 return NT_STATUS_NO_MEMORY;
2269 if (num_priv) {
2271 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
2272 num_priv);
2273 if (!r->names) {
2274 return NT_STATUS_NO_MEMORY;
2277 for (i=0; i<num_priv; i++) {
2278 init_lsa_StringLarge(&r->names[i], privname_array[i]);
2281 r->count = num_priv;
2284 return NT_STATUS_OK;
2287 /***************************************************************************
2288 _lsa_EnumAccountRights
2289 ***************************************************************************/
2291 NTSTATUS _lsa_EnumAccountRights(pipes_struct *p,
2292 struct lsa_EnumAccountRights *r)
2294 NTSTATUS status;
2295 struct lsa_info *info = NULL;
2296 DOM_SID sid;
2297 PRIVILEGE_SET privileges;
2298 SE_PRIV mask;
2300 /* find the connection policy handle. */
2302 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2303 return NT_STATUS_INVALID_HANDLE;
2305 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2306 return NT_STATUS_INVALID_HANDLE;
2309 if (!(info->access & LSA_ACCOUNT_VIEW)) {
2310 return NT_STATUS_ACCESS_DENIED;
2313 /* according to an NT4 PDC, you can add privileges to SIDs even without
2314 call_lsa_create_account() first. And you can use any arbitrary SID. */
2316 sid_copy( &sid, r->in.sid );
2318 /* according to MS-LSAD 3.1.4.5.10 it is required to return
2319 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
2320 * the lsa database */
2322 if (!get_privileges_for_sids(&mask, &sid, 1)) {
2323 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2326 status = privilege_set_init(&privileges);
2327 if (!NT_STATUS_IS_OK(status)) {
2328 return status;
2331 se_priv_to_privilege_set(&privileges, &mask);
2333 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
2334 sid_string_dbg(&sid), privileges.count));
2336 status = init_lsa_right_set(p->mem_ctx, r->out.rights, &privileges);
2338 privilege_set_free( &privileges );
2340 return status;
2343 /***************************************************************************
2344 _lsa_LookupPrivValue
2345 ***************************************************************************/
2347 NTSTATUS _lsa_LookupPrivValue(pipes_struct *p,
2348 struct lsa_LookupPrivValue *r)
2350 struct lsa_info *info = NULL;
2351 const char *name = NULL;
2352 LUID_ATTR priv_luid;
2353 SE_PRIV mask;
2355 /* find the connection policy handle. */
2357 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2358 return NT_STATUS_INVALID_HANDLE;
2360 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2361 return NT_STATUS_INVALID_HANDLE;
2364 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
2365 return NT_STATUS_ACCESS_DENIED;
2367 name = r->in.name->string;
2369 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
2371 if ( !se_priv_from_name( name, &mask ) )
2372 return NT_STATUS_NO_SUCH_PRIVILEGE;
2374 priv_luid = get_privilege_luid( &mask );
2376 r->out.luid->low = priv_luid.luid.low;
2377 r->out.luid->high = priv_luid.luid.high;
2379 return NT_STATUS_OK;
2382 /***************************************************************************
2383 _lsa_EnumAccountsWithUserRight
2384 ***************************************************************************/
2386 NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p,
2387 struct lsa_EnumAccountsWithUserRight *r)
2389 NTSTATUS status;
2390 struct lsa_info *info = NULL;
2391 struct dom_sid *sids = NULL;
2392 int num_sids = 0;
2393 uint32_t i;
2394 SE_PRIV mask;
2396 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2397 return NT_STATUS_INVALID_HANDLE;
2400 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2401 return NT_STATUS_INVALID_HANDLE;
2404 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
2405 return NT_STATUS_ACCESS_DENIED;
2408 if (!r->in.name || !r->in.name->string) {
2409 return NT_STATUS_NO_SUCH_PRIVILEGE;
2412 if (!se_priv_from_name(r->in.name->string, &mask)) {
2413 return NT_STATUS_NO_SUCH_PRIVILEGE;
2416 status = privilege_enum_sids(&mask, p->mem_ctx,
2417 &sids, &num_sids);
2418 if (!NT_STATUS_IS_OK(status)) {
2419 return status;
2422 r->out.sids->num_sids = num_sids;
2423 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
2424 r->out.sids->num_sids);
2426 for (i=0; i < r->out.sids->num_sids; i++) {
2427 r->out.sids->sids[i].sid = sid_dup_talloc(r->out.sids->sids,
2428 &sids[i]);
2429 if (!r->out.sids->sids[i].sid) {
2430 TALLOC_FREE(r->out.sids->sids);
2431 r->out.sids->num_sids = 0;
2432 return NT_STATUS_NO_MEMORY;
2436 return NT_STATUS_OK;
2439 /***************************************************************************
2440 _lsa_Delete
2441 ***************************************************************************/
2443 NTSTATUS _lsa_Delete(pipes_struct *p,
2444 struct lsa_Delete *r)
2446 return NT_STATUS_NOT_SUPPORTED;
2450 * From here on the server routines are just dummy ones to make smbd link with
2451 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
2452 * pulling the server stubs across one by one.
2455 NTSTATUS _lsa_SetSecObj(pipes_struct *p, struct lsa_SetSecObj *r)
2457 p->rng_fault_state = True;
2458 return NT_STATUS_NOT_IMPLEMENTED;
2461 NTSTATUS _lsa_ChangePassword(pipes_struct *p, struct lsa_ChangePassword *r)
2463 p->rng_fault_state = True;
2464 return NT_STATUS_NOT_IMPLEMENTED;
2467 NTSTATUS _lsa_SetInfoPolicy(pipes_struct *p, struct lsa_SetInfoPolicy *r)
2469 p->rng_fault_state = True;
2470 return NT_STATUS_NOT_IMPLEMENTED;
2473 NTSTATUS _lsa_ClearAuditLog(pipes_struct *p, struct lsa_ClearAuditLog *r)
2475 p->rng_fault_state = True;
2476 return NT_STATUS_NOT_IMPLEMENTED;
2479 NTSTATUS _lsa_GetQuotasForAccount(pipes_struct *p, struct lsa_GetQuotasForAccount *r)
2481 p->rng_fault_state = True;
2482 return NT_STATUS_NOT_IMPLEMENTED;
2485 NTSTATUS _lsa_SetQuotasForAccount(pipes_struct *p, struct lsa_SetQuotasForAccount *r)
2487 p->rng_fault_state = True;
2488 return NT_STATUS_NOT_IMPLEMENTED;
2491 NTSTATUS _lsa_QueryTrustedDomainInfo(pipes_struct *p, struct lsa_QueryTrustedDomainInfo *r)
2493 p->rng_fault_state = True;
2494 return NT_STATUS_NOT_IMPLEMENTED;
2497 NTSTATUS _lsa_SetInformationTrustedDomain(pipes_struct *p, struct lsa_SetInformationTrustedDomain *r)
2499 p->rng_fault_state = True;
2500 return NT_STATUS_NOT_IMPLEMENTED;
2503 NTSTATUS _lsa_QuerySecret(pipes_struct *p, struct lsa_QuerySecret *r)
2505 p->rng_fault_state = True;
2506 return NT_STATUS_NOT_IMPLEMENTED;
2509 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(pipes_struct *p, struct lsa_QueryTrustedDomainInfoBySid *r)
2511 p->rng_fault_state = True;
2512 return NT_STATUS_NOT_IMPLEMENTED;
2515 NTSTATUS _lsa_SetTrustedDomainInfo(pipes_struct *p, struct lsa_SetTrustedDomainInfo *r)
2517 p->rng_fault_state = True;
2518 return NT_STATUS_NOT_IMPLEMENTED;
2521 NTSTATUS _lsa_DeleteTrustedDomain(pipes_struct *p, struct lsa_DeleteTrustedDomain *r)
2523 p->rng_fault_state = True;
2524 return NT_STATUS_NOT_IMPLEMENTED;
2527 NTSTATUS _lsa_StorePrivateData(pipes_struct *p, struct lsa_StorePrivateData *r)
2529 p->rng_fault_state = True;
2530 return NT_STATUS_NOT_IMPLEMENTED;
2533 NTSTATUS _lsa_RetrievePrivateData(pipes_struct *p, struct lsa_RetrievePrivateData *r)
2535 p->rng_fault_state = True;
2536 return NT_STATUS_NOT_IMPLEMENTED;
2539 NTSTATUS _lsa_SetInfoPolicy2(pipes_struct *p, struct lsa_SetInfoPolicy2 *r)
2541 p->rng_fault_state = True;
2542 return NT_STATUS_NOT_IMPLEMENTED;
2545 NTSTATUS _lsa_QueryTrustedDomainInfoByName(pipes_struct *p, struct lsa_QueryTrustedDomainInfoByName *r)
2547 p->rng_fault_state = True;
2548 return NT_STATUS_NOT_IMPLEMENTED;
2551 NTSTATUS _lsa_SetTrustedDomainInfoByName(pipes_struct *p, struct lsa_SetTrustedDomainInfoByName *r)
2553 p->rng_fault_state = True;
2554 return NT_STATUS_NOT_IMPLEMENTED;
2557 NTSTATUS _lsa_EnumTrustedDomainsEx(pipes_struct *p, struct lsa_EnumTrustedDomainsEx *r)
2559 p->rng_fault_state = True;
2560 return NT_STATUS_NOT_IMPLEMENTED;
2563 NTSTATUS _lsa_CreateTrustedDomainEx(pipes_struct *p, struct lsa_CreateTrustedDomainEx *r)
2565 p->rng_fault_state = True;
2566 return NT_STATUS_NOT_IMPLEMENTED;
2569 NTSTATUS _lsa_CloseTrustedDomainEx(pipes_struct *p, struct lsa_CloseTrustedDomainEx *r)
2571 p->rng_fault_state = True;
2572 return NT_STATUS_NOT_IMPLEMENTED;
2575 NTSTATUS _lsa_QueryDomainInformationPolicy(pipes_struct *p, struct lsa_QueryDomainInformationPolicy *r)
2577 p->rng_fault_state = True;
2578 return NT_STATUS_NOT_IMPLEMENTED;
2581 NTSTATUS _lsa_SetDomainInformationPolicy(pipes_struct *p, struct lsa_SetDomainInformationPolicy *r)
2583 p->rng_fault_state = True;
2584 return NT_STATUS_NOT_IMPLEMENTED;
2587 NTSTATUS _lsa_OpenTrustedDomainByName(pipes_struct *p, struct lsa_OpenTrustedDomainByName *r)
2589 p->rng_fault_state = True;
2590 return NT_STATUS_NOT_IMPLEMENTED;
2593 NTSTATUS _lsa_TestCall(pipes_struct *p, struct lsa_TestCall *r)
2595 p->rng_fault_state = True;
2596 return NT_STATUS_NOT_IMPLEMENTED;
2599 NTSTATUS _lsa_CreateTrustedDomainEx2(pipes_struct *p, struct lsa_CreateTrustedDomainEx2 *r)
2601 p->rng_fault_state = True;
2602 return NT_STATUS_NOT_IMPLEMENTED;
2605 NTSTATUS _lsa_CREDRWRITE(pipes_struct *p, struct lsa_CREDRWRITE *r)
2607 p->rng_fault_state = True;
2608 return NT_STATUS_NOT_IMPLEMENTED;
2611 NTSTATUS _lsa_CREDRREAD(pipes_struct *p, struct lsa_CREDRREAD *r)
2613 p->rng_fault_state = True;
2614 return NT_STATUS_NOT_IMPLEMENTED;
2617 NTSTATUS _lsa_CREDRENUMERATE(pipes_struct *p, struct lsa_CREDRENUMERATE *r)
2619 p->rng_fault_state = True;
2620 return NT_STATUS_NOT_IMPLEMENTED;
2623 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(pipes_struct *p, struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2625 p->rng_fault_state = True;
2626 return NT_STATUS_NOT_IMPLEMENTED;
2629 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(pipes_struct *p, struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2631 p->rng_fault_state = True;
2632 return NT_STATUS_NOT_IMPLEMENTED;
2635 NTSTATUS _lsa_CREDRDELETE(pipes_struct *p, struct lsa_CREDRDELETE *r)
2637 p->rng_fault_state = True;
2638 return NT_STATUS_NOT_IMPLEMENTED;
2641 NTSTATUS _lsa_CREDRGETTARGETINFO(pipes_struct *p, struct lsa_CREDRGETTARGETINFO *r)
2643 p->rng_fault_state = True;
2644 return NT_STATUS_NOT_IMPLEMENTED;
2647 NTSTATUS _lsa_CREDRPROFILELOADED(pipes_struct *p, struct lsa_CREDRPROFILELOADED *r)
2649 p->rng_fault_state = True;
2650 return NT_STATUS_NOT_IMPLEMENTED;
2653 NTSTATUS _lsa_CREDRGETSESSIONTYPES(pipes_struct *p, struct lsa_CREDRGETSESSIONTYPES *r)
2655 p->rng_fault_state = True;
2656 return NT_STATUS_NOT_IMPLEMENTED;
2659 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARREGISTERAUDITEVENT *r)
2661 p->rng_fault_state = True;
2662 return NT_STATUS_NOT_IMPLEMENTED;
2665 NTSTATUS _lsa_LSARGENAUDITEVENT(pipes_struct *p, struct lsa_LSARGENAUDITEVENT *r)
2667 p->rng_fault_state = True;
2668 return NT_STATUS_NOT_IMPLEMENTED;
2671 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARUNREGISTERAUDITEVENT *r)
2673 p->rng_fault_state = True;
2674 return NT_STATUS_NOT_IMPLEMENTED;
2677 NTSTATUS _lsa_lsaRQueryForestTrustInformation(pipes_struct *p, struct lsa_lsaRQueryForestTrustInformation *r)
2679 p->rng_fault_state = True;
2680 return NT_STATUS_NOT_IMPLEMENTED;
2683 NTSTATUS _lsa_LSARSETFORESTTRUSTINFORMATION(pipes_struct *p, struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2685 p->rng_fault_state = True;
2686 return NT_STATUS_NOT_IMPLEMENTED;
2689 NTSTATUS _lsa_CREDRRENAME(pipes_struct *p, struct lsa_CREDRRENAME *r)
2691 p->rng_fault_state = True;
2692 return NT_STATUS_NOT_IMPLEMENTED;
2695 NTSTATUS _lsa_LSAROPENPOLICYSCE(pipes_struct *p, struct lsa_LSAROPENPOLICYSCE *r)
2697 p->rng_fault_state = True;
2698 return NT_STATUS_NOT_IMPLEMENTED;
2701 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(pipes_struct *p, struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2703 p->rng_fault_state = True;
2704 return NT_STATUS_NOT_IMPLEMENTED;
2707 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(pipes_struct *p, struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2709 p->rng_fault_state = True;
2710 return NT_STATUS_NOT_IMPLEMENTED;
2713 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(pipes_struct *p, struct lsa_LSARADTREPORTSECURITYEVENT *r)
2715 p->rng_fault_state = True;
2716 return NT_STATUS_NOT_IMPLEMENTED;