s4:"dns_update_list" file: install it properly into the private directory
[Samba/cd1.git] / source3 / rpc_server / srv_lsa_nt.c
blob857040ec8b2b743017d86d3be7798940e4516dce
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"
32 #include "../librpc/gen_ndr/srv_lsa.h"
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
37 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
39 extern PRIVS privs[];
41 enum lsa_handle_type { LSA_HANDLE_POLICY_TYPE = 1, LSA_HANDLE_ACCOUNT_TYPE };
43 struct lsa_info {
44 DOM_SID sid;
45 const char *name;
46 uint32 access;
47 enum lsa_handle_type type;
48 struct security_descriptor *sd;
51 const struct generic_mapping lsa_account_mapping = {
52 LSA_ACCOUNT_READ,
53 LSA_ACCOUNT_WRITE,
54 LSA_ACCOUNT_EXECUTE,
55 LSA_ACCOUNT_ALL_ACCESS
58 const struct generic_mapping lsa_policy_mapping = {
59 LSA_POLICY_READ,
60 LSA_POLICY_WRITE,
61 LSA_POLICY_EXECUTE,
62 LSA_POLICY_ALL_ACCESS
65 const struct generic_mapping lsa_secret_mapping = {
66 LSA_SECRET_READ,
67 LSA_SECRET_WRITE,
68 LSA_SECRET_EXECUTE,
69 LSA_SECRET_ALL_ACCESS
72 const struct generic_mapping lsa_trusted_domain_mapping = {
73 LSA_TRUSTED_DOMAIN_READ,
74 LSA_TRUSTED_DOMAIN_WRITE,
75 LSA_TRUSTED_DOMAIN_EXECUTE,
76 LSA_TRUSTED_DOMAIN_ALL_ACCESS
79 /***************************************************************************
80 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
81 ***************************************************************************/
83 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
84 struct lsa_RefDomainList *ref,
85 const char *dom_name,
86 DOM_SID *dom_sid)
88 int num = 0;
90 if (dom_name != NULL) {
91 for (num = 0; num < ref->count; num++) {
92 if (sid_equal(dom_sid, ref->domains[num].sid)) {
93 return num;
96 } else {
97 num = ref->count;
100 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
101 /* index not found, already at maximum domain limit */
102 return -1;
105 ref->count = num + 1;
106 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
108 ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains,
109 struct lsa_DomainInfo, ref->count);
110 if (!ref->domains) {
111 return -1;
114 ZERO_STRUCT(ref->domains[num]);
116 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
117 ref->domains[num].sid = sid_dup_talloc(mem_ctx, dom_sid);
118 if (!ref->domains[num].sid) {
119 return -1;
122 return num;
126 /***************************************************************************
127 initialize a lsa_DomainInfo structure.
128 ***************************************************************************/
130 static void init_dom_query_3(struct lsa_DomainInfo *r,
131 const char *name,
132 DOM_SID *sid)
134 init_lsa_StringLarge(&r->name, name);
135 r->sid = sid;
138 /***************************************************************************
139 initialize a lsa_DomainInfo structure.
140 ***************************************************************************/
142 static void init_dom_query_5(struct lsa_DomainInfo *r,
143 const char *name,
144 DOM_SID *sid)
146 init_lsa_StringLarge(&r->name, name);
147 r->sid = sid;
150 /***************************************************************************
151 lookup_lsa_rids. Must be called as root for lookup_name to work.
152 ***************************************************************************/
154 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
155 struct lsa_RefDomainList *ref,
156 struct lsa_TranslatedSid *prid,
157 uint32_t num_entries,
158 struct lsa_String *name,
159 int flags,
160 uint32_t *pmapped_count)
162 uint32 mapped_count, i;
164 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
166 mapped_count = 0;
167 *pmapped_count = 0;
169 for (i = 0; i < num_entries; i++) {
170 DOM_SID sid;
171 uint32 rid;
172 int dom_idx;
173 const char *full_name;
174 const char *domain;
175 enum lsa_SidType type = SID_NAME_UNKNOWN;
177 /* Split name into domain and user component */
179 /* follow w2k8 behavior and return the builtin domain when no
180 * input has been passed in */
182 if (name[i].string) {
183 full_name = name[i].string;
184 } else {
185 full_name = "BUILTIN";
188 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
190 /* We can ignore the result of lookup_name, it will not touch
191 "type" if it's not successful */
193 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
194 &sid, &type);
196 switch (type) {
197 case SID_NAME_USER:
198 case SID_NAME_DOM_GRP:
199 case SID_NAME_DOMAIN:
200 case SID_NAME_ALIAS:
201 case SID_NAME_WKN_GRP:
202 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
203 /* Leave these unchanged */
204 break;
205 default:
206 /* Don't hand out anything but the list above */
207 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
208 type = SID_NAME_UNKNOWN;
209 break;
212 rid = 0;
213 dom_idx = -1;
215 if (type != SID_NAME_UNKNOWN) {
216 if (type == SID_NAME_DOMAIN) {
217 rid = (uint32_t)-1;
218 } else {
219 sid_split_rid(&sid, &rid);
221 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
222 mapped_count++;
225 prid[i].sid_type = type;
226 prid[i].rid = rid;
227 prid[i].sid_index = dom_idx;
230 *pmapped_count = mapped_count;
231 return NT_STATUS_OK;
234 /***************************************************************************
235 lookup_lsa_sids. Must be called as root for lookup_name to work.
236 ***************************************************************************/
238 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
239 struct lsa_RefDomainList *ref,
240 struct lsa_TranslatedSid3 *trans_sids,
241 uint32_t num_entries,
242 struct lsa_String *name,
243 int flags,
244 uint32 *pmapped_count)
246 uint32 mapped_count, i;
248 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
250 mapped_count = 0;
251 *pmapped_count = 0;
253 for (i = 0; i < num_entries; i++) {
254 DOM_SID sid;
255 uint32 rid;
256 int dom_idx;
257 const char *full_name;
258 const char *domain;
259 enum lsa_SidType type = SID_NAME_UNKNOWN;
261 ZERO_STRUCT(sid);
263 /* Split name into domain and user component */
265 full_name = name[i].string;
266 if (full_name == NULL) {
267 return NT_STATUS_NO_MEMORY;
270 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
272 /* We can ignore the result of lookup_name, it will not touch
273 "type" if it's not successful */
275 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
276 &sid, &type);
278 switch (type) {
279 case SID_NAME_USER:
280 case SID_NAME_DOM_GRP:
281 case SID_NAME_DOMAIN:
282 case SID_NAME_ALIAS:
283 case SID_NAME_WKN_GRP:
284 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
285 /* Leave these unchanged */
286 break;
287 default:
288 /* Don't hand out anything but the list above */
289 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
290 type = SID_NAME_UNKNOWN;
291 break;
294 rid = 0;
295 dom_idx = -1;
297 if (type != SID_NAME_UNKNOWN) {
298 DOM_SID domain_sid;
299 sid_copy(&domain_sid, &sid);
300 sid_split_rid(&domain_sid, &rid);
301 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
302 mapped_count++;
305 /* Initialize the lsa_TranslatedSid3 return. */
306 trans_sids[i].sid_type = type;
307 trans_sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
308 trans_sids[i].sid_index = dom_idx;
311 *pmapped_count = mapped_count;
312 return NT_STATUS_OK;
315 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size,
316 const struct generic_mapping *map,
317 DOM_SID *sid, uint32_t sid_access)
319 DOM_SID adm_sid;
320 SEC_ACE ace[5];
321 size_t i = 0;
323 SEC_ACL *psa = NULL;
325 /* READ|EXECUTE access for Everyone */
327 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
328 map->generic_execute | map->generic_read, 0);
330 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
332 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
333 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
334 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
335 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
337 /* Add Full Access for Domain Admins */
338 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_GROUP_RID_ADMINS);
339 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
340 map->generic_all, 0);
342 /* If we have a sid, give it some special access */
344 if (sid) {
345 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
346 sid_access, 0);
349 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
350 return NT_STATUS_NO_MEMORY;
352 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
353 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
354 psa, sd_size)) == NULL)
355 return NT_STATUS_NO_MEMORY;
357 return NT_STATUS_OK;
361 /***************************************************************************
362 _lsa_OpenPolicy2
363 ***************************************************************************/
365 NTSTATUS _lsa_OpenPolicy2(pipes_struct *p,
366 struct lsa_OpenPolicy2 *r)
368 struct lsa_info *info;
369 SEC_DESC *psd = NULL;
370 size_t sd_size;
371 uint32 des_access = r->in.access_mask;
372 uint32 acc_granted;
373 NTSTATUS status;
375 /* Work out max allowed. */
376 map_max_allowed_access(p->server_info->ptok,
377 &p->server_info->utok,
378 &des_access);
380 /* map the generic bits to the lsa policy ones */
381 se_map_generic(&des_access, &lsa_policy_mapping);
383 /* get the generic lsa policy SD until we store it */
384 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
385 NULL, 0);
386 if (!NT_STATUS_IS_OK(status)) {
387 return status;
390 status = access_check_object(psd, p->server_info->ptok,
391 NULL, 0, des_access,
392 &acc_granted, "_lsa_OpenPolicy2" );
393 if (!NT_STATUS_IS_OK(status)) {
394 return status;
397 /* associate the domain SID with the (unique) handle. */
398 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
399 if (info == NULL) {
400 return NT_STATUS_NO_MEMORY;
403 sid_copy(&info->sid,get_global_sam_sid());
404 info->access = acc_granted;
405 info->type = LSA_HANDLE_POLICY_TYPE;
407 /* set up the LSA QUERY INFO response */
408 if (!create_policy_hnd(p, r->out.handle, info))
409 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
411 return NT_STATUS_OK;
414 /***************************************************************************
415 _lsa_OpenPolicy
416 ***************************************************************************/
418 NTSTATUS _lsa_OpenPolicy(pipes_struct *p,
419 struct lsa_OpenPolicy *r)
421 struct lsa_OpenPolicy2 o;
423 o.in.system_name = NULL; /* should be ignored */
424 o.in.attr = r->in.attr;
425 o.in.access_mask = r->in.access_mask;
427 o.out.handle = r->out.handle;
429 return _lsa_OpenPolicy2(p, &o);
432 /***************************************************************************
433 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
434 ufff, done :) mimir
435 ***************************************************************************/
437 NTSTATUS _lsa_EnumTrustDom(pipes_struct *p,
438 struct lsa_EnumTrustDom *r)
440 struct lsa_info *info;
441 uint32_t count;
442 struct trustdom_info **domains;
443 struct lsa_DomainInfo *entries;
444 int i;
445 NTSTATUS nt_status;
447 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
448 return NT_STATUS_INVALID_HANDLE;
450 if (info->type != LSA_HANDLE_POLICY_TYPE) {
451 return NT_STATUS_INVALID_HANDLE;
454 /* check if the user has enough rights */
455 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
456 return NT_STATUS_ACCESS_DENIED;
458 become_root();
459 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
460 unbecome_root();
462 if (!NT_STATUS_IS_OK(nt_status)) {
463 return nt_status;
466 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo, count);
467 if (!entries) {
468 return NT_STATUS_NO_MEMORY;
471 for (i=0; i<count; i++) {
472 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
473 entries[i].sid = &domains[i]->sid;
476 if (*r->in.resume_handle >= count) {
477 *r->out.resume_handle = -1;
478 TALLOC_FREE(entries);
479 return NT_STATUS_NO_MORE_ENTRIES;
482 /* return the rest, limit by max_size. Note that we
483 use the w2k3 element size value of 60 */
484 r->out.domains->count = count - *r->in.resume_handle;
485 r->out.domains->count = MIN(r->out.domains->count,
486 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
488 r->out.domains->domains = entries + *r->in.resume_handle;
490 if (r->out.domains->count < count - *r->in.resume_handle) {
491 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
492 return STATUS_MORE_ENTRIES;
495 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
496 * always be larger than the previous input resume handle, in
497 * particular when hitting the last query it is vital to set the
498 * resume handle correctly to avoid infinite client loops, as
499 * seen e.g. with Windows XP SP3 when resume handle is 0 and
500 * status is NT_STATUS_OK - gd */
502 *r->out.resume_handle = (uint32_t)-1;
504 return NT_STATUS_OK;
507 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
508 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
509 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
511 /***************************************************************************
512 _lsa_QueryInfoPolicy
513 ***************************************************************************/
515 NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p,
516 struct lsa_QueryInfoPolicy *r)
518 NTSTATUS status = NT_STATUS_OK;
519 struct lsa_info *handle;
520 DOM_SID domain_sid;
521 const char *name;
522 DOM_SID *sid = NULL;
523 union lsa_PolicyInformation *info = NULL;
524 uint32_t acc_required = 0;
526 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
527 return NT_STATUS_INVALID_HANDLE;
529 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
530 return NT_STATUS_INVALID_HANDLE;
533 switch (r->in.level) {
534 case LSA_POLICY_INFO_AUDIT_LOG:
535 case LSA_POLICY_INFO_AUDIT_EVENTS:
536 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
537 break;
538 case LSA_POLICY_INFO_DOMAIN:
539 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
540 break;
541 case LSA_POLICY_INFO_PD:
542 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
543 break;
544 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
545 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
546 break;
547 case LSA_POLICY_INFO_ROLE:
548 case LSA_POLICY_INFO_REPLICA:
549 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
550 break;
551 case LSA_POLICY_INFO_QUOTA:
552 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
553 break;
554 case LSA_POLICY_INFO_MOD:
555 case LSA_POLICY_INFO_AUDIT_FULL_SET:
556 /* according to MS-LSAD 3.1.4.4.3 */
557 return NT_STATUS_INVALID_PARAMETER;
558 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
559 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
560 break;
561 case LSA_POLICY_INFO_DNS:
562 case LSA_POLICY_INFO_DNS_INT:
563 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
564 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
565 break;
566 default:
567 break;
570 if (!(handle->access & acc_required)) {
571 /* return NT_STATUS_ACCESS_DENIED; */
574 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
575 if (!info) {
576 return NT_STATUS_NO_MEMORY;
579 switch (r->in.level) {
580 /* according to MS-LSAD 3.1.4.4.3 */
581 case LSA_POLICY_INFO_MOD:
582 case LSA_POLICY_INFO_AUDIT_FULL_SET:
583 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
584 return NT_STATUS_INVALID_PARAMETER;
585 case LSA_POLICY_INFO_AUDIT_LOG:
586 info->audit_log.percent_full = 0;
587 info->audit_log.maximum_log_size = 0;
588 info->audit_log.retention_time = 0;
589 info->audit_log.shutdown_in_progress = 0;
590 info->audit_log.time_to_shutdown = 0;
591 info->audit_log.next_audit_record = 0;
592 status = NT_STATUS_OK;
593 break;
594 case LSA_POLICY_INFO_PD:
595 info->pd.name.string = NULL;
596 status = NT_STATUS_OK;
597 break;
598 case LSA_POLICY_INFO_REPLICA:
599 info->replica.source.string = NULL;
600 info->replica.account.string = NULL;
601 status = NT_STATUS_OK;
602 break;
603 case LSA_POLICY_INFO_QUOTA:
604 info->quota.paged_pool = 0;
605 info->quota.non_paged_pool = 0;
606 info->quota.min_wss = 0;
607 info->quota.max_wss = 0;
608 info->quota.pagefile = 0;
609 info->quota.unknown = 0;
610 status = NT_STATUS_OK;
611 break;
612 case LSA_POLICY_INFO_AUDIT_EVENTS:
615 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
617 /* check if the user has enough rights */
618 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
619 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
620 return NT_STATUS_ACCESS_DENIED;
623 /* fake info: We audit everything. ;) */
625 info->audit_events.auditing_mode = true;
626 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
627 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
628 enum lsa_PolicyAuditPolicy,
629 info->audit_events.count);
630 if (!info->audit_events.settings) {
631 return NT_STATUS_NO_MEMORY;
634 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
635 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
636 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
637 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
638 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
639 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
640 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
642 break;
644 case LSA_POLICY_INFO_DOMAIN:
645 /* check if the user has enough rights */
646 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
647 return NT_STATUS_ACCESS_DENIED;
649 /* Request PolicyPrimaryDomainInformation. */
650 switch (lp_server_role()) {
651 case ROLE_DOMAIN_PDC:
652 case ROLE_DOMAIN_BDC:
653 name = get_global_sam_name();
654 sid = sid_dup_talloc(p->mem_ctx, get_global_sam_sid());
655 if (!sid) {
656 return NT_STATUS_NO_MEMORY;
658 break;
659 case ROLE_DOMAIN_MEMBER:
660 name = lp_workgroup();
661 /* We need to return the Domain SID here. */
662 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
663 sid = sid_dup_talloc(p->mem_ctx, &domain_sid);
664 if (!sid) {
665 return NT_STATUS_NO_MEMORY;
667 } else {
668 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
670 break;
671 case ROLE_STANDALONE:
672 name = lp_workgroup();
673 sid = NULL;
674 break;
675 default:
676 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
678 init_dom_query_3(&info->domain, name, sid);
679 break;
680 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
681 /* check if the user has enough rights */
682 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
683 return NT_STATUS_ACCESS_DENIED;
685 /* Request PolicyAccountDomainInformation. */
686 name = get_global_sam_name();
687 sid = get_global_sam_sid();
689 init_dom_query_5(&info->account_domain, name, sid);
690 break;
691 case LSA_POLICY_INFO_ROLE:
692 /* check if the user has enough rights */
693 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
694 return NT_STATUS_ACCESS_DENIED;
696 switch (lp_server_role()) {
697 case ROLE_DOMAIN_BDC:
699 * only a BDC is a backup controller
700 * of the domain, it controls.
702 info->role.role = LSA_ROLE_BACKUP;
703 break;
704 default:
706 * any other role is a primary
707 * of the domain, it controls.
709 info->role.role = LSA_ROLE_PRIMARY;
710 break;
712 break;
713 case LSA_POLICY_INFO_DNS:
714 case LSA_POLICY_INFO_DNS_INT: {
715 struct pdb_domain_info *dominfo;
717 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
718 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
719 "without ADS passdb backend\n"));
720 status = NT_STATUS_INVALID_INFO_CLASS;
721 break;
724 dominfo = pdb_get_domain_info(info);
725 if (dominfo == NULL) {
726 status = NT_STATUS_NO_MEMORY;
727 break;
730 init_lsa_StringLarge(&info->dns.name,
731 dominfo->name);
732 init_lsa_StringLarge(&info->dns.dns_domain,
733 dominfo->dns_domain);
734 init_lsa_StringLarge(&info->dns.dns_forest,
735 dominfo->dns_forest);
736 info->dns.domain_guid = dominfo->guid;
737 info->dns.sid = &dominfo->sid;
738 break;
740 default:
741 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
742 r->in.level));
743 status = NT_STATUS_INVALID_INFO_CLASS;
744 break;
747 *r->out.info = info;
749 return status;
752 /***************************************************************************
753 _lsa_QueryInfoPolicy2
754 ***************************************************************************/
756 NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p,
757 struct lsa_QueryInfoPolicy2 *r2)
759 struct lsa_QueryInfoPolicy r;
761 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
762 p->rng_fault_state = True;
763 return NT_STATUS_NOT_IMPLEMENTED;
766 ZERO_STRUCT(r);
767 r.in.handle = r2->in.handle;
768 r.in.level = r2->in.level;
769 r.out.info = r2->out.info;
771 return _lsa_QueryInfoPolicy(p, &r);
774 /***************************************************************************
775 _lsa_lookup_sids_internal
776 ***************************************************************************/
778 static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p,
779 TALLOC_CTX *mem_ctx,
780 uint16_t level, /* input */
781 int num_sids, /* input */
782 struct lsa_SidPtr *sid, /* input */
783 struct lsa_RefDomainList **pp_ref, /* input/output */
784 struct lsa_TranslatedName2 **pp_names,/* input/output */
785 uint32_t *pp_mapped_count) /* input/output */
787 NTSTATUS status;
788 int i;
789 const DOM_SID **sids = NULL;
790 struct lsa_RefDomainList *ref = NULL;
791 uint32 mapped_count = 0;
792 struct lsa_dom_info *dom_infos = NULL;
793 struct lsa_name_info *name_infos = NULL;
794 struct lsa_TranslatedName2 *names = NULL;
796 *pp_mapped_count = 0;
797 *pp_names = NULL;
798 *pp_ref = NULL;
800 if (num_sids == 0) {
801 return NT_STATUS_OK;
804 sids = TALLOC_ARRAY(p->mem_ctx, const DOM_SID *, num_sids);
805 ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
807 if (sids == NULL || ref == NULL) {
808 return NT_STATUS_NO_MEMORY;
811 for (i=0; i<num_sids; i++) {
812 sids[i] = sid[i].sid;
815 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
816 &dom_infos, &name_infos);
818 if (!NT_STATUS_IS_OK(status)) {
819 return status;
822 names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
823 if (names == NULL) {
824 return NT_STATUS_NO_MEMORY;
827 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
829 if (!dom_infos[i].valid) {
830 break;
833 if (init_lsa_ref_domain_list(mem_ctx, ref,
834 dom_infos[i].name,
835 &dom_infos[i].sid) != i) {
836 DEBUG(0, ("Domain %s mentioned twice??\n",
837 dom_infos[i].name));
838 return NT_STATUS_INTERNAL_ERROR;
842 for (i=0; i<num_sids; i++) {
843 struct lsa_name_info *name = &name_infos[i];
845 if (name->type == SID_NAME_UNKNOWN) {
846 fstring tmp;
847 name->dom_idx = -1;
848 /* Unknown sids should return the string
849 * representation of the SID. Windows 2003 behaves
850 * rather erratic here, in many cases it returns the
851 * RID as 8 bytes hex, in others it returns the full
852 * SID. We (Jerry/VL) could not figure out which the
853 * hard cases are, so leave it with the SID. */
854 name->name = talloc_asprintf(p->mem_ctx, "%s",
855 sid_to_fstring(tmp,
856 sids[i]));
857 if (name->name == NULL) {
858 return NT_STATUS_NO_MEMORY;
860 } else {
861 mapped_count += 1;
864 names[i].sid_type = name->type;
865 names[i].name.string = name->name;
866 names[i].sid_index = name->dom_idx;
867 names[i].unknown = 0;
870 status = NT_STATUS_NONE_MAPPED;
871 if (mapped_count > 0) {
872 status = (mapped_count < num_sids) ?
873 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
876 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
877 num_sids, mapped_count, nt_errstr(status)));
879 *pp_mapped_count = mapped_count;
880 *pp_names = names;
881 *pp_ref = ref;
883 return status;
886 /***************************************************************************
887 _lsa_LookupSids
888 ***************************************************************************/
890 NTSTATUS _lsa_LookupSids(pipes_struct *p,
891 struct lsa_LookupSids *r)
893 NTSTATUS status;
894 struct lsa_info *handle;
895 int num_sids = r->in.sids->num_sids;
896 uint32 mapped_count = 0;
897 struct lsa_RefDomainList *domains = NULL;
898 struct lsa_TranslatedName *names_out = NULL;
899 struct lsa_TranslatedName2 *names = NULL;
900 int i;
902 if ((r->in.level < 1) || (r->in.level > 6)) {
903 return NT_STATUS_INVALID_PARAMETER;
906 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
907 return NT_STATUS_INVALID_HANDLE;
910 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
911 return NT_STATUS_INVALID_HANDLE;
914 /* check if the user has enough rights */
915 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
916 return NT_STATUS_ACCESS_DENIED;
919 if (num_sids > MAX_LOOKUP_SIDS) {
920 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
921 MAX_LOOKUP_SIDS, num_sids));
922 return NT_STATUS_NONE_MAPPED;
925 status = _lsa_lookup_sids_internal(p,
926 p->mem_ctx,
927 r->in.level,
928 num_sids,
929 r->in.sids->sids,
930 &domains,
931 &names,
932 &mapped_count);
934 /* Only return here when there is a real error.
935 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
936 the requested sids could be resolved. Older versions of XP (pre SP3)
937 rely that we return with the string representations of those SIDs in
938 that case. If we don't, XP crashes - Guenther
941 if (NT_STATUS_IS_ERR(status) &&
942 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
943 return status;
946 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
947 names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
948 num_sids);
949 if (!names_out) {
950 return NT_STATUS_NO_MEMORY;
953 for (i=0; i<num_sids; i++) {
954 names_out[i].sid_type = names[i].sid_type;
955 names_out[i].name = names[i].name;
956 names_out[i].sid_index = names[i].sid_index;
959 *r->out.domains = domains;
960 r->out.names->count = num_sids;
961 r->out.names->names = names_out;
962 *r->out.count = mapped_count;
964 return status;
967 /***************************************************************************
968 _lsa_LookupSids2
969 ***************************************************************************/
971 NTSTATUS _lsa_LookupSids2(pipes_struct *p,
972 struct lsa_LookupSids2 *r)
974 NTSTATUS status;
975 struct lsa_info *handle;
976 int num_sids = r->in.sids->num_sids;
977 uint32 mapped_count = 0;
978 struct lsa_RefDomainList *domains = NULL;
979 struct lsa_TranslatedName2 *names = NULL;
980 bool check_policy = true;
982 switch (p->hdr_req.opnum) {
983 case NDR_LSA_LOOKUPSIDS3:
984 check_policy = false;
985 break;
986 case NDR_LSA_LOOKUPSIDS2:
987 default:
988 check_policy = true;
991 if ((r->in.level < 1) || (r->in.level > 6)) {
992 return NT_STATUS_INVALID_PARAMETER;
995 if (check_policy) {
996 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
997 return NT_STATUS_INVALID_HANDLE;
1000 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1001 return NT_STATUS_INVALID_HANDLE;
1004 /* check if the user has enough rights */
1005 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1006 return NT_STATUS_ACCESS_DENIED;
1010 if (num_sids > MAX_LOOKUP_SIDS) {
1011 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1012 MAX_LOOKUP_SIDS, num_sids));
1013 return NT_STATUS_NONE_MAPPED;
1016 status = _lsa_lookup_sids_internal(p,
1017 p->mem_ctx,
1018 r->in.level,
1019 num_sids,
1020 r->in.sids->sids,
1021 &domains,
1022 &names,
1023 &mapped_count);
1025 *r->out.domains = domains;
1026 r->out.names->count = num_sids;
1027 r->out.names->names = names;
1028 *r->out.count = mapped_count;
1030 return status;
1033 /***************************************************************************
1034 _lsa_LookupSids3
1035 ***************************************************************************/
1037 NTSTATUS _lsa_LookupSids3(pipes_struct *p,
1038 struct lsa_LookupSids3 *r)
1040 struct lsa_LookupSids2 q;
1042 /* No policy handle on this call. Restrict to crypto connections. */
1043 if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
1044 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1045 get_remote_machine_name() ));
1046 return NT_STATUS_INVALID_PARAMETER;
1049 q.in.handle = NULL;
1050 q.in.sids = r->in.sids;
1051 q.in.level = r->in.level;
1052 q.in.lookup_options = r->in.lookup_options;
1053 q.in.client_revision = r->in.client_revision;
1054 q.in.names = r->in.names;
1055 q.in.count = r->in.count;
1057 q.out.domains = r->out.domains;
1058 q.out.names = r->out.names;
1059 q.out.count = r->out.count;
1061 return _lsa_LookupSids2(p, &q);
1064 /***************************************************************************
1065 ***************************************************************************/
1067 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1069 int flags;
1071 switch (level) {
1072 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1073 flags = LOOKUP_NAME_ALL;
1074 break;
1075 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1076 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1077 break;
1078 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1079 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1080 break;
1081 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1082 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1083 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1084 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1085 default:
1086 flags = LOOKUP_NAME_NONE;
1087 break;
1090 return flags;
1093 /***************************************************************************
1094 _lsa_LookupNames
1095 ***************************************************************************/
1097 NTSTATUS _lsa_LookupNames(pipes_struct *p,
1098 struct lsa_LookupNames *r)
1100 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1101 struct lsa_info *handle;
1102 struct lsa_String *names = r->in.names;
1103 uint32 num_entries = r->in.num_names;
1104 struct lsa_RefDomainList *domains = NULL;
1105 struct lsa_TranslatedSid *rids = NULL;
1106 uint32 mapped_count = 0;
1107 int flags = 0;
1109 if (num_entries > MAX_LOOKUP_SIDS) {
1110 num_entries = MAX_LOOKUP_SIDS;
1111 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1112 num_entries));
1115 flags = lsa_lookup_level_to_flags(r->in.level);
1117 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1118 if (!domains) {
1119 return NT_STATUS_NO_MEMORY;
1122 if (num_entries) {
1123 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1124 num_entries);
1125 if (!rids) {
1126 return NT_STATUS_NO_MEMORY;
1128 } else {
1129 rids = NULL;
1132 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1133 status = NT_STATUS_INVALID_HANDLE;
1134 goto done;
1137 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1138 return NT_STATUS_INVALID_HANDLE;
1141 /* check if the user has enough rights */
1142 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1143 status = NT_STATUS_ACCESS_DENIED;
1144 goto done;
1147 /* set up the LSA Lookup RIDs response */
1148 become_root(); /* lookup_name can require root privs */
1149 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1150 names, flags, &mapped_count);
1151 unbecome_root();
1153 done:
1155 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1156 if (mapped_count == 0) {
1157 status = NT_STATUS_NONE_MAPPED;
1158 } else if (mapped_count != num_entries) {
1159 status = STATUS_SOME_UNMAPPED;
1163 *r->out.count = mapped_count;
1164 *r->out.domains = domains;
1165 r->out.sids->sids = rids;
1166 r->out.sids->count = num_entries;
1168 return status;
1171 /***************************************************************************
1172 _lsa_LookupNames2
1173 ***************************************************************************/
1175 NTSTATUS _lsa_LookupNames2(pipes_struct *p,
1176 struct lsa_LookupNames2 *r)
1178 NTSTATUS status;
1179 struct lsa_LookupNames q;
1180 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1181 struct lsa_TransSidArray *sid_array = NULL;
1182 uint32_t i;
1184 sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1185 if (!sid_array) {
1186 return NT_STATUS_NO_MEMORY;
1189 q.in.handle = r->in.handle;
1190 q.in.num_names = r->in.num_names;
1191 q.in.names = r->in.names;
1192 q.in.level = r->in.level;
1193 q.in.sids = sid_array;
1194 q.in.count = r->in.count;
1195 /* we do not know what this is for */
1196 /* = r->in.unknown1; */
1197 /* = r->in.unknown2; */
1199 q.out.domains = r->out.domains;
1200 q.out.sids = sid_array;
1201 q.out.count = r->out.count;
1203 status = _lsa_LookupNames(p, &q);
1205 sid_array2->count = sid_array->count;
1206 sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1207 if (!sid_array2->sids) {
1208 return NT_STATUS_NO_MEMORY;
1211 for (i=0; i<sid_array->count; i++) {
1212 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1213 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1214 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1215 sid_array2->sids[i].unknown = 0;
1218 r->out.sids = sid_array2;
1220 return status;
1223 /***************************************************************************
1224 _lsa_LookupNames3
1225 ***************************************************************************/
1227 NTSTATUS _lsa_LookupNames3(pipes_struct *p,
1228 struct lsa_LookupNames3 *r)
1230 NTSTATUS status;
1231 struct lsa_info *handle;
1232 struct lsa_String *names = r->in.names;
1233 uint32 num_entries = r->in.num_names;
1234 struct lsa_RefDomainList *domains = NULL;
1235 struct lsa_TranslatedSid3 *trans_sids = NULL;
1236 uint32 mapped_count = 0;
1237 int flags = 0;
1238 bool check_policy = true;
1240 switch (p->hdr_req.opnum) {
1241 case NDR_LSA_LOOKUPNAMES4:
1242 check_policy = false;
1243 break;
1244 case NDR_LSA_LOOKUPNAMES3:
1245 default:
1246 check_policy = true;
1249 if (num_entries > MAX_LOOKUP_SIDS) {
1250 num_entries = MAX_LOOKUP_SIDS;
1251 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1254 /* Probably the lookup_level is some sort of bitmask. */
1255 if (r->in.level == 1) {
1256 flags = LOOKUP_NAME_ALL;
1259 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1260 if (!domains) {
1261 return NT_STATUS_NO_MEMORY;
1264 if (num_entries) {
1265 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1266 num_entries);
1267 if (!trans_sids) {
1268 return NT_STATUS_NO_MEMORY;
1270 } else {
1271 trans_sids = NULL;
1274 if (check_policy) {
1276 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1277 status = NT_STATUS_INVALID_HANDLE;
1278 goto done;
1281 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1282 return NT_STATUS_INVALID_HANDLE;
1285 /* check if the user has enough rights */
1286 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1287 status = NT_STATUS_ACCESS_DENIED;
1288 goto done;
1292 /* set up the LSA Lookup SIDs response */
1293 become_root(); /* lookup_name can require root privs */
1294 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1295 names, flags, &mapped_count);
1296 unbecome_root();
1298 done:
1300 if (NT_STATUS_IS_OK(status)) {
1301 if (mapped_count == 0) {
1302 status = NT_STATUS_NONE_MAPPED;
1303 } else if (mapped_count != num_entries) {
1304 status = STATUS_SOME_UNMAPPED;
1308 *r->out.count = mapped_count;
1309 *r->out.domains = domains;
1310 r->out.sids->sids = trans_sids;
1311 r->out.sids->count = num_entries;
1313 return status;
1316 /***************************************************************************
1317 _lsa_LookupNames4
1318 ***************************************************************************/
1320 NTSTATUS _lsa_LookupNames4(pipes_struct *p,
1321 struct lsa_LookupNames4 *r)
1323 struct lsa_LookupNames3 q;
1325 /* No policy handle on this call. Restrict to crypto connections. */
1326 if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
1327 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1328 get_remote_machine_name() ));
1329 return NT_STATUS_INVALID_PARAMETER;
1332 q.in.handle = NULL;
1333 q.in.num_names = r->in.num_names;
1334 q.in.names = r->in.names;
1335 q.in.level = r->in.level;
1336 q.in.lookup_options = r->in.lookup_options;
1337 q.in.client_revision = r->in.client_revision;
1338 q.in.sids = r->in.sids;
1339 q.in.count = r->in.count;
1341 q.out.domains = r->out.domains;
1342 q.out.sids = r->out.sids;
1343 q.out.count = r->out.count;
1345 return _lsa_LookupNames3(p, &q);
1348 /***************************************************************************
1349 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1350 ***************************************************************************/
1352 NTSTATUS _lsa_Close(pipes_struct *p, struct lsa_Close *r)
1354 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1355 return NT_STATUS_INVALID_HANDLE;
1358 close_policy_hnd(p, r->in.handle);
1359 ZERO_STRUCTP(r->out.handle);
1360 return NT_STATUS_OK;
1363 /***************************************************************************
1364 ***************************************************************************/
1366 NTSTATUS _lsa_OpenSecret(pipes_struct *p, struct lsa_OpenSecret *r)
1368 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1371 /***************************************************************************
1372 ***************************************************************************/
1374 NTSTATUS _lsa_OpenTrustedDomain(pipes_struct *p, struct lsa_OpenTrustedDomain *r)
1376 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1379 /***************************************************************************
1380 ***************************************************************************/
1382 NTSTATUS _lsa_CreateTrustedDomain(pipes_struct *p, struct lsa_CreateTrustedDomain *r)
1384 return NT_STATUS_ACCESS_DENIED;
1387 /***************************************************************************
1388 ***************************************************************************/
1390 NTSTATUS _lsa_CreateSecret(pipes_struct *p, struct lsa_CreateSecret *r)
1392 return NT_STATUS_ACCESS_DENIED;
1395 /***************************************************************************
1396 ***************************************************************************/
1398 NTSTATUS _lsa_SetSecret(pipes_struct *p, struct lsa_SetSecret *r)
1400 return NT_STATUS_ACCESS_DENIED;
1403 /***************************************************************************
1404 _lsa_DeleteObject
1405 ***************************************************************************/
1407 NTSTATUS _lsa_DeleteObject(pipes_struct *p,
1408 struct lsa_DeleteObject *r)
1410 NTSTATUS status;
1411 struct lsa_info *info = NULL;
1413 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
1414 return NT_STATUS_INVALID_HANDLE;
1417 if (!(info->access & STD_RIGHT_DELETE_ACCESS)) {
1418 return NT_STATUS_ACCESS_DENIED;
1421 switch (info->type) {
1422 case LSA_HANDLE_ACCOUNT_TYPE:
1423 status = privilege_delete_account(&info->sid);
1424 if (!NT_STATUS_IS_OK(status)) {
1425 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
1426 nt_errstr(status)));
1427 return status;
1429 break;
1430 default:
1431 return NT_STATUS_INVALID_HANDLE;
1434 close_policy_hnd(p, r->in.handle);
1435 ZERO_STRUCTP(r->out.handle);
1437 return status;
1440 /***************************************************************************
1441 _lsa_EnumPrivs
1442 ***************************************************************************/
1444 NTSTATUS _lsa_EnumPrivs(pipes_struct *p,
1445 struct lsa_EnumPrivs *r)
1447 struct lsa_info *handle;
1448 uint32 i;
1449 uint32 enum_context = *r->in.resume_handle;
1450 int num_privs = count_all_privileges();
1451 struct lsa_PrivEntry *entries = NULL;
1452 LUID_ATTR luid;
1454 /* remember that the enum_context starts at 0 and not 1 */
1456 if ( enum_context >= num_privs )
1457 return NT_STATUS_NO_MORE_ENTRIES;
1459 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
1460 enum_context, num_privs));
1462 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1463 return NT_STATUS_INVALID_HANDLE;
1465 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1466 return NT_STATUS_INVALID_HANDLE;
1469 /* check if the user has enough rights
1470 I don't know if it's the right one. not documented. */
1472 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1473 return NT_STATUS_ACCESS_DENIED;
1475 if (num_privs) {
1476 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
1477 if (!entries) {
1478 return NT_STATUS_NO_MEMORY;
1480 } else {
1481 entries = NULL;
1484 for (i = 0; i < num_privs; i++) {
1485 if( i < enum_context) {
1487 init_lsa_StringLarge(&entries[i].name, NULL);
1489 entries[i].luid.low = 0;
1490 entries[i].luid.high = 0;
1491 } else {
1493 init_lsa_StringLarge(&entries[i].name, privs[i].name);
1495 luid = get_privilege_luid( &privs[i].se_priv );
1497 entries[i].luid.low = luid.luid.low;
1498 entries[i].luid.high = luid.luid.high;
1502 enum_context = num_privs;
1504 *r->out.resume_handle = enum_context;
1505 r->out.privs->count = num_privs;
1506 r->out.privs->privs = entries;
1508 return NT_STATUS_OK;
1511 /***************************************************************************
1512 _lsa_LookupPrivDisplayName
1513 ***************************************************************************/
1515 NTSTATUS _lsa_LookupPrivDisplayName(pipes_struct *p,
1516 struct lsa_LookupPrivDisplayName *r)
1518 struct lsa_info *handle;
1519 const char *description;
1520 struct lsa_StringLarge *lsa_name;
1522 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1523 return NT_STATUS_INVALID_HANDLE;
1525 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1526 return NT_STATUS_INVALID_HANDLE;
1529 /* check if the user has enough rights */
1532 * I don't know if it's the right one. not documented.
1534 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1535 return NT_STATUS_ACCESS_DENIED;
1537 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
1539 description = get_privilege_dispname(r->in.name->string);
1540 if (!description) {
1541 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
1542 return NT_STATUS_NO_SUCH_PRIVILEGE;
1545 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
1547 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
1548 if (!lsa_name) {
1549 return NT_STATUS_NO_MEMORY;
1552 init_lsa_StringLarge(lsa_name, description);
1554 *r->out.returned_language_id = r->in.language_id;
1555 *r->out.disp_name = lsa_name;
1557 return NT_STATUS_OK;
1560 /***************************************************************************
1561 _lsa_EnumAccounts
1562 ***************************************************************************/
1564 NTSTATUS _lsa_EnumAccounts(pipes_struct *p,
1565 struct lsa_EnumAccounts *r)
1567 struct lsa_info *handle;
1568 DOM_SID *sid_list;
1569 int i, j, num_entries;
1570 NTSTATUS status;
1571 struct lsa_SidPtr *sids = NULL;
1573 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1574 return NT_STATUS_INVALID_HANDLE;
1576 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1577 return NT_STATUS_INVALID_HANDLE;
1580 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1581 return NT_STATUS_ACCESS_DENIED;
1583 sid_list = NULL;
1584 num_entries = 0;
1586 /* The only way we can currently find out all the SIDs that have been
1587 privileged is to scan all privileges */
1589 status = privilege_enumerate_accounts(&sid_list, &num_entries);
1590 if (!NT_STATUS_IS_OK(status)) {
1591 return status;
1594 if (*r->in.resume_handle >= num_entries) {
1595 return NT_STATUS_NO_MORE_ENTRIES;
1598 if (num_entries - *r->in.resume_handle) {
1599 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
1600 num_entries - *r->in.resume_handle);
1601 if (!sids) {
1602 talloc_free(sid_list);
1603 return NT_STATUS_NO_MEMORY;
1606 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
1607 sids[j].sid = sid_dup_talloc(p->mem_ctx, &sid_list[i]);
1608 if (!sids[j].sid) {
1609 talloc_free(sid_list);
1610 return NT_STATUS_NO_MEMORY;
1615 talloc_free(sid_list);
1617 *r->out.resume_handle = num_entries;
1618 r->out.sids->num_sids = num_entries;
1619 r->out.sids->sids = sids;
1621 return NT_STATUS_OK;
1624 /***************************************************************************
1625 _lsa_GetUserName
1626 ***************************************************************************/
1628 NTSTATUS _lsa_GetUserName(pipes_struct *p,
1629 struct lsa_GetUserName *r)
1631 const char *username, *domname;
1632 struct lsa_String *account_name = NULL;
1633 struct lsa_String *authority_name = NULL;
1635 if (r->in.account_name &&
1636 *r->in.account_name) {
1637 return NT_STATUS_INVALID_PARAMETER;
1640 if (r->in.authority_name &&
1641 *r->in.authority_name) {
1642 return NT_STATUS_INVALID_PARAMETER;
1645 if (p->server_info->guest) {
1647 * I'm 99% sure this is not the right place to do this,
1648 * global_sid_Anonymous should probably be put into the token
1649 * instead of the guest id -- vl
1651 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
1652 &domname, &username, NULL)) {
1653 return NT_STATUS_NO_MEMORY;
1655 } else {
1656 username = p->server_info->sanitized_username;
1657 domname = pdb_get_domain(p->server_info->sam_account);
1660 account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1661 if (!account_name) {
1662 return NT_STATUS_NO_MEMORY;
1664 init_lsa_String(account_name, username);
1666 if (r->out.authority_name) {
1667 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1668 if (!authority_name) {
1669 return NT_STATUS_NO_MEMORY;
1671 init_lsa_String(authority_name, domname);
1674 *r->out.account_name = account_name;
1675 if (r->out.authority_name) {
1676 *r->out.authority_name = authority_name;
1679 return NT_STATUS_OK;
1682 /***************************************************************************
1683 _lsa_CreateAccount
1684 ***************************************************************************/
1686 NTSTATUS _lsa_CreateAccount(pipes_struct *p,
1687 struct lsa_CreateAccount *r)
1689 NTSTATUS status;
1690 struct lsa_info *handle;
1691 struct lsa_info *info;
1692 uint32_t acc_granted;
1693 struct security_descriptor *psd;
1694 size_t sd_size;
1696 /* find the connection policy handle. */
1697 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1698 return NT_STATUS_INVALID_HANDLE;
1700 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1701 return NT_STATUS_INVALID_HANDLE;
1704 /* check if the user has enough rights */
1706 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
1707 return NT_STATUS_ACCESS_DENIED;
1710 /* Work out max allowed. */
1711 map_max_allowed_access(p->server_info->ptok,
1712 &p->server_info->utok,
1713 &r->in.access_mask);
1715 /* map the generic bits to the lsa policy ones */
1716 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1718 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1719 &lsa_account_mapping,
1720 r->in.sid, LSA_POLICY_ALL_ACCESS);
1721 if (!NT_STATUS_IS_OK(status)) {
1722 return status;
1725 status = access_check_object(psd, p->server_info->ptok,
1726 NULL, 0, r->in.access_mask,
1727 &acc_granted, "_lsa_CreateAccount");
1728 if (!NT_STATUS_IS_OK(status)) {
1729 return status;
1732 if ( is_privileged_sid( r->in.sid ) )
1733 return NT_STATUS_OBJECT_NAME_COLLISION;
1735 /* associate the user/group SID with the (unique) handle. */
1737 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1738 if (info == NULL) {
1739 return NT_STATUS_NO_MEMORY;
1742 info->sid = *r->in.sid;
1743 info->access = acc_granted;
1744 info->type = LSA_HANDLE_ACCOUNT_TYPE;
1746 /* get a (unique) handle. open a policy on it. */
1747 if (!create_policy_hnd(p, r->out.acct_handle, info))
1748 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1750 return privilege_create_account( &info->sid );
1753 /***************************************************************************
1754 _lsa_OpenAccount
1755 ***************************************************************************/
1757 NTSTATUS _lsa_OpenAccount(pipes_struct *p,
1758 struct lsa_OpenAccount *r)
1760 struct lsa_info *handle;
1761 struct lsa_info *info;
1762 SEC_DESC *psd = NULL;
1763 size_t sd_size;
1764 uint32_t des_access = r->in.access_mask;
1765 uint32_t acc_granted;
1766 NTSTATUS status;
1768 /* find the connection policy handle. */
1769 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1770 return NT_STATUS_INVALID_HANDLE;
1772 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1773 return NT_STATUS_INVALID_HANDLE;
1776 /* des_access is for the account here, not the policy
1777 * handle - so don't check against policy handle. */
1779 /* Work out max allowed. */
1780 map_max_allowed_access(p->server_info->ptok,
1781 &p->server_info->utok,
1782 &des_access);
1784 /* map the generic bits to the lsa account ones */
1785 se_map_generic(&des_access, &lsa_account_mapping);
1787 /* get the generic lsa account SD until we store it */
1788 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1789 &lsa_account_mapping,
1790 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
1791 if (!NT_STATUS_IS_OK(status)) {
1792 return status;
1795 status = access_check_object(psd, p->server_info->ptok,
1796 NULL, 0, des_access,
1797 &acc_granted, "_lsa_OpenAccount" );
1798 if (!NT_STATUS_IS_OK(status)) {
1799 return status;
1802 /* TODO: Fis the parsing routine before reenabling this check! */
1803 #if 0
1804 if (!lookup_sid(&handle->sid, dom_name, name, &type))
1805 return NT_STATUS_ACCESS_DENIED;
1806 #endif
1807 /* associate the user/group SID with the (unique) handle. */
1808 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1809 if (info == NULL) {
1810 return NT_STATUS_NO_MEMORY;
1813 info->sid = *r->in.sid;
1814 info->access = acc_granted;
1815 info->type = LSA_HANDLE_ACCOUNT_TYPE;
1817 /* get a (unique) handle. open a policy on it. */
1818 if (!create_policy_hnd(p, r->out.acct_handle, info))
1819 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1821 return NT_STATUS_OK;
1824 /***************************************************************************
1825 _lsa_EnumPrivsAccount
1826 For a given SID, enumerate all the privilege this account has.
1827 ***************************************************************************/
1829 NTSTATUS _lsa_EnumPrivsAccount(pipes_struct *p,
1830 struct lsa_EnumPrivsAccount *r)
1832 NTSTATUS status = NT_STATUS_OK;
1833 struct lsa_info *info=NULL;
1834 SE_PRIV mask;
1835 PRIVILEGE_SET privileges;
1836 struct lsa_PrivilegeSet *priv_set = NULL;
1837 struct lsa_LUIDAttribute *luid_attrs = NULL;
1838 int i;
1840 /* find the connection policy handle. */
1841 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1842 return NT_STATUS_INVALID_HANDLE;
1844 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1845 return NT_STATUS_INVALID_HANDLE;
1848 if (!(info->access & LSA_ACCOUNT_VIEW))
1849 return NT_STATUS_ACCESS_DENIED;
1851 get_privileges_for_sids(&mask, &info->sid, 1);
1853 privilege_set_init( &privileges );
1855 priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
1856 if (!priv_set) {
1857 status = NT_STATUS_NO_MEMORY;
1858 goto done;
1861 if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
1863 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
1864 sid_string_dbg(&info->sid),
1865 privileges.count));
1867 luid_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx,
1868 struct lsa_LUIDAttribute,
1869 privileges.count);
1870 if (!luid_attrs) {
1871 status = NT_STATUS_NO_MEMORY;
1872 goto done;
1875 for (i=0; i<privileges.count; i++) {
1876 luid_attrs[i].luid.low = privileges.set[i].luid.low;
1877 luid_attrs[i].luid.high = privileges.set[i].luid.high;
1878 luid_attrs[i].attribute = privileges.set[i].attr;
1881 priv_set->count = privileges.count;
1882 priv_set->unknown = 0;
1883 priv_set->set = luid_attrs;
1885 } else {
1886 priv_set->count = 0;
1887 priv_set->unknown = 0;
1888 priv_set->set = NULL;
1891 *r->out.privs = priv_set;
1893 done:
1894 privilege_set_free( &privileges );
1896 return status;
1899 /***************************************************************************
1900 _lsa_GetSystemAccessAccount
1901 ***************************************************************************/
1903 NTSTATUS _lsa_GetSystemAccessAccount(pipes_struct *p,
1904 struct lsa_GetSystemAccessAccount *r)
1906 NTSTATUS status;
1907 struct lsa_info *info = NULL;
1908 struct lsa_EnumPrivsAccount e;
1909 struct lsa_PrivilegeSet *privset;
1911 /* find the connection policy handle. */
1913 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1914 return NT_STATUS_INVALID_HANDLE;
1916 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1917 return NT_STATUS_INVALID_HANDLE;
1920 if (!(info->access & LSA_ACCOUNT_VIEW))
1921 return NT_STATUS_ACCESS_DENIED;
1923 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
1924 if (!privset) {
1925 return NT_STATUS_NO_MEMORY;
1928 e.in.handle = r->in.handle;
1929 e.out.privs = &privset;
1931 status = _lsa_EnumPrivsAccount(p, &e);
1932 if (!NT_STATUS_IS_OK(status)) {
1933 DEBUG(10,("_lsa_GetSystemAccessAccount: "
1934 "failed to call _lsa_EnumPrivsAccount(): %s\n",
1935 nt_errstr(status)));
1936 return status;
1939 /* Samba4 would iterate over the privset to merge the policy mode bits,
1940 * not sure samba3 can do the same here, so just return what we did in
1941 * the past - gd */
1944 0x01 -> Log on locally
1945 0x02 -> Access this computer from network
1946 0x04 -> Log on as a batch job
1947 0x10 -> Log on as a service
1949 they can be ORed together
1952 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
1953 LSA_POLICY_MODE_NETWORK;
1955 return NT_STATUS_OK;
1958 /***************************************************************************
1959 update the systemaccount information
1960 ***************************************************************************/
1962 NTSTATUS _lsa_SetSystemAccessAccount(pipes_struct *p,
1963 struct lsa_SetSystemAccessAccount *r)
1965 struct lsa_info *info=NULL;
1966 GROUP_MAP map;
1968 /* find the connection policy handle. */
1969 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1970 return NT_STATUS_INVALID_HANDLE;
1972 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1973 return NT_STATUS_INVALID_HANDLE;
1976 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
1977 return NT_STATUS_ACCESS_DENIED;
1980 if (!pdb_getgrsid(&map, info->sid))
1981 return NT_STATUS_NO_SUCH_GROUP;
1983 return pdb_update_group_mapping_entry(&map);
1986 /***************************************************************************
1987 _lsa_AddPrivilegesToAccount
1988 For a given SID, add some privileges.
1989 ***************************************************************************/
1991 NTSTATUS _lsa_AddPrivilegesToAccount(pipes_struct *p,
1992 struct lsa_AddPrivilegesToAccount *r)
1994 struct lsa_info *info = NULL;
1995 SE_PRIV mask;
1996 struct lsa_PrivilegeSet *set = NULL;
1998 /* find the connection policy handle. */
1999 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2000 return NT_STATUS_INVALID_HANDLE;
2002 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2003 return NT_STATUS_INVALID_HANDLE;
2006 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2007 return NT_STATUS_ACCESS_DENIED;
2010 set = r->in.privs;
2011 if ( !privilege_set_to_se_priv( &mask, set ) )
2012 return NT_STATUS_NO_SUCH_PRIVILEGE;
2014 if ( !grant_privilege( &info->sid, &mask ) ) {
2015 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege(%s) failed!\n",
2016 sid_string_dbg(&info->sid) ));
2017 DEBUG(3,("Privilege mask:\n"));
2018 dump_se_priv( DBGC_ALL, 3, &mask );
2019 return NT_STATUS_NO_SUCH_PRIVILEGE;
2022 return NT_STATUS_OK;
2025 /***************************************************************************
2026 _lsa_RemovePrivilegesFromAccount
2027 For a given SID, remove some privileges.
2028 ***************************************************************************/
2030 NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p,
2031 struct lsa_RemovePrivilegesFromAccount *r)
2033 struct lsa_info *info = NULL;
2034 SE_PRIV mask;
2035 struct lsa_PrivilegeSet *set = NULL;
2037 /* find the connection policy handle. */
2038 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2039 return NT_STATUS_INVALID_HANDLE;
2041 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2042 return NT_STATUS_INVALID_HANDLE;
2045 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2046 return NT_STATUS_ACCESS_DENIED;
2049 set = r->in.privs;
2051 if ( !privilege_set_to_se_priv( &mask, set ) )
2052 return NT_STATUS_NO_SUCH_PRIVILEGE;
2054 if ( !revoke_privilege( &info->sid, &mask ) ) {
2055 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2056 sid_string_dbg(&info->sid) ));
2057 DEBUG(3,("Privilege mask:\n"));
2058 dump_se_priv( DBGC_ALL, 3, &mask );
2059 return NT_STATUS_NO_SUCH_PRIVILEGE;
2062 return NT_STATUS_OK;
2065 /***************************************************************************
2066 _lsa_LookupPrivName
2067 ***************************************************************************/
2069 NTSTATUS _lsa_LookupPrivName(pipes_struct *p,
2070 struct lsa_LookupPrivName *r)
2072 struct lsa_info *info = NULL;
2073 const char *name;
2074 struct lsa_StringLarge *lsa_name;
2076 /* find the connection policy handle. */
2077 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2078 return NT_STATUS_INVALID_HANDLE;
2081 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2082 return NT_STATUS_INVALID_HANDLE;
2085 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2086 return NT_STATUS_ACCESS_DENIED;
2089 name = luid_to_privilege_name((LUID *)r->in.luid);
2090 if (!name) {
2091 return NT_STATUS_NO_SUCH_PRIVILEGE;
2094 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2095 if (!lsa_name) {
2096 return NT_STATUS_NO_MEMORY;
2099 lsa_name->string = talloc_strdup(lsa_name, name);
2100 if (!lsa_name->string) {
2101 TALLOC_FREE(lsa_name);
2102 return NT_STATUS_NO_MEMORY;
2105 *r->out.name = lsa_name;
2107 return NT_STATUS_OK;
2110 /***************************************************************************
2111 _lsa_QuerySecurity
2112 ***************************************************************************/
2114 NTSTATUS _lsa_QuerySecurity(pipes_struct *p,
2115 struct lsa_QuerySecurity *r)
2117 struct lsa_info *handle=NULL;
2118 SEC_DESC *psd = NULL;
2119 size_t sd_size;
2120 NTSTATUS status;
2122 /* find the connection policy handle. */
2123 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2124 return NT_STATUS_INVALID_HANDLE;
2126 switch (handle->type) {
2127 case LSA_HANDLE_POLICY_TYPE:
2128 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2129 &lsa_policy_mapping, NULL, 0);
2130 break;
2131 case LSA_HANDLE_ACCOUNT_TYPE:
2132 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2133 &lsa_account_mapping,
2134 &handle->sid, LSA_ACCOUNT_ALL_ACCESS);
2135 break;
2136 default:
2137 status = NT_STATUS_INVALID_HANDLE;
2138 break;
2141 if (!NT_STATUS_IS_OK(status)) {
2142 return status;
2145 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2146 if (!*r->out.sdbuf) {
2147 return NT_STATUS_NO_MEMORY;
2150 return status;
2153 /***************************************************************************
2154 _lsa_AddAccountRights
2155 ***************************************************************************/
2157 NTSTATUS _lsa_AddAccountRights(pipes_struct *p,
2158 struct lsa_AddAccountRights *r)
2160 struct lsa_info *info = NULL;
2161 int i = 0;
2162 uint32_t acc_granted = 0;
2163 SEC_DESC *psd = NULL;
2164 size_t sd_size;
2165 DOM_SID sid;
2166 NTSTATUS status;
2168 /* find the connection policy handle. */
2169 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2170 return NT_STATUS_INVALID_HANDLE;
2172 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2173 return NT_STATUS_INVALID_HANDLE;
2176 /* get the generic lsa account SD for this SID until we store it */
2177 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2178 &lsa_account_mapping,
2179 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2180 if (!NT_STATUS_IS_OK(status)) {
2181 return status;
2185 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2186 * on the policy handle. If it does, ask for
2187 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2188 * on the account sid. We don't check here so just use the latter. JRA.
2191 status = access_check_object(psd, p->server_info->ptok,
2192 NULL, 0,
2193 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2194 &acc_granted, "_lsa_AddAccountRights" );
2195 if (!NT_STATUS_IS_OK(status)) {
2196 return status;
2199 /* according to an NT4 PDC, you can add privileges to SIDs even without
2200 call_lsa_create_account() first. And you can use any arbitrary SID. */
2202 sid_copy( &sid, r->in.sid );
2204 for ( i=0; i < r->in.rights->count; i++ ) {
2206 const char *privname = r->in.rights->names[i].string;
2208 /* only try to add non-null strings */
2210 if ( !privname )
2211 continue;
2213 if ( !grant_privilege_by_name( &sid, privname ) ) {
2214 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2215 privname ));
2216 return NT_STATUS_NO_SUCH_PRIVILEGE;
2220 return NT_STATUS_OK;
2223 /***************************************************************************
2224 _lsa_RemoveAccountRights
2225 ***************************************************************************/
2227 NTSTATUS _lsa_RemoveAccountRights(pipes_struct *p,
2228 struct lsa_RemoveAccountRights *r)
2230 struct lsa_info *info = NULL;
2231 int i = 0;
2232 SEC_DESC *psd = NULL;
2233 size_t sd_size;
2234 DOM_SID sid;
2235 const char *privname = NULL;
2236 uint32_t acc_granted = 0;
2237 NTSTATUS status;
2239 /* find the connection policy handle. */
2240 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2241 return NT_STATUS_INVALID_HANDLE;
2243 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2244 return NT_STATUS_INVALID_HANDLE;
2247 /* get the generic lsa account SD for this SID until we store it */
2248 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2249 &lsa_account_mapping,
2250 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2251 if (!NT_STATUS_IS_OK(status)) {
2252 return status;
2256 * From the MS DOCs. We need
2257 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2258 * and DELETE on the account sid.
2261 status = access_check_object(psd, p->server_info->ptok,
2262 NULL, 0,
2263 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2264 LSA_ACCOUNT_VIEW|STD_RIGHT_DELETE_ACCESS,
2265 &acc_granted, "_lsa_RemoveAccountRights");
2266 if (!NT_STATUS_IS_OK(status)) {
2267 return status;
2270 sid_copy( &sid, r->in.sid );
2272 if ( r->in.remove_all ) {
2273 if ( !revoke_all_privileges( &sid ) )
2274 return NT_STATUS_ACCESS_DENIED;
2276 return NT_STATUS_OK;
2279 for ( i=0; i < r->in.rights->count; i++ ) {
2281 privname = r->in.rights->names[i].string;
2283 /* only try to add non-null strings */
2285 if ( !privname )
2286 continue;
2288 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2289 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2290 privname ));
2291 return NT_STATUS_NO_SUCH_PRIVILEGE;
2295 return NT_STATUS_OK;
2298 /*******************************************************************
2299 ********************************************************************/
2301 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
2302 struct lsa_RightSet *r,
2303 PRIVILEGE_SET *privileges)
2305 uint32 i;
2306 const char *privname;
2307 const char **privname_array = NULL;
2308 int num_priv = 0;
2310 for (i=0; i<privileges->count; i++) {
2312 privname = luid_to_privilege_name(&privileges->set[i].luid);
2313 if (privname) {
2314 if (!add_string_to_array(mem_ctx, privname,
2315 &privname_array, &num_priv)) {
2316 return NT_STATUS_NO_MEMORY;
2321 if (num_priv) {
2323 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
2324 num_priv);
2325 if (!r->names) {
2326 return NT_STATUS_NO_MEMORY;
2329 for (i=0; i<num_priv; i++) {
2330 init_lsa_StringLarge(&r->names[i], privname_array[i]);
2333 r->count = num_priv;
2336 return NT_STATUS_OK;
2339 /***************************************************************************
2340 _lsa_EnumAccountRights
2341 ***************************************************************************/
2343 NTSTATUS _lsa_EnumAccountRights(pipes_struct *p,
2344 struct lsa_EnumAccountRights *r)
2346 NTSTATUS status;
2347 struct lsa_info *info = NULL;
2348 DOM_SID sid;
2349 PRIVILEGE_SET privileges;
2350 SE_PRIV mask;
2352 /* find the connection policy handle. */
2354 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2355 return NT_STATUS_INVALID_HANDLE;
2357 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2358 return NT_STATUS_INVALID_HANDLE;
2361 if (!(info->access & LSA_ACCOUNT_VIEW)) {
2362 return NT_STATUS_ACCESS_DENIED;
2365 /* according to an NT4 PDC, you can add privileges to SIDs even without
2366 call_lsa_create_account() first. And you can use any arbitrary SID. */
2368 sid_copy( &sid, r->in.sid );
2370 /* according to MS-LSAD 3.1.4.5.10 it is required to return
2371 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
2372 * the lsa database */
2374 if (!get_privileges_for_sids(&mask, &sid, 1)) {
2375 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2378 status = privilege_set_init(&privileges);
2379 if (!NT_STATUS_IS_OK(status)) {
2380 return status;
2383 se_priv_to_privilege_set(&privileges, &mask);
2385 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
2386 sid_string_dbg(&sid), privileges.count));
2388 status = init_lsa_right_set(p->mem_ctx, r->out.rights, &privileges);
2390 privilege_set_free( &privileges );
2392 return status;
2395 /***************************************************************************
2396 _lsa_LookupPrivValue
2397 ***************************************************************************/
2399 NTSTATUS _lsa_LookupPrivValue(pipes_struct *p,
2400 struct lsa_LookupPrivValue *r)
2402 struct lsa_info *info = NULL;
2403 const char *name = NULL;
2404 LUID_ATTR priv_luid;
2405 SE_PRIV mask;
2407 /* find the connection policy handle. */
2409 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2410 return NT_STATUS_INVALID_HANDLE;
2412 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2413 return NT_STATUS_INVALID_HANDLE;
2416 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
2417 return NT_STATUS_ACCESS_DENIED;
2419 name = r->in.name->string;
2421 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
2423 if ( !se_priv_from_name( name, &mask ) )
2424 return NT_STATUS_NO_SUCH_PRIVILEGE;
2426 priv_luid = get_privilege_luid( &mask );
2428 r->out.luid->low = priv_luid.luid.low;
2429 r->out.luid->high = priv_luid.luid.high;
2431 return NT_STATUS_OK;
2434 /***************************************************************************
2435 _lsa_EnumAccountsWithUserRight
2436 ***************************************************************************/
2438 NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p,
2439 struct lsa_EnumAccountsWithUserRight *r)
2441 NTSTATUS status;
2442 struct lsa_info *info = NULL;
2443 struct dom_sid *sids = NULL;
2444 int num_sids = 0;
2445 uint32_t i;
2446 SE_PRIV mask;
2448 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2449 return NT_STATUS_INVALID_HANDLE;
2452 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2453 return NT_STATUS_INVALID_HANDLE;
2456 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
2457 return NT_STATUS_ACCESS_DENIED;
2460 if (!r->in.name || !r->in.name->string) {
2461 return NT_STATUS_NO_SUCH_PRIVILEGE;
2464 if (!se_priv_from_name(r->in.name->string, &mask)) {
2465 return NT_STATUS_NO_SUCH_PRIVILEGE;
2468 status = privilege_enum_sids(&mask, p->mem_ctx,
2469 &sids, &num_sids);
2470 if (!NT_STATUS_IS_OK(status)) {
2471 return status;
2474 r->out.sids->num_sids = num_sids;
2475 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
2476 r->out.sids->num_sids);
2478 for (i=0; i < r->out.sids->num_sids; i++) {
2479 r->out.sids->sids[i].sid = sid_dup_talloc(r->out.sids->sids,
2480 &sids[i]);
2481 if (!r->out.sids->sids[i].sid) {
2482 TALLOC_FREE(r->out.sids->sids);
2483 r->out.sids->num_sids = 0;
2484 return NT_STATUS_NO_MEMORY;
2488 return NT_STATUS_OK;
2491 /***************************************************************************
2492 _lsa_Delete
2493 ***************************************************************************/
2495 NTSTATUS _lsa_Delete(pipes_struct *p,
2496 struct lsa_Delete *r)
2498 return NT_STATUS_NOT_SUPPORTED;
2502 * From here on the server routines are just dummy ones to make smbd link with
2503 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
2504 * pulling the server stubs across one by one.
2507 NTSTATUS _lsa_SetSecObj(pipes_struct *p, struct lsa_SetSecObj *r)
2509 p->rng_fault_state = True;
2510 return NT_STATUS_NOT_IMPLEMENTED;
2513 NTSTATUS _lsa_ChangePassword(pipes_struct *p, struct lsa_ChangePassword *r)
2515 p->rng_fault_state = True;
2516 return NT_STATUS_NOT_IMPLEMENTED;
2519 NTSTATUS _lsa_SetInfoPolicy(pipes_struct *p, struct lsa_SetInfoPolicy *r)
2521 p->rng_fault_state = True;
2522 return NT_STATUS_NOT_IMPLEMENTED;
2525 NTSTATUS _lsa_ClearAuditLog(pipes_struct *p, struct lsa_ClearAuditLog *r)
2527 p->rng_fault_state = True;
2528 return NT_STATUS_NOT_IMPLEMENTED;
2531 NTSTATUS _lsa_GetQuotasForAccount(pipes_struct *p, struct lsa_GetQuotasForAccount *r)
2533 p->rng_fault_state = True;
2534 return NT_STATUS_NOT_IMPLEMENTED;
2537 NTSTATUS _lsa_SetQuotasForAccount(pipes_struct *p, struct lsa_SetQuotasForAccount *r)
2539 p->rng_fault_state = True;
2540 return NT_STATUS_NOT_IMPLEMENTED;
2543 NTSTATUS _lsa_QueryTrustedDomainInfo(pipes_struct *p, struct lsa_QueryTrustedDomainInfo *r)
2545 p->rng_fault_state = True;
2546 return NT_STATUS_NOT_IMPLEMENTED;
2549 NTSTATUS _lsa_SetInformationTrustedDomain(pipes_struct *p, struct lsa_SetInformationTrustedDomain *r)
2551 p->rng_fault_state = True;
2552 return NT_STATUS_NOT_IMPLEMENTED;
2555 NTSTATUS _lsa_QuerySecret(pipes_struct *p, struct lsa_QuerySecret *r)
2557 p->rng_fault_state = True;
2558 return NT_STATUS_NOT_IMPLEMENTED;
2561 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(pipes_struct *p, struct lsa_QueryTrustedDomainInfoBySid *r)
2563 p->rng_fault_state = True;
2564 return NT_STATUS_NOT_IMPLEMENTED;
2567 NTSTATUS _lsa_SetTrustedDomainInfo(pipes_struct *p, struct lsa_SetTrustedDomainInfo *r)
2569 p->rng_fault_state = True;
2570 return NT_STATUS_NOT_IMPLEMENTED;
2573 NTSTATUS _lsa_DeleteTrustedDomain(pipes_struct *p, struct lsa_DeleteTrustedDomain *r)
2575 p->rng_fault_state = True;
2576 return NT_STATUS_NOT_IMPLEMENTED;
2579 NTSTATUS _lsa_StorePrivateData(pipes_struct *p, struct lsa_StorePrivateData *r)
2581 p->rng_fault_state = True;
2582 return NT_STATUS_NOT_IMPLEMENTED;
2585 NTSTATUS _lsa_RetrievePrivateData(pipes_struct *p, struct lsa_RetrievePrivateData *r)
2587 p->rng_fault_state = True;
2588 return NT_STATUS_NOT_IMPLEMENTED;
2591 NTSTATUS _lsa_SetInfoPolicy2(pipes_struct *p, struct lsa_SetInfoPolicy2 *r)
2593 p->rng_fault_state = True;
2594 return NT_STATUS_NOT_IMPLEMENTED;
2597 NTSTATUS _lsa_QueryTrustedDomainInfoByName(pipes_struct *p, struct lsa_QueryTrustedDomainInfoByName *r)
2599 p->rng_fault_state = True;
2600 return NT_STATUS_NOT_IMPLEMENTED;
2603 NTSTATUS _lsa_SetTrustedDomainInfoByName(pipes_struct *p, struct lsa_SetTrustedDomainInfoByName *r)
2605 p->rng_fault_state = True;
2606 return NT_STATUS_NOT_IMPLEMENTED;
2609 NTSTATUS _lsa_EnumTrustedDomainsEx(pipes_struct *p, struct lsa_EnumTrustedDomainsEx *r)
2611 p->rng_fault_state = True;
2612 return NT_STATUS_NOT_IMPLEMENTED;
2615 NTSTATUS _lsa_CreateTrustedDomainEx(pipes_struct *p, struct lsa_CreateTrustedDomainEx *r)
2617 p->rng_fault_state = True;
2618 return NT_STATUS_NOT_IMPLEMENTED;
2621 NTSTATUS _lsa_CloseTrustedDomainEx(pipes_struct *p, struct lsa_CloseTrustedDomainEx *r)
2623 p->rng_fault_state = True;
2624 return NT_STATUS_NOT_IMPLEMENTED;
2627 NTSTATUS _lsa_QueryDomainInformationPolicy(pipes_struct *p, struct lsa_QueryDomainInformationPolicy *r)
2629 p->rng_fault_state = True;
2630 return NT_STATUS_NOT_IMPLEMENTED;
2633 NTSTATUS _lsa_SetDomainInformationPolicy(pipes_struct *p, struct lsa_SetDomainInformationPolicy *r)
2635 p->rng_fault_state = True;
2636 return NT_STATUS_NOT_IMPLEMENTED;
2639 NTSTATUS _lsa_OpenTrustedDomainByName(pipes_struct *p, struct lsa_OpenTrustedDomainByName *r)
2641 p->rng_fault_state = True;
2642 return NT_STATUS_NOT_IMPLEMENTED;
2645 NTSTATUS _lsa_TestCall(pipes_struct *p, struct lsa_TestCall *r)
2647 p->rng_fault_state = True;
2648 return NT_STATUS_NOT_IMPLEMENTED;
2651 NTSTATUS _lsa_CreateTrustedDomainEx2(pipes_struct *p, struct lsa_CreateTrustedDomainEx2 *r)
2653 p->rng_fault_state = True;
2654 return NT_STATUS_NOT_IMPLEMENTED;
2657 NTSTATUS _lsa_CREDRWRITE(pipes_struct *p, struct lsa_CREDRWRITE *r)
2659 p->rng_fault_state = True;
2660 return NT_STATUS_NOT_IMPLEMENTED;
2663 NTSTATUS _lsa_CREDRREAD(pipes_struct *p, struct lsa_CREDRREAD *r)
2665 p->rng_fault_state = True;
2666 return NT_STATUS_NOT_IMPLEMENTED;
2669 NTSTATUS _lsa_CREDRENUMERATE(pipes_struct *p, struct lsa_CREDRENUMERATE *r)
2671 p->rng_fault_state = True;
2672 return NT_STATUS_NOT_IMPLEMENTED;
2675 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(pipes_struct *p, struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2677 p->rng_fault_state = True;
2678 return NT_STATUS_NOT_IMPLEMENTED;
2681 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(pipes_struct *p, struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2683 p->rng_fault_state = True;
2684 return NT_STATUS_NOT_IMPLEMENTED;
2687 NTSTATUS _lsa_CREDRDELETE(pipes_struct *p, struct lsa_CREDRDELETE *r)
2689 p->rng_fault_state = True;
2690 return NT_STATUS_NOT_IMPLEMENTED;
2693 NTSTATUS _lsa_CREDRGETTARGETINFO(pipes_struct *p, struct lsa_CREDRGETTARGETINFO *r)
2695 p->rng_fault_state = True;
2696 return NT_STATUS_NOT_IMPLEMENTED;
2699 NTSTATUS _lsa_CREDRPROFILELOADED(pipes_struct *p, struct lsa_CREDRPROFILELOADED *r)
2701 p->rng_fault_state = True;
2702 return NT_STATUS_NOT_IMPLEMENTED;
2705 NTSTATUS _lsa_CREDRGETSESSIONTYPES(pipes_struct *p, struct lsa_CREDRGETSESSIONTYPES *r)
2707 p->rng_fault_state = True;
2708 return NT_STATUS_NOT_IMPLEMENTED;
2711 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARREGISTERAUDITEVENT *r)
2713 p->rng_fault_state = True;
2714 return NT_STATUS_NOT_IMPLEMENTED;
2717 NTSTATUS _lsa_LSARGENAUDITEVENT(pipes_struct *p, struct lsa_LSARGENAUDITEVENT *r)
2719 p->rng_fault_state = True;
2720 return NT_STATUS_NOT_IMPLEMENTED;
2723 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARUNREGISTERAUDITEVENT *r)
2725 p->rng_fault_state = True;
2726 return NT_STATUS_NOT_IMPLEMENTED;
2729 NTSTATUS _lsa_lsaRQueryForestTrustInformation(pipes_struct *p, struct lsa_lsaRQueryForestTrustInformation *r)
2731 p->rng_fault_state = True;
2732 return NT_STATUS_NOT_IMPLEMENTED;
2735 NTSTATUS _lsa_LSARSETFORESTTRUSTINFORMATION(pipes_struct *p, struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2737 p->rng_fault_state = True;
2738 return NT_STATUS_NOT_IMPLEMENTED;
2741 NTSTATUS _lsa_CREDRRENAME(pipes_struct *p, struct lsa_CREDRRENAME *r)
2743 p->rng_fault_state = True;
2744 return NT_STATUS_NOT_IMPLEMENTED;
2747 NTSTATUS _lsa_LSAROPENPOLICYSCE(pipes_struct *p, struct lsa_LSAROPENPOLICYSCE *r)
2749 p->rng_fault_state = True;
2750 return NT_STATUS_NOT_IMPLEMENTED;
2753 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(pipes_struct *p, struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2755 p->rng_fault_state = True;
2756 return NT_STATUS_NOT_IMPLEMENTED;
2759 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(pipes_struct *p, struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2761 p->rng_fault_state = True;
2762 return NT_STATUS_NOT_IMPLEMENTED;
2765 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(pipes_struct *p, struct lsa_LSARADTREPORTSECURITYEVENT *r)
2767 p->rng_fault_state = True;
2768 return NT_STATUS_NOT_IMPLEMENTED;