libcli/security Remove luid_to_se_priv() and luid_to_privilege_name()
[Samba/bb.git] / source3 / rpc_server / srv_lsa_nt.c
blobe8ffb5cee9cd9dba084a60a2b0f3050e1259182d
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"
33 #include "secrets.h"
34 #include "../librpc/gen_ndr/netlogon.h"
35 #include "rpc_client/init_lsa.h"
37 #undef DBGC_CLASS
38 #define DBGC_CLASS DBGC_RPC_SRV
40 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
42 enum lsa_handle_type { LSA_HANDLE_POLICY_TYPE = 1, LSA_HANDLE_ACCOUNT_TYPE };
44 struct lsa_info {
45 struct dom_sid sid;
46 const char *name;
47 uint32 access;
48 enum lsa_handle_type type;
49 struct security_descriptor *sd;
52 const struct generic_mapping lsa_account_mapping = {
53 LSA_ACCOUNT_READ,
54 LSA_ACCOUNT_WRITE,
55 LSA_ACCOUNT_EXECUTE,
56 LSA_ACCOUNT_ALL_ACCESS
59 const struct generic_mapping lsa_policy_mapping = {
60 LSA_POLICY_READ,
61 LSA_POLICY_WRITE,
62 LSA_POLICY_EXECUTE,
63 LSA_POLICY_ALL_ACCESS
66 const struct generic_mapping lsa_secret_mapping = {
67 LSA_SECRET_READ,
68 LSA_SECRET_WRITE,
69 LSA_SECRET_EXECUTE,
70 LSA_SECRET_ALL_ACCESS
73 const struct generic_mapping lsa_trusted_domain_mapping = {
74 LSA_TRUSTED_DOMAIN_READ,
75 LSA_TRUSTED_DOMAIN_WRITE,
76 LSA_TRUSTED_DOMAIN_EXECUTE,
77 LSA_TRUSTED_DOMAIN_ALL_ACCESS
80 /***************************************************************************
81 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
82 ***************************************************************************/
84 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
85 struct lsa_RefDomainList *ref,
86 const char *dom_name,
87 struct dom_sid *dom_sid)
89 int num = 0;
91 if (dom_name != NULL) {
92 for (num = 0; num < ref->count; num++) {
93 if (sid_equal(dom_sid, ref->domains[num].sid)) {
94 return num;
97 } else {
98 num = ref->count;
101 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
102 /* index not found, already at maximum domain limit */
103 return -1;
106 ref->count = num + 1;
107 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
109 ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains,
110 struct lsa_DomainInfo, ref->count);
111 if (!ref->domains) {
112 return -1;
115 ZERO_STRUCT(ref->domains[num]);
117 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
118 ref->domains[num].sid = sid_dup_talloc(mem_ctx, dom_sid);
119 if (!ref->domains[num].sid) {
120 return -1;
123 return num;
127 /***************************************************************************
128 initialize a lsa_DomainInfo structure.
129 ***************************************************************************/
131 static void init_dom_query_3(struct lsa_DomainInfo *r,
132 const char *name,
133 struct dom_sid *sid)
135 init_lsa_StringLarge(&r->name, name);
136 r->sid = sid;
139 /***************************************************************************
140 initialize a lsa_DomainInfo structure.
141 ***************************************************************************/
143 static void init_dom_query_5(struct lsa_DomainInfo *r,
144 const char *name,
145 struct dom_sid *sid)
147 init_lsa_StringLarge(&r->name, name);
148 r->sid = sid;
151 /***************************************************************************
152 lookup_lsa_rids. Must be called as root for lookup_name to work.
153 ***************************************************************************/
155 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
156 struct lsa_RefDomainList *ref,
157 struct lsa_TranslatedSid *prid,
158 uint32_t num_entries,
159 struct lsa_String *name,
160 int flags,
161 uint32_t *pmapped_count)
163 uint32 mapped_count, i;
165 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
167 mapped_count = 0;
168 *pmapped_count = 0;
170 for (i = 0; i < num_entries; i++) {
171 struct dom_sid sid;
172 uint32 rid;
173 int dom_idx;
174 const char *full_name;
175 const char *domain;
176 enum lsa_SidType type = SID_NAME_UNKNOWN;
178 /* Split name into domain and user component */
180 /* follow w2k8 behavior and return the builtin domain when no
181 * input has been passed in */
183 if (name[i].string) {
184 full_name = name[i].string;
185 } else {
186 full_name = "BUILTIN";
189 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
191 /* We can ignore the result of lookup_name, it will not touch
192 "type" if it's not successful */
194 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
195 &sid, &type);
197 switch (type) {
198 case SID_NAME_USER:
199 case SID_NAME_DOM_GRP:
200 case SID_NAME_DOMAIN:
201 case SID_NAME_ALIAS:
202 case SID_NAME_WKN_GRP:
203 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
204 /* Leave these unchanged */
205 break;
206 default:
207 /* Don't hand out anything but the list above */
208 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
209 type = SID_NAME_UNKNOWN;
210 break;
213 rid = 0;
214 dom_idx = -1;
216 if (type != SID_NAME_UNKNOWN) {
217 if (type == SID_NAME_DOMAIN) {
218 rid = (uint32_t)-1;
219 } else {
220 sid_split_rid(&sid, &rid);
222 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
223 mapped_count++;
226 prid[i].sid_type = type;
227 prid[i].rid = rid;
228 prid[i].sid_index = dom_idx;
231 *pmapped_count = mapped_count;
232 return NT_STATUS_OK;
235 /***************************************************************************
236 lookup_lsa_sids. Must be called as root for lookup_name to work.
237 ***************************************************************************/
239 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
240 struct lsa_RefDomainList *ref,
241 struct lsa_TranslatedSid3 *trans_sids,
242 uint32_t num_entries,
243 struct lsa_String *name,
244 int flags,
245 uint32 *pmapped_count)
247 uint32 mapped_count, i;
249 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
251 mapped_count = 0;
252 *pmapped_count = 0;
254 for (i = 0; i < num_entries; i++) {
255 struct dom_sid sid;
256 uint32 rid;
257 int dom_idx;
258 const char *full_name;
259 const char *domain;
260 enum lsa_SidType type = SID_NAME_UNKNOWN;
262 ZERO_STRUCT(sid);
264 /* Split name into domain and user component */
266 full_name = name[i].string;
267 if (full_name == NULL) {
268 return NT_STATUS_NO_MEMORY;
271 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
273 /* We can ignore the result of lookup_name, it will not touch
274 "type" if it's not successful */
276 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
277 &sid, &type);
279 switch (type) {
280 case SID_NAME_USER:
281 case SID_NAME_DOM_GRP:
282 case SID_NAME_DOMAIN:
283 case SID_NAME_ALIAS:
284 case SID_NAME_WKN_GRP:
285 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
286 /* Leave these unchanged */
287 break;
288 default:
289 /* Don't hand out anything but the list above */
290 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
291 type = SID_NAME_UNKNOWN;
292 break;
295 rid = 0;
296 dom_idx = -1;
298 if (type != SID_NAME_UNKNOWN) {
299 struct dom_sid domain_sid;
300 sid_copy(&domain_sid, &sid);
301 sid_split_rid(&domain_sid, &rid);
302 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
303 mapped_count++;
306 /* Initialize the lsa_TranslatedSid3 return. */
307 trans_sids[i].sid_type = type;
308 trans_sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
309 trans_sids[i].sid_index = dom_idx;
312 *pmapped_count = mapped_count;
313 return NT_STATUS_OK;
316 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
317 const struct generic_mapping *map,
318 struct dom_sid *sid, uint32_t sid_access)
320 struct dom_sid adm_sid;
321 struct security_ace ace[5];
322 size_t i = 0;
324 struct security_acl *psa = NULL;
326 /* READ|EXECUTE access for Everyone */
328 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
329 map->generic_execute | map->generic_read, 0);
331 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
333 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
334 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
335 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
336 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
338 /* Add Full Access for Domain Admins */
339 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
340 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
341 map->generic_all, 0);
343 /* If we have a sid, give it some special access */
345 if (sid) {
346 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
347 sid_access, 0);
350 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
351 return NT_STATUS_NO_MEMORY;
353 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
354 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
355 psa, sd_size)) == NULL)
356 return NT_STATUS_NO_MEMORY;
358 return NT_STATUS_OK;
362 /***************************************************************************
363 _lsa_OpenPolicy2
364 ***************************************************************************/
366 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
367 struct lsa_OpenPolicy2 *r)
369 struct lsa_info *info;
370 struct security_descriptor *psd = NULL;
371 size_t sd_size;
372 uint32 des_access = r->in.access_mask;
373 uint32 acc_granted;
374 NTSTATUS status;
376 /* Work out max allowed. */
377 map_max_allowed_access(p->server_info->ptok,
378 &p->server_info->utok,
379 &des_access);
381 /* map the generic bits to the lsa policy ones */
382 se_map_generic(&des_access, &lsa_policy_mapping);
384 /* get the generic lsa policy SD until we store it */
385 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
386 NULL, 0);
387 if (!NT_STATUS_IS_OK(status)) {
388 return status;
391 status = access_check_object(psd, p->server_info->ptok,
392 NULL, 0, des_access,
393 &acc_granted, "_lsa_OpenPolicy2" );
394 if (!NT_STATUS_IS_OK(status)) {
395 return status;
398 /* associate the domain SID with the (unique) handle. */
399 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
400 if (info == NULL) {
401 return NT_STATUS_NO_MEMORY;
404 sid_copy(&info->sid,get_global_sam_sid());
405 info->access = acc_granted;
406 info->type = LSA_HANDLE_POLICY_TYPE;
408 /* set up the LSA QUERY INFO response */
409 if (!create_policy_hnd(p, r->out.handle, info))
410 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
412 return NT_STATUS_OK;
415 /***************************************************************************
416 _lsa_OpenPolicy
417 ***************************************************************************/
419 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
420 struct lsa_OpenPolicy *r)
422 struct lsa_OpenPolicy2 o;
424 o.in.system_name = NULL; /* should be ignored */
425 o.in.attr = r->in.attr;
426 o.in.access_mask = r->in.access_mask;
428 o.out.handle = r->out.handle;
430 return _lsa_OpenPolicy2(p, &o);
433 /***************************************************************************
434 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
435 ufff, done :) mimir
436 ***************************************************************************/
438 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
439 struct lsa_EnumTrustDom *r)
441 struct lsa_info *info;
442 uint32_t count;
443 struct trustdom_info **domains;
444 struct lsa_DomainInfo *entries;
445 int i;
446 NTSTATUS nt_status;
448 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
449 return NT_STATUS_INVALID_HANDLE;
451 if (info->type != LSA_HANDLE_POLICY_TYPE) {
452 return NT_STATUS_INVALID_HANDLE;
455 /* check if the user has enough rights */
456 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
457 return NT_STATUS_ACCESS_DENIED;
459 become_root();
460 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
461 unbecome_root();
463 if (!NT_STATUS_IS_OK(nt_status)) {
464 return nt_status;
467 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo, count);
468 if (!entries) {
469 return NT_STATUS_NO_MEMORY;
472 for (i=0; i<count; i++) {
473 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
474 entries[i].sid = &domains[i]->sid;
477 if (*r->in.resume_handle >= count) {
478 *r->out.resume_handle = -1;
479 TALLOC_FREE(entries);
480 return NT_STATUS_NO_MORE_ENTRIES;
483 /* return the rest, limit by max_size. Note that we
484 use the w2k3 element size value of 60 */
485 r->out.domains->count = count - *r->in.resume_handle;
486 r->out.domains->count = MIN(r->out.domains->count,
487 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
489 r->out.domains->domains = entries + *r->in.resume_handle;
491 if (r->out.domains->count < count - *r->in.resume_handle) {
492 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
493 return STATUS_MORE_ENTRIES;
496 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
497 * always be larger than the previous input resume handle, in
498 * particular when hitting the last query it is vital to set the
499 * resume handle correctly to avoid infinite client loops, as
500 * seen e.g. with Windows XP SP3 when resume handle is 0 and
501 * status is NT_STATUS_OK - gd */
503 *r->out.resume_handle = (uint32_t)-1;
505 return NT_STATUS_OK;
508 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
509 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
510 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
512 /***************************************************************************
513 _lsa_QueryInfoPolicy
514 ***************************************************************************/
516 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
517 struct lsa_QueryInfoPolicy *r)
519 NTSTATUS status = NT_STATUS_OK;
520 struct lsa_info *handle;
521 struct dom_sid domain_sid;
522 const char *name;
523 struct dom_sid *sid = NULL;
524 union lsa_PolicyInformation *info = NULL;
525 uint32_t acc_required = 0;
527 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
528 return NT_STATUS_INVALID_HANDLE;
530 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
531 return NT_STATUS_INVALID_HANDLE;
534 switch (r->in.level) {
535 case LSA_POLICY_INFO_AUDIT_LOG:
536 case LSA_POLICY_INFO_AUDIT_EVENTS:
537 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
538 break;
539 case LSA_POLICY_INFO_DOMAIN:
540 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
541 break;
542 case LSA_POLICY_INFO_PD:
543 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
544 break;
545 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
546 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
547 break;
548 case LSA_POLICY_INFO_ROLE:
549 case LSA_POLICY_INFO_REPLICA:
550 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
551 break;
552 case LSA_POLICY_INFO_QUOTA:
553 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
554 break;
555 case LSA_POLICY_INFO_MOD:
556 case LSA_POLICY_INFO_AUDIT_FULL_SET:
557 /* according to MS-LSAD 3.1.4.4.3 */
558 return NT_STATUS_INVALID_PARAMETER;
559 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
560 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
561 break;
562 case LSA_POLICY_INFO_DNS:
563 case LSA_POLICY_INFO_DNS_INT:
564 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
565 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
566 break;
567 default:
568 break;
571 if (!(handle->access & acc_required)) {
572 /* return NT_STATUS_ACCESS_DENIED; */
575 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
576 if (!info) {
577 return NT_STATUS_NO_MEMORY;
580 switch (r->in.level) {
581 /* according to MS-LSAD 3.1.4.4.3 */
582 case LSA_POLICY_INFO_MOD:
583 case LSA_POLICY_INFO_AUDIT_FULL_SET:
584 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
585 return NT_STATUS_INVALID_PARAMETER;
586 case LSA_POLICY_INFO_AUDIT_LOG:
587 info->audit_log.percent_full = 0;
588 info->audit_log.maximum_log_size = 0;
589 info->audit_log.retention_time = 0;
590 info->audit_log.shutdown_in_progress = 0;
591 info->audit_log.time_to_shutdown = 0;
592 info->audit_log.next_audit_record = 0;
593 status = NT_STATUS_OK;
594 break;
595 case LSA_POLICY_INFO_PD:
596 info->pd.name.string = NULL;
597 status = NT_STATUS_OK;
598 break;
599 case LSA_POLICY_INFO_REPLICA:
600 info->replica.source.string = NULL;
601 info->replica.account.string = NULL;
602 status = NT_STATUS_OK;
603 break;
604 case LSA_POLICY_INFO_QUOTA:
605 info->quota.paged_pool = 0;
606 info->quota.non_paged_pool = 0;
607 info->quota.min_wss = 0;
608 info->quota.max_wss = 0;
609 info->quota.pagefile = 0;
610 info->quota.unknown = 0;
611 status = NT_STATUS_OK;
612 break;
613 case LSA_POLICY_INFO_AUDIT_EVENTS:
616 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
618 /* check if the user has enough rights */
619 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
620 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
621 return NT_STATUS_ACCESS_DENIED;
624 /* fake info: We audit everything. ;) */
626 info->audit_events.auditing_mode = true;
627 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
628 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
629 enum lsa_PolicyAuditPolicy,
630 info->audit_events.count);
631 if (!info->audit_events.settings) {
632 return NT_STATUS_NO_MEMORY;
635 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
636 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
637 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
638 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
639 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
640 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
641 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
643 break;
645 case LSA_POLICY_INFO_DOMAIN:
646 /* check if the user has enough rights */
647 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
648 return NT_STATUS_ACCESS_DENIED;
650 /* Request PolicyPrimaryDomainInformation. */
651 switch (lp_server_role()) {
652 case ROLE_DOMAIN_PDC:
653 case ROLE_DOMAIN_BDC:
654 name = get_global_sam_name();
655 sid = sid_dup_talloc(p->mem_ctx, get_global_sam_sid());
656 if (!sid) {
657 return NT_STATUS_NO_MEMORY;
659 break;
660 case ROLE_DOMAIN_MEMBER:
661 name = lp_workgroup();
662 /* We need to return the Domain SID here. */
663 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
664 sid = sid_dup_talloc(p->mem_ctx, &domain_sid);
665 if (!sid) {
666 return NT_STATUS_NO_MEMORY;
668 } else {
669 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
671 break;
672 case ROLE_STANDALONE:
673 name = lp_workgroup();
674 sid = NULL;
675 break;
676 default:
677 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
679 init_dom_query_3(&info->domain, name, sid);
680 break;
681 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
682 /* check if the user has enough rights */
683 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
684 return NT_STATUS_ACCESS_DENIED;
686 /* Request PolicyAccountDomainInformation. */
687 name = get_global_sam_name();
688 sid = get_global_sam_sid();
690 init_dom_query_5(&info->account_domain, name, sid);
691 break;
692 case LSA_POLICY_INFO_ROLE:
693 /* check if the user has enough rights */
694 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
695 return NT_STATUS_ACCESS_DENIED;
697 switch (lp_server_role()) {
698 case ROLE_DOMAIN_BDC:
700 * only a BDC is a backup controller
701 * of the domain, it controls.
703 info->role.role = LSA_ROLE_BACKUP;
704 break;
705 default:
707 * any other role is a primary
708 * of the domain, it controls.
710 info->role.role = LSA_ROLE_PRIMARY;
711 break;
713 break;
714 case LSA_POLICY_INFO_DNS:
715 case LSA_POLICY_INFO_DNS_INT: {
716 struct pdb_domain_info *dominfo;
718 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
719 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
720 "without ADS passdb backend\n"));
721 status = NT_STATUS_INVALID_INFO_CLASS;
722 break;
725 dominfo = pdb_get_domain_info(info);
726 if (dominfo == NULL) {
727 status = NT_STATUS_NO_MEMORY;
728 break;
731 init_lsa_StringLarge(&info->dns.name,
732 dominfo->name);
733 init_lsa_StringLarge(&info->dns.dns_domain,
734 dominfo->dns_domain);
735 init_lsa_StringLarge(&info->dns.dns_forest,
736 dominfo->dns_forest);
737 info->dns.domain_guid = dominfo->guid;
738 info->dns.sid = &dominfo->sid;
739 break;
741 default:
742 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
743 r->in.level));
744 status = NT_STATUS_INVALID_INFO_CLASS;
745 break;
748 *r->out.info = info;
750 return status;
753 /***************************************************************************
754 _lsa_QueryInfoPolicy2
755 ***************************************************************************/
757 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
758 struct lsa_QueryInfoPolicy2 *r2)
760 struct lsa_QueryInfoPolicy r;
762 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
763 p->rng_fault_state = True;
764 return NT_STATUS_NOT_IMPLEMENTED;
767 ZERO_STRUCT(r);
768 r.in.handle = r2->in.handle;
769 r.in.level = r2->in.level;
770 r.out.info = r2->out.info;
772 return _lsa_QueryInfoPolicy(p, &r);
775 /***************************************************************************
776 _lsa_lookup_sids_internal
777 ***************************************************************************/
779 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
780 TALLOC_CTX *mem_ctx,
781 uint16_t level, /* input */
782 int num_sids, /* input */
783 struct lsa_SidPtr *sid, /* input */
784 struct lsa_RefDomainList **pp_ref, /* input/output */
785 struct lsa_TranslatedName2 **pp_names,/* input/output */
786 uint32_t *pp_mapped_count) /* input/output */
788 NTSTATUS status;
789 int i;
790 const struct dom_sid **sids = NULL;
791 struct lsa_RefDomainList *ref = NULL;
792 uint32 mapped_count = 0;
793 struct lsa_dom_info *dom_infos = NULL;
794 struct lsa_name_info *name_infos = NULL;
795 struct lsa_TranslatedName2 *names = NULL;
797 *pp_mapped_count = 0;
798 *pp_names = NULL;
799 *pp_ref = NULL;
801 if (num_sids == 0) {
802 return NT_STATUS_OK;
805 sids = TALLOC_ARRAY(p->mem_ctx, const struct dom_sid *, num_sids);
806 ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
808 if (sids == NULL || ref == NULL) {
809 return NT_STATUS_NO_MEMORY;
812 for (i=0; i<num_sids; i++) {
813 sids[i] = sid[i].sid;
816 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
817 &dom_infos, &name_infos);
819 if (!NT_STATUS_IS_OK(status)) {
820 return status;
823 names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
824 if (names == NULL) {
825 return NT_STATUS_NO_MEMORY;
828 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
830 if (!dom_infos[i].valid) {
831 break;
834 if (init_lsa_ref_domain_list(mem_ctx, ref,
835 dom_infos[i].name,
836 &dom_infos[i].sid) != i) {
837 DEBUG(0, ("Domain %s mentioned twice??\n",
838 dom_infos[i].name));
839 return NT_STATUS_INTERNAL_ERROR;
843 for (i=0; i<num_sids; i++) {
844 struct lsa_name_info *name = &name_infos[i];
846 if (name->type == SID_NAME_UNKNOWN) {
847 fstring tmp;
848 name->dom_idx = -1;
849 /* Unknown sids should return the string
850 * representation of the SID. Windows 2003 behaves
851 * rather erratic here, in many cases it returns the
852 * RID as 8 bytes hex, in others it returns the full
853 * SID. We (Jerry/VL) could not figure out which the
854 * hard cases are, so leave it with the SID. */
855 name->name = talloc_asprintf(p->mem_ctx, "%s",
856 sid_to_fstring(tmp,
857 sids[i]));
858 if (name->name == NULL) {
859 return NT_STATUS_NO_MEMORY;
861 } else {
862 mapped_count += 1;
865 names[i].sid_type = name->type;
866 names[i].name.string = name->name;
867 names[i].sid_index = name->dom_idx;
868 names[i].unknown = 0;
871 status = NT_STATUS_NONE_MAPPED;
872 if (mapped_count > 0) {
873 status = (mapped_count < num_sids) ?
874 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
877 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
878 num_sids, mapped_count, nt_errstr(status)));
880 *pp_mapped_count = mapped_count;
881 *pp_names = names;
882 *pp_ref = ref;
884 return status;
887 /***************************************************************************
888 _lsa_LookupSids
889 ***************************************************************************/
891 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
892 struct lsa_LookupSids *r)
894 NTSTATUS status;
895 struct lsa_info *handle;
896 int num_sids = r->in.sids->num_sids;
897 uint32 mapped_count = 0;
898 struct lsa_RefDomainList *domains = NULL;
899 struct lsa_TranslatedName *names_out = NULL;
900 struct lsa_TranslatedName2 *names = NULL;
901 int i;
903 if ((r->in.level < 1) || (r->in.level > 6)) {
904 return NT_STATUS_INVALID_PARAMETER;
907 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
908 return NT_STATUS_INVALID_HANDLE;
911 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
912 return NT_STATUS_INVALID_HANDLE;
915 /* check if the user has enough rights */
916 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
917 return NT_STATUS_ACCESS_DENIED;
920 if (num_sids > MAX_LOOKUP_SIDS) {
921 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
922 MAX_LOOKUP_SIDS, num_sids));
923 return NT_STATUS_NONE_MAPPED;
926 status = _lsa_lookup_sids_internal(p,
927 p->mem_ctx,
928 r->in.level,
929 num_sids,
930 r->in.sids->sids,
931 &domains,
932 &names,
933 &mapped_count);
935 /* Only return here when there is a real error.
936 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
937 the requested sids could be resolved. Older versions of XP (pre SP3)
938 rely that we return with the string representations of those SIDs in
939 that case. If we don't, XP crashes - Guenther
942 if (NT_STATUS_IS_ERR(status) &&
943 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
944 return status;
947 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
948 names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
949 num_sids);
950 if (!names_out) {
951 return NT_STATUS_NO_MEMORY;
954 for (i=0; i<num_sids; i++) {
955 names_out[i].sid_type = names[i].sid_type;
956 names_out[i].name = names[i].name;
957 names_out[i].sid_index = names[i].sid_index;
960 *r->out.domains = domains;
961 r->out.names->count = num_sids;
962 r->out.names->names = names_out;
963 *r->out.count = mapped_count;
965 return status;
968 /***************************************************************************
969 _lsa_LookupSids2
970 ***************************************************************************/
972 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
973 struct lsa_LookupSids2 *r)
975 NTSTATUS status;
976 struct lsa_info *handle;
977 int num_sids = r->in.sids->num_sids;
978 uint32 mapped_count = 0;
979 struct lsa_RefDomainList *domains = NULL;
980 struct lsa_TranslatedName2 *names = NULL;
981 bool check_policy = true;
983 switch (p->opnum) {
984 case NDR_LSA_LOOKUPSIDS3:
985 check_policy = false;
986 break;
987 case NDR_LSA_LOOKUPSIDS2:
988 default:
989 check_policy = true;
992 if ((r->in.level < 1) || (r->in.level > 6)) {
993 return NT_STATUS_INVALID_PARAMETER;
996 if (check_policy) {
997 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
998 return NT_STATUS_INVALID_HANDLE;
1001 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1002 return NT_STATUS_INVALID_HANDLE;
1005 /* check if the user has enough rights */
1006 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1007 return NT_STATUS_ACCESS_DENIED;
1011 if (num_sids > MAX_LOOKUP_SIDS) {
1012 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1013 MAX_LOOKUP_SIDS, num_sids));
1014 return NT_STATUS_NONE_MAPPED;
1017 status = _lsa_lookup_sids_internal(p,
1018 p->mem_ctx,
1019 r->in.level,
1020 num_sids,
1021 r->in.sids->sids,
1022 &domains,
1023 &names,
1024 &mapped_count);
1026 *r->out.domains = domains;
1027 r->out.names->count = num_sids;
1028 r->out.names->names = names;
1029 *r->out.count = mapped_count;
1031 return status;
1034 /***************************************************************************
1035 _lsa_LookupSids3
1036 ***************************************************************************/
1038 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1039 struct lsa_LookupSids3 *r)
1041 struct lsa_LookupSids2 q;
1043 /* No policy handle on this call. Restrict to crypto connections. */
1044 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1045 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1046 get_remote_machine_name() ));
1047 return NT_STATUS_INVALID_PARAMETER;
1050 q.in.handle = NULL;
1051 q.in.sids = r->in.sids;
1052 q.in.level = r->in.level;
1053 q.in.lookup_options = r->in.lookup_options;
1054 q.in.client_revision = r->in.client_revision;
1055 q.in.names = r->in.names;
1056 q.in.count = r->in.count;
1058 q.out.domains = r->out.domains;
1059 q.out.names = r->out.names;
1060 q.out.count = r->out.count;
1062 return _lsa_LookupSids2(p, &q);
1065 /***************************************************************************
1066 ***************************************************************************/
1068 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1070 int flags;
1072 switch (level) {
1073 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1074 flags = LOOKUP_NAME_ALL;
1075 break;
1076 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1077 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1078 break;
1079 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1080 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1081 break;
1082 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1083 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1084 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1085 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1086 default:
1087 flags = LOOKUP_NAME_NONE;
1088 break;
1091 return flags;
1094 /***************************************************************************
1095 _lsa_LookupNames
1096 ***************************************************************************/
1098 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1099 struct lsa_LookupNames *r)
1101 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1102 struct lsa_info *handle;
1103 struct lsa_String *names = r->in.names;
1104 uint32 num_entries = r->in.num_names;
1105 struct lsa_RefDomainList *domains = NULL;
1106 struct lsa_TranslatedSid *rids = NULL;
1107 uint32 mapped_count = 0;
1108 int flags = 0;
1110 if (num_entries > MAX_LOOKUP_SIDS) {
1111 num_entries = MAX_LOOKUP_SIDS;
1112 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1113 num_entries));
1116 flags = lsa_lookup_level_to_flags(r->in.level);
1118 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1119 if (!domains) {
1120 return NT_STATUS_NO_MEMORY;
1123 if (num_entries) {
1124 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1125 num_entries);
1126 if (!rids) {
1127 return NT_STATUS_NO_MEMORY;
1129 } else {
1130 rids = NULL;
1133 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1134 status = NT_STATUS_INVALID_HANDLE;
1135 goto done;
1138 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1139 return NT_STATUS_INVALID_HANDLE;
1142 /* check if the user has enough rights */
1143 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1144 status = NT_STATUS_ACCESS_DENIED;
1145 goto done;
1148 /* set up the LSA Lookup RIDs response */
1149 become_root(); /* lookup_name can require root privs */
1150 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1151 names, flags, &mapped_count);
1152 unbecome_root();
1154 done:
1156 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1157 if (mapped_count == 0) {
1158 status = NT_STATUS_NONE_MAPPED;
1159 } else if (mapped_count != num_entries) {
1160 status = STATUS_SOME_UNMAPPED;
1164 *r->out.count = mapped_count;
1165 *r->out.domains = domains;
1166 r->out.sids->sids = rids;
1167 r->out.sids->count = num_entries;
1169 return status;
1172 /***************************************************************************
1173 _lsa_LookupNames2
1174 ***************************************************************************/
1176 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1177 struct lsa_LookupNames2 *r)
1179 NTSTATUS status;
1180 struct lsa_LookupNames q;
1181 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1182 struct lsa_TransSidArray *sid_array = NULL;
1183 uint32_t i;
1185 sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1186 if (!sid_array) {
1187 return NT_STATUS_NO_MEMORY;
1190 q.in.handle = r->in.handle;
1191 q.in.num_names = r->in.num_names;
1192 q.in.names = r->in.names;
1193 q.in.level = r->in.level;
1194 q.in.sids = sid_array;
1195 q.in.count = r->in.count;
1196 /* we do not know what this is for */
1197 /* = r->in.unknown1; */
1198 /* = r->in.unknown2; */
1200 q.out.domains = r->out.domains;
1201 q.out.sids = sid_array;
1202 q.out.count = r->out.count;
1204 status = _lsa_LookupNames(p, &q);
1206 sid_array2->count = sid_array->count;
1207 sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1208 if (!sid_array2->sids) {
1209 return NT_STATUS_NO_MEMORY;
1212 for (i=0; i<sid_array->count; i++) {
1213 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1214 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1215 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1216 sid_array2->sids[i].unknown = 0;
1219 r->out.sids = sid_array2;
1221 return status;
1224 /***************************************************************************
1225 _lsa_LookupNames3
1226 ***************************************************************************/
1228 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1229 struct lsa_LookupNames3 *r)
1231 NTSTATUS status;
1232 struct lsa_info *handle;
1233 struct lsa_String *names = r->in.names;
1234 uint32 num_entries = r->in.num_names;
1235 struct lsa_RefDomainList *domains = NULL;
1236 struct lsa_TranslatedSid3 *trans_sids = NULL;
1237 uint32 mapped_count = 0;
1238 int flags = 0;
1239 bool check_policy = true;
1241 switch (p->opnum) {
1242 case NDR_LSA_LOOKUPNAMES4:
1243 check_policy = false;
1244 break;
1245 case NDR_LSA_LOOKUPNAMES3:
1246 default:
1247 check_policy = true;
1250 if (num_entries > MAX_LOOKUP_SIDS) {
1251 num_entries = MAX_LOOKUP_SIDS;
1252 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1255 /* Probably the lookup_level is some sort of bitmask. */
1256 if (r->in.level == 1) {
1257 flags = LOOKUP_NAME_ALL;
1260 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1261 if (!domains) {
1262 return NT_STATUS_NO_MEMORY;
1265 if (num_entries) {
1266 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1267 num_entries);
1268 if (!trans_sids) {
1269 return NT_STATUS_NO_MEMORY;
1271 } else {
1272 trans_sids = NULL;
1275 if (check_policy) {
1277 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1278 status = NT_STATUS_INVALID_HANDLE;
1279 goto done;
1282 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1283 return NT_STATUS_INVALID_HANDLE;
1286 /* check if the user has enough rights */
1287 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1288 status = NT_STATUS_ACCESS_DENIED;
1289 goto done;
1293 /* set up the LSA Lookup SIDs response */
1294 become_root(); /* lookup_name can require root privs */
1295 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1296 names, flags, &mapped_count);
1297 unbecome_root();
1299 done:
1301 if (NT_STATUS_IS_OK(status)) {
1302 if (mapped_count == 0) {
1303 status = NT_STATUS_NONE_MAPPED;
1304 } else if (mapped_count != num_entries) {
1305 status = STATUS_SOME_UNMAPPED;
1309 *r->out.count = mapped_count;
1310 *r->out.domains = domains;
1311 r->out.sids->sids = trans_sids;
1312 r->out.sids->count = num_entries;
1314 return status;
1317 /***************************************************************************
1318 _lsa_LookupNames4
1319 ***************************************************************************/
1321 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1322 struct lsa_LookupNames4 *r)
1324 struct lsa_LookupNames3 q;
1326 /* No policy handle on this call. Restrict to crypto connections. */
1327 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1328 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1329 get_remote_machine_name() ));
1330 return NT_STATUS_INVALID_PARAMETER;
1333 q.in.handle = NULL;
1334 q.in.num_names = r->in.num_names;
1335 q.in.names = r->in.names;
1336 q.in.level = r->in.level;
1337 q.in.lookup_options = r->in.lookup_options;
1338 q.in.client_revision = r->in.client_revision;
1339 q.in.sids = r->in.sids;
1340 q.in.count = r->in.count;
1342 q.out.domains = r->out.domains;
1343 q.out.sids = r->out.sids;
1344 q.out.count = r->out.count;
1346 return _lsa_LookupNames3(p, &q);
1349 /***************************************************************************
1350 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1351 ***************************************************************************/
1353 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1355 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1356 return NT_STATUS_INVALID_HANDLE;
1359 close_policy_hnd(p, r->in.handle);
1360 ZERO_STRUCTP(r->out.handle);
1361 return NT_STATUS_OK;
1364 /***************************************************************************
1365 ***************************************************************************/
1367 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p, struct lsa_OpenSecret *r)
1369 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1372 /***************************************************************************
1373 ***************************************************************************/
1375 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1376 struct lsa_OpenTrustedDomain *r)
1378 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1381 /***************************************************************************
1382 ***************************************************************************/
1384 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1385 struct lsa_CreateTrustedDomain *r)
1387 return NT_STATUS_ACCESS_DENIED;
1390 /***************************************************************************
1391 ***************************************************************************/
1393 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p, struct lsa_CreateSecret *r)
1395 return NT_STATUS_ACCESS_DENIED;
1398 /***************************************************************************
1399 ***************************************************************************/
1401 NTSTATUS _lsa_SetSecret(struct pipes_struct *p, struct lsa_SetSecret *r)
1403 return NT_STATUS_ACCESS_DENIED;
1406 /***************************************************************************
1407 _lsa_DeleteObject
1408 ***************************************************************************/
1410 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
1411 struct lsa_DeleteObject *r)
1413 NTSTATUS status;
1414 struct lsa_info *info = NULL;
1416 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
1417 return NT_STATUS_INVALID_HANDLE;
1420 if (!(info->access & SEC_STD_DELETE)) {
1421 return NT_STATUS_ACCESS_DENIED;
1424 switch (info->type) {
1425 case LSA_HANDLE_ACCOUNT_TYPE:
1426 status = privilege_delete_account(&info->sid);
1427 if (!NT_STATUS_IS_OK(status)) {
1428 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
1429 nt_errstr(status)));
1430 return status;
1432 break;
1433 default:
1434 return NT_STATUS_INVALID_HANDLE;
1437 close_policy_hnd(p, r->in.handle);
1438 ZERO_STRUCTP(r->out.handle);
1440 return status;
1443 /***************************************************************************
1444 _lsa_EnumPrivs
1445 ***************************************************************************/
1447 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
1448 struct lsa_EnumPrivs *r)
1450 struct lsa_info *handle;
1451 uint32 i;
1452 uint32 enum_context = *r->in.resume_handle;
1453 int num_privs = num_privileges_in_short_list();
1454 struct lsa_PrivEntry *entries = NULL;
1456 /* remember that the enum_context starts at 0 and not 1 */
1458 if ( enum_context >= num_privs )
1459 return NT_STATUS_NO_MORE_ENTRIES;
1461 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
1462 enum_context, num_privs));
1464 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1465 return NT_STATUS_INVALID_HANDLE;
1467 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1468 return NT_STATUS_INVALID_HANDLE;
1471 /* check if the user has enough rights
1472 I don't know if it's the right one. not documented. */
1474 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1475 return NT_STATUS_ACCESS_DENIED;
1477 if (num_privs) {
1478 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
1479 if (!entries) {
1480 return NT_STATUS_NO_MEMORY;
1482 } else {
1483 entries = NULL;
1486 for (i = 0; i < num_privs; i++) {
1487 if( i < enum_context) {
1489 init_lsa_StringLarge(&entries[i].name, NULL);
1491 entries[i].luid.low = 0;
1492 entries[i].luid.high = 0;
1493 } else {
1495 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
1497 entries[i].luid.low = sec_privilege_from_index(i);
1498 entries[i].luid.high = 0;
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(struct 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(struct pipes_struct *p,
1565 struct lsa_EnumAccounts *r)
1567 struct lsa_info *handle;
1568 struct 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(struct 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 = p->server_info->info3->base.domain.string;
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(struct 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(struct pipes_struct *p,
1758 struct lsa_OpenAccount *r)
1760 struct lsa_info *handle;
1761 struct lsa_info *info;
1762 struct security_descriptor *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(struct pipes_struct *p,
1830 struct lsa_EnumPrivsAccount *r)
1832 NTSTATUS status = NT_STATUS_OK;
1833 struct lsa_info *info=NULL;
1834 uint64_t 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] = privileges.set[i];
1879 priv_set->count = privileges.count;
1880 priv_set->unknown = 0;
1881 priv_set->set = luid_attrs;
1883 } else {
1884 priv_set->count = 0;
1885 priv_set->unknown = 0;
1886 priv_set->set = NULL;
1889 *r->out.privs = priv_set;
1891 done:
1892 privilege_set_free( &privileges );
1894 return status;
1897 /***************************************************************************
1898 _lsa_GetSystemAccessAccount
1899 ***************************************************************************/
1901 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
1902 struct lsa_GetSystemAccessAccount *r)
1904 NTSTATUS status;
1905 struct lsa_info *info = NULL;
1906 struct lsa_EnumPrivsAccount e;
1907 struct lsa_PrivilegeSet *privset;
1909 /* find the connection policy handle. */
1911 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1912 return NT_STATUS_INVALID_HANDLE;
1914 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1915 return NT_STATUS_INVALID_HANDLE;
1918 if (!(info->access & LSA_ACCOUNT_VIEW))
1919 return NT_STATUS_ACCESS_DENIED;
1921 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
1922 if (!privset) {
1923 return NT_STATUS_NO_MEMORY;
1926 e.in.handle = r->in.handle;
1927 e.out.privs = &privset;
1929 status = _lsa_EnumPrivsAccount(p, &e);
1930 if (!NT_STATUS_IS_OK(status)) {
1931 DEBUG(10,("_lsa_GetSystemAccessAccount: "
1932 "failed to call _lsa_EnumPrivsAccount(): %s\n",
1933 nt_errstr(status)));
1934 return status;
1937 /* Samba4 would iterate over the privset to merge the policy mode bits,
1938 * not sure samba3 can do the same here, so just return what we did in
1939 * the past - gd */
1942 0x01 -> Log on locally
1943 0x02 -> Access this computer from network
1944 0x04 -> Log on as a batch job
1945 0x10 -> Log on as a service
1947 they can be ORed together
1950 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
1951 LSA_POLICY_MODE_NETWORK;
1953 return NT_STATUS_OK;
1956 /***************************************************************************
1957 update the systemaccount information
1958 ***************************************************************************/
1960 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
1961 struct lsa_SetSystemAccessAccount *r)
1963 struct lsa_info *info=NULL;
1964 GROUP_MAP map;
1966 /* find the connection policy handle. */
1967 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1968 return NT_STATUS_INVALID_HANDLE;
1970 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1971 return NT_STATUS_INVALID_HANDLE;
1974 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
1975 return NT_STATUS_ACCESS_DENIED;
1978 if (!pdb_getgrsid(&map, info->sid))
1979 return NT_STATUS_NO_SUCH_GROUP;
1981 return pdb_update_group_mapping_entry(&map);
1984 /***************************************************************************
1985 _lsa_AddPrivilegesToAccount
1986 For a given SID, add some privileges.
1987 ***************************************************************************/
1989 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
1990 struct lsa_AddPrivilegesToAccount *r)
1992 struct lsa_info *info = NULL;
1993 uint64_t mask;
1994 struct lsa_PrivilegeSet *set = NULL;
1996 /* find the connection policy handle. */
1997 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1998 return NT_STATUS_INVALID_HANDLE;
2000 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2001 return NT_STATUS_INVALID_HANDLE;
2004 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2005 return NT_STATUS_ACCESS_DENIED;
2008 set = r->in.privs;
2009 if ( !privilege_set_to_se_priv( &mask, set ) )
2010 return NT_STATUS_NO_SUCH_PRIVILEGE;
2012 if ( !grant_privilege( &info->sid, mask ) ) {
2013 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege(%s) failed!\n",
2014 sid_string_dbg(&info->sid) ));
2015 DEBUG(3,("Privilege mask: 0x%llx\n", (unsigned long long)mask));
2016 return NT_STATUS_NO_SUCH_PRIVILEGE;
2019 return NT_STATUS_OK;
2022 /***************************************************************************
2023 _lsa_RemovePrivilegesFromAccount
2024 For a given SID, remove some privileges.
2025 ***************************************************************************/
2027 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2028 struct lsa_RemovePrivilegesFromAccount *r)
2030 struct lsa_info *info = NULL;
2031 uint64_t mask;
2032 struct lsa_PrivilegeSet *set = NULL;
2034 /* find the connection policy handle. */
2035 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2036 return NT_STATUS_INVALID_HANDLE;
2038 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2039 return NT_STATUS_INVALID_HANDLE;
2042 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2043 return NT_STATUS_ACCESS_DENIED;
2046 set = r->in.privs;
2048 if ( !privilege_set_to_se_priv( &mask, set ) )
2049 return NT_STATUS_NO_SUCH_PRIVILEGE;
2051 if ( !revoke_privilege( &info->sid, mask ) ) {
2052 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2053 sid_string_dbg(&info->sid) ));
2054 DEBUG(3,("Privilege mask: 0x%llx\n", (unsigned long long)mask));
2055 return NT_STATUS_NO_SUCH_PRIVILEGE;
2058 return NT_STATUS_OK;
2061 /***************************************************************************
2062 _lsa_LookupPrivName
2063 ***************************************************************************/
2065 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2066 struct lsa_LookupPrivName *r)
2068 struct lsa_info *info = NULL;
2069 const char *name;
2070 struct lsa_StringLarge *lsa_name;
2072 /* find the connection policy handle. */
2073 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2074 return NT_STATUS_INVALID_HANDLE;
2077 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2078 return NT_STATUS_INVALID_HANDLE;
2081 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2082 return NT_STATUS_ACCESS_DENIED;
2085 if (r->in.luid->high != 0) {
2086 return NT_STATUS_NO_SUCH_PRIVILEGE;
2089 name = sec_privilege_name(r->in.luid->low);
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(struct pipes_struct *p,
2115 struct lsa_QuerySecurity *r)
2117 struct lsa_info *handle=NULL;
2118 struct security_descriptor *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(struct 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 struct security_descriptor *psd = NULL;
2164 size_t sd_size;
2165 struct 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(struct pipes_struct *p,
2228 struct lsa_RemoveAccountRights *r)
2230 struct lsa_info *info = NULL;
2231 int i = 0;
2232 struct security_descriptor *psd = NULL;
2233 size_t sd_size;
2234 struct 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|SEC_STD_DELETE,
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++) {
2311 if (privileges->set[i].luid.high) {
2312 continue;
2314 privname = sec_privilege_name(privileges->set[i].luid.low);
2315 if (privname) {
2316 if (!add_string_to_array(mem_ctx, privname,
2317 &privname_array, &num_priv)) {
2318 return NT_STATUS_NO_MEMORY;
2323 if (num_priv) {
2325 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
2326 num_priv);
2327 if (!r->names) {
2328 return NT_STATUS_NO_MEMORY;
2331 for (i=0; i<num_priv; i++) {
2332 init_lsa_StringLarge(&r->names[i], privname_array[i]);
2335 r->count = num_priv;
2338 return NT_STATUS_OK;
2341 /***************************************************************************
2342 _lsa_EnumAccountRights
2343 ***************************************************************************/
2345 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
2346 struct lsa_EnumAccountRights *r)
2348 NTSTATUS status;
2349 struct lsa_info *info = NULL;
2350 struct dom_sid sid;
2351 PRIVILEGE_SET privileges;
2352 uint64_t mask;
2354 /* find the connection policy handle. */
2356 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2357 return NT_STATUS_INVALID_HANDLE;
2359 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2360 return NT_STATUS_INVALID_HANDLE;
2363 if (!(info->access & LSA_ACCOUNT_VIEW)) {
2364 return NT_STATUS_ACCESS_DENIED;
2367 /* according to an NT4 PDC, you can add privileges to SIDs even without
2368 call_lsa_create_account() first. And you can use any arbitrary SID. */
2370 sid_copy( &sid, r->in.sid );
2372 /* according to MS-LSAD 3.1.4.5.10 it is required to return
2373 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
2374 * the lsa database */
2376 if (!get_privileges_for_sids(&mask, &sid, 1)) {
2377 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2380 status = privilege_set_init(&privileges);
2381 if (!NT_STATUS_IS_OK(status)) {
2382 return status;
2385 se_priv_to_privilege_set(&privileges, mask);
2387 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
2388 sid_string_dbg(&sid), privileges.count));
2390 status = init_lsa_right_set(p->mem_ctx, r->out.rights, &privileges);
2392 privilege_set_free( &privileges );
2394 return status;
2397 /***************************************************************************
2398 _lsa_LookupPrivValue
2399 ***************************************************************************/
2401 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
2402 struct lsa_LookupPrivValue *r)
2404 struct lsa_info *info = NULL;
2405 const char *name = NULL;
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 r->out.luid->low = sec_privilege_id(name);
2424 r->out.luid->high = 0;
2425 if (r->out.luid->low == -1) {
2426 return NT_STATUS_NO_SUCH_PRIVILEGE;
2428 return NT_STATUS_OK;
2431 /***************************************************************************
2432 _lsa_EnumAccountsWithUserRight
2433 ***************************************************************************/
2435 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
2436 struct lsa_EnumAccountsWithUserRight *r)
2438 NTSTATUS status;
2439 struct lsa_info *info = NULL;
2440 struct dom_sid *sids = NULL;
2441 int num_sids = 0;
2442 uint32_t i;
2443 uint64_t mask;
2445 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2446 return NT_STATUS_INVALID_HANDLE;
2449 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2450 return NT_STATUS_INVALID_HANDLE;
2453 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
2454 return NT_STATUS_ACCESS_DENIED;
2457 if (!r->in.name || !r->in.name->string) {
2458 return NT_STATUS_NO_SUCH_PRIVILEGE;
2461 if (!se_priv_from_name(r->in.name->string, &mask)) {
2462 return NT_STATUS_NO_SUCH_PRIVILEGE;
2465 status = privilege_enum_sids(&mask, p->mem_ctx,
2466 &sids, &num_sids);
2467 if (!NT_STATUS_IS_OK(status)) {
2468 return status;
2471 r->out.sids->num_sids = num_sids;
2472 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
2473 r->out.sids->num_sids);
2475 for (i=0; i < r->out.sids->num_sids; i++) {
2476 r->out.sids->sids[i].sid = sid_dup_talloc(r->out.sids->sids,
2477 &sids[i]);
2478 if (!r->out.sids->sids[i].sid) {
2479 TALLOC_FREE(r->out.sids->sids);
2480 r->out.sids->num_sids = 0;
2481 return NT_STATUS_NO_MEMORY;
2485 return NT_STATUS_OK;
2488 /***************************************************************************
2489 _lsa_Delete
2490 ***************************************************************************/
2492 NTSTATUS _lsa_Delete(struct pipes_struct *p,
2493 struct lsa_Delete *r)
2495 return NT_STATUS_NOT_SUPPORTED;
2499 * From here on the server routines are just dummy ones to make smbd link with
2500 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
2501 * pulling the server stubs across one by one.
2504 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
2506 p->rng_fault_state = True;
2507 return NT_STATUS_NOT_IMPLEMENTED;
2510 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
2511 struct lsa_ChangePassword *r)
2513 p->rng_fault_state = True;
2514 return NT_STATUS_NOT_IMPLEMENTED;
2517 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
2519 p->rng_fault_state = True;
2520 return NT_STATUS_NOT_IMPLEMENTED;
2523 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
2525 p->rng_fault_state = True;
2526 return NT_STATUS_NOT_IMPLEMENTED;
2529 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
2530 struct lsa_GetQuotasForAccount *r)
2532 p->rng_fault_state = True;
2533 return NT_STATUS_NOT_IMPLEMENTED;
2536 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
2537 struct lsa_SetQuotasForAccount *r)
2539 p->rng_fault_state = True;
2540 return NT_STATUS_NOT_IMPLEMENTED;
2543 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
2544 struct lsa_QueryTrustedDomainInfo *r)
2546 p->rng_fault_state = True;
2547 return NT_STATUS_NOT_IMPLEMENTED;
2550 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
2551 struct lsa_SetInformationTrustedDomain *r)
2553 p->rng_fault_state = True;
2554 return NT_STATUS_NOT_IMPLEMENTED;
2557 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
2559 p->rng_fault_state = True;
2560 return NT_STATUS_NOT_IMPLEMENTED;
2563 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2564 struct lsa_QueryTrustedDomainInfoBySid *r)
2566 p->rng_fault_state = True;
2567 return NT_STATUS_NOT_IMPLEMENTED;
2570 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
2571 struct lsa_SetTrustedDomainInfo *r)
2573 p->rng_fault_state = True;
2574 return NT_STATUS_NOT_IMPLEMENTED;
2577 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
2578 struct lsa_DeleteTrustedDomain *r)
2580 p->rng_fault_state = True;
2581 return NT_STATUS_NOT_IMPLEMENTED;
2584 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
2585 struct lsa_StorePrivateData *r)
2587 p->rng_fault_state = True;
2588 return NT_STATUS_NOT_IMPLEMENTED;
2591 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
2592 struct lsa_RetrievePrivateData *r)
2594 p->rng_fault_state = True;
2595 return NT_STATUS_NOT_IMPLEMENTED;
2598 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
2599 struct lsa_SetInfoPolicy2 *r)
2601 p->rng_fault_state = True;
2602 return NT_STATUS_NOT_IMPLEMENTED;
2605 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2606 struct lsa_QueryTrustedDomainInfoByName *r)
2608 p->rng_fault_state = True;
2609 return NT_STATUS_NOT_IMPLEMENTED;
2612 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
2613 struct lsa_SetTrustedDomainInfoByName *r)
2615 p->rng_fault_state = True;
2616 return NT_STATUS_NOT_IMPLEMENTED;
2619 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
2620 struct lsa_EnumTrustedDomainsEx *r)
2622 p->rng_fault_state = True;
2623 return NT_STATUS_NOT_IMPLEMENTED;
2626 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
2627 struct lsa_CreateTrustedDomainEx *r)
2629 p->rng_fault_state = True;
2630 return NT_STATUS_NOT_IMPLEMENTED;
2633 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
2634 struct lsa_CloseTrustedDomainEx *r)
2636 p->rng_fault_state = True;
2637 return NT_STATUS_NOT_IMPLEMENTED;
2640 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
2641 struct lsa_QueryDomainInformationPolicy *r)
2643 p->rng_fault_state = True;
2644 return NT_STATUS_NOT_IMPLEMENTED;
2647 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
2648 struct lsa_SetDomainInformationPolicy *r)
2650 p->rng_fault_state = True;
2651 return NT_STATUS_NOT_IMPLEMENTED;
2654 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
2655 struct lsa_OpenTrustedDomainByName *r)
2657 p->rng_fault_state = True;
2658 return NT_STATUS_NOT_IMPLEMENTED;
2661 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
2663 p->rng_fault_state = True;
2664 return NT_STATUS_NOT_IMPLEMENTED;
2667 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
2668 struct lsa_CreateTrustedDomainEx2 *r)
2670 p->rng_fault_state = True;
2671 return NT_STATUS_NOT_IMPLEMENTED;
2674 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
2676 p->rng_fault_state = True;
2677 return NT_STATUS_NOT_IMPLEMENTED;
2680 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
2682 p->rng_fault_state = True;
2683 return NT_STATUS_NOT_IMPLEMENTED;
2686 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
2688 p->rng_fault_state = True;
2689 return NT_STATUS_NOT_IMPLEMENTED;
2692 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
2693 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2695 p->rng_fault_state = True;
2696 return NT_STATUS_NOT_IMPLEMENTED;
2699 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
2700 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2702 p->rng_fault_state = True;
2703 return NT_STATUS_NOT_IMPLEMENTED;
2706 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
2708 p->rng_fault_state = True;
2709 return NT_STATUS_NOT_IMPLEMENTED;
2712 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
2713 struct lsa_CREDRGETTARGETINFO *r)
2715 p->rng_fault_state = True;
2716 return NT_STATUS_NOT_IMPLEMENTED;
2719 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
2720 struct lsa_CREDRPROFILELOADED *r)
2722 p->rng_fault_state = True;
2723 return NT_STATUS_NOT_IMPLEMENTED;
2726 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
2727 struct lsa_CREDRGETSESSIONTYPES *r)
2729 p->rng_fault_state = True;
2730 return NT_STATUS_NOT_IMPLEMENTED;
2733 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
2734 struct lsa_LSARREGISTERAUDITEVENT *r)
2736 p->rng_fault_state = True;
2737 return NT_STATUS_NOT_IMPLEMENTED;
2740 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
2741 struct lsa_LSARGENAUDITEVENT *r)
2743 p->rng_fault_state = True;
2744 return NT_STATUS_NOT_IMPLEMENTED;
2747 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
2748 struct lsa_LSARUNREGISTERAUDITEVENT *r)
2750 p->rng_fault_state = True;
2751 return NT_STATUS_NOT_IMPLEMENTED;
2754 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
2755 struct lsa_lsaRQueryForestTrustInformation *r)
2757 p->rng_fault_state = True;
2758 return NT_STATUS_NOT_IMPLEMENTED;
2761 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
2762 struct lsa_lsaRSetForestTrustInformation *r)
2764 p->rng_fault_state = True;
2765 return NT_STATUS_NOT_IMPLEMENTED;
2768 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
2769 struct lsa_CREDRRENAME *r)
2771 p->rng_fault_state = True;
2772 return NT_STATUS_NOT_IMPLEMENTED;
2775 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
2776 struct lsa_LSAROPENPOLICYSCE *r)
2778 p->rng_fault_state = True;
2779 return NT_STATUS_NOT_IMPLEMENTED;
2782 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
2783 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2785 p->rng_fault_state = True;
2786 return NT_STATUS_NOT_IMPLEMENTED;
2789 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
2790 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2792 p->rng_fault_state = True;
2793 return NT_STATUS_NOT_IMPLEMENTED;
2796 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
2797 struct lsa_LSARADTREPORTSECURITYEVENT *r)
2799 p->rng_fault_state = True;
2800 return NT_STATUS_NOT_IMPLEMENTED;