lib/util: usec_time_diff takes arguments the other way round than TvalDiff did
[Samba.git] / source3 / rpc_server / srv_lsa_nt.c
blob49bdca7b7f59d3351bb98b4080672d10b59fba56
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.
14 * Copyright (C) Andrew Bartlett 2010.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
30 /* This is the implementation of the lsa server code. */
32 #include "includes.h"
33 #include "../librpc/gen_ndr/srv_lsa.h"
34 #include "secrets.h"
35 #include "../librpc/gen_ndr/netlogon.h"
36 #include "rpc_client/init_lsa.h"
38 #undef DBGC_CLASS
39 #define DBGC_CLASS DBGC_RPC_SRV
41 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
43 enum lsa_handle_type { LSA_HANDLE_POLICY_TYPE = 1, LSA_HANDLE_ACCOUNT_TYPE };
45 struct lsa_info {
46 struct dom_sid sid;
47 const char *name;
48 uint32 access;
49 enum lsa_handle_type type;
50 struct security_descriptor *sd;
53 const struct generic_mapping lsa_account_mapping = {
54 LSA_ACCOUNT_READ,
55 LSA_ACCOUNT_WRITE,
56 LSA_ACCOUNT_EXECUTE,
57 LSA_ACCOUNT_ALL_ACCESS
60 const struct generic_mapping lsa_policy_mapping = {
61 LSA_POLICY_READ,
62 LSA_POLICY_WRITE,
63 LSA_POLICY_EXECUTE,
64 LSA_POLICY_ALL_ACCESS
67 const struct generic_mapping lsa_secret_mapping = {
68 LSA_SECRET_READ,
69 LSA_SECRET_WRITE,
70 LSA_SECRET_EXECUTE,
71 LSA_SECRET_ALL_ACCESS
74 const struct generic_mapping lsa_trusted_domain_mapping = {
75 LSA_TRUSTED_DOMAIN_READ,
76 LSA_TRUSTED_DOMAIN_WRITE,
77 LSA_TRUSTED_DOMAIN_EXECUTE,
78 LSA_TRUSTED_DOMAIN_ALL_ACCESS
81 /***************************************************************************
82 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
83 ***************************************************************************/
85 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
86 struct lsa_RefDomainList *ref,
87 const char *dom_name,
88 struct dom_sid *dom_sid)
90 int num = 0;
92 if (dom_name != NULL) {
93 for (num = 0; num < ref->count; num++) {
94 if (sid_equal(dom_sid, ref->domains[num].sid)) {
95 return num;
98 } else {
99 num = ref->count;
102 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
103 /* index not found, already at maximum domain limit */
104 return -1;
107 ref->count = num + 1;
108 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
110 ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains,
111 struct lsa_DomainInfo, ref->count);
112 if (!ref->domains) {
113 return -1;
116 ZERO_STRUCT(ref->domains[num]);
118 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
119 ref->domains[num].sid = sid_dup_talloc(mem_ctx, dom_sid);
120 if (!ref->domains[num].sid) {
121 return -1;
124 return num;
128 /***************************************************************************
129 initialize a lsa_DomainInfo structure.
130 ***************************************************************************/
132 static void init_dom_query_3(struct lsa_DomainInfo *r,
133 const char *name,
134 struct dom_sid *sid)
136 init_lsa_StringLarge(&r->name, name);
137 r->sid = sid;
140 /***************************************************************************
141 initialize a lsa_DomainInfo structure.
142 ***************************************************************************/
144 static void init_dom_query_5(struct lsa_DomainInfo *r,
145 const char *name,
146 struct dom_sid *sid)
148 init_lsa_StringLarge(&r->name, name);
149 r->sid = sid;
152 /***************************************************************************
153 lookup_lsa_rids. Must be called as root for lookup_name to work.
154 ***************************************************************************/
156 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
157 struct lsa_RefDomainList *ref,
158 struct lsa_TranslatedSid *prid,
159 uint32_t num_entries,
160 struct lsa_String *name,
161 int flags,
162 uint32_t *pmapped_count)
164 uint32 mapped_count, i;
166 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
168 mapped_count = 0;
169 *pmapped_count = 0;
171 for (i = 0; i < num_entries; i++) {
172 struct dom_sid sid;
173 uint32 rid;
174 int dom_idx;
175 const char *full_name;
176 const char *domain;
177 enum lsa_SidType type = SID_NAME_UNKNOWN;
179 /* Split name into domain and user component */
181 /* follow w2k8 behavior and return the builtin domain when no
182 * input has been passed in */
184 if (name[i].string) {
185 full_name = name[i].string;
186 } else {
187 full_name = "BUILTIN";
190 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
192 /* We can ignore the result of lookup_name, it will not touch
193 "type" if it's not successful */
195 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
196 &sid, &type);
198 switch (type) {
199 case SID_NAME_USER:
200 case SID_NAME_DOM_GRP:
201 case SID_NAME_DOMAIN:
202 case SID_NAME_ALIAS:
203 case SID_NAME_WKN_GRP:
204 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
205 /* Leave these unchanged */
206 break;
207 default:
208 /* Don't hand out anything but the list above */
209 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
210 type = SID_NAME_UNKNOWN;
211 break;
214 rid = 0;
215 dom_idx = -1;
217 if (type != SID_NAME_UNKNOWN) {
218 if (type == SID_NAME_DOMAIN) {
219 rid = (uint32_t)-1;
220 } else {
221 sid_split_rid(&sid, &rid);
223 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
224 mapped_count++;
227 prid[i].sid_type = type;
228 prid[i].rid = rid;
229 prid[i].sid_index = dom_idx;
232 *pmapped_count = mapped_count;
233 return NT_STATUS_OK;
236 /***************************************************************************
237 lookup_lsa_sids. Must be called as root for lookup_name to work.
238 ***************************************************************************/
240 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
241 struct lsa_RefDomainList *ref,
242 struct lsa_TranslatedSid3 *trans_sids,
243 uint32_t num_entries,
244 struct lsa_String *name,
245 int flags,
246 uint32 *pmapped_count)
248 uint32 mapped_count, i;
250 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
252 mapped_count = 0;
253 *pmapped_count = 0;
255 for (i = 0; i < num_entries; i++) {
256 struct dom_sid sid;
257 uint32 rid;
258 int dom_idx;
259 const char *full_name;
260 const char *domain;
261 enum lsa_SidType type = SID_NAME_UNKNOWN;
263 ZERO_STRUCT(sid);
265 /* Split name into domain and user component */
267 full_name = name[i].string;
268 if (full_name == NULL) {
269 return NT_STATUS_NO_MEMORY;
272 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
274 /* We can ignore the result of lookup_name, it will not touch
275 "type" if it's not successful */
277 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
278 &sid, &type);
280 switch (type) {
281 case SID_NAME_USER:
282 case SID_NAME_DOM_GRP:
283 case SID_NAME_DOMAIN:
284 case SID_NAME_ALIAS:
285 case SID_NAME_WKN_GRP:
286 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
287 /* Leave these unchanged */
288 break;
289 default:
290 /* Don't hand out anything but the list above */
291 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
292 type = SID_NAME_UNKNOWN;
293 break;
296 rid = 0;
297 dom_idx = -1;
299 if (type != SID_NAME_UNKNOWN) {
300 struct dom_sid domain_sid;
301 sid_copy(&domain_sid, &sid);
302 sid_split_rid(&domain_sid, &rid);
303 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
304 mapped_count++;
307 /* Initialize the lsa_TranslatedSid3 return. */
308 trans_sids[i].sid_type = type;
309 trans_sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
310 trans_sids[i].sid_index = dom_idx;
313 *pmapped_count = mapped_count;
314 return NT_STATUS_OK;
317 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
318 const struct generic_mapping *map,
319 struct dom_sid *sid, uint32_t sid_access)
321 struct dom_sid adm_sid;
322 struct security_ace ace[5];
323 size_t i = 0;
325 struct security_acl *psa = NULL;
327 /* READ|EXECUTE access for Everyone */
329 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
330 map->generic_execute | map->generic_read, 0);
332 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
334 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
335 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
336 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
337 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
339 /* Add Full Access for Domain Admins */
340 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
341 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
342 map->generic_all, 0);
344 /* If we have a sid, give it some special access */
346 if (sid) {
347 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
348 sid_access, 0);
351 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
352 return NT_STATUS_NO_MEMORY;
354 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
355 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
356 psa, sd_size)) == NULL)
357 return NT_STATUS_NO_MEMORY;
359 return NT_STATUS_OK;
363 /***************************************************************************
364 _lsa_OpenPolicy2
365 ***************************************************************************/
367 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
368 struct lsa_OpenPolicy2 *r)
370 struct lsa_info *info;
371 struct security_descriptor *psd = NULL;
372 size_t sd_size;
373 uint32 des_access = r->in.access_mask;
374 uint32 acc_granted;
375 NTSTATUS status;
377 /* Work out max allowed. */
378 map_max_allowed_access(p->server_info->ptok,
379 &p->server_info->utok,
380 &des_access);
382 /* map the generic bits to the lsa policy ones */
383 se_map_generic(&des_access, &lsa_policy_mapping);
385 /* get the generic lsa policy SD until we store it */
386 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
387 NULL, 0);
388 if (!NT_STATUS_IS_OK(status)) {
389 return status;
392 status = access_check_object(psd, p->server_info->ptok,
393 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
394 &acc_granted, "_lsa_OpenPolicy2" );
395 if (!NT_STATUS_IS_OK(status)) {
396 return status;
399 /* associate the domain SID with the (unique) handle. */
400 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
401 if (info == NULL) {
402 return NT_STATUS_NO_MEMORY;
405 sid_copy(&info->sid,get_global_sam_sid());
406 info->access = acc_granted;
407 info->type = LSA_HANDLE_POLICY_TYPE;
409 /* set up the LSA QUERY INFO response */
410 if (!create_policy_hnd(p, r->out.handle, info))
411 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
413 return NT_STATUS_OK;
416 /***************************************************************************
417 _lsa_OpenPolicy
418 ***************************************************************************/
420 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
421 struct lsa_OpenPolicy *r)
423 struct lsa_OpenPolicy2 o;
425 o.in.system_name = NULL; /* should be ignored */
426 o.in.attr = r->in.attr;
427 o.in.access_mask = r->in.access_mask;
429 o.out.handle = r->out.handle;
431 return _lsa_OpenPolicy2(p, &o);
434 /***************************************************************************
435 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
436 ufff, done :) mimir
437 ***************************************************************************/
439 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
440 struct lsa_EnumTrustDom *r)
442 struct lsa_info *info;
443 uint32_t count;
444 struct trustdom_info **domains;
445 struct lsa_DomainInfo *entries;
446 int i;
447 NTSTATUS nt_status;
449 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
450 return NT_STATUS_INVALID_HANDLE;
452 if (info->type != LSA_HANDLE_POLICY_TYPE) {
453 return NT_STATUS_INVALID_HANDLE;
456 /* check if the user has enough rights */
457 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
458 return NT_STATUS_ACCESS_DENIED;
460 become_root();
461 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
462 unbecome_root();
464 if (!NT_STATUS_IS_OK(nt_status)) {
465 return nt_status;
468 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo, count);
469 if (!entries) {
470 return NT_STATUS_NO_MEMORY;
473 for (i=0; i<count; i++) {
474 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
475 entries[i].sid = &domains[i]->sid;
478 if (*r->in.resume_handle >= count) {
479 *r->out.resume_handle = -1;
480 TALLOC_FREE(entries);
481 return NT_STATUS_NO_MORE_ENTRIES;
484 /* return the rest, limit by max_size. Note that we
485 use the w2k3 element size value of 60 */
486 r->out.domains->count = count - *r->in.resume_handle;
487 r->out.domains->count = MIN(r->out.domains->count,
488 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
490 r->out.domains->domains = entries + *r->in.resume_handle;
492 if (r->out.domains->count < count - *r->in.resume_handle) {
493 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
494 return STATUS_MORE_ENTRIES;
497 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
498 * always be larger than the previous input resume handle, in
499 * particular when hitting the last query it is vital to set the
500 * resume handle correctly to avoid infinite client loops, as
501 * seen e.g. with Windows XP SP3 when resume handle is 0 and
502 * status is NT_STATUS_OK - gd */
504 *r->out.resume_handle = (uint32_t)-1;
506 return NT_STATUS_OK;
509 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
510 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
511 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
513 /***************************************************************************
514 _lsa_QueryInfoPolicy
515 ***************************************************************************/
517 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
518 struct lsa_QueryInfoPolicy *r)
520 NTSTATUS status = NT_STATUS_OK;
521 struct lsa_info *handle;
522 struct dom_sid domain_sid;
523 const char *name;
524 struct dom_sid *sid = NULL;
525 union lsa_PolicyInformation *info = NULL;
526 uint32_t acc_required = 0;
528 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
529 return NT_STATUS_INVALID_HANDLE;
531 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
532 return NT_STATUS_INVALID_HANDLE;
535 switch (r->in.level) {
536 case LSA_POLICY_INFO_AUDIT_LOG:
537 case LSA_POLICY_INFO_AUDIT_EVENTS:
538 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
539 break;
540 case LSA_POLICY_INFO_DOMAIN:
541 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
542 break;
543 case LSA_POLICY_INFO_PD:
544 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
545 break;
546 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
547 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
548 break;
549 case LSA_POLICY_INFO_ROLE:
550 case LSA_POLICY_INFO_REPLICA:
551 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
552 break;
553 case LSA_POLICY_INFO_QUOTA:
554 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
555 break;
556 case LSA_POLICY_INFO_MOD:
557 case LSA_POLICY_INFO_AUDIT_FULL_SET:
558 /* according to MS-LSAD 3.1.4.4.3 */
559 return NT_STATUS_INVALID_PARAMETER;
560 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
561 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
562 break;
563 case LSA_POLICY_INFO_DNS:
564 case LSA_POLICY_INFO_DNS_INT:
565 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
566 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
567 break;
568 default:
569 break;
572 if (!(handle->access & acc_required)) {
573 /* return NT_STATUS_ACCESS_DENIED; */
576 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
577 if (!info) {
578 return NT_STATUS_NO_MEMORY;
581 switch (r->in.level) {
582 /* according to MS-LSAD 3.1.4.4.3 */
583 case LSA_POLICY_INFO_MOD:
584 case LSA_POLICY_INFO_AUDIT_FULL_SET:
585 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
586 return NT_STATUS_INVALID_PARAMETER;
587 case LSA_POLICY_INFO_AUDIT_LOG:
588 info->audit_log.percent_full = 0;
589 info->audit_log.maximum_log_size = 0;
590 info->audit_log.retention_time = 0;
591 info->audit_log.shutdown_in_progress = 0;
592 info->audit_log.time_to_shutdown = 0;
593 info->audit_log.next_audit_record = 0;
594 status = NT_STATUS_OK;
595 break;
596 case LSA_POLICY_INFO_PD:
597 info->pd.name.string = NULL;
598 status = NT_STATUS_OK;
599 break;
600 case LSA_POLICY_INFO_REPLICA:
601 info->replica.source.string = NULL;
602 info->replica.account.string = NULL;
603 status = NT_STATUS_OK;
604 break;
605 case LSA_POLICY_INFO_QUOTA:
606 info->quota.paged_pool = 0;
607 info->quota.non_paged_pool = 0;
608 info->quota.min_wss = 0;
609 info->quota.max_wss = 0;
610 info->quota.pagefile = 0;
611 info->quota.unknown = 0;
612 status = NT_STATUS_OK;
613 break;
614 case LSA_POLICY_INFO_AUDIT_EVENTS:
617 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
619 /* check if the user has enough rights */
620 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
621 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
622 return NT_STATUS_ACCESS_DENIED;
625 /* fake info: We audit everything. ;) */
627 info->audit_events.auditing_mode = true;
628 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
629 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
630 enum lsa_PolicyAuditPolicy,
631 info->audit_events.count);
632 if (!info->audit_events.settings) {
633 return NT_STATUS_NO_MEMORY;
636 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
637 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
638 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
639 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
640 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
641 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
642 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
644 break;
646 case LSA_POLICY_INFO_DOMAIN:
647 /* check if the user has enough rights */
648 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
649 return NT_STATUS_ACCESS_DENIED;
651 /* Request PolicyPrimaryDomainInformation. */
652 switch (lp_server_role()) {
653 case ROLE_DOMAIN_PDC:
654 case ROLE_DOMAIN_BDC:
655 name = get_global_sam_name();
656 sid = sid_dup_talloc(p->mem_ctx, get_global_sam_sid());
657 if (!sid) {
658 return NT_STATUS_NO_MEMORY;
660 break;
661 case ROLE_DOMAIN_MEMBER:
662 name = lp_workgroup();
663 /* We need to return the Domain SID here. */
664 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
665 sid = sid_dup_talloc(p->mem_ctx, &domain_sid);
666 if (!sid) {
667 return NT_STATUS_NO_MEMORY;
669 } else {
670 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
672 break;
673 case ROLE_STANDALONE:
674 name = lp_workgroup();
675 sid = NULL;
676 break;
677 default:
678 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
680 init_dom_query_3(&info->domain, name, sid);
681 break;
682 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
683 /* check if the user has enough rights */
684 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
685 return NT_STATUS_ACCESS_DENIED;
687 /* Request PolicyAccountDomainInformation. */
688 name = get_global_sam_name();
689 sid = get_global_sam_sid();
691 init_dom_query_5(&info->account_domain, name, sid);
692 break;
693 case LSA_POLICY_INFO_ROLE:
694 /* check if the user has enough rights */
695 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
696 return NT_STATUS_ACCESS_DENIED;
698 switch (lp_server_role()) {
699 case ROLE_DOMAIN_BDC:
701 * only a BDC is a backup controller
702 * of the domain, it controls.
704 info->role.role = LSA_ROLE_BACKUP;
705 break;
706 default:
708 * any other role is a primary
709 * of the domain, it controls.
711 info->role.role = LSA_ROLE_PRIMARY;
712 break;
714 break;
715 case LSA_POLICY_INFO_DNS:
716 case LSA_POLICY_INFO_DNS_INT: {
717 struct pdb_domain_info *dominfo;
719 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
720 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
721 "without ADS passdb backend\n"));
722 status = NT_STATUS_INVALID_INFO_CLASS;
723 break;
726 dominfo = pdb_get_domain_info(info);
727 if (dominfo == NULL) {
728 status = NT_STATUS_NO_MEMORY;
729 break;
732 init_lsa_StringLarge(&info->dns.name,
733 dominfo->name);
734 init_lsa_StringLarge(&info->dns.dns_domain,
735 dominfo->dns_domain);
736 init_lsa_StringLarge(&info->dns.dns_forest,
737 dominfo->dns_forest);
738 info->dns.domain_guid = dominfo->guid;
739 info->dns.sid = &dominfo->sid;
740 break;
742 default:
743 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
744 r->in.level));
745 status = NT_STATUS_INVALID_INFO_CLASS;
746 break;
749 *r->out.info = info;
751 return status;
754 /***************************************************************************
755 _lsa_QueryInfoPolicy2
756 ***************************************************************************/
758 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
759 struct lsa_QueryInfoPolicy2 *r2)
761 struct lsa_QueryInfoPolicy r;
763 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
764 p->rng_fault_state = True;
765 return NT_STATUS_NOT_IMPLEMENTED;
768 ZERO_STRUCT(r);
769 r.in.handle = r2->in.handle;
770 r.in.level = r2->in.level;
771 r.out.info = r2->out.info;
773 return _lsa_QueryInfoPolicy(p, &r);
776 /***************************************************************************
777 _lsa_lookup_sids_internal
778 ***************************************************************************/
780 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
781 TALLOC_CTX *mem_ctx,
782 uint16_t level, /* input */
783 int num_sids, /* input */
784 struct lsa_SidPtr *sid, /* input */
785 struct lsa_RefDomainList **pp_ref, /* input/output */
786 struct lsa_TranslatedName2 **pp_names,/* input/output */
787 uint32_t *pp_mapped_count) /* input/output */
789 NTSTATUS status;
790 int i;
791 const struct dom_sid **sids = NULL;
792 struct lsa_RefDomainList *ref = NULL;
793 uint32 mapped_count = 0;
794 struct lsa_dom_info *dom_infos = NULL;
795 struct lsa_name_info *name_infos = NULL;
796 struct lsa_TranslatedName2 *names = NULL;
798 *pp_mapped_count = 0;
799 *pp_names = NULL;
800 *pp_ref = NULL;
802 if (num_sids == 0) {
803 return NT_STATUS_OK;
806 sids = TALLOC_ARRAY(p->mem_ctx, const struct dom_sid *, num_sids);
807 ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
809 if (sids == NULL || ref == NULL) {
810 return NT_STATUS_NO_MEMORY;
813 for (i=0; i<num_sids; i++) {
814 sids[i] = sid[i].sid;
817 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
818 &dom_infos, &name_infos);
820 if (!NT_STATUS_IS_OK(status)) {
821 return status;
824 names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
825 if (names == NULL) {
826 return NT_STATUS_NO_MEMORY;
829 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
831 if (!dom_infos[i].valid) {
832 break;
835 if (init_lsa_ref_domain_list(mem_ctx, ref,
836 dom_infos[i].name,
837 &dom_infos[i].sid) != i) {
838 DEBUG(0, ("Domain %s mentioned twice??\n",
839 dom_infos[i].name));
840 return NT_STATUS_INTERNAL_ERROR;
844 for (i=0; i<num_sids; i++) {
845 struct lsa_name_info *name = &name_infos[i];
847 if (name->type == SID_NAME_UNKNOWN) {
848 fstring tmp;
849 name->dom_idx = -1;
850 /* Unknown sids should return the string
851 * representation of the SID. Windows 2003 behaves
852 * rather erratic here, in many cases it returns the
853 * RID as 8 bytes hex, in others it returns the full
854 * SID. We (Jerry/VL) could not figure out which the
855 * hard cases are, so leave it with the SID. */
856 name->name = talloc_asprintf(p->mem_ctx, "%s",
857 sid_to_fstring(tmp,
858 sids[i]));
859 if (name->name == NULL) {
860 return NT_STATUS_NO_MEMORY;
862 } else {
863 mapped_count += 1;
866 names[i].sid_type = name->type;
867 names[i].name.string = name->name;
868 names[i].sid_index = name->dom_idx;
869 names[i].unknown = 0;
872 status = NT_STATUS_NONE_MAPPED;
873 if (mapped_count > 0) {
874 status = (mapped_count < num_sids) ?
875 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
878 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
879 num_sids, mapped_count, nt_errstr(status)));
881 *pp_mapped_count = mapped_count;
882 *pp_names = names;
883 *pp_ref = ref;
885 return status;
888 /***************************************************************************
889 _lsa_LookupSids
890 ***************************************************************************/
892 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
893 struct lsa_LookupSids *r)
895 NTSTATUS status;
896 struct lsa_info *handle;
897 int num_sids = r->in.sids->num_sids;
898 uint32 mapped_count = 0;
899 struct lsa_RefDomainList *domains = NULL;
900 struct lsa_TranslatedName *names_out = NULL;
901 struct lsa_TranslatedName2 *names = NULL;
902 int i;
904 if ((r->in.level < 1) || (r->in.level > 6)) {
905 return NT_STATUS_INVALID_PARAMETER;
908 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
909 return NT_STATUS_INVALID_HANDLE;
912 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
913 return NT_STATUS_INVALID_HANDLE;
916 /* check if the user has enough rights */
917 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
918 return NT_STATUS_ACCESS_DENIED;
921 if (num_sids > MAX_LOOKUP_SIDS) {
922 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
923 MAX_LOOKUP_SIDS, num_sids));
924 return NT_STATUS_NONE_MAPPED;
927 status = _lsa_lookup_sids_internal(p,
928 p->mem_ctx,
929 r->in.level,
930 num_sids,
931 r->in.sids->sids,
932 &domains,
933 &names,
934 &mapped_count);
936 /* Only return here when there is a real error.
937 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
938 the requested sids could be resolved. Older versions of XP (pre SP3)
939 rely that we return with the string representations of those SIDs in
940 that case. If we don't, XP crashes - Guenther
943 if (NT_STATUS_IS_ERR(status) &&
944 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
945 return status;
948 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
949 names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
950 num_sids);
951 if (!names_out) {
952 return NT_STATUS_NO_MEMORY;
955 for (i=0; i<num_sids; i++) {
956 names_out[i].sid_type = names[i].sid_type;
957 names_out[i].name = names[i].name;
958 names_out[i].sid_index = names[i].sid_index;
961 *r->out.domains = domains;
962 r->out.names->count = num_sids;
963 r->out.names->names = names_out;
964 *r->out.count = mapped_count;
966 return status;
969 /***************************************************************************
970 _lsa_LookupSids2
971 ***************************************************************************/
973 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
974 struct lsa_LookupSids2 *r)
976 NTSTATUS status;
977 struct lsa_info *handle;
978 int num_sids = r->in.sids->num_sids;
979 uint32 mapped_count = 0;
980 struct lsa_RefDomainList *domains = NULL;
981 struct lsa_TranslatedName2 *names = NULL;
982 bool check_policy = true;
984 switch (p->opnum) {
985 case NDR_LSA_LOOKUPSIDS3:
986 check_policy = false;
987 break;
988 case NDR_LSA_LOOKUPSIDS2:
989 default:
990 check_policy = true;
993 if ((r->in.level < 1) || (r->in.level > 6)) {
994 return NT_STATUS_INVALID_PARAMETER;
997 if (check_policy) {
998 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
999 return NT_STATUS_INVALID_HANDLE;
1002 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1003 return NT_STATUS_INVALID_HANDLE;
1006 /* check if the user has enough rights */
1007 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1008 return NT_STATUS_ACCESS_DENIED;
1012 if (num_sids > MAX_LOOKUP_SIDS) {
1013 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1014 MAX_LOOKUP_SIDS, num_sids));
1015 return NT_STATUS_NONE_MAPPED;
1018 status = _lsa_lookup_sids_internal(p,
1019 p->mem_ctx,
1020 r->in.level,
1021 num_sids,
1022 r->in.sids->sids,
1023 &domains,
1024 &names,
1025 &mapped_count);
1027 *r->out.domains = domains;
1028 r->out.names->count = num_sids;
1029 r->out.names->names = names;
1030 *r->out.count = mapped_count;
1032 return status;
1035 /***************************************************************************
1036 _lsa_LookupSids3
1037 ***************************************************************************/
1039 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1040 struct lsa_LookupSids3 *r)
1042 struct lsa_LookupSids2 q;
1044 /* No policy handle on this call. Restrict to crypto connections. */
1045 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1046 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1047 get_remote_machine_name() ));
1048 return NT_STATUS_INVALID_PARAMETER;
1051 q.in.handle = NULL;
1052 q.in.sids = r->in.sids;
1053 q.in.level = r->in.level;
1054 q.in.lookup_options = r->in.lookup_options;
1055 q.in.client_revision = r->in.client_revision;
1056 q.in.names = r->in.names;
1057 q.in.count = r->in.count;
1059 q.out.domains = r->out.domains;
1060 q.out.names = r->out.names;
1061 q.out.count = r->out.count;
1063 return _lsa_LookupSids2(p, &q);
1066 /***************************************************************************
1067 ***************************************************************************/
1069 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1071 int flags;
1073 switch (level) {
1074 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1075 flags = LOOKUP_NAME_ALL;
1076 break;
1077 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1078 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1079 break;
1080 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1081 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1082 break;
1083 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1084 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1085 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1086 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1087 default:
1088 flags = LOOKUP_NAME_NONE;
1089 break;
1092 return flags;
1095 /***************************************************************************
1096 _lsa_LookupNames
1097 ***************************************************************************/
1099 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1100 struct lsa_LookupNames *r)
1102 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1103 struct lsa_info *handle;
1104 struct lsa_String *names = r->in.names;
1105 uint32 num_entries = r->in.num_names;
1106 struct lsa_RefDomainList *domains = NULL;
1107 struct lsa_TranslatedSid *rids = NULL;
1108 uint32 mapped_count = 0;
1109 int flags = 0;
1111 if (num_entries > MAX_LOOKUP_SIDS) {
1112 num_entries = MAX_LOOKUP_SIDS;
1113 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1114 num_entries));
1117 flags = lsa_lookup_level_to_flags(r->in.level);
1119 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1120 if (!domains) {
1121 return NT_STATUS_NO_MEMORY;
1124 if (num_entries) {
1125 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1126 num_entries);
1127 if (!rids) {
1128 return NT_STATUS_NO_MEMORY;
1130 } else {
1131 rids = NULL;
1134 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1135 status = NT_STATUS_INVALID_HANDLE;
1136 goto done;
1139 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1140 return NT_STATUS_INVALID_HANDLE;
1143 /* check if the user has enough rights */
1144 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1145 status = NT_STATUS_ACCESS_DENIED;
1146 goto done;
1149 /* set up the LSA Lookup RIDs response */
1150 become_root(); /* lookup_name can require root privs */
1151 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1152 names, flags, &mapped_count);
1153 unbecome_root();
1155 done:
1157 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1158 if (mapped_count == 0) {
1159 status = NT_STATUS_NONE_MAPPED;
1160 } else if (mapped_count != num_entries) {
1161 status = STATUS_SOME_UNMAPPED;
1165 *r->out.count = mapped_count;
1166 *r->out.domains = domains;
1167 r->out.sids->sids = rids;
1168 r->out.sids->count = num_entries;
1170 return status;
1173 /***************************************************************************
1174 _lsa_LookupNames2
1175 ***************************************************************************/
1177 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1178 struct lsa_LookupNames2 *r)
1180 NTSTATUS status;
1181 struct lsa_LookupNames q;
1182 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1183 struct lsa_TransSidArray *sid_array = NULL;
1184 uint32_t i;
1186 sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1187 if (!sid_array) {
1188 return NT_STATUS_NO_MEMORY;
1191 q.in.handle = r->in.handle;
1192 q.in.num_names = r->in.num_names;
1193 q.in.names = r->in.names;
1194 q.in.level = r->in.level;
1195 q.in.sids = sid_array;
1196 q.in.count = r->in.count;
1197 /* we do not know what this is for */
1198 /* = r->in.unknown1; */
1199 /* = r->in.unknown2; */
1201 q.out.domains = r->out.domains;
1202 q.out.sids = sid_array;
1203 q.out.count = r->out.count;
1205 status = _lsa_LookupNames(p, &q);
1207 sid_array2->count = sid_array->count;
1208 sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1209 if (!sid_array2->sids) {
1210 return NT_STATUS_NO_MEMORY;
1213 for (i=0; i<sid_array->count; i++) {
1214 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1215 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1216 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1217 sid_array2->sids[i].unknown = 0;
1220 r->out.sids = sid_array2;
1222 return status;
1225 /***************************************************************************
1226 _lsa_LookupNames3
1227 ***************************************************************************/
1229 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1230 struct lsa_LookupNames3 *r)
1232 NTSTATUS status;
1233 struct lsa_info *handle;
1234 struct lsa_String *names = r->in.names;
1235 uint32 num_entries = r->in.num_names;
1236 struct lsa_RefDomainList *domains = NULL;
1237 struct lsa_TranslatedSid3 *trans_sids = NULL;
1238 uint32 mapped_count = 0;
1239 int flags = 0;
1240 bool check_policy = true;
1242 switch (p->opnum) {
1243 case NDR_LSA_LOOKUPNAMES4:
1244 check_policy = false;
1245 break;
1246 case NDR_LSA_LOOKUPNAMES3:
1247 default:
1248 check_policy = true;
1251 if (num_entries > MAX_LOOKUP_SIDS) {
1252 num_entries = MAX_LOOKUP_SIDS;
1253 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1256 /* Probably the lookup_level is some sort of bitmask. */
1257 if (r->in.level == 1) {
1258 flags = LOOKUP_NAME_ALL;
1261 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1262 if (!domains) {
1263 return NT_STATUS_NO_MEMORY;
1266 if (num_entries) {
1267 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1268 num_entries);
1269 if (!trans_sids) {
1270 return NT_STATUS_NO_MEMORY;
1272 } else {
1273 trans_sids = NULL;
1276 if (check_policy) {
1278 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1279 status = NT_STATUS_INVALID_HANDLE;
1280 goto done;
1283 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1284 return NT_STATUS_INVALID_HANDLE;
1287 /* check if the user has enough rights */
1288 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1289 status = NT_STATUS_ACCESS_DENIED;
1290 goto done;
1294 /* set up the LSA Lookup SIDs response */
1295 become_root(); /* lookup_name can require root privs */
1296 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1297 names, flags, &mapped_count);
1298 unbecome_root();
1300 done:
1302 if (NT_STATUS_IS_OK(status)) {
1303 if (mapped_count == 0) {
1304 status = NT_STATUS_NONE_MAPPED;
1305 } else if (mapped_count != num_entries) {
1306 status = STATUS_SOME_UNMAPPED;
1310 *r->out.count = mapped_count;
1311 *r->out.domains = domains;
1312 r->out.sids->sids = trans_sids;
1313 r->out.sids->count = num_entries;
1315 return status;
1318 /***************************************************************************
1319 _lsa_LookupNames4
1320 ***************************************************************************/
1322 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1323 struct lsa_LookupNames4 *r)
1325 struct lsa_LookupNames3 q;
1327 /* No policy handle on this call. Restrict to crypto connections. */
1328 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1329 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1330 get_remote_machine_name() ));
1331 return NT_STATUS_INVALID_PARAMETER;
1334 q.in.handle = NULL;
1335 q.in.num_names = r->in.num_names;
1336 q.in.names = r->in.names;
1337 q.in.level = r->in.level;
1338 q.in.lookup_options = r->in.lookup_options;
1339 q.in.client_revision = r->in.client_revision;
1340 q.in.sids = r->in.sids;
1341 q.in.count = r->in.count;
1343 q.out.domains = r->out.domains;
1344 q.out.sids = r->out.sids;
1345 q.out.count = r->out.count;
1347 return _lsa_LookupNames3(p, &q);
1350 /***************************************************************************
1351 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1352 ***************************************************************************/
1354 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1356 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1357 return NT_STATUS_INVALID_HANDLE;
1360 close_policy_hnd(p, r->in.handle);
1361 ZERO_STRUCTP(r->out.handle);
1362 return NT_STATUS_OK;
1365 /***************************************************************************
1366 ***************************************************************************/
1368 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p, struct lsa_OpenSecret *r)
1370 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1373 /***************************************************************************
1374 ***************************************************************************/
1376 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1377 struct lsa_OpenTrustedDomain *r)
1379 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1382 /***************************************************************************
1383 ***************************************************************************/
1385 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1386 struct lsa_CreateTrustedDomain *r)
1388 return NT_STATUS_ACCESS_DENIED;
1391 /***************************************************************************
1392 ***************************************************************************/
1394 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p, struct lsa_CreateSecret *r)
1396 return NT_STATUS_ACCESS_DENIED;
1399 /***************************************************************************
1400 ***************************************************************************/
1402 NTSTATUS _lsa_SetSecret(struct pipes_struct *p, struct lsa_SetSecret *r)
1404 return NT_STATUS_ACCESS_DENIED;
1407 /***************************************************************************
1408 _lsa_DeleteObject
1409 ***************************************************************************/
1411 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
1412 struct lsa_DeleteObject *r)
1414 NTSTATUS status;
1415 struct lsa_info *info = NULL;
1417 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
1418 return NT_STATUS_INVALID_HANDLE;
1421 if (!(info->access & SEC_STD_DELETE)) {
1422 return NT_STATUS_ACCESS_DENIED;
1425 switch (info->type) {
1426 case LSA_HANDLE_ACCOUNT_TYPE:
1427 status = privilege_delete_account(&info->sid);
1428 if (!NT_STATUS_IS_OK(status)) {
1429 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
1430 nt_errstr(status)));
1431 return status;
1433 break;
1434 default:
1435 return NT_STATUS_INVALID_HANDLE;
1438 close_policy_hnd(p, r->in.handle);
1439 ZERO_STRUCTP(r->out.handle);
1441 return status;
1444 /***************************************************************************
1445 _lsa_EnumPrivs
1446 ***************************************************************************/
1448 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
1449 struct lsa_EnumPrivs *r)
1451 struct lsa_info *handle;
1452 uint32 i;
1453 uint32 enum_context = *r->in.resume_handle;
1454 int num_privs = num_privileges_in_short_list();
1455 struct lsa_PrivEntry *entries = NULL;
1457 /* remember that the enum_context starts at 0 and not 1 */
1459 if ( enum_context >= num_privs )
1460 return NT_STATUS_NO_MORE_ENTRIES;
1462 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
1463 enum_context, num_privs));
1465 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1466 return NT_STATUS_INVALID_HANDLE;
1468 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1469 return NT_STATUS_INVALID_HANDLE;
1472 /* check if the user has enough rights
1473 I don't know if it's the right one. not documented. */
1475 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1476 return NT_STATUS_ACCESS_DENIED;
1478 if (num_privs) {
1479 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
1480 if (!entries) {
1481 return NT_STATUS_NO_MEMORY;
1483 } else {
1484 entries = NULL;
1487 for (i = 0; i < num_privs; i++) {
1488 if( i < enum_context) {
1490 init_lsa_StringLarge(&entries[i].name, NULL);
1492 entries[i].luid.low = 0;
1493 entries[i].luid.high = 0;
1494 } else {
1496 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
1498 entries[i].luid.low = sec_privilege_from_index(i);
1499 entries[i].luid.high = 0;
1503 enum_context = num_privs;
1505 *r->out.resume_handle = enum_context;
1506 r->out.privs->count = num_privs;
1507 r->out.privs->privs = entries;
1509 return NT_STATUS_OK;
1512 /***************************************************************************
1513 _lsa_LookupPrivDisplayName
1514 ***************************************************************************/
1516 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
1517 struct lsa_LookupPrivDisplayName *r)
1519 struct lsa_info *handle;
1520 const char *description;
1521 struct lsa_StringLarge *lsa_name;
1523 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1524 return NT_STATUS_INVALID_HANDLE;
1526 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1527 return NT_STATUS_INVALID_HANDLE;
1530 /* check if the user has enough rights */
1533 * I don't know if it's the right one. not documented.
1535 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1536 return NT_STATUS_ACCESS_DENIED;
1538 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
1540 description = get_privilege_dispname(r->in.name->string);
1541 if (!description) {
1542 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
1543 return NT_STATUS_NO_SUCH_PRIVILEGE;
1546 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
1548 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
1549 if (!lsa_name) {
1550 return NT_STATUS_NO_MEMORY;
1553 init_lsa_StringLarge(lsa_name, description);
1555 *r->out.returned_language_id = r->in.language_id;
1556 *r->out.disp_name = lsa_name;
1558 return NT_STATUS_OK;
1561 /***************************************************************************
1562 _lsa_EnumAccounts
1563 ***************************************************************************/
1565 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
1566 struct lsa_EnumAccounts *r)
1568 struct lsa_info *handle;
1569 struct dom_sid *sid_list;
1570 int i, j, num_entries;
1571 NTSTATUS status;
1572 struct lsa_SidPtr *sids = NULL;
1574 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1575 return NT_STATUS_INVALID_HANDLE;
1577 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1578 return NT_STATUS_INVALID_HANDLE;
1581 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
1582 return NT_STATUS_ACCESS_DENIED;
1584 sid_list = NULL;
1585 num_entries = 0;
1587 /* The only way we can currently find out all the SIDs that have been
1588 privileged is to scan all privileges */
1590 status = privilege_enumerate_accounts(&sid_list, &num_entries);
1591 if (!NT_STATUS_IS_OK(status)) {
1592 return status;
1595 if (*r->in.resume_handle >= num_entries) {
1596 return NT_STATUS_NO_MORE_ENTRIES;
1599 if (num_entries - *r->in.resume_handle) {
1600 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
1601 num_entries - *r->in.resume_handle);
1602 if (!sids) {
1603 talloc_free(sid_list);
1604 return NT_STATUS_NO_MEMORY;
1607 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
1608 sids[j].sid = sid_dup_talloc(p->mem_ctx, &sid_list[i]);
1609 if (!sids[j].sid) {
1610 talloc_free(sid_list);
1611 return NT_STATUS_NO_MEMORY;
1616 talloc_free(sid_list);
1618 *r->out.resume_handle = num_entries;
1619 r->out.sids->num_sids = num_entries;
1620 r->out.sids->sids = sids;
1622 return NT_STATUS_OK;
1625 /***************************************************************************
1626 _lsa_GetUserName
1627 ***************************************************************************/
1629 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
1630 struct lsa_GetUserName *r)
1632 const char *username, *domname;
1633 struct lsa_String *account_name = NULL;
1634 struct lsa_String *authority_name = NULL;
1636 if (r->in.account_name &&
1637 *r->in.account_name) {
1638 return NT_STATUS_INVALID_PARAMETER;
1641 if (r->in.authority_name &&
1642 *r->in.authority_name) {
1643 return NT_STATUS_INVALID_PARAMETER;
1646 if (p->server_info->guest) {
1648 * I'm 99% sure this is not the right place to do this,
1649 * global_sid_Anonymous should probably be put into the token
1650 * instead of the guest id -- vl
1652 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
1653 &domname, &username, NULL)) {
1654 return NT_STATUS_NO_MEMORY;
1656 } else {
1657 username = p->server_info->sanitized_username;
1658 domname = p->server_info->info3->base.domain.string;
1661 account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1662 if (!account_name) {
1663 return NT_STATUS_NO_MEMORY;
1665 init_lsa_String(account_name, username);
1667 if (r->out.authority_name) {
1668 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
1669 if (!authority_name) {
1670 return NT_STATUS_NO_MEMORY;
1672 init_lsa_String(authority_name, domname);
1675 *r->out.account_name = account_name;
1676 if (r->out.authority_name) {
1677 *r->out.authority_name = authority_name;
1680 return NT_STATUS_OK;
1683 /***************************************************************************
1684 _lsa_CreateAccount
1685 ***************************************************************************/
1687 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
1688 struct lsa_CreateAccount *r)
1690 NTSTATUS status;
1691 struct lsa_info *handle;
1692 struct lsa_info *info;
1693 uint32_t acc_granted;
1694 struct security_descriptor *psd;
1695 size_t sd_size;
1697 /* find the connection policy handle. */
1698 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1699 return NT_STATUS_INVALID_HANDLE;
1701 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1702 return NT_STATUS_INVALID_HANDLE;
1705 /* check if the user has enough rights */
1707 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
1708 return NT_STATUS_ACCESS_DENIED;
1711 /* Work out max allowed. */
1712 map_max_allowed_access(p->server_info->ptok,
1713 &p->server_info->utok,
1714 &r->in.access_mask);
1716 /* map the generic bits to the lsa policy ones */
1717 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1719 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1720 &lsa_account_mapping,
1721 r->in.sid, LSA_POLICY_ALL_ACCESS);
1722 if (!NT_STATUS_IS_OK(status)) {
1723 return status;
1726 status = access_check_object(psd, p->server_info->ptok,
1727 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
1728 &acc_granted, "_lsa_CreateAccount");
1729 if (!NT_STATUS_IS_OK(status)) {
1730 return status;
1733 if ( is_privileged_sid( r->in.sid ) )
1734 return NT_STATUS_OBJECT_NAME_COLLISION;
1736 /* associate the user/group SID with the (unique) handle. */
1738 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1739 if (info == NULL) {
1740 return NT_STATUS_NO_MEMORY;
1743 info->sid = *r->in.sid;
1744 info->access = acc_granted;
1745 info->type = LSA_HANDLE_ACCOUNT_TYPE;
1747 /* get a (unique) handle. open a policy on it. */
1748 if (!create_policy_hnd(p, r->out.acct_handle, info))
1749 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1751 return privilege_create_account( &info->sid );
1754 /***************************************************************************
1755 _lsa_OpenAccount
1756 ***************************************************************************/
1758 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
1759 struct lsa_OpenAccount *r)
1761 struct lsa_info *handle;
1762 struct lsa_info *info;
1763 struct security_descriptor *psd = NULL;
1764 size_t sd_size;
1765 uint32_t des_access = r->in.access_mask;
1766 uint32_t acc_granted;
1767 NTSTATUS status;
1769 /* find the connection policy handle. */
1770 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
1771 return NT_STATUS_INVALID_HANDLE;
1773 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1774 return NT_STATUS_INVALID_HANDLE;
1777 /* des_access is for the account here, not the policy
1778 * handle - so don't check against policy handle. */
1780 /* Work out max allowed. */
1781 map_max_allowed_access(p->server_info->ptok,
1782 &p->server_info->utok,
1783 &des_access);
1785 /* map the generic bits to the lsa account ones */
1786 se_map_generic(&des_access, &lsa_account_mapping);
1788 /* get the generic lsa account SD until we store it */
1789 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1790 &lsa_account_mapping,
1791 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
1792 if (!NT_STATUS_IS_OK(status)) {
1793 return status;
1796 status = access_check_object(psd, p->server_info->ptok,
1797 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
1798 &acc_granted, "_lsa_OpenAccount" );
1799 if (!NT_STATUS_IS_OK(status)) {
1800 return status;
1803 /* TODO: Fis the parsing routine before reenabling this check! */
1804 #if 0
1805 if (!lookup_sid(&handle->sid, dom_name, name, &type))
1806 return NT_STATUS_ACCESS_DENIED;
1807 #endif
1808 /* associate the user/group SID with the (unique) handle. */
1809 info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
1810 if (info == NULL) {
1811 return NT_STATUS_NO_MEMORY;
1814 info->sid = *r->in.sid;
1815 info->access = acc_granted;
1816 info->type = LSA_HANDLE_ACCOUNT_TYPE;
1818 /* get a (unique) handle. open a policy on it. */
1819 if (!create_policy_hnd(p, r->out.acct_handle, info))
1820 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1822 return NT_STATUS_OK;
1825 /***************************************************************************
1826 _lsa_EnumPrivsAccount
1827 For a given SID, enumerate all the privilege this account has.
1828 ***************************************************************************/
1830 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
1831 struct lsa_EnumPrivsAccount *r)
1833 NTSTATUS status = NT_STATUS_OK;
1834 struct lsa_info *info=NULL;
1835 PRIVILEGE_SET *privileges;
1836 struct lsa_PrivilegeSet *priv_set = NULL;
1838 /* find the connection policy handle. */
1839 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1840 return NT_STATUS_INVALID_HANDLE;
1842 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1843 return NT_STATUS_INVALID_HANDLE;
1846 if (!(info->access & LSA_ACCOUNT_VIEW))
1847 return NT_STATUS_ACCESS_DENIED;
1849 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
1850 if (!NT_STATUS_IS_OK(status)) {
1851 return status;
1854 *r->out.privs = priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
1855 if (!priv_set) {
1856 return NT_STATUS_NO_MEMORY;
1859 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
1860 sid_string_dbg(&info->sid),
1861 privileges->count));
1863 priv_set->count = privileges->count;
1864 priv_set->unknown = 0;
1865 priv_set->set = talloc_move(priv_set, &privileges->set);
1867 return status;
1870 /***************************************************************************
1871 _lsa_GetSystemAccessAccount
1872 ***************************************************************************/
1874 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
1875 struct lsa_GetSystemAccessAccount *r)
1877 NTSTATUS status;
1878 struct lsa_info *info = NULL;
1879 struct lsa_EnumPrivsAccount e;
1880 struct lsa_PrivilegeSet *privset;
1882 /* find the connection policy handle. */
1884 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1885 return NT_STATUS_INVALID_HANDLE;
1887 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1888 return NT_STATUS_INVALID_HANDLE;
1891 if (!(info->access & LSA_ACCOUNT_VIEW))
1892 return NT_STATUS_ACCESS_DENIED;
1894 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
1895 if (!privset) {
1896 return NT_STATUS_NO_MEMORY;
1899 e.in.handle = r->in.handle;
1900 e.out.privs = &privset;
1902 status = _lsa_EnumPrivsAccount(p, &e);
1903 if (!NT_STATUS_IS_OK(status)) {
1904 DEBUG(10,("_lsa_GetSystemAccessAccount: "
1905 "failed to call _lsa_EnumPrivsAccount(): %s\n",
1906 nt_errstr(status)));
1907 return status;
1910 /* Samba4 would iterate over the privset to merge the policy mode bits,
1911 * not sure samba3 can do the same here, so just return what we did in
1912 * the past - gd */
1915 0x01 -> Log on locally
1916 0x02 -> Access this computer from network
1917 0x04 -> Log on as a batch job
1918 0x10 -> Log on as a service
1920 they can be ORed together
1923 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
1924 LSA_POLICY_MODE_NETWORK;
1926 return NT_STATUS_OK;
1929 /***************************************************************************
1930 update the systemaccount information
1931 ***************************************************************************/
1933 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
1934 struct lsa_SetSystemAccessAccount *r)
1936 struct lsa_info *info=NULL;
1937 GROUP_MAP map;
1939 /* find the connection policy handle. */
1940 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
1941 return NT_STATUS_INVALID_HANDLE;
1943 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
1944 return NT_STATUS_INVALID_HANDLE;
1947 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
1948 return NT_STATUS_ACCESS_DENIED;
1951 if (!pdb_getgrsid(&map, info->sid))
1952 return NT_STATUS_NO_SUCH_GROUP;
1954 return pdb_update_group_mapping_entry(&map);
1957 /***************************************************************************
1958 _lsa_AddPrivilegesToAccount
1959 For a given SID, add some privileges.
1960 ***************************************************************************/
1962 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
1963 struct lsa_AddPrivilegesToAccount *r)
1965 struct lsa_info *info = NULL;
1966 struct lsa_PrivilegeSet *set = NULL;
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_PRIVILEGES)) {
1977 return NT_STATUS_ACCESS_DENIED;
1980 set = r->in.privs;
1982 if ( !grant_privilege_set( &info->sid, set ) ) {
1983 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
1984 sid_string_dbg(&info->sid) ));
1985 return NT_STATUS_NO_SUCH_PRIVILEGE;
1988 return NT_STATUS_OK;
1991 /***************************************************************************
1992 _lsa_RemovePrivilegesFromAccount
1993 For a given SID, remove some privileges.
1994 ***************************************************************************/
1996 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
1997 struct lsa_RemovePrivilegesFromAccount *r)
1999 struct lsa_info *info = NULL;
2000 struct lsa_PrivilegeSet *set = NULL;
2002 /* find the connection policy handle. */
2003 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2004 return NT_STATUS_INVALID_HANDLE;
2006 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2007 return NT_STATUS_INVALID_HANDLE;
2010 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2011 return NT_STATUS_ACCESS_DENIED;
2014 set = r->in.privs;
2016 if ( !revoke_privilege_set( &info->sid, set) ) {
2017 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2018 sid_string_dbg(&info->sid) ));
2019 return NT_STATUS_NO_SUCH_PRIVILEGE;
2022 return NT_STATUS_OK;
2025 /***************************************************************************
2026 _lsa_LookupPrivName
2027 ***************************************************************************/
2029 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2030 struct lsa_LookupPrivName *r)
2032 struct lsa_info *info = NULL;
2033 const char *name;
2034 struct lsa_StringLarge *lsa_name;
2036 /* find the connection policy handle. */
2037 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2038 return NT_STATUS_INVALID_HANDLE;
2041 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2042 return NT_STATUS_INVALID_HANDLE;
2045 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2046 return NT_STATUS_ACCESS_DENIED;
2049 if (r->in.luid->high != 0) {
2050 return NT_STATUS_NO_SUCH_PRIVILEGE;
2053 name = sec_privilege_name(r->in.luid->low);
2054 if (!name) {
2055 return NT_STATUS_NO_SUCH_PRIVILEGE;
2058 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2059 if (!lsa_name) {
2060 return NT_STATUS_NO_MEMORY;
2063 lsa_name->string = talloc_strdup(lsa_name, name);
2064 if (!lsa_name->string) {
2065 TALLOC_FREE(lsa_name);
2066 return NT_STATUS_NO_MEMORY;
2069 *r->out.name = lsa_name;
2071 return NT_STATUS_OK;
2074 /***************************************************************************
2075 _lsa_QuerySecurity
2076 ***************************************************************************/
2078 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
2079 struct lsa_QuerySecurity *r)
2081 struct lsa_info *handle=NULL;
2082 struct security_descriptor *psd = NULL;
2083 size_t sd_size;
2084 NTSTATUS status;
2086 /* find the connection policy handle. */
2087 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2088 return NT_STATUS_INVALID_HANDLE;
2090 switch (handle->type) {
2091 case LSA_HANDLE_POLICY_TYPE:
2092 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2093 &lsa_policy_mapping, NULL, 0);
2094 break;
2095 case LSA_HANDLE_ACCOUNT_TYPE:
2096 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2097 &lsa_account_mapping,
2098 &handle->sid, LSA_ACCOUNT_ALL_ACCESS);
2099 break;
2100 default:
2101 status = NT_STATUS_INVALID_HANDLE;
2102 break;
2105 if (!NT_STATUS_IS_OK(status)) {
2106 return status;
2109 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2110 if (!*r->out.sdbuf) {
2111 return NT_STATUS_NO_MEMORY;
2114 return status;
2117 /***************************************************************************
2118 _lsa_AddAccountRights
2119 ***************************************************************************/
2121 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
2122 struct lsa_AddAccountRights *r)
2124 struct lsa_info *info = NULL;
2125 int i = 0;
2126 uint32_t acc_granted = 0;
2127 struct security_descriptor *psd = NULL;
2128 size_t sd_size;
2129 struct dom_sid sid;
2130 NTSTATUS status;
2132 /* find the connection policy handle. */
2133 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2134 return NT_STATUS_INVALID_HANDLE;
2136 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2137 return NT_STATUS_INVALID_HANDLE;
2140 /* get the generic lsa account SD for this SID until we store it */
2141 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2142 &lsa_account_mapping,
2143 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2144 if (!NT_STATUS_IS_OK(status)) {
2145 return status;
2149 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2150 * on the policy handle. If it does, ask for
2151 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2152 * on the account sid. We don't check here so just use the latter. JRA.
2155 status = access_check_object(psd, p->server_info->ptok,
2156 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2157 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2158 &acc_granted, "_lsa_AddAccountRights" );
2159 if (!NT_STATUS_IS_OK(status)) {
2160 return status;
2163 /* according to an NT4 PDC, you can add privileges to SIDs even without
2164 call_lsa_create_account() first. And you can use any arbitrary SID. */
2166 sid_copy( &sid, r->in.sid );
2168 for ( i=0; i < r->in.rights->count; i++ ) {
2170 const char *privname = r->in.rights->names[i].string;
2172 /* only try to add non-null strings */
2174 if ( !privname )
2175 continue;
2177 if ( !grant_privilege_by_name( &sid, privname ) ) {
2178 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2179 privname ));
2180 return NT_STATUS_NO_SUCH_PRIVILEGE;
2184 return NT_STATUS_OK;
2187 /***************************************************************************
2188 _lsa_RemoveAccountRights
2189 ***************************************************************************/
2191 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
2192 struct lsa_RemoveAccountRights *r)
2194 struct lsa_info *info = NULL;
2195 int i = 0;
2196 struct security_descriptor *psd = NULL;
2197 size_t sd_size;
2198 struct dom_sid sid;
2199 const char *privname = NULL;
2200 uint32_t acc_granted = 0;
2201 NTSTATUS status;
2203 /* find the connection policy handle. */
2204 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2205 return NT_STATUS_INVALID_HANDLE;
2207 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2208 return NT_STATUS_INVALID_HANDLE;
2211 /* get the generic lsa account SD for this SID until we store it */
2212 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2213 &lsa_account_mapping,
2214 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2215 if (!NT_STATUS_IS_OK(status)) {
2216 return status;
2220 * From the MS DOCs. We need
2221 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2222 * and DELETE on the account sid.
2225 status = access_check_object(psd, p->server_info->ptok,
2226 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2227 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2228 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
2229 &acc_granted, "_lsa_RemoveAccountRights");
2230 if (!NT_STATUS_IS_OK(status)) {
2231 return status;
2234 sid_copy( &sid, r->in.sid );
2236 if ( r->in.remove_all ) {
2237 if ( !revoke_all_privileges( &sid ) )
2238 return NT_STATUS_ACCESS_DENIED;
2240 return NT_STATUS_OK;
2243 for ( i=0; i < r->in.rights->count; i++ ) {
2245 privname = r->in.rights->names[i].string;
2247 /* only try to add non-null strings */
2249 if ( !privname )
2250 continue;
2252 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2253 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2254 privname ));
2255 return NT_STATUS_NO_SUCH_PRIVILEGE;
2259 return NT_STATUS_OK;
2262 /*******************************************************************
2263 ********************************************************************/
2265 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
2266 struct lsa_RightSet *r,
2267 PRIVILEGE_SET *privileges)
2269 uint32 i;
2270 const char *privname;
2271 const char **privname_array = NULL;
2272 int num_priv = 0;
2274 for (i=0; i<privileges->count; i++) {
2275 if (privileges->set[i].luid.high) {
2276 continue;
2278 privname = sec_privilege_name(privileges->set[i].luid.low);
2279 if (privname) {
2280 if (!add_string_to_array(mem_ctx, privname,
2281 &privname_array, &num_priv)) {
2282 return NT_STATUS_NO_MEMORY;
2287 if (num_priv) {
2289 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
2290 num_priv);
2291 if (!r->names) {
2292 return NT_STATUS_NO_MEMORY;
2295 for (i=0; i<num_priv; i++) {
2296 init_lsa_StringLarge(&r->names[i], privname_array[i]);
2299 r->count = num_priv;
2302 return NT_STATUS_OK;
2305 /***************************************************************************
2306 _lsa_EnumAccountRights
2307 ***************************************************************************/
2309 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
2310 struct lsa_EnumAccountRights *r)
2312 NTSTATUS status;
2313 struct lsa_info *info = NULL;
2314 struct dom_sid sid;
2315 PRIVILEGE_SET *privileges;
2317 /* find the connection policy handle. */
2319 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2320 return NT_STATUS_INVALID_HANDLE;
2322 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2323 return NT_STATUS_INVALID_HANDLE;
2326 if (!(info->access & LSA_ACCOUNT_VIEW)) {
2327 return NT_STATUS_ACCESS_DENIED;
2330 /* according to an NT4 PDC, you can add privileges to SIDs even without
2331 call_lsa_create_account() first. And you can use any arbitrary SID. */
2333 /* according to MS-LSAD 3.1.4.5.10 it is required to return
2334 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
2335 * the lsa database */
2337 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
2338 if (!NT_STATUS_IS_OK(status)) {
2339 return status;
2342 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
2343 sid_string_dbg(&sid), privileges->count));
2345 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
2347 return status;
2350 /***************************************************************************
2351 _lsa_LookupPrivValue
2352 ***************************************************************************/
2354 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
2355 struct lsa_LookupPrivValue *r)
2357 struct lsa_info *info = NULL;
2358 const char *name = NULL;
2360 /* find the connection policy handle. */
2362 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2363 return NT_STATUS_INVALID_HANDLE;
2365 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2366 return NT_STATUS_INVALID_HANDLE;
2369 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
2370 return NT_STATUS_ACCESS_DENIED;
2372 name = r->in.name->string;
2374 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
2376 r->out.luid->low = sec_privilege_id(name);
2377 r->out.luid->high = 0;
2378 if (r->out.luid->low == SEC_PRIV_INVALID) {
2379 return NT_STATUS_NO_SUCH_PRIVILEGE;
2381 return NT_STATUS_OK;
2384 /***************************************************************************
2385 _lsa_EnumAccountsWithUserRight
2386 ***************************************************************************/
2388 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
2389 struct lsa_EnumAccountsWithUserRight *r)
2391 NTSTATUS status;
2392 struct lsa_info *info = NULL;
2393 struct dom_sid *sids = NULL;
2394 int num_sids = 0;
2395 uint32_t i;
2396 enum sec_privilege privilege;
2398 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2399 return NT_STATUS_INVALID_HANDLE;
2402 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2403 return NT_STATUS_INVALID_HANDLE;
2406 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
2407 return NT_STATUS_ACCESS_DENIED;
2410 if (!r->in.name || !r->in.name->string) {
2411 return NT_STATUS_NO_SUCH_PRIVILEGE;
2414 privilege = sec_privilege_id(r->in.name->string);
2415 if (privilege == SEC_PRIV_INVALID) {
2416 return NT_STATUS_NO_SUCH_PRIVILEGE;
2419 status = privilege_enum_sids(privilege, p->mem_ctx,
2420 &sids, &num_sids);
2421 if (!NT_STATUS_IS_OK(status)) {
2422 return status;
2425 r->out.sids->num_sids = num_sids;
2426 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
2427 r->out.sids->num_sids);
2429 for (i=0; i < r->out.sids->num_sids; i++) {
2430 r->out.sids->sids[i].sid = sid_dup_talloc(r->out.sids->sids,
2431 &sids[i]);
2432 if (!r->out.sids->sids[i].sid) {
2433 TALLOC_FREE(r->out.sids->sids);
2434 r->out.sids->num_sids = 0;
2435 return NT_STATUS_NO_MEMORY;
2439 return NT_STATUS_OK;
2442 /***************************************************************************
2443 _lsa_Delete
2444 ***************************************************************************/
2446 NTSTATUS _lsa_Delete(struct pipes_struct *p,
2447 struct lsa_Delete *r)
2449 return NT_STATUS_NOT_SUPPORTED;
2453 * From here on the server routines are just dummy ones to make smbd link with
2454 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
2455 * pulling the server stubs across one by one.
2458 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
2460 p->rng_fault_state = True;
2461 return NT_STATUS_NOT_IMPLEMENTED;
2464 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
2465 struct lsa_ChangePassword *r)
2467 p->rng_fault_state = True;
2468 return NT_STATUS_NOT_IMPLEMENTED;
2471 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
2473 p->rng_fault_state = True;
2474 return NT_STATUS_NOT_IMPLEMENTED;
2477 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
2479 p->rng_fault_state = True;
2480 return NT_STATUS_NOT_IMPLEMENTED;
2483 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
2484 struct lsa_GetQuotasForAccount *r)
2486 p->rng_fault_state = True;
2487 return NT_STATUS_NOT_IMPLEMENTED;
2490 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
2491 struct lsa_SetQuotasForAccount *r)
2493 p->rng_fault_state = True;
2494 return NT_STATUS_NOT_IMPLEMENTED;
2497 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
2498 struct lsa_QueryTrustedDomainInfo *r)
2500 p->rng_fault_state = True;
2501 return NT_STATUS_NOT_IMPLEMENTED;
2504 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
2505 struct lsa_SetInformationTrustedDomain *r)
2507 p->rng_fault_state = True;
2508 return NT_STATUS_NOT_IMPLEMENTED;
2511 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
2513 p->rng_fault_state = True;
2514 return NT_STATUS_NOT_IMPLEMENTED;
2517 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2518 struct lsa_QueryTrustedDomainInfoBySid *r)
2520 p->rng_fault_state = True;
2521 return NT_STATUS_NOT_IMPLEMENTED;
2524 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
2525 struct lsa_SetTrustedDomainInfo *r)
2527 p->rng_fault_state = True;
2528 return NT_STATUS_NOT_IMPLEMENTED;
2531 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
2532 struct lsa_DeleteTrustedDomain *r)
2534 p->rng_fault_state = True;
2535 return NT_STATUS_NOT_IMPLEMENTED;
2538 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
2539 struct lsa_StorePrivateData *r)
2541 p->rng_fault_state = True;
2542 return NT_STATUS_NOT_IMPLEMENTED;
2545 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
2546 struct lsa_RetrievePrivateData *r)
2548 p->rng_fault_state = True;
2549 return NT_STATUS_NOT_IMPLEMENTED;
2552 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
2553 struct lsa_SetInfoPolicy2 *r)
2555 p->rng_fault_state = True;
2556 return NT_STATUS_NOT_IMPLEMENTED;
2559 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2560 struct lsa_QueryTrustedDomainInfoByName *r)
2562 p->rng_fault_state = True;
2563 return NT_STATUS_NOT_IMPLEMENTED;
2566 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
2567 struct lsa_SetTrustedDomainInfoByName *r)
2569 p->rng_fault_state = True;
2570 return NT_STATUS_NOT_IMPLEMENTED;
2573 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
2574 struct lsa_EnumTrustedDomainsEx *r)
2576 p->rng_fault_state = True;
2577 return NT_STATUS_NOT_IMPLEMENTED;
2580 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
2581 struct lsa_CreateTrustedDomainEx *r)
2583 p->rng_fault_state = True;
2584 return NT_STATUS_NOT_IMPLEMENTED;
2587 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
2588 struct lsa_CloseTrustedDomainEx *r)
2590 p->rng_fault_state = True;
2591 return NT_STATUS_NOT_IMPLEMENTED;
2594 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
2595 struct lsa_QueryDomainInformationPolicy *r)
2597 p->rng_fault_state = True;
2598 return NT_STATUS_NOT_IMPLEMENTED;
2601 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
2602 struct lsa_SetDomainInformationPolicy *r)
2604 p->rng_fault_state = True;
2605 return NT_STATUS_NOT_IMPLEMENTED;
2608 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
2609 struct lsa_OpenTrustedDomainByName *r)
2611 p->rng_fault_state = True;
2612 return NT_STATUS_NOT_IMPLEMENTED;
2615 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
2617 p->rng_fault_state = True;
2618 return NT_STATUS_NOT_IMPLEMENTED;
2621 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
2622 struct lsa_CreateTrustedDomainEx2 *r)
2624 p->rng_fault_state = True;
2625 return NT_STATUS_NOT_IMPLEMENTED;
2628 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
2630 p->rng_fault_state = True;
2631 return NT_STATUS_NOT_IMPLEMENTED;
2634 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
2636 p->rng_fault_state = True;
2637 return NT_STATUS_NOT_IMPLEMENTED;
2640 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
2642 p->rng_fault_state = True;
2643 return NT_STATUS_NOT_IMPLEMENTED;
2646 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
2647 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2649 p->rng_fault_state = True;
2650 return NT_STATUS_NOT_IMPLEMENTED;
2653 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
2654 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2656 p->rng_fault_state = True;
2657 return NT_STATUS_NOT_IMPLEMENTED;
2660 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
2662 p->rng_fault_state = True;
2663 return NT_STATUS_NOT_IMPLEMENTED;
2666 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
2667 struct lsa_CREDRGETTARGETINFO *r)
2669 p->rng_fault_state = True;
2670 return NT_STATUS_NOT_IMPLEMENTED;
2673 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
2674 struct lsa_CREDRPROFILELOADED *r)
2676 p->rng_fault_state = True;
2677 return NT_STATUS_NOT_IMPLEMENTED;
2680 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
2681 struct lsa_CREDRGETSESSIONTYPES *r)
2683 p->rng_fault_state = True;
2684 return NT_STATUS_NOT_IMPLEMENTED;
2687 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
2688 struct lsa_LSARREGISTERAUDITEVENT *r)
2690 p->rng_fault_state = True;
2691 return NT_STATUS_NOT_IMPLEMENTED;
2694 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
2695 struct lsa_LSARGENAUDITEVENT *r)
2697 p->rng_fault_state = True;
2698 return NT_STATUS_NOT_IMPLEMENTED;
2701 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
2702 struct lsa_LSARUNREGISTERAUDITEVENT *r)
2704 p->rng_fault_state = True;
2705 return NT_STATUS_NOT_IMPLEMENTED;
2708 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
2709 struct lsa_lsaRQueryForestTrustInformation *r)
2711 p->rng_fault_state = True;
2712 return NT_STATUS_NOT_IMPLEMENTED;
2715 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
2716 struct lsa_lsaRSetForestTrustInformation *r)
2718 p->rng_fault_state = True;
2719 return NT_STATUS_NOT_IMPLEMENTED;
2722 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
2723 struct lsa_CREDRRENAME *r)
2725 p->rng_fault_state = True;
2726 return NT_STATUS_NOT_IMPLEMENTED;
2729 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
2730 struct lsa_LSAROPENPOLICYSCE *r)
2732 p->rng_fault_state = True;
2733 return NT_STATUS_NOT_IMPLEMENTED;
2736 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
2737 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2739 p->rng_fault_state = True;
2740 return NT_STATUS_NOT_IMPLEMENTED;
2743 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
2744 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2746 p->rng_fault_state = True;
2747 return NT_STATUS_NOT_IMPLEMENTED;
2750 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
2751 struct lsa_LSARADTREPORTSECURITYEVENT *r)
2753 p->rng_fault_state = True;
2754 return NT_STATUS_NOT_IMPLEMENTED;