s3-lsa: Extract auth info from trustDomainPasswords
[Samba/gebeck_regimport.git] / source3 / rpc_server / lsa / srv_lsa_nt.c
blobaba6e6491705db057a699f21b52b2bb1e7174a3b
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"
37 #include "../libcli/security/security.h"
38 #include "../libcli/security/dom_sid.h"
39 #include "../librpc/gen_ndr/drsblobs.h"
40 #include "../librpc/gen_ndr/ndr_drsblobs.h"
41 #include "../lib/crypto/arcfour.h"
43 #undef DBGC_CLASS
44 #define DBGC_CLASS DBGC_RPC_SRV
46 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
48 enum lsa_handle_type {
49 LSA_HANDLE_POLICY_TYPE = 1,
50 LSA_HANDLE_ACCOUNT_TYPE = 2,
51 LSA_HANDLE_TRUST_TYPE = 3};
53 struct lsa_info {
54 struct dom_sid sid;
55 const char *name;
56 uint32 access;
57 enum lsa_handle_type type;
58 struct security_descriptor *sd;
61 const struct generic_mapping lsa_account_mapping = {
62 LSA_ACCOUNT_READ,
63 LSA_ACCOUNT_WRITE,
64 LSA_ACCOUNT_EXECUTE,
65 LSA_ACCOUNT_ALL_ACCESS
68 const struct generic_mapping lsa_policy_mapping = {
69 LSA_POLICY_READ,
70 LSA_POLICY_WRITE,
71 LSA_POLICY_EXECUTE,
72 LSA_POLICY_ALL_ACCESS
75 const struct generic_mapping lsa_secret_mapping = {
76 LSA_SECRET_READ,
77 LSA_SECRET_WRITE,
78 LSA_SECRET_EXECUTE,
79 LSA_SECRET_ALL_ACCESS
82 const struct generic_mapping lsa_trusted_domain_mapping = {
83 LSA_TRUSTED_DOMAIN_READ,
84 LSA_TRUSTED_DOMAIN_WRITE,
85 LSA_TRUSTED_DOMAIN_EXECUTE,
86 LSA_TRUSTED_DOMAIN_ALL_ACCESS
89 /***************************************************************************
90 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
91 ***************************************************************************/
93 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
94 struct lsa_RefDomainList *ref,
95 const char *dom_name,
96 struct dom_sid *dom_sid)
98 int num = 0;
100 if (dom_name != NULL) {
101 for (num = 0; num < ref->count; num++) {
102 if (dom_sid_equal(dom_sid, ref->domains[num].sid)) {
103 return num;
106 } else {
107 num = ref->count;
110 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
111 /* index not found, already at maximum domain limit */
112 return -1;
115 ref->count = num + 1;
116 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
118 ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains,
119 struct lsa_DomainInfo, ref->count);
120 if (!ref->domains) {
121 return -1;
124 ZERO_STRUCT(ref->domains[num]);
126 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
127 ref->domains[num].sid = dom_sid_dup(mem_ctx, dom_sid);
128 if (!ref->domains[num].sid) {
129 return -1;
132 return num;
136 /***************************************************************************
137 initialize a lsa_DomainInfo structure.
138 ***************************************************************************/
140 static void init_dom_query_3(struct lsa_DomainInfo *r,
141 const char *name,
142 struct dom_sid *sid)
144 init_lsa_StringLarge(&r->name, name);
145 r->sid = sid;
148 /***************************************************************************
149 initialize a lsa_DomainInfo structure.
150 ***************************************************************************/
152 static void init_dom_query_5(struct lsa_DomainInfo *r,
153 const char *name,
154 struct dom_sid *sid)
156 init_lsa_StringLarge(&r->name, name);
157 r->sid = sid;
160 /***************************************************************************
161 lookup_lsa_rids. Must be called as root for lookup_name to work.
162 ***************************************************************************/
164 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
165 struct lsa_RefDomainList *ref,
166 struct lsa_TranslatedSid *prid,
167 uint32_t num_entries,
168 struct lsa_String *name,
169 int flags,
170 uint32_t *pmapped_count)
172 uint32 mapped_count, i;
174 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
176 mapped_count = 0;
177 *pmapped_count = 0;
179 for (i = 0; i < num_entries; i++) {
180 struct dom_sid sid;
181 uint32 rid;
182 int dom_idx;
183 const char *full_name;
184 const char *domain;
185 enum lsa_SidType type = SID_NAME_UNKNOWN;
187 /* Split name into domain and user component */
189 /* follow w2k8 behavior and return the builtin domain when no
190 * input has been passed in */
192 if (name[i].string) {
193 full_name = name[i].string;
194 } else {
195 full_name = "BUILTIN";
198 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
200 /* We can ignore the result of lookup_name, it will not touch
201 "type" if it's not successful */
203 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
204 &sid, &type);
206 switch (type) {
207 case SID_NAME_USER:
208 case SID_NAME_DOM_GRP:
209 case SID_NAME_DOMAIN:
210 case SID_NAME_ALIAS:
211 case SID_NAME_WKN_GRP:
212 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
213 /* Leave these unchanged */
214 break;
215 default:
216 /* Don't hand out anything but the list above */
217 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
218 type = SID_NAME_UNKNOWN;
219 break;
222 rid = 0;
223 dom_idx = -1;
225 if (type != SID_NAME_UNKNOWN) {
226 if (type == SID_NAME_DOMAIN) {
227 rid = (uint32_t)-1;
228 } else {
229 sid_split_rid(&sid, &rid);
231 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
232 mapped_count++;
235 prid[i].sid_type = type;
236 prid[i].rid = rid;
237 prid[i].sid_index = dom_idx;
240 *pmapped_count = mapped_count;
241 return NT_STATUS_OK;
244 /***************************************************************************
245 lookup_lsa_sids. Must be called as root for lookup_name to work.
246 ***************************************************************************/
248 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
249 struct lsa_RefDomainList *ref,
250 struct lsa_TranslatedSid3 *trans_sids,
251 uint32_t num_entries,
252 struct lsa_String *name,
253 int flags,
254 uint32 *pmapped_count)
256 uint32 mapped_count, i;
258 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
260 mapped_count = 0;
261 *pmapped_count = 0;
263 for (i = 0; i < num_entries; i++) {
264 struct dom_sid sid;
265 uint32 rid;
266 int dom_idx;
267 const char *full_name;
268 const char *domain;
269 enum lsa_SidType type = SID_NAME_UNKNOWN;
271 ZERO_STRUCT(sid);
273 /* Split name into domain and user component */
275 full_name = name[i].string;
276 if (full_name == NULL) {
277 return NT_STATUS_NO_MEMORY;
280 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
282 /* We can ignore the result of lookup_name, it will not touch
283 "type" if it's not successful */
285 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
286 &sid, &type);
288 switch (type) {
289 case SID_NAME_USER:
290 case SID_NAME_DOM_GRP:
291 case SID_NAME_DOMAIN:
292 case SID_NAME_ALIAS:
293 case SID_NAME_WKN_GRP:
294 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
295 /* Leave these unchanged */
296 break;
297 default:
298 /* Don't hand out anything but the list above */
299 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
300 type = SID_NAME_UNKNOWN;
301 break;
304 rid = 0;
305 dom_idx = -1;
307 if (type != SID_NAME_UNKNOWN) {
308 struct dom_sid domain_sid;
309 sid_copy(&domain_sid, &sid);
310 sid_split_rid(&domain_sid, &rid);
311 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
312 mapped_count++;
315 /* Initialize the lsa_TranslatedSid3 return. */
316 trans_sids[i].sid_type = type;
317 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
318 trans_sids[i].sid_index = dom_idx;
321 *pmapped_count = mapped_count;
322 return NT_STATUS_OK;
325 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
326 const struct generic_mapping *map,
327 struct dom_sid *sid, uint32_t sid_access)
329 struct dom_sid adm_sid;
330 struct security_ace ace[5];
331 size_t i = 0;
333 struct security_acl *psa = NULL;
335 /* READ|EXECUTE access for Everyone */
337 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
338 map->generic_execute | map->generic_read, 0);
340 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
342 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
343 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
344 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
345 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
347 /* Add Full Access for Domain Admins */
348 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
349 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
350 map->generic_all, 0);
352 /* If we have a sid, give it some special access */
354 if (sid) {
355 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
356 sid_access, 0);
359 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
360 return NT_STATUS_NO_MEMORY;
362 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
363 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
364 psa, sd_size)) == NULL)
365 return NT_STATUS_NO_MEMORY;
367 return NT_STATUS_OK;
370 /***************************************************************************
371 ***************************************************************************/
373 static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
374 struct pipes_struct *p,
375 enum lsa_handle_type type,
376 uint32_t acc_granted,
377 struct dom_sid *sid,
378 const char *name,
379 const struct security_descriptor *sd,
380 struct policy_handle *handle)
382 struct lsa_info *info;
384 ZERO_STRUCTP(handle);
386 info = talloc_zero(mem_ctx, struct lsa_info);
387 if (!info) {
388 return NT_STATUS_NO_MEMORY;
391 info->type = type;
392 info->access = acc_granted;
394 if (sid) {
395 sid_copy(&info->sid, sid);
398 info->name = talloc_strdup(info, name);
400 if (sd) {
401 info->sd = dup_sec_desc(info, sd);
402 if (!info->sd) {
403 talloc_free(info);
404 return NT_STATUS_NO_MEMORY;
408 if (!create_policy_hnd(p, handle, info)) {
409 talloc_free(info);
410 ZERO_STRUCTP(handle);
411 return NT_STATUS_NO_MEMORY;
414 return NT_STATUS_OK;
417 /***************************************************************************
418 _lsa_OpenPolicy2
419 ***************************************************************************/
421 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
422 struct lsa_OpenPolicy2 *r)
424 struct security_descriptor *psd = NULL;
425 size_t sd_size;
426 uint32 des_access = r->in.access_mask;
427 uint32 acc_granted;
428 NTSTATUS status;
430 /* Work out max allowed. */
431 map_max_allowed_access(p->server_info->security_token,
432 &p->server_info->utok,
433 &des_access);
435 /* map the generic bits to the lsa policy ones */
436 se_map_generic(&des_access, &lsa_policy_mapping);
438 /* get the generic lsa policy SD until we store it */
439 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
440 NULL, 0);
441 if (!NT_STATUS_IS_OK(status)) {
442 return status;
445 status = access_check_object(psd, p->server_info->security_token,
446 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
447 &acc_granted, "_lsa_OpenPolicy2" );
448 if (!NT_STATUS_IS_OK(status)) {
449 return status;
452 status = create_lsa_policy_handle(p->mem_ctx, p,
453 LSA_HANDLE_POLICY_TYPE,
454 acc_granted,
455 get_global_sam_sid(),
456 NULL,
457 psd,
458 r->out.handle);
459 if (!NT_STATUS_IS_OK(status)) {
460 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
463 return NT_STATUS_OK;
466 /***************************************************************************
467 _lsa_OpenPolicy
468 ***************************************************************************/
470 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
471 struct lsa_OpenPolicy *r)
473 struct lsa_OpenPolicy2 o;
475 o.in.system_name = NULL; /* should be ignored */
476 o.in.attr = r->in.attr;
477 o.in.access_mask = r->in.access_mask;
479 o.out.handle = r->out.handle;
481 return _lsa_OpenPolicy2(p, &o);
484 /***************************************************************************
485 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
486 ufff, done :) mimir
487 ***************************************************************************/
489 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
490 struct lsa_EnumTrustDom *r)
492 struct lsa_info *info;
493 uint32_t count;
494 struct trustdom_info **domains;
495 struct lsa_DomainInfo *entries;
496 int i;
497 NTSTATUS nt_status;
499 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
500 return NT_STATUS_INVALID_HANDLE;
502 if (info->type != LSA_HANDLE_POLICY_TYPE) {
503 return NT_STATUS_INVALID_HANDLE;
506 /* check if the user has enough rights */
507 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
508 return NT_STATUS_ACCESS_DENIED;
510 become_root();
511 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
512 unbecome_root();
514 if (!NT_STATUS_IS_OK(nt_status)) {
515 return nt_status;
518 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo, count);
519 if (!entries) {
520 return NT_STATUS_NO_MEMORY;
523 for (i=0; i<count; i++) {
524 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
525 entries[i].sid = &domains[i]->sid;
528 if (*r->in.resume_handle >= count) {
529 *r->out.resume_handle = -1;
530 TALLOC_FREE(entries);
531 return NT_STATUS_NO_MORE_ENTRIES;
534 /* return the rest, limit by max_size. Note that we
535 use the w2k3 element size value of 60 */
536 r->out.domains->count = count - *r->in.resume_handle;
537 r->out.domains->count = MIN(r->out.domains->count,
538 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
540 r->out.domains->domains = entries + *r->in.resume_handle;
542 if (r->out.domains->count < count - *r->in.resume_handle) {
543 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
544 return STATUS_MORE_ENTRIES;
547 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
548 * always be larger than the previous input resume handle, in
549 * particular when hitting the last query it is vital to set the
550 * resume handle correctly to avoid infinite client loops, as
551 * seen e.g. with Windows XP SP3 when resume handle is 0 and
552 * status is NT_STATUS_OK - gd */
554 *r->out.resume_handle = (uint32_t)-1;
556 return NT_STATUS_OK;
559 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
560 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
561 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
563 /***************************************************************************
564 _lsa_QueryInfoPolicy
565 ***************************************************************************/
567 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
568 struct lsa_QueryInfoPolicy *r)
570 NTSTATUS status = NT_STATUS_OK;
571 struct lsa_info *handle;
572 struct dom_sid domain_sid;
573 const char *name;
574 struct dom_sid *sid = NULL;
575 union lsa_PolicyInformation *info = NULL;
576 uint32_t acc_required = 0;
578 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
579 return NT_STATUS_INVALID_HANDLE;
581 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
582 return NT_STATUS_INVALID_HANDLE;
585 switch (r->in.level) {
586 case LSA_POLICY_INFO_AUDIT_LOG:
587 case LSA_POLICY_INFO_AUDIT_EVENTS:
588 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
589 break;
590 case LSA_POLICY_INFO_DOMAIN:
591 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
592 break;
593 case LSA_POLICY_INFO_PD:
594 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
595 break;
596 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
597 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
598 break;
599 case LSA_POLICY_INFO_ROLE:
600 case LSA_POLICY_INFO_REPLICA:
601 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
602 break;
603 case LSA_POLICY_INFO_QUOTA:
604 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
605 break;
606 case LSA_POLICY_INFO_MOD:
607 case LSA_POLICY_INFO_AUDIT_FULL_SET:
608 /* according to MS-LSAD 3.1.4.4.3 */
609 return NT_STATUS_INVALID_PARAMETER;
610 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
611 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
612 break;
613 case LSA_POLICY_INFO_DNS:
614 case LSA_POLICY_INFO_DNS_INT:
615 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
616 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
617 break;
618 default:
619 break;
622 if (!(handle->access & acc_required)) {
623 /* return NT_STATUS_ACCESS_DENIED; */
626 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
627 if (!info) {
628 return NT_STATUS_NO_MEMORY;
631 switch (r->in.level) {
632 /* according to MS-LSAD 3.1.4.4.3 */
633 case LSA_POLICY_INFO_MOD:
634 case LSA_POLICY_INFO_AUDIT_FULL_SET:
635 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
636 return NT_STATUS_INVALID_PARAMETER;
637 case LSA_POLICY_INFO_AUDIT_LOG:
638 info->audit_log.percent_full = 0;
639 info->audit_log.maximum_log_size = 0;
640 info->audit_log.retention_time = 0;
641 info->audit_log.shutdown_in_progress = 0;
642 info->audit_log.time_to_shutdown = 0;
643 info->audit_log.next_audit_record = 0;
644 status = NT_STATUS_OK;
645 break;
646 case LSA_POLICY_INFO_PD:
647 info->pd.name.string = NULL;
648 status = NT_STATUS_OK;
649 break;
650 case LSA_POLICY_INFO_REPLICA:
651 info->replica.source.string = NULL;
652 info->replica.account.string = NULL;
653 status = NT_STATUS_OK;
654 break;
655 case LSA_POLICY_INFO_QUOTA:
656 info->quota.paged_pool = 0;
657 info->quota.non_paged_pool = 0;
658 info->quota.min_wss = 0;
659 info->quota.max_wss = 0;
660 info->quota.pagefile = 0;
661 info->quota.unknown = 0;
662 status = NT_STATUS_OK;
663 break;
664 case LSA_POLICY_INFO_AUDIT_EVENTS:
667 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
669 /* check if the user has enough rights */
670 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
671 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
672 return NT_STATUS_ACCESS_DENIED;
675 /* fake info: We audit everything. ;) */
677 info->audit_events.auditing_mode = true;
678 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
679 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
680 enum lsa_PolicyAuditPolicy,
681 info->audit_events.count);
682 if (!info->audit_events.settings) {
683 return NT_STATUS_NO_MEMORY;
686 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
687 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
688 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
689 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
690 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
691 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
692 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
694 break;
696 case LSA_POLICY_INFO_DOMAIN:
697 /* check if the user has enough rights */
698 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
699 return NT_STATUS_ACCESS_DENIED;
701 /* Request PolicyPrimaryDomainInformation. */
702 switch (lp_server_role()) {
703 case ROLE_DOMAIN_PDC:
704 case ROLE_DOMAIN_BDC:
705 name = get_global_sam_name();
706 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
707 if (!sid) {
708 return NT_STATUS_NO_MEMORY;
710 break;
711 case ROLE_DOMAIN_MEMBER:
712 name = lp_workgroup();
713 /* We need to return the Domain SID here. */
714 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
715 sid = dom_sid_dup(p->mem_ctx, &domain_sid);
716 if (!sid) {
717 return NT_STATUS_NO_MEMORY;
719 } else {
720 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
722 break;
723 case ROLE_STANDALONE:
724 name = lp_workgroup();
725 sid = NULL;
726 break;
727 default:
728 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
730 init_dom_query_3(&info->domain, name, sid);
731 break;
732 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
733 /* check if the user has enough rights */
734 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
735 return NT_STATUS_ACCESS_DENIED;
737 /* Request PolicyAccountDomainInformation. */
738 name = get_global_sam_name();
739 sid = get_global_sam_sid();
741 init_dom_query_5(&info->account_domain, name, sid);
742 break;
743 case LSA_POLICY_INFO_ROLE:
744 /* check if the user has enough rights */
745 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
746 return NT_STATUS_ACCESS_DENIED;
748 switch (lp_server_role()) {
749 case ROLE_DOMAIN_BDC:
751 * only a BDC is a backup controller
752 * of the domain, it controls.
754 info->role.role = LSA_ROLE_BACKUP;
755 break;
756 default:
758 * any other role is a primary
759 * of the domain, it controls.
761 info->role.role = LSA_ROLE_PRIMARY;
762 break;
764 break;
765 case LSA_POLICY_INFO_DNS:
766 case LSA_POLICY_INFO_DNS_INT: {
767 struct pdb_domain_info *dominfo;
769 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
770 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
771 "without ADS passdb backend\n"));
772 status = NT_STATUS_INVALID_INFO_CLASS;
773 break;
776 dominfo = pdb_get_domain_info(info);
777 if (dominfo == NULL) {
778 status = NT_STATUS_NO_MEMORY;
779 break;
782 init_lsa_StringLarge(&info->dns.name,
783 dominfo->name);
784 init_lsa_StringLarge(&info->dns.dns_domain,
785 dominfo->dns_domain);
786 init_lsa_StringLarge(&info->dns.dns_forest,
787 dominfo->dns_forest);
788 info->dns.domain_guid = dominfo->guid;
789 info->dns.sid = &dominfo->sid;
790 break;
792 default:
793 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
794 r->in.level));
795 status = NT_STATUS_INVALID_INFO_CLASS;
796 break;
799 *r->out.info = info;
801 return status;
804 /***************************************************************************
805 _lsa_QueryInfoPolicy2
806 ***************************************************************************/
808 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
809 struct lsa_QueryInfoPolicy2 *r2)
811 struct lsa_QueryInfoPolicy r;
813 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
814 p->rng_fault_state = True;
815 return NT_STATUS_NOT_IMPLEMENTED;
818 ZERO_STRUCT(r);
819 r.in.handle = r2->in.handle;
820 r.in.level = r2->in.level;
821 r.out.info = r2->out.info;
823 return _lsa_QueryInfoPolicy(p, &r);
826 /***************************************************************************
827 _lsa_lookup_sids_internal
828 ***************************************************************************/
830 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
831 TALLOC_CTX *mem_ctx,
832 uint16_t level, /* input */
833 int num_sids, /* input */
834 struct lsa_SidPtr *sid, /* input */
835 struct lsa_RefDomainList **pp_ref, /* input/output */
836 struct lsa_TranslatedName2 **pp_names,/* input/output */
837 uint32_t *pp_mapped_count) /* input/output */
839 NTSTATUS status;
840 int i;
841 const struct dom_sid **sids = NULL;
842 struct lsa_RefDomainList *ref = NULL;
843 uint32 mapped_count = 0;
844 struct lsa_dom_info *dom_infos = NULL;
845 struct lsa_name_info *name_infos = NULL;
846 struct lsa_TranslatedName2 *names = NULL;
848 *pp_mapped_count = 0;
849 *pp_names = NULL;
850 *pp_ref = NULL;
852 if (num_sids == 0) {
853 return NT_STATUS_OK;
856 sids = TALLOC_ARRAY(p->mem_ctx, const struct dom_sid *, num_sids);
857 ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
859 if (sids == NULL || ref == NULL) {
860 return NT_STATUS_NO_MEMORY;
863 for (i=0; i<num_sids; i++) {
864 sids[i] = sid[i].sid;
867 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
868 &dom_infos, &name_infos);
870 if (!NT_STATUS_IS_OK(status)) {
871 return status;
874 names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
875 if (names == NULL) {
876 return NT_STATUS_NO_MEMORY;
879 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
881 if (!dom_infos[i].valid) {
882 break;
885 if (init_lsa_ref_domain_list(mem_ctx, ref,
886 dom_infos[i].name,
887 &dom_infos[i].sid) != i) {
888 DEBUG(0, ("Domain %s mentioned twice??\n",
889 dom_infos[i].name));
890 return NT_STATUS_INTERNAL_ERROR;
894 for (i=0; i<num_sids; i++) {
895 struct lsa_name_info *name = &name_infos[i];
897 if (name->type == SID_NAME_UNKNOWN) {
898 fstring tmp;
899 name->dom_idx = -1;
900 /* Unknown sids should return the string
901 * representation of the SID. Windows 2003 behaves
902 * rather erratic here, in many cases it returns the
903 * RID as 8 bytes hex, in others it returns the full
904 * SID. We (Jerry/VL) could not figure out which the
905 * hard cases are, so leave it with the SID. */
906 name->name = talloc_asprintf(p->mem_ctx, "%s",
907 sid_to_fstring(tmp,
908 sids[i]));
909 if (name->name == NULL) {
910 return NT_STATUS_NO_MEMORY;
912 } else {
913 mapped_count += 1;
916 names[i].sid_type = name->type;
917 names[i].name.string = name->name;
918 names[i].sid_index = name->dom_idx;
919 names[i].unknown = 0;
922 status = NT_STATUS_NONE_MAPPED;
923 if (mapped_count > 0) {
924 status = (mapped_count < num_sids) ?
925 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
928 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
929 num_sids, mapped_count, nt_errstr(status)));
931 *pp_mapped_count = mapped_count;
932 *pp_names = names;
933 *pp_ref = ref;
935 return status;
938 /***************************************************************************
939 _lsa_LookupSids
940 ***************************************************************************/
942 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
943 struct lsa_LookupSids *r)
945 NTSTATUS status;
946 struct lsa_info *handle;
947 int num_sids = r->in.sids->num_sids;
948 uint32 mapped_count = 0;
949 struct lsa_RefDomainList *domains = NULL;
950 struct lsa_TranslatedName *names_out = NULL;
951 struct lsa_TranslatedName2 *names = NULL;
952 int i;
954 if ((r->in.level < 1) || (r->in.level > 6)) {
955 return NT_STATUS_INVALID_PARAMETER;
958 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
959 return NT_STATUS_INVALID_HANDLE;
962 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
963 return NT_STATUS_INVALID_HANDLE;
966 /* check if the user has enough rights */
967 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
968 return NT_STATUS_ACCESS_DENIED;
971 if (num_sids > MAX_LOOKUP_SIDS) {
972 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
973 MAX_LOOKUP_SIDS, num_sids));
974 return NT_STATUS_NONE_MAPPED;
977 status = _lsa_lookup_sids_internal(p,
978 p->mem_ctx,
979 r->in.level,
980 num_sids,
981 r->in.sids->sids,
982 &domains,
983 &names,
984 &mapped_count);
986 /* Only return here when there is a real error.
987 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
988 the requested sids could be resolved. Older versions of XP (pre SP3)
989 rely that we return with the string representations of those SIDs in
990 that case. If we don't, XP crashes - Guenther
993 if (NT_STATUS_IS_ERR(status) &&
994 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
995 return status;
998 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
999 names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
1000 num_sids);
1001 if (!names_out) {
1002 return NT_STATUS_NO_MEMORY;
1005 for (i=0; i<num_sids; i++) {
1006 names_out[i].sid_type = names[i].sid_type;
1007 names_out[i].name = names[i].name;
1008 names_out[i].sid_index = names[i].sid_index;
1011 *r->out.domains = domains;
1012 r->out.names->count = num_sids;
1013 r->out.names->names = names_out;
1014 *r->out.count = mapped_count;
1016 return status;
1019 /***************************************************************************
1020 _lsa_LookupSids2
1021 ***************************************************************************/
1023 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1024 struct lsa_LookupSids2 *r)
1026 NTSTATUS status;
1027 struct lsa_info *handle;
1028 int num_sids = r->in.sids->num_sids;
1029 uint32 mapped_count = 0;
1030 struct lsa_RefDomainList *domains = NULL;
1031 struct lsa_TranslatedName2 *names = NULL;
1032 bool check_policy = true;
1034 switch (p->opnum) {
1035 case NDR_LSA_LOOKUPSIDS3:
1036 check_policy = false;
1037 break;
1038 case NDR_LSA_LOOKUPSIDS2:
1039 default:
1040 check_policy = true;
1043 if ((r->in.level < 1) || (r->in.level > 6)) {
1044 return NT_STATUS_INVALID_PARAMETER;
1047 if (check_policy) {
1048 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1049 return NT_STATUS_INVALID_HANDLE;
1052 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1053 return NT_STATUS_INVALID_HANDLE;
1056 /* check if the user has enough rights */
1057 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1058 return NT_STATUS_ACCESS_DENIED;
1062 if (num_sids > MAX_LOOKUP_SIDS) {
1063 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1064 MAX_LOOKUP_SIDS, num_sids));
1065 return NT_STATUS_NONE_MAPPED;
1068 status = _lsa_lookup_sids_internal(p,
1069 p->mem_ctx,
1070 r->in.level,
1071 num_sids,
1072 r->in.sids->sids,
1073 &domains,
1074 &names,
1075 &mapped_count);
1077 *r->out.domains = domains;
1078 r->out.names->count = num_sids;
1079 r->out.names->names = names;
1080 *r->out.count = mapped_count;
1082 return status;
1085 /***************************************************************************
1086 _lsa_LookupSids3
1087 ***************************************************************************/
1089 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1090 struct lsa_LookupSids3 *r)
1092 struct lsa_LookupSids2 q;
1094 /* No policy handle on this call. Restrict to crypto connections. */
1095 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1096 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1097 get_remote_machine_name() ));
1098 return NT_STATUS_INVALID_PARAMETER;
1101 q.in.handle = NULL;
1102 q.in.sids = r->in.sids;
1103 q.in.level = r->in.level;
1104 q.in.lookup_options = r->in.lookup_options;
1105 q.in.client_revision = r->in.client_revision;
1106 q.in.names = r->in.names;
1107 q.in.count = r->in.count;
1109 q.out.domains = r->out.domains;
1110 q.out.names = r->out.names;
1111 q.out.count = r->out.count;
1113 return _lsa_LookupSids2(p, &q);
1116 /***************************************************************************
1117 ***************************************************************************/
1119 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1121 int flags;
1123 switch (level) {
1124 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1125 flags = LOOKUP_NAME_ALL;
1126 break;
1127 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1128 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1129 break;
1130 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1131 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1132 break;
1133 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1134 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1135 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1136 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1137 default:
1138 flags = LOOKUP_NAME_NONE;
1139 break;
1142 return flags;
1145 /***************************************************************************
1146 _lsa_LookupNames
1147 ***************************************************************************/
1149 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1150 struct lsa_LookupNames *r)
1152 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1153 struct lsa_info *handle;
1154 struct lsa_String *names = r->in.names;
1155 uint32 num_entries = r->in.num_names;
1156 struct lsa_RefDomainList *domains = NULL;
1157 struct lsa_TranslatedSid *rids = NULL;
1158 uint32 mapped_count = 0;
1159 int flags = 0;
1161 if (num_entries > MAX_LOOKUP_SIDS) {
1162 num_entries = MAX_LOOKUP_SIDS;
1163 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1164 num_entries));
1167 flags = lsa_lookup_level_to_flags(r->in.level);
1169 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1170 if (!domains) {
1171 return NT_STATUS_NO_MEMORY;
1174 if (num_entries) {
1175 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1176 num_entries);
1177 if (!rids) {
1178 return NT_STATUS_NO_MEMORY;
1180 } else {
1181 rids = NULL;
1184 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1185 status = NT_STATUS_INVALID_HANDLE;
1186 goto done;
1189 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1190 return NT_STATUS_INVALID_HANDLE;
1193 /* check if the user has enough rights */
1194 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1195 status = NT_STATUS_ACCESS_DENIED;
1196 goto done;
1199 /* set up the LSA Lookup RIDs response */
1200 become_root(); /* lookup_name can require root privs */
1201 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1202 names, flags, &mapped_count);
1203 unbecome_root();
1205 done:
1207 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1208 if (mapped_count == 0) {
1209 status = NT_STATUS_NONE_MAPPED;
1210 } else if (mapped_count != num_entries) {
1211 status = STATUS_SOME_UNMAPPED;
1215 *r->out.count = mapped_count;
1216 *r->out.domains = domains;
1217 r->out.sids->sids = rids;
1218 r->out.sids->count = num_entries;
1220 return status;
1223 /***************************************************************************
1224 _lsa_LookupNames2
1225 ***************************************************************************/
1227 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1228 struct lsa_LookupNames2 *r)
1230 NTSTATUS status;
1231 struct lsa_LookupNames q;
1232 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1233 struct lsa_TransSidArray *sid_array = NULL;
1234 uint32_t i;
1236 sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1237 if (!sid_array) {
1238 return NT_STATUS_NO_MEMORY;
1241 q.in.handle = r->in.handle;
1242 q.in.num_names = r->in.num_names;
1243 q.in.names = r->in.names;
1244 q.in.level = r->in.level;
1245 q.in.sids = sid_array;
1246 q.in.count = r->in.count;
1247 /* we do not know what this is for */
1248 /* = r->in.unknown1; */
1249 /* = r->in.unknown2; */
1251 q.out.domains = r->out.domains;
1252 q.out.sids = sid_array;
1253 q.out.count = r->out.count;
1255 status = _lsa_LookupNames(p, &q);
1257 sid_array2->count = sid_array->count;
1258 sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1259 if (!sid_array2->sids) {
1260 return NT_STATUS_NO_MEMORY;
1263 for (i=0; i<sid_array->count; i++) {
1264 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1265 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1266 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1267 sid_array2->sids[i].unknown = 0;
1270 r->out.sids = sid_array2;
1272 return status;
1275 /***************************************************************************
1276 _lsa_LookupNames3
1277 ***************************************************************************/
1279 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1280 struct lsa_LookupNames3 *r)
1282 NTSTATUS status;
1283 struct lsa_info *handle;
1284 struct lsa_String *names = r->in.names;
1285 uint32 num_entries = r->in.num_names;
1286 struct lsa_RefDomainList *domains = NULL;
1287 struct lsa_TranslatedSid3 *trans_sids = NULL;
1288 uint32 mapped_count = 0;
1289 int flags = 0;
1290 bool check_policy = true;
1292 switch (p->opnum) {
1293 case NDR_LSA_LOOKUPNAMES4:
1294 check_policy = false;
1295 break;
1296 case NDR_LSA_LOOKUPNAMES3:
1297 default:
1298 check_policy = true;
1301 if (num_entries > MAX_LOOKUP_SIDS) {
1302 num_entries = MAX_LOOKUP_SIDS;
1303 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1306 /* Probably the lookup_level is some sort of bitmask. */
1307 if (r->in.level == 1) {
1308 flags = LOOKUP_NAME_ALL;
1311 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1312 if (!domains) {
1313 return NT_STATUS_NO_MEMORY;
1316 if (num_entries) {
1317 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1318 num_entries);
1319 if (!trans_sids) {
1320 return NT_STATUS_NO_MEMORY;
1322 } else {
1323 trans_sids = NULL;
1326 if (check_policy) {
1328 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1329 status = NT_STATUS_INVALID_HANDLE;
1330 goto done;
1333 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1334 return NT_STATUS_INVALID_HANDLE;
1337 /* check if the user has enough rights */
1338 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1339 status = NT_STATUS_ACCESS_DENIED;
1340 goto done;
1344 /* set up the LSA Lookup SIDs response */
1345 become_root(); /* lookup_name can require root privs */
1346 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1347 names, flags, &mapped_count);
1348 unbecome_root();
1350 done:
1352 if (NT_STATUS_IS_OK(status)) {
1353 if (mapped_count == 0) {
1354 status = NT_STATUS_NONE_MAPPED;
1355 } else if (mapped_count != num_entries) {
1356 status = STATUS_SOME_UNMAPPED;
1360 *r->out.count = mapped_count;
1361 *r->out.domains = domains;
1362 r->out.sids->sids = trans_sids;
1363 r->out.sids->count = num_entries;
1365 return status;
1368 /***************************************************************************
1369 _lsa_LookupNames4
1370 ***************************************************************************/
1372 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1373 struct lsa_LookupNames4 *r)
1375 struct lsa_LookupNames3 q;
1377 /* No policy handle on this call. Restrict to crypto connections. */
1378 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1379 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1380 get_remote_machine_name() ));
1381 return NT_STATUS_INVALID_PARAMETER;
1384 q.in.handle = NULL;
1385 q.in.num_names = r->in.num_names;
1386 q.in.names = r->in.names;
1387 q.in.level = r->in.level;
1388 q.in.lookup_options = r->in.lookup_options;
1389 q.in.client_revision = r->in.client_revision;
1390 q.in.sids = r->in.sids;
1391 q.in.count = r->in.count;
1393 q.out.domains = r->out.domains;
1394 q.out.sids = r->out.sids;
1395 q.out.count = r->out.count;
1397 return _lsa_LookupNames3(p, &q);
1400 /***************************************************************************
1401 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1402 ***************************************************************************/
1404 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1406 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1407 return NT_STATUS_INVALID_HANDLE;
1410 close_policy_hnd(p, r->in.handle);
1411 ZERO_STRUCTP(r->out.handle);
1412 return NT_STATUS_OK;
1415 /***************************************************************************
1416 ***************************************************************************/
1418 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1419 const struct dom_sid *sid,
1420 struct trustdom_info **info)
1422 NTSTATUS status;
1423 uint32_t num_domains = 0;
1424 struct trustdom_info **domains = NULL;
1425 int i;
1427 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1428 if (!NT_STATUS_IS_OK(status)) {
1429 return status;
1432 for (i=0; i < num_domains; i++) {
1433 if (dom_sid_equal(&domains[i]->sid, sid)) {
1434 break;
1438 if (i == num_domains) {
1439 return NT_STATUS_INVALID_PARAMETER;
1442 *info = domains[i];
1444 return NT_STATUS_OK;
1447 /***************************************************************************
1448 ***************************************************************************/
1450 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1451 const char *netbios_domain_name,
1452 struct trustdom_info **info_p)
1454 NTSTATUS status;
1455 struct trustdom_info *info;
1456 struct pdb_trusted_domain *td;
1458 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1459 if (!NT_STATUS_IS_OK(status)) {
1460 return status;
1463 info = talloc(mem_ctx, struct trustdom_info);
1464 if (!info) {
1465 return NT_STATUS_NO_MEMORY;
1468 info->name = talloc_strdup(info, netbios_domain_name);
1469 NT_STATUS_HAVE_NO_MEMORY(info->name);
1471 sid_copy(&info->sid, &td->security_identifier);
1473 *info_p = info;
1475 return NT_STATUS_OK;
1478 /***************************************************************************
1479 ***************************************************************************/
1481 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p, struct lsa_OpenSecret *r)
1483 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1486 /***************************************************************************
1487 _lsa_OpenTrustedDomain_base
1488 ***************************************************************************/
1490 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1491 uint32_t access_mask,
1492 struct trustdom_info *info,
1493 struct policy_handle *handle)
1495 struct security_descriptor *psd = NULL;
1496 size_t sd_size;
1497 uint32_t acc_granted;
1498 NTSTATUS status;
1500 /* des_access is for the account here, not the policy
1501 * handle - so don't check against policy handle. */
1503 /* Work out max allowed. */
1504 map_max_allowed_access(p->server_info->security_token,
1505 &p->server_info->utok,
1506 &access_mask);
1508 /* map the generic bits to the lsa account ones */
1509 se_map_generic(&access_mask, &lsa_account_mapping);
1511 /* get the generic lsa account SD until we store it */
1512 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1513 &lsa_trusted_domain_mapping,
1514 NULL, 0);
1515 if (!NT_STATUS_IS_OK(status)) {
1516 return status;
1519 status = access_check_object(psd, p->server_info->security_token,
1520 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1521 access_mask, &acc_granted,
1522 "_lsa_OpenTrustedDomain");
1523 if (!NT_STATUS_IS_OK(status)) {
1524 return status;
1527 status = create_lsa_policy_handle(p->mem_ctx, p,
1528 LSA_HANDLE_TRUST_TYPE,
1529 acc_granted,
1530 &info->sid,
1531 info->name,
1532 psd,
1533 handle);
1534 if (!NT_STATUS_IS_OK(status)) {
1535 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1538 return NT_STATUS_OK;
1541 /***************************************************************************
1542 _lsa_OpenTrustedDomain
1543 ***************************************************************************/
1545 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1546 struct lsa_OpenTrustedDomain *r)
1548 struct lsa_info *handle = NULL;
1549 struct trustdom_info *info;
1550 NTSTATUS status;
1552 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1553 return NT_STATUS_INVALID_HANDLE;
1556 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1557 return NT_STATUS_INVALID_HANDLE;
1560 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1561 r->in.sid,
1562 &info);
1563 if (!NT_STATUS_IS_OK(status)) {
1564 return status;
1567 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1568 r->out.trustdom_handle);
1571 /***************************************************************************
1572 _lsa_OpenTrustedDomainByName
1573 ***************************************************************************/
1575 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1576 struct lsa_OpenTrustedDomainByName *r)
1578 struct lsa_info *handle = NULL;
1579 struct trustdom_info *info;
1580 NTSTATUS status;
1582 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1583 return NT_STATUS_INVALID_HANDLE;
1586 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1587 return NT_STATUS_INVALID_HANDLE;
1590 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1591 r->in.name.string,
1592 &info);
1593 if (!NT_STATUS_IS_OK(status)) {
1594 return status;
1597 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1598 r->out.trustdom_handle);
1601 /***************************************************************************
1602 _lsa_CreateTrustedDomainEx2
1603 ***************************************************************************/
1605 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1606 struct lsa_CreateTrustedDomainEx2 *r)
1608 struct lsa_info *policy;
1609 NTSTATUS status;
1610 uint32_t acc_granted;
1611 struct security_descriptor *psd;
1612 size_t sd_size;
1613 struct pdb_trusted_domain td;
1614 struct trustDomainPasswords auth_struct;
1615 enum ndr_err_code ndr_err;
1616 DATA_BLOB auth_blob;
1618 if (!IS_DC) {
1619 return NT_STATUS_NOT_SUPPORTED;
1622 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1623 return NT_STATUS_INVALID_HANDLE;
1626 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1627 return NT_STATUS_ACCESS_DENIED;
1630 if (p->server_info->utok.uid != sec_initial_uid() &&
1631 !nt_token_check_domain_rid(p->server_info->security_token, DOMAIN_RID_ADMINS)) {
1632 return NT_STATUS_ACCESS_DENIED;
1635 /* Work out max allowed. */
1636 map_max_allowed_access(p->server_info->security_token,
1637 &p->server_info->utok,
1638 &r->in.access_mask);
1640 /* map the generic bits to the lsa policy ones */
1641 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1643 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1644 &lsa_trusted_domain_mapping,
1645 NULL, 0);
1646 if (!NT_STATUS_IS_OK(status)) {
1647 return status;
1650 status = access_check_object(psd, p->server_info->security_token,
1651 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1652 r->in.access_mask, &acc_granted,
1653 "_lsa_CreateTrustedDomainEx2");
1654 if (!NT_STATUS_IS_OK(status)) {
1655 return status;
1658 ZERO_STRUCT(td);
1660 td.domain_name = talloc_strdup(p->mem_ctx,
1661 r->in.info->domain_name.string);
1662 if (td.domain_name == NULL) {
1663 return NT_STATUS_NO_MEMORY;
1665 td.netbios_name = talloc_strdup(p->mem_ctx,
1666 r->in.info->netbios_name.string);
1667 if (td.netbios_name == NULL) {
1668 return NT_STATUS_NO_MEMORY;
1670 sid_copy(&td.security_identifier, r->in.info->sid);
1671 td.trust_direction = r->in.info->trust_direction;
1672 td.trust_type = r->in.info->trust_type;
1673 td.trust_attributes = r->in.info->trust_attributes;
1675 if (r->in.auth_info->auth_blob.size != 0) {
1676 auth_blob.length = r->in.auth_info->auth_blob.size;
1677 auth_blob.data = r->in.auth_info->auth_blob.data;
1679 arcfour_crypt_blob(auth_blob.data, auth_blob.length,
1680 &p->server_info->user_session_key);
1682 ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
1683 &auth_struct,
1684 (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
1685 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1686 return NT_STATUS_UNSUCCESSFUL;
1689 ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
1690 &auth_struct.incoming,
1691 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1692 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1693 return NT_STATUS_UNSUCCESSFUL;
1696 ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
1697 &auth_struct.outgoing,
1698 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1699 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1700 return NT_STATUS_UNSUCCESSFUL;
1702 } else {
1703 td.trust_auth_incoming.data = NULL;
1704 td.trust_auth_incoming.length = 0;
1705 td.trust_auth_outgoing.data = NULL;
1706 td.trust_auth_outgoing.length = 0;
1709 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1710 if (!NT_STATUS_IS_OK(status)) {
1711 return status;
1714 status = create_lsa_policy_handle(p->mem_ctx, p,
1715 LSA_HANDLE_TRUST_TYPE,
1716 acc_granted,
1717 r->in.info->sid,
1718 r->in.info->netbios_name.string,
1719 psd,
1720 r->out.trustdom_handle);
1721 if (!NT_STATUS_IS_OK(status)) {
1722 pdb_del_trusteddom_pw(r->in.info->netbios_name.string);
1723 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1726 return NT_STATUS_OK;
1729 /***************************************************************************
1730 _lsa_CreateTrustedDomainEx
1731 ***************************************************************************/
1733 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1734 struct lsa_CreateTrustedDomainEx *r)
1736 struct lsa_CreateTrustedDomainEx2 q;
1738 q.in.policy_handle = r->in.policy_handle;
1739 q.in.info = r->in.info;
1740 q.in.auth_info = r->in.auth_info;
1741 q.in.access_mask = r->in.access_mask;
1742 q.out.trustdom_handle = r->out.trustdom_handle;
1744 return _lsa_CreateTrustedDomainEx2(p, &q);
1747 /***************************************************************************
1748 _lsa_CreateTrustedDomain
1749 ***************************************************************************/
1751 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1752 struct lsa_CreateTrustedDomain *r)
1754 struct lsa_CreateTrustedDomainEx2 c;
1755 struct lsa_TrustDomainInfoInfoEx info;
1756 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1758 ZERO_STRUCT(auth_info);
1760 info.domain_name = r->in.info->name;
1761 info.netbios_name = r->in.info->name;
1762 info.sid = r->in.info->sid;
1763 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1764 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1765 info.trust_attributes = 0;
1767 c.in.policy_handle = r->in.policy_handle;
1768 c.in.info = &info;
1769 c.in.auth_info = &auth_info;
1770 c.in.access_mask = r->in.access_mask;
1771 c.out.trustdom_handle = r->out.trustdom_handle;
1773 return _lsa_CreateTrustedDomainEx2(p, &c);
1776 /***************************************************************************
1777 _lsa_DeleteTrustedDomain
1778 ***************************************************************************/
1780 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1781 struct lsa_DeleteTrustedDomain *r)
1783 NTSTATUS status;
1784 struct lsa_info *handle;
1785 struct trustdom_info *info;
1787 /* find the connection policy handle. */
1788 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1789 return NT_STATUS_INVALID_HANDLE;
1792 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1793 return NT_STATUS_INVALID_HANDLE;
1796 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1797 return NT_STATUS_ACCESS_DENIED;
1800 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1801 r->in.dom_sid,
1802 &info);
1803 if (!NT_STATUS_IS_OK(status)) {
1804 return status;
1807 status = pdb_del_trusted_domain(info->name);
1808 if (!NT_STATUS_IS_OK(status)) {
1809 return status;
1812 return NT_STATUS_OK;
1815 /***************************************************************************
1816 _lsa_CloseTrustedDomainEx
1817 ***************************************************************************/
1819 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1820 struct lsa_CloseTrustedDomainEx *r)
1822 return NT_STATUS_NOT_IMPLEMENTED;
1825 /***************************************************************************
1826 _lsa_QueryTrustedDomainInfo
1827 ***************************************************************************/
1829 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
1830 struct lsa_QueryTrustedDomainInfo *r)
1832 NTSTATUS status;
1833 struct lsa_info *handle;
1834 union lsa_TrustedDomainInfo *info;
1835 struct pdb_trusted_domain *td;
1836 uint32_t acc_required;
1838 /* find the connection policy handle. */
1839 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
1840 return NT_STATUS_INVALID_HANDLE;
1843 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
1844 return NT_STATUS_INVALID_HANDLE;
1847 switch (r->in.level) {
1848 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1849 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1850 break;
1851 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1852 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
1853 break;
1854 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1855 acc_required = LSA_TRUSTED_QUERY_POSIX;
1856 break;
1857 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
1858 acc_required = LSA_TRUSTED_QUERY_AUTH;
1859 break;
1860 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1861 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1862 break;
1863 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1864 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1865 break;
1866 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1867 acc_required = LSA_TRUSTED_QUERY_AUTH;
1868 break;
1869 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1870 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1871 LSA_TRUSTED_QUERY_POSIX |
1872 LSA_TRUSTED_QUERY_AUTH;
1873 break;
1874 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1875 acc_required = LSA_TRUSTED_QUERY_AUTH;
1876 break;
1877 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1878 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1879 LSA_TRUSTED_QUERY_POSIX |
1880 LSA_TRUSTED_QUERY_AUTH;
1881 break;
1882 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1883 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1884 break;
1885 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1886 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1887 LSA_TRUSTED_QUERY_POSIX |
1888 LSA_TRUSTED_QUERY_AUTH;
1889 break;
1890 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1891 acc_required = LSA_TRUSTED_QUERY_POSIX;
1892 break;
1893 default:
1894 return NT_STATUS_INVALID_PARAMETER;
1897 if (!(handle->access & acc_required)) {
1898 return NT_STATUS_ACCESS_DENIED;
1901 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
1902 if (!NT_STATUS_IS_OK(status)) {
1903 return status;
1906 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_TrustedDomainInfo);
1907 if (!info) {
1908 return NT_STATUS_NO_MEMORY;
1911 switch (r->in.level) {
1912 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1913 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
1914 break;
1915 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1916 return NT_STATUS_INVALID_PARAMETER;
1917 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1918 break;
1919 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
1920 return NT_STATUS_INVALID_INFO_CLASS;
1921 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1922 return NT_STATUS_INVALID_PARAMETER;
1923 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1924 init_lsa_StringLarge(&info->info_ex.domain_name, td->domain_name);
1925 init_lsa_StringLarge(&info->info_ex.netbios_name, td->netbios_name);
1926 info->info_ex.sid = dom_sid_dup(info, &td->security_identifier);
1927 if (!info->info_ex.sid) {
1928 return NT_STATUS_NO_MEMORY;
1930 info->info_ex.trust_direction = td->trust_direction;
1931 info->info_ex.trust_type = td->trust_type;
1932 info->info_ex.trust_attributes = td->trust_attributes;
1933 break;
1934 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1935 return NT_STATUS_INVALID_INFO_CLASS;
1936 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1937 break;
1938 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1939 return NT_STATUS_INVALID_INFO_CLASS;
1940 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1941 return NT_STATUS_INVALID_INFO_CLASS;
1942 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1943 return NT_STATUS_INVALID_PARAMETER;
1944 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1945 break;
1946 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1947 break;
1948 default:
1949 return NT_STATUS_INVALID_PARAMETER;
1952 *r->out.info = info;
1954 return NT_STATUS_OK;
1957 /***************************************************************************
1958 _lsa_QueryTrustedDomainInfoBySid
1959 ***************************************************************************/
1961 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
1962 struct lsa_QueryTrustedDomainInfoBySid *r)
1964 NTSTATUS status;
1965 struct policy_handle trustdom_handle;
1966 struct lsa_OpenTrustedDomain o;
1967 struct lsa_QueryTrustedDomainInfo q;
1968 struct lsa_Close c;
1970 o.in.handle = r->in.handle;
1971 o.in.sid = r->in.dom_sid;
1972 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1973 o.out.trustdom_handle = &trustdom_handle;
1975 status = _lsa_OpenTrustedDomain(p, &o);
1976 if (!NT_STATUS_IS_OK(status)) {
1977 return status;
1980 q.in.trustdom_handle = &trustdom_handle;
1981 q.in.level = r->in.level;
1982 q.out.info = r->out.info;
1984 status = _lsa_QueryTrustedDomainInfo(p, &q);
1985 if (!NT_STATUS_IS_OK(status)) {
1986 return status;
1989 c.in.handle = &trustdom_handle;
1990 c.out.handle = &trustdom_handle;
1992 return _lsa_Close(p, &c);
1995 /***************************************************************************
1996 _lsa_QueryTrustedDomainInfoByName
1997 ***************************************************************************/
1999 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2000 struct lsa_QueryTrustedDomainInfoByName *r)
2002 NTSTATUS status;
2003 struct policy_handle trustdom_handle;
2004 struct lsa_OpenTrustedDomainByName o;
2005 struct lsa_QueryTrustedDomainInfo q;
2006 struct lsa_Close c;
2008 o.in.handle = r->in.handle;
2009 o.in.name.string = r->in.trusted_domain->string;
2010 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2011 o.out.trustdom_handle = &trustdom_handle;
2013 status = _lsa_OpenTrustedDomainByName(p, &o);
2014 if (!NT_STATUS_IS_OK(status)) {
2015 return status;
2018 q.in.trustdom_handle = &trustdom_handle;
2019 q.in.level = r->in.level;
2020 q.out.info = r->out.info;
2022 status = _lsa_QueryTrustedDomainInfo(p, &q);
2023 if (!NT_STATUS_IS_OK(status)) {
2024 return status;
2027 c.in.handle = &trustdom_handle;
2028 c.out.handle = &trustdom_handle;
2030 return _lsa_Close(p, &c);
2033 /***************************************************************************
2034 ***************************************************************************/
2036 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p, struct lsa_CreateSecret *r)
2038 return NT_STATUS_ACCESS_DENIED;
2041 /***************************************************************************
2042 ***************************************************************************/
2044 NTSTATUS _lsa_SetSecret(struct pipes_struct *p, struct lsa_SetSecret *r)
2046 return NT_STATUS_ACCESS_DENIED;
2049 /***************************************************************************
2050 _lsa_DeleteObject
2051 ***************************************************************************/
2053 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2054 struct lsa_DeleteObject *r)
2056 NTSTATUS status;
2057 struct lsa_info *info = NULL;
2059 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2060 return NT_STATUS_INVALID_HANDLE;
2063 if (!(info->access & SEC_STD_DELETE)) {
2064 return NT_STATUS_ACCESS_DENIED;
2067 switch (info->type) {
2068 case LSA_HANDLE_ACCOUNT_TYPE:
2069 status = privilege_delete_account(&info->sid);
2070 if (!NT_STATUS_IS_OK(status)) {
2071 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2072 nt_errstr(status)));
2073 return status;
2075 break;
2076 default:
2077 return NT_STATUS_INVALID_HANDLE;
2080 close_policy_hnd(p, r->in.handle);
2081 ZERO_STRUCTP(r->out.handle);
2083 return status;
2086 /***************************************************************************
2087 _lsa_EnumPrivs
2088 ***************************************************************************/
2090 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2091 struct lsa_EnumPrivs *r)
2093 struct lsa_info *handle;
2094 uint32 i;
2095 uint32 enum_context = *r->in.resume_handle;
2096 int num_privs = num_privileges_in_short_list();
2097 struct lsa_PrivEntry *entries = NULL;
2099 /* remember that the enum_context starts at 0 and not 1 */
2101 if ( enum_context >= num_privs )
2102 return NT_STATUS_NO_MORE_ENTRIES;
2104 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2105 enum_context, num_privs));
2107 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2108 return NT_STATUS_INVALID_HANDLE;
2110 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2111 return NT_STATUS_INVALID_HANDLE;
2114 /* check if the user has enough rights
2115 I don't know if it's the right one. not documented. */
2117 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2118 return NT_STATUS_ACCESS_DENIED;
2120 if (num_privs) {
2121 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2122 if (!entries) {
2123 return NT_STATUS_NO_MEMORY;
2125 } else {
2126 entries = NULL;
2129 for (i = 0; i < num_privs; i++) {
2130 if( i < enum_context) {
2132 init_lsa_StringLarge(&entries[i].name, NULL);
2134 entries[i].luid.low = 0;
2135 entries[i].luid.high = 0;
2136 } else {
2138 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2140 entries[i].luid.low = sec_privilege_from_index(i);
2141 entries[i].luid.high = 0;
2145 enum_context = num_privs;
2147 *r->out.resume_handle = enum_context;
2148 r->out.privs->count = num_privs;
2149 r->out.privs->privs = entries;
2151 return NT_STATUS_OK;
2154 /***************************************************************************
2155 _lsa_LookupPrivDisplayName
2156 ***************************************************************************/
2158 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2159 struct lsa_LookupPrivDisplayName *r)
2161 struct lsa_info *handle;
2162 const char *description;
2163 struct lsa_StringLarge *lsa_name;
2165 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2166 return NT_STATUS_INVALID_HANDLE;
2168 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2169 return NT_STATUS_INVALID_HANDLE;
2172 /* check if the user has enough rights */
2175 * I don't know if it's the right one. not documented.
2177 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2178 return NT_STATUS_ACCESS_DENIED;
2180 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2182 description = get_privilege_dispname(r->in.name->string);
2183 if (!description) {
2184 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2185 return NT_STATUS_NO_SUCH_PRIVILEGE;
2188 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2190 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2191 if (!lsa_name) {
2192 return NT_STATUS_NO_MEMORY;
2195 init_lsa_StringLarge(lsa_name, description);
2197 *r->out.returned_language_id = r->in.language_id;
2198 *r->out.disp_name = lsa_name;
2200 return NT_STATUS_OK;
2203 /***************************************************************************
2204 _lsa_EnumAccounts
2205 ***************************************************************************/
2207 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2208 struct lsa_EnumAccounts *r)
2210 struct lsa_info *handle;
2211 struct dom_sid *sid_list;
2212 int i, j, num_entries;
2213 NTSTATUS status;
2214 struct lsa_SidPtr *sids = NULL;
2216 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2217 return NT_STATUS_INVALID_HANDLE;
2219 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2220 return NT_STATUS_INVALID_HANDLE;
2223 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2224 return NT_STATUS_ACCESS_DENIED;
2226 sid_list = NULL;
2227 num_entries = 0;
2229 /* The only way we can currently find out all the SIDs that have been
2230 privileged is to scan all privileges */
2232 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2233 if (!NT_STATUS_IS_OK(status)) {
2234 return status;
2237 if (*r->in.resume_handle >= num_entries) {
2238 return NT_STATUS_NO_MORE_ENTRIES;
2241 if (num_entries - *r->in.resume_handle) {
2242 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
2243 num_entries - *r->in.resume_handle);
2244 if (!sids) {
2245 talloc_free(sid_list);
2246 return NT_STATUS_NO_MEMORY;
2249 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2250 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2251 if (!sids[j].sid) {
2252 talloc_free(sid_list);
2253 return NT_STATUS_NO_MEMORY;
2258 talloc_free(sid_list);
2260 *r->out.resume_handle = num_entries;
2261 r->out.sids->num_sids = num_entries;
2262 r->out.sids->sids = sids;
2264 return NT_STATUS_OK;
2267 /***************************************************************************
2268 _lsa_GetUserName
2269 ***************************************************************************/
2271 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2272 struct lsa_GetUserName *r)
2274 const char *username, *domname;
2275 struct lsa_String *account_name = NULL;
2276 struct lsa_String *authority_name = NULL;
2278 if (r->in.account_name &&
2279 *r->in.account_name) {
2280 return NT_STATUS_INVALID_PARAMETER;
2283 if (r->in.authority_name &&
2284 *r->in.authority_name) {
2285 return NT_STATUS_INVALID_PARAMETER;
2288 if (p->server_info->guest) {
2290 * I'm 99% sure this is not the right place to do this,
2291 * global_sid_Anonymous should probably be put into the token
2292 * instead of the guest id -- vl
2294 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2295 &domname, &username, NULL)) {
2296 return NT_STATUS_NO_MEMORY;
2298 } else {
2299 username = p->server_info->sanitized_username;
2300 domname = p->server_info->info3->base.domain.string;
2303 account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2304 if (!account_name) {
2305 return NT_STATUS_NO_MEMORY;
2307 init_lsa_String(account_name, username);
2309 if (r->out.authority_name) {
2310 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2311 if (!authority_name) {
2312 return NT_STATUS_NO_MEMORY;
2314 init_lsa_String(authority_name, domname);
2317 *r->out.account_name = account_name;
2318 if (r->out.authority_name) {
2319 *r->out.authority_name = authority_name;
2322 return NT_STATUS_OK;
2325 /***************************************************************************
2326 _lsa_CreateAccount
2327 ***************************************************************************/
2329 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2330 struct lsa_CreateAccount *r)
2332 NTSTATUS status;
2333 struct lsa_info *handle;
2334 uint32_t acc_granted;
2335 struct security_descriptor *psd;
2336 size_t sd_size;
2338 /* find the connection policy handle. */
2339 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2340 return NT_STATUS_INVALID_HANDLE;
2342 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2343 return NT_STATUS_INVALID_HANDLE;
2346 /* check if the user has enough rights */
2348 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2349 return NT_STATUS_ACCESS_DENIED;
2352 /* Work out max allowed. */
2353 map_max_allowed_access(p->server_info->security_token,
2354 &p->server_info->utok,
2355 &r->in.access_mask);
2357 /* map the generic bits to the lsa policy ones */
2358 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2360 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2361 &lsa_account_mapping,
2362 r->in.sid, LSA_POLICY_ALL_ACCESS);
2363 if (!NT_STATUS_IS_OK(status)) {
2364 return status;
2367 status = access_check_object(psd, p->server_info->security_token,
2368 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2369 &acc_granted, "_lsa_CreateAccount");
2370 if (!NT_STATUS_IS_OK(status)) {
2371 return status;
2374 if ( is_privileged_sid( r->in.sid ) )
2375 return NT_STATUS_OBJECT_NAME_COLLISION;
2377 status = create_lsa_policy_handle(p->mem_ctx, p,
2378 LSA_HANDLE_ACCOUNT_TYPE,
2379 acc_granted,
2380 r->in.sid,
2381 NULL,
2382 psd,
2383 r->out.acct_handle);
2384 if (!NT_STATUS_IS_OK(status)) {
2385 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2388 return privilege_create_account(r->in.sid);
2391 /***************************************************************************
2392 _lsa_OpenAccount
2393 ***************************************************************************/
2395 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2396 struct lsa_OpenAccount *r)
2398 struct lsa_info *handle;
2399 struct security_descriptor *psd = NULL;
2400 size_t sd_size;
2401 uint32_t des_access = r->in.access_mask;
2402 uint32_t acc_granted;
2403 NTSTATUS status;
2405 /* find the connection policy handle. */
2406 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2407 return NT_STATUS_INVALID_HANDLE;
2409 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2410 return NT_STATUS_INVALID_HANDLE;
2413 /* des_access is for the account here, not the policy
2414 * handle - so don't check against policy handle. */
2416 /* Work out max allowed. */
2417 map_max_allowed_access(p->server_info->security_token,
2418 &p->server_info->utok,
2419 &des_access);
2421 /* map the generic bits to the lsa account ones */
2422 se_map_generic(&des_access, &lsa_account_mapping);
2424 /* get the generic lsa account SD until we store it */
2425 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2426 &lsa_account_mapping,
2427 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2428 if (!NT_STATUS_IS_OK(status)) {
2429 return status;
2432 status = access_check_object(psd, p->server_info->security_token,
2433 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2434 &acc_granted, "_lsa_OpenAccount" );
2435 if (!NT_STATUS_IS_OK(status)) {
2436 return status;
2439 /* TODO: Fis the parsing routine before reenabling this check! */
2440 #if 0
2441 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2442 return NT_STATUS_ACCESS_DENIED;
2443 #endif
2445 status = create_lsa_policy_handle(p->mem_ctx, p,
2446 LSA_HANDLE_ACCOUNT_TYPE,
2447 acc_granted,
2448 r->in.sid,
2449 NULL,
2450 psd,
2451 r->out.acct_handle);
2452 if (!NT_STATUS_IS_OK(status)) {
2453 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2456 return NT_STATUS_OK;
2459 /***************************************************************************
2460 _lsa_EnumPrivsAccount
2461 For a given SID, enumerate all the privilege this account has.
2462 ***************************************************************************/
2464 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2465 struct lsa_EnumPrivsAccount *r)
2467 NTSTATUS status = NT_STATUS_OK;
2468 struct lsa_info *info=NULL;
2469 PRIVILEGE_SET *privileges;
2470 struct lsa_PrivilegeSet *priv_set = NULL;
2472 /* find the connection policy handle. */
2473 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2474 return NT_STATUS_INVALID_HANDLE;
2476 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2477 return NT_STATUS_INVALID_HANDLE;
2480 if (!(info->access & LSA_ACCOUNT_VIEW))
2481 return NT_STATUS_ACCESS_DENIED;
2483 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2484 if (!NT_STATUS_IS_OK(status)) {
2485 return status;
2488 *r->out.privs = priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
2489 if (!priv_set) {
2490 return NT_STATUS_NO_MEMORY;
2493 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2494 sid_string_dbg(&info->sid),
2495 privileges->count));
2497 priv_set->count = privileges->count;
2498 priv_set->unknown = 0;
2499 priv_set->set = talloc_move(priv_set, &privileges->set);
2501 return status;
2504 /***************************************************************************
2505 _lsa_GetSystemAccessAccount
2506 ***************************************************************************/
2508 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2509 struct lsa_GetSystemAccessAccount *r)
2511 NTSTATUS status;
2512 struct lsa_info *info = NULL;
2513 struct lsa_EnumPrivsAccount e;
2514 struct lsa_PrivilegeSet *privset;
2516 /* find the connection policy handle. */
2518 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2519 return NT_STATUS_INVALID_HANDLE;
2521 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2522 return NT_STATUS_INVALID_HANDLE;
2525 if (!(info->access & LSA_ACCOUNT_VIEW))
2526 return NT_STATUS_ACCESS_DENIED;
2528 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2529 if (!privset) {
2530 return NT_STATUS_NO_MEMORY;
2533 e.in.handle = r->in.handle;
2534 e.out.privs = &privset;
2536 status = _lsa_EnumPrivsAccount(p, &e);
2537 if (!NT_STATUS_IS_OK(status)) {
2538 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2539 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2540 nt_errstr(status)));
2541 return status;
2544 /* Samba4 would iterate over the privset to merge the policy mode bits,
2545 * not sure samba3 can do the same here, so just return what we did in
2546 * the past - gd */
2549 0x01 -> Log on locally
2550 0x02 -> Access this computer from network
2551 0x04 -> Log on as a batch job
2552 0x10 -> Log on as a service
2554 they can be ORed together
2557 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2558 LSA_POLICY_MODE_NETWORK;
2560 return NT_STATUS_OK;
2563 /***************************************************************************
2564 update the systemaccount information
2565 ***************************************************************************/
2567 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2568 struct lsa_SetSystemAccessAccount *r)
2570 struct lsa_info *info=NULL;
2571 GROUP_MAP map;
2573 /* find the connection policy handle. */
2574 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2575 return NT_STATUS_INVALID_HANDLE;
2577 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2578 return NT_STATUS_INVALID_HANDLE;
2581 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2582 return NT_STATUS_ACCESS_DENIED;
2585 if (!pdb_getgrsid(&map, info->sid))
2586 return NT_STATUS_NO_SUCH_GROUP;
2588 return pdb_update_group_mapping_entry(&map);
2591 /***************************************************************************
2592 _lsa_AddPrivilegesToAccount
2593 For a given SID, add some privileges.
2594 ***************************************************************************/
2596 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
2597 struct lsa_AddPrivilegesToAccount *r)
2599 struct lsa_info *info = NULL;
2600 struct lsa_PrivilegeSet *set = NULL;
2602 /* find the connection policy handle. */
2603 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2604 return NT_STATUS_INVALID_HANDLE;
2606 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2607 return NT_STATUS_INVALID_HANDLE;
2610 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2611 return NT_STATUS_ACCESS_DENIED;
2614 set = r->in.privs;
2616 if ( !grant_privilege_set( &info->sid, set ) ) {
2617 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2618 sid_string_dbg(&info->sid) ));
2619 return NT_STATUS_NO_SUCH_PRIVILEGE;
2622 return NT_STATUS_OK;
2625 /***************************************************************************
2626 _lsa_RemovePrivilegesFromAccount
2627 For a given SID, remove some privileges.
2628 ***************************************************************************/
2630 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2631 struct lsa_RemovePrivilegesFromAccount *r)
2633 struct lsa_info *info = NULL;
2634 struct lsa_PrivilegeSet *set = NULL;
2636 /* find the connection policy handle. */
2637 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2638 return NT_STATUS_INVALID_HANDLE;
2640 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2641 return NT_STATUS_INVALID_HANDLE;
2644 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2645 return NT_STATUS_ACCESS_DENIED;
2648 set = r->in.privs;
2650 if ( !revoke_privilege_set( &info->sid, set) ) {
2651 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2652 sid_string_dbg(&info->sid) ));
2653 return NT_STATUS_NO_SUCH_PRIVILEGE;
2656 return NT_STATUS_OK;
2659 /***************************************************************************
2660 _lsa_LookupPrivName
2661 ***************************************************************************/
2663 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2664 struct lsa_LookupPrivName *r)
2666 struct lsa_info *info = NULL;
2667 const char *name;
2668 struct lsa_StringLarge *lsa_name;
2670 /* find the connection policy handle. */
2671 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2672 return NT_STATUS_INVALID_HANDLE;
2675 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2676 return NT_STATUS_INVALID_HANDLE;
2679 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2680 return NT_STATUS_ACCESS_DENIED;
2683 if (r->in.luid->high != 0) {
2684 return NT_STATUS_NO_SUCH_PRIVILEGE;
2687 name = sec_privilege_name(r->in.luid->low);
2688 if (!name) {
2689 return NT_STATUS_NO_SUCH_PRIVILEGE;
2692 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2693 if (!lsa_name) {
2694 return NT_STATUS_NO_MEMORY;
2697 lsa_name->string = talloc_strdup(lsa_name, name);
2698 if (!lsa_name->string) {
2699 TALLOC_FREE(lsa_name);
2700 return NT_STATUS_NO_MEMORY;
2703 *r->out.name = lsa_name;
2705 return NT_STATUS_OK;
2708 /***************************************************************************
2709 _lsa_QuerySecurity
2710 ***************************************************************************/
2712 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
2713 struct lsa_QuerySecurity *r)
2715 struct lsa_info *handle=NULL;
2716 struct security_descriptor *psd = NULL;
2717 size_t sd_size;
2718 NTSTATUS status;
2720 /* find the connection policy handle. */
2721 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2722 return NT_STATUS_INVALID_HANDLE;
2724 switch (handle->type) {
2725 case LSA_HANDLE_POLICY_TYPE:
2726 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2727 &lsa_policy_mapping, NULL, 0);
2728 break;
2729 case LSA_HANDLE_ACCOUNT_TYPE:
2730 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2731 &lsa_account_mapping,
2732 &handle->sid, LSA_ACCOUNT_ALL_ACCESS);
2733 break;
2734 default:
2735 status = NT_STATUS_INVALID_HANDLE;
2736 break;
2739 if (!NT_STATUS_IS_OK(status)) {
2740 return status;
2743 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2744 if (!*r->out.sdbuf) {
2745 return NT_STATUS_NO_MEMORY;
2748 return status;
2751 /***************************************************************************
2752 _lsa_AddAccountRights
2753 ***************************************************************************/
2755 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
2756 struct lsa_AddAccountRights *r)
2758 struct lsa_info *info = NULL;
2759 int i = 0;
2760 uint32_t acc_granted = 0;
2761 struct security_descriptor *psd = NULL;
2762 size_t sd_size;
2763 struct dom_sid sid;
2764 NTSTATUS status;
2766 /* find the connection policy handle. */
2767 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2768 return NT_STATUS_INVALID_HANDLE;
2770 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2771 return NT_STATUS_INVALID_HANDLE;
2774 /* get the generic lsa account SD for this SID until we store it */
2775 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2776 &lsa_account_mapping,
2777 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2778 if (!NT_STATUS_IS_OK(status)) {
2779 return status;
2783 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2784 * on the policy handle. If it does, ask for
2785 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2786 * on the account sid. We don't check here so just use the latter. JRA.
2789 status = access_check_object(psd, p->server_info->security_token,
2790 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2791 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2792 &acc_granted, "_lsa_AddAccountRights" );
2793 if (!NT_STATUS_IS_OK(status)) {
2794 return status;
2797 /* according to an NT4 PDC, you can add privileges to SIDs even without
2798 call_lsa_create_account() first. And you can use any arbitrary SID. */
2800 sid_copy( &sid, r->in.sid );
2802 for ( i=0; i < r->in.rights->count; i++ ) {
2804 const char *privname = r->in.rights->names[i].string;
2806 /* only try to add non-null strings */
2808 if ( !privname )
2809 continue;
2811 if ( !grant_privilege_by_name( &sid, privname ) ) {
2812 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2813 privname ));
2814 return NT_STATUS_NO_SUCH_PRIVILEGE;
2818 return NT_STATUS_OK;
2821 /***************************************************************************
2822 _lsa_RemoveAccountRights
2823 ***************************************************************************/
2825 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
2826 struct lsa_RemoveAccountRights *r)
2828 struct lsa_info *info = NULL;
2829 int i = 0;
2830 struct security_descriptor *psd = NULL;
2831 size_t sd_size;
2832 struct dom_sid sid;
2833 const char *privname = NULL;
2834 uint32_t acc_granted = 0;
2835 NTSTATUS status;
2837 /* find the connection policy handle. */
2838 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2839 return NT_STATUS_INVALID_HANDLE;
2841 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2842 return NT_STATUS_INVALID_HANDLE;
2845 /* get the generic lsa account SD for this SID until we store it */
2846 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2847 &lsa_account_mapping,
2848 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2849 if (!NT_STATUS_IS_OK(status)) {
2850 return status;
2854 * From the MS DOCs. We need
2855 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2856 * and DELETE on the account sid.
2859 status = access_check_object(psd, p->server_info->security_token,
2860 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2861 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2862 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
2863 &acc_granted, "_lsa_RemoveAccountRights");
2864 if (!NT_STATUS_IS_OK(status)) {
2865 return status;
2868 sid_copy( &sid, r->in.sid );
2870 if ( r->in.remove_all ) {
2871 if ( !revoke_all_privileges( &sid ) )
2872 return NT_STATUS_ACCESS_DENIED;
2874 return NT_STATUS_OK;
2877 for ( i=0; i < r->in.rights->count; i++ ) {
2879 privname = r->in.rights->names[i].string;
2881 /* only try to add non-null strings */
2883 if ( !privname )
2884 continue;
2886 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2887 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2888 privname ));
2889 return NT_STATUS_NO_SUCH_PRIVILEGE;
2893 return NT_STATUS_OK;
2896 /*******************************************************************
2897 ********************************************************************/
2899 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
2900 struct lsa_RightSet *r,
2901 PRIVILEGE_SET *privileges)
2903 uint32 i;
2904 const char *privname;
2905 const char **privname_array = NULL;
2906 int num_priv = 0;
2908 for (i=0; i<privileges->count; i++) {
2909 if (privileges->set[i].luid.high) {
2910 continue;
2912 privname = sec_privilege_name(privileges->set[i].luid.low);
2913 if (privname) {
2914 if (!add_string_to_array(mem_ctx, privname,
2915 &privname_array, &num_priv)) {
2916 return NT_STATUS_NO_MEMORY;
2921 if (num_priv) {
2923 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
2924 num_priv);
2925 if (!r->names) {
2926 return NT_STATUS_NO_MEMORY;
2929 for (i=0; i<num_priv; i++) {
2930 init_lsa_StringLarge(&r->names[i], privname_array[i]);
2933 r->count = num_priv;
2936 return NT_STATUS_OK;
2939 /***************************************************************************
2940 _lsa_EnumAccountRights
2941 ***************************************************************************/
2943 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
2944 struct lsa_EnumAccountRights *r)
2946 NTSTATUS status;
2947 struct lsa_info *info = NULL;
2948 PRIVILEGE_SET *privileges;
2950 /* find the connection policy handle. */
2952 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2953 return NT_STATUS_INVALID_HANDLE;
2955 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2956 return NT_STATUS_INVALID_HANDLE;
2959 if (!(info->access & LSA_ACCOUNT_VIEW)) {
2960 return NT_STATUS_ACCESS_DENIED;
2963 /* according to an NT4 PDC, you can add privileges to SIDs even without
2964 call_lsa_create_account() first. And you can use any arbitrary SID. */
2966 /* according to MS-LSAD 3.1.4.5.10 it is required to return
2967 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
2968 * the lsa database */
2970 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
2971 if (!NT_STATUS_IS_OK(status)) {
2972 return status;
2975 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
2976 sid_string_dbg(r->in.sid), privileges->count));
2978 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
2980 return status;
2983 /***************************************************************************
2984 _lsa_LookupPrivValue
2985 ***************************************************************************/
2987 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
2988 struct lsa_LookupPrivValue *r)
2990 struct lsa_info *info = NULL;
2991 const char *name = NULL;
2993 /* find the connection policy handle. */
2995 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2996 return NT_STATUS_INVALID_HANDLE;
2998 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2999 return NT_STATUS_INVALID_HANDLE;
3002 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3003 return NT_STATUS_ACCESS_DENIED;
3005 name = r->in.name->string;
3007 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3009 r->out.luid->low = sec_privilege_id(name);
3010 r->out.luid->high = 0;
3011 if (r->out.luid->low == SEC_PRIV_INVALID) {
3012 return NT_STATUS_NO_SUCH_PRIVILEGE;
3014 return NT_STATUS_OK;
3017 /***************************************************************************
3018 _lsa_EnumAccountsWithUserRight
3019 ***************************************************************************/
3021 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3022 struct lsa_EnumAccountsWithUserRight *r)
3024 NTSTATUS status;
3025 struct lsa_info *info = NULL;
3026 struct dom_sid *sids = NULL;
3027 int num_sids = 0;
3028 uint32_t i;
3029 enum sec_privilege privilege;
3031 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3032 return NT_STATUS_INVALID_HANDLE;
3035 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3036 return NT_STATUS_INVALID_HANDLE;
3039 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3040 return NT_STATUS_ACCESS_DENIED;
3043 if (!r->in.name || !r->in.name->string) {
3044 return NT_STATUS_NO_SUCH_PRIVILEGE;
3047 privilege = sec_privilege_id(r->in.name->string);
3048 if (privilege == SEC_PRIV_INVALID) {
3049 return NT_STATUS_NO_SUCH_PRIVILEGE;
3052 status = privilege_enum_sids(privilege, p->mem_ctx,
3053 &sids, &num_sids);
3054 if (!NT_STATUS_IS_OK(status)) {
3055 return status;
3058 r->out.sids->num_sids = num_sids;
3059 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3060 r->out.sids->num_sids);
3062 for (i=0; i < r->out.sids->num_sids; i++) {
3063 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3064 &sids[i]);
3065 if (!r->out.sids->sids[i].sid) {
3066 TALLOC_FREE(r->out.sids->sids);
3067 r->out.sids->num_sids = 0;
3068 return NT_STATUS_NO_MEMORY;
3072 return NT_STATUS_OK;
3075 /***************************************************************************
3076 _lsa_Delete
3077 ***************************************************************************/
3079 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3080 struct lsa_Delete *r)
3082 return NT_STATUS_NOT_SUPPORTED;
3086 * From here on the server routines are just dummy ones to make smbd link with
3087 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3088 * pulling the server stubs across one by one.
3091 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3093 p->rng_fault_state = True;
3094 return NT_STATUS_NOT_IMPLEMENTED;
3097 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3098 struct lsa_ChangePassword *r)
3100 p->rng_fault_state = True;
3101 return NT_STATUS_NOT_IMPLEMENTED;
3104 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3106 p->rng_fault_state = True;
3107 return NT_STATUS_NOT_IMPLEMENTED;
3110 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3112 p->rng_fault_state = True;
3113 return NT_STATUS_NOT_IMPLEMENTED;
3116 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3117 struct lsa_GetQuotasForAccount *r)
3119 p->rng_fault_state = True;
3120 return NT_STATUS_NOT_IMPLEMENTED;
3123 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3124 struct lsa_SetQuotasForAccount *r)
3126 p->rng_fault_state = True;
3127 return NT_STATUS_NOT_IMPLEMENTED;
3130 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3131 struct lsa_SetInformationTrustedDomain *r)
3133 p->rng_fault_state = True;
3134 return NT_STATUS_NOT_IMPLEMENTED;
3137 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
3139 p->rng_fault_state = True;
3140 return NT_STATUS_NOT_IMPLEMENTED;
3143 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3144 struct lsa_SetTrustedDomainInfo *r)
3146 p->rng_fault_state = True;
3147 return NT_STATUS_NOT_IMPLEMENTED;
3150 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3151 struct lsa_StorePrivateData *r)
3153 p->rng_fault_state = True;
3154 return NT_STATUS_NOT_IMPLEMENTED;
3157 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3158 struct lsa_RetrievePrivateData *r)
3160 p->rng_fault_state = True;
3161 return NT_STATUS_NOT_IMPLEMENTED;
3164 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3165 struct lsa_SetInfoPolicy2 *r)
3167 p->rng_fault_state = True;
3168 return NT_STATUS_NOT_IMPLEMENTED;
3171 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3172 struct lsa_SetTrustedDomainInfoByName *r)
3174 p->rng_fault_state = True;
3175 return NT_STATUS_NOT_IMPLEMENTED;
3178 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3179 struct lsa_EnumTrustedDomainsEx *r)
3181 struct lsa_info *info;
3182 uint32_t count;
3183 struct pdb_trusted_domain **domains;
3184 struct lsa_TrustDomainInfoInfoEx *entries;
3185 int i;
3186 NTSTATUS nt_status;
3188 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3189 return NT_STATUS_INVALID_HANDLE;
3191 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3192 return NT_STATUS_INVALID_HANDLE;
3195 /* check if the user has enough rights */
3196 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3197 return NT_STATUS_ACCESS_DENIED;
3199 become_root();
3200 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3201 unbecome_root();
3203 if (!NT_STATUS_IS_OK(nt_status)) {
3204 return nt_status;
3207 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3208 count);
3209 if (!entries) {
3210 return NT_STATUS_NO_MEMORY;
3213 for (i=0; i<count; i++) {
3214 init_lsa_StringLarge(&entries[i].netbios_name,
3215 domains[i]->netbios_name);
3216 entries[i].sid = &domains[i]->security_identifier;
3219 if (*r->in.resume_handle >= count) {
3220 *r->out.resume_handle = -1;
3221 TALLOC_FREE(entries);
3222 return NT_STATUS_NO_MORE_ENTRIES;
3225 /* return the rest, limit by max_size. Note that we
3226 use the w2k3 element size value of 60 */
3227 r->out.domains->count = count - *r->in.resume_handle;
3228 r->out.domains->count = MIN(r->out.domains->count,
3229 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3231 r->out.domains->domains = entries + *r->in.resume_handle;
3233 if (r->out.domains->count < count - *r->in.resume_handle) {
3234 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3235 return STATUS_MORE_ENTRIES;
3238 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3239 * always be larger than the previous input resume handle, in
3240 * particular when hitting the last query it is vital to set the
3241 * resume handle correctly to avoid infinite client loops, as
3242 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3243 * status is NT_STATUS_OK - gd */
3245 *r->out.resume_handle = (uint32_t)-1;
3247 return NT_STATUS_OK;
3250 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3251 struct lsa_QueryDomainInformationPolicy *r)
3253 p->rng_fault_state = True;
3254 return NT_STATUS_NOT_IMPLEMENTED;
3257 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3258 struct lsa_SetDomainInformationPolicy *r)
3260 p->rng_fault_state = True;
3261 return NT_STATUS_NOT_IMPLEMENTED;
3264 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3266 p->rng_fault_state = True;
3267 return NT_STATUS_NOT_IMPLEMENTED;
3270 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3272 p->rng_fault_state = True;
3273 return NT_STATUS_NOT_IMPLEMENTED;
3276 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3278 p->rng_fault_state = True;
3279 return NT_STATUS_NOT_IMPLEMENTED;
3282 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3284 p->rng_fault_state = True;
3285 return NT_STATUS_NOT_IMPLEMENTED;
3288 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3289 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3291 p->rng_fault_state = True;
3292 return NT_STATUS_NOT_IMPLEMENTED;
3295 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3296 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3298 p->rng_fault_state = True;
3299 return NT_STATUS_NOT_IMPLEMENTED;
3302 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3304 p->rng_fault_state = True;
3305 return NT_STATUS_NOT_IMPLEMENTED;
3308 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3309 struct lsa_CREDRGETTARGETINFO *r)
3311 p->rng_fault_state = True;
3312 return NT_STATUS_NOT_IMPLEMENTED;
3315 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3316 struct lsa_CREDRPROFILELOADED *r)
3318 p->rng_fault_state = True;
3319 return NT_STATUS_NOT_IMPLEMENTED;
3322 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3323 struct lsa_CREDRGETSESSIONTYPES *r)
3325 p->rng_fault_state = True;
3326 return NT_STATUS_NOT_IMPLEMENTED;
3329 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3330 struct lsa_LSARREGISTERAUDITEVENT *r)
3332 p->rng_fault_state = True;
3333 return NT_STATUS_NOT_IMPLEMENTED;
3336 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3337 struct lsa_LSARGENAUDITEVENT *r)
3339 p->rng_fault_state = True;
3340 return NT_STATUS_NOT_IMPLEMENTED;
3343 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3344 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3346 p->rng_fault_state = True;
3347 return NT_STATUS_NOT_IMPLEMENTED;
3350 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3351 struct lsa_lsaRQueryForestTrustInformation *r)
3353 p->rng_fault_state = True;
3354 return NT_STATUS_NOT_IMPLEMENTED;
3357 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
3358 struct lsa_lsaRSetForestTrustInformation *r)
3360 p->rng_fault_state = True;
3361 return NT_STATUS_NOT_IMPLEMENTED;
3364 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
3365 struct lsa_CREDRRENAME *r)
3367 p->rng_fault_state = True;
3368 return NT_STATUS_NOT_IMPLEMENTED;
3371 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
3372 struct lsa_LSAROPENPOLICYSCE *r)
3374 p->rng_fault_state = True;
3375 return NT_STATUS_NOT_IMPLEMENTED;
3378 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
3379 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3381 p->rng_fault_state = True;
3382 return NT_STATUS_NOT_IMPLEMENTED;
3385 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
3386 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3388 p->rng_fault_state = True;
3389 return NT_STATUS_NOT_IMPLEMENTED;
3392 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
3393 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3395 p->rng_fault_state = True;
3396 return NT_STATUS_NOT_IMPLEMENTED;