s3: Fix Coverity ID 1013, CHECKED_RETURN
[Samba.git] / source3 / rpc_server / lsa / srv_lsa_nt.c
blobeeea5163b2abb77316d5344d489a7c0a804b798f
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"
42 #include "../libcli/security/dom_sid.h"
43 #include "../librpc/gen_ndr/ndr_security.h"
45 #undef DBGC_CLASS
46 #define DBGC_CLASS DBGC_RPC_SRV
48 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
50 enum lsa_handle_type {
51 LSA_HANDLE_POLICY_TYPE = 1,
52 LSA_HANDLE_ACCOUNT_TYPE = 2,
53 LSA_HANDLE_TRUST_TYPE = 3};
55 struct lsa_info {
56 struct dom_sid sid;
57 const char *name;
58 uint32 access;
59 enum lsa_handle_type type;
60 struct security_descriptor *sd;
63 const struct generic_mapping lsa_account_mapping = {
64 LSA_ACCOUNT_READ,
65 LSA_ACCOUNT_WRITE,
66 LSA_ACCOUNT_EXECUTE,
67 LSA_ACCOUNT_ALL_ACCESS
70 const struct generic_mapping lsa_policy_mapping = {
71 LSA_POLICY_READ,
72 LSA_POLICY_WRITE,
73 LSA_POLICY_EXECUTE,
74 LSA_POLICY_ALL_ACCESS
77 const struct generic_mapping lsa_secret_mapping = {
78 LSA_SECRET_READ,
79 LSA_SECRET_WRITE,
80 LSA_SECRET_EXECUTE,
81 LSA_SECRET_ALL_ACCESS
84 const struct generic_mapping lsa_trusted_domain_mapping = {
85 LSA_TRUSTED_DOMAIN_READ,
86 LSA_TRUSTED_DOMAIN_WRITE,
87 LSA_TRUSTED_DOMAIN_EXECUTE,
88 LSA_TRUSTED_DOMAIN_ALL_ACCESS
91 /***************************************************************************
92 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
93 ***************************************************************************/
95 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
96 struct lsa_RefDomainList *ref,
97 const char *dom_name,
98 struct dom_sid *dom_sid)
100 int num = 0;
102 if (dom_name != NULL) {
103 for (num = 0; num < ref->count; num++) {
104 if (dom_sid_equal(dom_sid, ref->domains[num].sid)) {
105 return num;
108 } else {
109 num = ref->count;
112 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
113 /* index not found, already at maximum domain limit */
114 return -1;
117 ref->count = num + 1;
118 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
120 ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains,
121 struct lsa_DomainInfo, ref->count);
122 if (!ref->domains) {
123 return -1;
126 ZERO_STRUCT(ref->domains[num]);
128 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
129 ref->domains[num].sid = dom_sid_dup(mem_ctx, dom_sid);
130 if (!ref->domains[num].sid) {
131 return -1;
134 return num;
138 /***************************************************************************
139 initialize a lsa_DomainInfo structure.
140 ***************************************************************************/
142 static void init_dom_query_3(struct lsa_DomainInfo *r,
143 const char *name,
144 struct dom_sid *sid)
146 init_lsa_StringLarge(&r->name, name);
147 r->sid = sid;
150 /***************************************************************************
151 initialize a lsa_DomainInfo structure.
152 ***************************************************************************/
154 static void init_dom_query_5(struct lsa_DomainInfo *r,
155 const char *name,
156 struct dom_sid *sid)
158 init_lsa_StringLarge(&r->name, name);
159 r->sid = sid;
162 /***************************************************************************
163 lookup_lsa_rids. Must be called as root for lookup_name to work.
164 ***************************************************************************/
166 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
167 struct lsa_RefDomainList *ref,
168 struct lsa_TranslatedSid *prid,
169 uint32_t num_entries,
170 struct lsa_String *name,
171 int flags,
172 uint32_t *pmapped_count)
174 uint32 mapped_count, i;
176 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
178 mapped_count = 0;
179 *pmapped_count = 0;
181 for (i = 0; i < num_entries; i++) {
182 struct dom_sid sid;
183 uint32 rid;
184 int dom_idx;
185 const char *full_name;
186 const char *domain;
187 enum lsa_SidType type = SID_NAME_UNKNOWN;
189 /* Split name into domain and user component */
191 /* follow w2k8 behavior and return the builtin domain when no
192 * input has been passed in */
194 if (name[i].string) {
195 full_name = name[i].string;
196 } else {
197 full_name = "BUILTIN";
200 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
202 /* We can ignore the result of lookup_name, it will not touch
203 "type" if it's not successful */
205 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
206 &sid, &type);
208 switch (type) {
209 case SID_NAME_USER:
210 case SID_NAME_DOM_GRP:
211 case SID_NAME_DOMAIN:
212 case SID_NAME_ALIAS:
213 case SID_NAME_WKN_GRP:
214 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
215 /* Leave these unchanged */
216 break;
217 default:
218 /* Don't hand out anything but the list above */
219 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
220 type = SID_NAME_UNKNOWN;
221 break;
224 rid = 0;
225 dom_idx = -1;
227 if (type != SID_NAME_UNKNOWN) {
228 if (type == SID_NAME_DOMAIN) {
229 rid = (uint32_t)-1;
230 } else {
231 sid_split_rid(&sid, &rid);
233 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
234 mapped_count++;
237 prid[i].sid_type = type;
238 prid[i].rid = rid;
239 prid[i].sid_index = dom_idx;
242 *pmapped_count = mapped_count;
243 return NT_STATUS_OK;
246 /***************************************************************************
247 lookup_lsa_sids. Must be called as root for lookup_name to work.
248 ***************************************************************************/
250 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
251 struct lsa_RefDomainList *ref,
252 struct lsa_TranslatedSid3 *trans_sids,
253 uint32_t num_entries,
254 struct lsa_String *name,
255 int flags,
256 uint32 *pmapped_count)
258 uint32 mapped_count, i;
260 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
262 mapped_count = 0;
263 *pmapped_count = 0;
265 for (i = 0; i < num_entries; i++) {
266 struct dom_sid sid;
267 uint32 rid;
268 int dom_idx;
269 const char *full_name;
270 const char *domain;
271 enum lsa_SidType type;
273 ZERO_STRUCT(sid);
275 /* Split name into domain and user component */
277 full_name = name[i].string;
278 if (full_name == NULL) {
279 return NT_STATUS_NO_MEMORY;
282 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
284 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
285 &sid, &type)) {
286 type = SID_NAME_UNKNOWN;
289 switch (type) {
290 case SID_NAME_USER:
291 case SID_NAME_DOM_GRP:
292 case SID_NAME_DOMAIN:
293 case SID_NAME_ALIAS:
294 case SID_NAME_WKN_GRP:
295 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
296 /* Leave these unchanged */
297 break;
298 default:
299 /* Don't hand out anything but the list above */
300 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
301 type = SID_NAME_UNKNOWN;
302 break;
305 rid = 0;
306 dom_idx = -1;
308 if (type != SID_NAME_UNKNOWN) {
309 struct dom_sid domain_sid;
310 sid_copy(&domain_sid, &sid);
311 sid_split_rid(&domain_sid, &rid);
312 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
313 mapped_count++;
316 /* Initialize the lsa_TranslatedSid3 return. */
317 trans_sids[i].sid_type = type;
318 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
319 trans_sids[i].sid_index = dom_idx;
322 *pmapped_count = mapped_count;
323 return NT_STATUS_OK;
326 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
327 const struct generic_mapping *map,
328 struct dom_sid *sid, uint32_t sid_access)
330 struct dom_sid adm_sid;
331 struct security_ace ace[5];
332 size_t i = 0;
334 struct security_acl *psa = NULL;
336 /* READ|EXECUTE access for Everyone */
338 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
339 map->generic_execute | map->generic_read, 0);
341 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
343 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
344 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
345 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
346 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
348 /* Add Full Access for Domain Admins */
349 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
350 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
351 map->generic_all, 0);
353 /* If we have a sid, give it some special access */
355 if (sid) {
356 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
357 sid_access, 0);
360 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
361 return NT_STATUS_NO_MEMORY;
363 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
364 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
365 psa, sd_size)) == NULL)
366 return NT_STATUS_NO_MEMORY;
368 return NT_STATUS_OK;
371 /***************************************************************************
372 ***************************************************************************/
374 static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
375 struct pipes_struct *p,
376 enum lsa_handle_type type,
377 uint32_t acc_granted,
378 struct dom_sid *sid,
379 const char *name,
380 const struct security_descriptor *sd,
381 struct policy_handle *handle)
383 struct lsa_info *info;
385 ZERO_STRUCTP(handle);
387 info = talloc_zero(mem_ctx, struct lsa_info);
388 if (!info) {
389 return NT_STATUS_NO_MEMORY;
392 info->type = type;
393 info->access = acc_granted;
395 if (sid) {
396 sid_copy(&info->sid, sid);
399 info->name = talloc_strdup(info, name);
401 if (sd) {
402 info->sd = dup_sec_desc(info, sd);
403 if (!info->sd) {
404 talloc_free(info);
405 return NT_STATUS_NO_MEMORY;
409 if (!create_policy_hnd(p, handle, info)) {
410 talloc_free(info);
411 ZERO_STRUCTP(handle);
412 return NT_STATUS_NO_MEMORY;
415 return NT_STATUS_OK;
418 /***************************************************************************
419 _lsa_OpenPolicy2
420 ***************************************************************************/
422 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
423 struct lsa_OpenPolicy2 *r)
425 struct security_descriptor *psd = NULL;
426 size_t sd_size;
427 uint32 des_access = r->in.access_mask;
428 uint32 acc_granted;
429 NTSTATUS status;
431 /* Work out max allowed. */
432 map_max_allowed_access(p->session_info->security_token,
433 &p->session_info->utok,
434 &des_access);
436 /* map the generic bits to the lsa policy ones */
437 se_map_generic(&des_access, &lsa_policy_mapping);
439 /* get the generic lsa policy SD until we store it */
440 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
441 NULL, 0);
442 if (!NT_STATUS_IS_OK(status)) {
443 return status;
446 status = access_check_object(psd, p->session_info->security_token,
447 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
448 &acc_granted, "_lsa_OpenPolicy2" );
449 if (!NT_STATUS_IS_OK(status)) {
450 return status;
453 status = create_lsa_policy_handle(p->mem_ctx, p,
454 LSA_HANDLE_POLICY_TYPE,
455 acc_granted,
456 get_global_sam_sid(),
457 NULL,
458 psd,
459 r->out.handle);
460 if (!NT_STATUS_IS_OK(status)) {
461 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
464 return NT_STATUS_OK;
467 /***************************************************************************
468 _lsa_OpenPolicy
469 ***************************************************************************/
471 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
472 struct lsa_OpenPolicy *r)
474 struct lsa_OpenPolicy2 o;
476 o.in.system_name = NULL; /* should be ignored */
477 o.in.attr = r->in.attr;
478 o.in.access_mask = r->in.access_mask;
480 o.out.handle = r->out.handle;
482 return _lsa_OpenPolicy2(p, &o);
485 /***************************************************************************
486 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
487 ufff, done :) mimir
488 ***************************************************************************/
490 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
491 struct lsa_EnumTrustDom *r)
493 struct lsa_info *info;
494 uint32_t count;
495 struct trustdom_info **domains;
496 struct lsa_DomainInfo *entries;
497 int i;
498 NTSTATUS nt_status;
500 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
501 return NT_STATUS_INVALID_HANDLE;
503 if (info->type != LSA_HANDLE_POLICY_TYPE) {
504 return NT_STATUS_INVALID_HANDLE;
507 /* check if the user has enough rights */
508 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
509 return NT_STATUS_ACCESS_DENIED;
511 become_root();
512 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
513 unbecome_root();
515 if (!NT_STATUS_IS_OK(nt_status)) {
516 return nt_status;
519 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo, count);
520 if (!entries) {
521 return NT_STATUS_NO_MEMORY;
524 for (i=0; i<count; i++) {
525 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
526 entries[i].sid = &domains[i]->sid;
529 if (*r->in.resume_handle >= count) {
530 *r->out.resume_handle = -1;
531 TALLOC_FREE(entries);
532 return NT_STATUS_NO_MORE_ENTRIES;
535 /* return the rest, limit by max_size. Note that we
536 use the w2k3 element size value of 60 */
537 r->out.domains->count = count - *r->in.resume_handle;
538 r->out.domains->count = MIN(r->out.domains->count,
539 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
541 r->out.domains->domains = entries + *r->in.resume_handle;
543 if (r->out.domains->count < count - *r->in.resume_handle) {
544 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
545 return STATUS_MORE_ENTRIES;
548 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
549 * always be larger than the previous input resume handle, in
550 * particular when hitting the last query it is vital to set the
551 * resume handle correctly to avoid infinite client loops, as
552 * seen e.g. with Windows XP SP3 when resume handle is 0 and
553 * status is NT_STATUS_OK - gd */
555 *r->out.resume_handle = (uint32_t)-1;
557 return NT_STATUS_OK;
560 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
561 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
562 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
564 /***************************************************************************
565 _lsa_QueryInfoPolicy
566 ***************************************************************************/
568 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
569 struct lsa_QueryInfoPolicy *r)
571 NTSTATUS status = NT_STATUS_OK;
572 struct lsa_info *handle;
573 struct dom_sid domain_sid;
574 const char *name;
575 struct dom_sid *sid = NULL;
576 union lsa_PolicyInformation *info = NULL;
577 uint32_t acc_required = 0;
579 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
580 return NT_STATUS_INVALID_HANDLE;
582 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
583 return NT_STATUS_INVALID_HANDLE;
586 switch (r->in.level) {
587 case LSA_POLICY_INFO_AUDIT_LOG:
588 case LSA_POLICY_INFO_AUDIT_EVENTS:
589 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
590 break;
591 case LSA_POLICY_INFO_DOMAIN:
592 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
593 break;
594 case LSA_POLICY_INFO_PD:
595 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
596 break;
597 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
598 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
599 break;
600 case LSA_POLICY_INFO_ROLE:
601 case LSA_POLICY_INFO_REPLICA:
602 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
603 break;
604 case LSA_POLICY_INFO_QUOTA:
605 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
606 break;
607 case LSA_POLICY_INFO_MOD:
608 case LSA_POLICY_INFO_AUDIT_FULL_SET:
609 /* according to MS-LSAD 3.1.4.4.3 */
610 return NT_STATUS_INVALID_PARAMETER;
611 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
612 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
613 break;
614 case LSA_POLICY_INFO_DNS:
615 case LSA_POLICY_INFO_DNS_INT:
616 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
617 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
618 break;
619 default:
620 break;
623 if (!(handle->access & acc_required)) {
624 /* return NT_STATUS_ACCESS_DENIED; */
627 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
628 if (!info) {
629 return NT_STATUS_NO_MEMORY;
632 switch (r->in.level) {
633 /* according to MS-LSAD 3.1.4.4.3 */
634 case LSA_POLICY_INFO_MOD:
635 case LSA_POLICY_INFO_AUDIT_FULL_SET:
636 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
637 return NT_STATUS_INVALID_PARAMETER;
638 case LSA_POLICY_INFO_AUDIT_LOG:
639 info->audit_log.percent_full = 0;
640 info->audit_log.maximum_log_size = 0;
641 info->audit_log.retention_time = 0;
642 info->audit_log.shutdown_in_progress = 0;
643 info->audit_log.time_to_shutdown = 0;
644 info->audit_log.next_audit_record = 0;
645 status = NT_STATUS_OK;
646 break;
647 case LSA_POLICY_INFO_PD:
648 info->pd.name.string = NULL;
649 status = NT_STATUS_OK;
650 break;
651 case LSA_POLICY_INFO_REPLICA:
652 info->replica.source.string = NULL;
653 info->replica.account.string = NULL;
654 status = NT_STATUS_OK;
655 break;
656 case LSA_POLICY_INFO_QUOTA:
657 info->quota.paged_pool = 0;
658 info->quota.non_paged_pool = 0;
659 info->quota.min_wss = 0;
660 info->quota.max_wss = 0;
661 info->quota.pagefile = 0;
662 info->quota.unknown = 0;
663 status = NT_STATUS_OK;
664 break;
665 case LSA_POLICY_INFO_AUDIT_EVENTS:
668 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
670 /* check if the user has enough rights */
671 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
672 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
673 return NT_STATUS_ACCESS_DENIED;
676 /* fake info: We audit everything. ;) */
678 info->audit_events.auditing_mode = true;
679 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
680 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
681 enum lsa_PolicyAuditPolicy,
682 info->audit_events.count);
683 if (!info->audit_events.settings) {
684 return NT_STATUS_NO_MEMORY;
687 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
688 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
689 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
690 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
691 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
692 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
693 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
695 break;
697 case LSA_POLICY_INFO_DOMAIN:
698 /* check if the user has enough rights */
699 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
700 return NT_STATUS_ACCESS_DENIED;
702 /* Request PolicyPrimaryDomainInformation. */
703 switch (lp_server_role()) {
704 case ROLE_DOMAIN_PDC:
705 case ROLE_DOMAIN_BDC:
706 name = get_global_sam_name();
707 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
708 if (!sid) {
709 return NT_STATUS_NO_MEMORY;
711 break;
712 case ROLE_DOMAIN_MEMBER:
713 name = lp_workgroup();
714 /* We need to return the Domain SID here. */
715 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
716 sid = dom_sid_dup(p->mem_ctx, &domain_sid);
717 if (!sid) {
718 return NT_STATUS_NO_MEMORY;
720 } else {
721 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
723 break;
724 case ROLE_STANDALONE:
725 name = lp_workgroup();
726 sid = NULL;
727 break;
728 default:
729 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
731 init_dom_query_3(&info->domain, name, sid);
732 break;
733 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
734 /* check if the user has enough rights */
735 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
736 return NT_STATUS_ACCESS_DENIED;
738 /* Request PolicyAccountDomainInformation. */
739 name = get_global_sam_name();
740 sid = get_global_sam_sid();
742 init_dom_query_5(&info->account_domain, name, sid);
743 break;
744 case LSA_POLICY_INFO_ROLE:
745 /* check if the user has enough rights */
746 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
747 return NT_STATUS_ACCESS_DENIED;
749 switch (lp_server_role()) {
750 case ROLE_DOMAIN_BDC:
752 * only a BDC is a backup controller
753 * of the domain, it controls.
755 info->role.role = LSA_ROLE_BACKUP;
756 break;
757 default:
759 * any other role is a primary
760 * of the domain, it controls.
762 info->role.role = LSA_ROLE_PRIMARY;
763 break;
765 break;
766 case LSA_POLICY_INFO_DNS:
767 case LSA_POLICY_INFO_DNS_INT: {
768 struct pdb_domain_info *dominfo;
770 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
771 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
772 "without ADS passdb backend\n"));
773 status = NT_STATUS_INVALID_INFO_CLASS;
774 break;
777 dominfo = pdb_get_domain_info(info);
778 if (dominfo == NULL) {
779 status = NT_STATUS_NO_MEMORY;
780 break;
783 init_lsa_StringLarge(&info->dns.name,
784 dominfo->name);
785 init_lsa_StringLarge(&info->dns.dns_domain,
786 dominfo->dns_domain);
787 init_lsa_StringLarge(&info->dns.dns_forest,
788 dominfo->dns_forest);
789 info->dns.domain_guid = dominfo->guid;
790 info->dns.sid = &dominfo->sid;
791 break;
793 default:
794 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
795 r->in.level));
796 status = NT_STATUS_INVALID_INFO_CLASS;
797 break;
800 *r->out.info = info;
802 return status;
805 /***************************************************************************
806 _lsa_QueryInfoPolicy2
807 ***************************************************************************/
809 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
810 struct lsa_QueryInfoPolicy2 *r2)
812 struct lsa_QueryInfoPolicy r;
814 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
815 p->rng_fault_state = True;
816 return NT_STATUS_NOT_IMPLEMENTED;
819 ZERO_STRUCT(r);
820 r.in.handle = r2->in.handle;
821 r.in.level = r2->in.level;
822 r.out.info = r2->out.info;
824 return _lsa_QueryInfoPolicy(p, &r);
827 /***************************************************************************
828 _lsa_lookup_sids_internal
829 ***************************************************************************/
831 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
832 TALLOC_CTX *mem_ctx,
833 uint16_t level, /* input */
834 int num_sids, /* input */
835 struct lsa_SidPtr *sid, /* input */
836 struct lsa_RefDomainList **pp_ref, /* input/output */
837 struct lsa_TranslatedName2 **pp_names,/* input/output */
838 uint32_t *pp_mapped_count) /* input/output */
840 NTSTATUS status;
841 int i;
842 const struct dom_sid **sids = NULL;
843 struct lsa_RefDomainList *ref = NULL;
844 uint32 mapped_count = 0;
845 struct lsa_dom_info *dom_infos = NULL;
846 struct lsa_name_info *name_infos = NULL;
847 struct lsa_TranslatedName2 *names = NULL;
849 *pp_mapped_count = 0;
850 *pp_names = NULL;
851 *pp_ref = NULL;
853 if (num_sids == 0) {
854 return NT_STATUS_OK;
857 sids = TALLOC_ARRAY(p->mem_ctx, const struct dom_sid *, num_sids);
858 ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
860 if (sids == NULL || ref == NULL) {
861 return NT_STATUS_NO_MEMORY;
864 for (i=0; i<num_sids; i++) {
865 sids[i] = sid[i].sid;
868 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
869 &dom_infos, &name_infos);
871 if (!NT_STATUS_IS_OK(status)) {
872 return status;
875 names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
876 if (names == NULL) {
877 return NT_STATUS_NO_MEMORY;
880 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
882 if (!dom_infos[i].valid) {
883 break;
886 if (init_lsa_ref_domain_list(mem_ctx, ref,
887 dom_infos[i].name,
888 &dom_infos[i].sid) != i) {
889 DEBUG(0, ("Domain %s mentioned twice??\n",
890 dom_infos[i].name));
891 return NT_STATUS_INTERNAL_ERROR;
895 for (i=0; i<num_sids; i++) {
896 struct lsa_name_info *name = &name_infos[i];
898 if (name->type == SID_NAME_UNKNOWN) {
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 = dom_sid_string(p->mem_ctx, sids[i]);
907 if (name->name == NULL) {
908 return NT_STATUS_NO_MEMORY;
910 } else {
911 mapped_count += 1;
914 names[i].sid_type = name->type;
915 names[i].name.string = name->name;
916 names[i].sid_index = name->dom_idx;
917 names[i].unknown = 0;
920 status = NT_STATUS_NONE_MAPPED;
921 if (mapped_count > 0) {
922 status = (mapped_count < num_sids) ?
923 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
926 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
927 num_sids, mapped_count, nt_errstr(status)));
929 *pp_mapped_count = mapped_count;
930 *pp_names = names;
931 *pp_ref = ref;
933 return status;
936 /***************************************************************************
937 _lsa_LookupSids
938 ***************************************************************************/
940 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
941 struct lsa_LookupSids *r)
943 NTSTATUS status;
944 struct lsa_info *handle;
945 int num_sids = r->in.sids->num_sids;
946 uint32 mapped_count = 0;
947 struct lsa_RefDomainList *domains = NULL;
948 struct lsa_TranslatedName *names_out = NULL;
949 struct lsa_TranslatedName2 *names = NULL;
950 int i;
952 if ((r->in.level < 1) || (r->in.level > 6)) {
953 return NT_STATUS_INVALID_PARAMETER;
956 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
957 return NT_STATUS_INVALID_HANDLE;
960 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
961 return NT_STATUS_INVALID_HANDLE;
964 /* check if the user has enough rights */
965 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
966 return NT_STATUS_ACCESS_DENIED;
969 if (num_sids > MAX_LOOKUP_SIDS) {
970 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
971 MAX_LOOKUP_SIDS, num_sids));
972 return NT_STATUS_NONE_MAPPED;
975 status = _lsa_lookup_sids_internal(p,
976 p->mem_ctx,
977 r->in.level,
978 num_sids,
979 r->in.sids->sids,
980 &domains,
981 &names,
982 &mapped_count);
984 /* Only return here when there is a real error.
985 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
986 the requested sids could be resolved. Older versions of XP (pre SP3)
987 rely that we return with the string representations of those SIDs in
988 that case. If we don't, XP crashes - Guenther
991 if (NT_STATUS_IS_ERR(status) &&
992 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
993 return status;
996 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
997 names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
998 num_sids);
999 if (!names_out) {
1000 return NT_STATUS_NO_MEMORY;
1003 for (i=0; i<num_sids; i++) {
1004 names_out[i].sid_type = names[i].sid_type;
1005 names_out[i].name = names[i].name;
1006 names_out[i].sid_index = names[i].sid_index;
1009 *r->out.domains = domains;
1010 r->out.names->count = num_sids;
1011 r->out.names->names = names_out;
1012 *r->out.count = mapped_count;
1014 return status;
1017 /***************************************************************************
1018 _lsa_LookupSids2
1019 ***************************************************************************/
1021 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1022 struct lsa_LookupSids2 *r)
1024 NTSTATUS status;
1025 struct lsa_info *handle;
1026 int num_sids = r->in.sids->num_sids;
1027 uint32 mapped_count = 0;
1028 struct lsa_RefDomainList *domains = NULL;
1029 struct lsa_TranslatedName2 *names = NULL;
1030 bool check_policy = true;
1032 switch (p->opnum) {
1033 case NDR_LSA_LOOKUPSIDS3:
1034 check_policy = false;
1035 break;
1036 case NDR_LSA_LOOKUPSIDS2:
1037 default:
1038 check_policy = true;
1041 if ((r->in.level < 1) || (r->in.level > 6)) {
1042 return NT_STATUS_INVALID_PARAMETER;
1045 if (check_policy) {
1046 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1047 return NT_STATUS_INVALID_HANDLE;
1050 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1051 return NT_STATUS_INVALID_HANDLE;
1054 /* check if the user has enough rights */
1055 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1056 return NT_STATUS_ACCESS_DENIED;
1060 if (num_sids > MAX_LOOKUP_SIDS) {
1061 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1062 MAX_LOOKUP_SIDS, num_sids));
1063 return NT_STATUS_NONE_MAPPED;
1066 status = _lsa_lookup_sids_internal(p,
1067 p->mem_ctx,
1068 r->in.level,
1069 num_sids,
1070 r->in.sids->sids,
1071 &domains,
1072 &names,
1073 &mapped_count);
1075 *r->out.domains = domains;
1076 r->out.names->count = num_sids;
1077 r->out.names->names = names;
1078 *r->out.count = mapped_count;
1080 return status;
1083 /***************************************************************************
1084 _lsa_LookupSids3
1085 ***************************************************************************/
1087 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1088 struct lsa_LookupSids3 *r)
1090 struct lsa_LookupSids2 q;
1092 /* No policy handle on this call. Restrict to crypto connections. */
1093 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1094 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1095 get_remote_machine_name() ));
1096 return NT_STATUS_INVALID_PARAMETER;
1099 q.in.handle = NULL;
1100 q.in.sids = r->in.sids;
1101 q.in.level = r->in.level;
1102 q.in.lookup_options = r->in.lookup_options;
1103 q.in.client_revision = r->in.client_revision;
1104 q.in.names = r->in.names;
1105 q.in.count = r->in.count;
1107 q.out.domains = r->out.domains;
1108 q.out.names = r->out.names;
1109 q.out.count = r->out.count;
1111 return _lsa_LookupSids2(p, &q);
1114 /***************************************************************************
1115 ***************************************************************************/
1117 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1119 int flags;
1121 switch (level) {
1122 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1123 flags = LOOKUP_NAME_ALL;
1124 break;
1125 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1126 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1127 break;
1128 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1129 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1130 break;
1131 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1132 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1133 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1134 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1135 default:
1136 flags = LOOKUP_NAME_NONE;
1137 break;
1140 return flags;
1143 /***************************************************************************
1144 _lsa_LookupNames
1145 ***************************************************************************/
1147 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1148 struct lsa_LookupNames *r)
1150 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1151 struct lsa_info *handle;
1152 struct lsa_String *names = r->in.names;
1153 uint32 num_entries = r->in.num_names;
1154 struct lsa_RefDomainList *domains = NULL;
1155 struct lsa_TranslatedSid *rids = NULL;
1156 uint32 mapped_count = 0;
1157 int flags = 0;
1159 if (num_entries > MAX_LOOKUP_SIDS) {
1160 num_entries = MAX_LOOKUP_SIDS;
1161 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1162 num_entries));
1165 flags = lsa_lookup_level_to_flags(r->in.level);
1167 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1168 if (!domains) {
1169 return NT_STATUS_NO_MEMORY;
1172 if (num_entries) {
1173 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1174 num_entries);
1175 if (!rids) {
1176 return NT_STATUS_NO_MEMORY;
1178 } else {
1179 rids = NULL;
1182 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1183 status = NT_STATUS_INVALID_HANDLE;
1184 goto done;
1187 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1188 return NT_STATUS_INVALID_HANDLE;
1191 /* check if the user has enough rights */
1192 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1193 status = NT_STATUS_ACCESS_DENIED;
1194 goto done;
1197 /* set up the LSA Lookup RIDs response */
1198 become_root(); /* lookup_name can require root privs */
1199 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1200 names, flags, &mapped_count);
1201 unbecome_root();
1203 done:
1205 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1206 if (mapped_count == 0) {
1207 status = NT_STATUS_NONE_MAPPED;
1208 } else if (mapped_count != num_entries) {
1209 status = STATUS_SOME_UNMAPPED;
1213 *r->out.count = mapped_count;
1214 *r->out.domains = domains;
1215 r->out.sids->sids = rids;
1216 r->out.sids->count = num_entries;
1218 return status;
1221 /***************************************************************************
1222 _lsa_LookupNames2
1223 ***************************************************************************/
1225 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1226 struct lsa_LookupNames2 *r)
1228 NTSTATUS status;
1229 struct lsa_LookupNames q;
1230 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1231 struct lsa_TransSidArray *sid_array = NULL;
1232 uint32_t i;
1234 sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1235 if (!sid_array) {
1236 return NT_STATUS_NO_MEMORY;
1239 q.in.handle = r->in.handle;
1240 q.in.num_names = r->in.num_names;
1241 q.in.names = r->in.names;
1242 q.in.level = r->in.level;
1243 q.in.sids = sid_array;
1244 q.in.count = r->in.count;
1245 /* we do not know what this is for */
1246 /* = r->in.unknown1; */
1247 /* = r->in.unknown2; */
1249 q.out.domains = r->out.domains;
1250 q.out.sids = sid_array;
1251 q.out.count = r->out.count;
1253 status = _lsa_LookupNames(p, &q);
1255 sid_array2->count = sid_array->count;
1256 sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1257 if (!sid_array2->sids) {
1258 return NT_STATUS_NO_MEMORY;
1261 for (i=0; i<sid_array->count; i++) {
1262 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1263 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1264 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1265 sid_array2->sids[i].unknown = 0;
1268 r->out.sids = sid_array2;
1270 return status;
1273 /***************************************************************************
1274 _lsa_LookupNames3
1275 ***************************************************************************/
1277 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1278 struct lsa_LookupNames3 *r)
1280 NTSTATUS status;
1281 struct lsa_info *handle;
1282 struct lsa_String *names = r->in.names;
1283 uint32 num_entries = r->in.num_names;
1284 struct lsa_RefDomainList *domains = NULL;
1285 struct lsa_TranslatedSid3 *trans_sids = NULL;
1286 uint32 mapped_count = 0;
1287 int flags = 0;
1288 bool check_policy = true;
1290 switch (p->opnum) {
1291 case NDR_LSA_LOOKUPNAMES4:
1292 check_policy = false;
1293 break;
1294 case NDR_LSA_LOOKUPNAMES3:
1295 default:
1296 check_policy = true;
1299 if (num_entries > MAX_LOOKUP_SIDS) {
1300 num_entries = MAX_LOOKUP_SIDS;
1301 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1304 /* Probably the lookup_level is some sort of bitmask. */
1305 if (r->in.level == 1) {
1306 flags = LOOKUP_NAME_ALL;
1309 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1310 if (!domains) {
1311 return NT_STATUS_NO_MEMORY;
1314 if (num_entries) {
1315 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1316 num_entries);
1317 if (!trans_sids) {
1318 return NT_STATUS_NO_MEMORY;
1320 } else {
1321 trans_sids = NULL;
1324 if (check_policy) {
1326 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1327 status = NT_STATUS_INVALID_HANDLE;
1328 goto done;
1331 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1332 return NT_STATUS_INVALID_HANDLE;
1335 /* check if the user has enough rights */
1336 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1337 status = NT_STATUS_ACCESS_DENIED;
1338 goto done;
1342 /* set up the LSA Lookup SIDs response */
1343 become_root(); /* lookup_name can require root privs */
1344 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1345 names, flags, &mapped_count);
1346 unbecome_root();
1348 done:
1350 if (NT_STATUS_IS_OK(status)) {
1351 if (mapped_count == 0) {
1352 status = NT_STATUS_NONE_MAPPED;
1353 } else if (mapped_count != num_entries) {
1354 status = STATUS_SOME_UNMAPPED;
1358 *r->out.count = mapped_count;
1359 *r->out.domains = domains;
1360 r->out.sids->sids = trans_sids;
1361 r->out.sids->count = num_entries;
1363 return status;
1366 /***************************************************************************
1367 _lsa_LookupNames4
1368 ***************************************************************************/
1370 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1371 struct lsa_LookupNames4 *r)
1373 struct lsa_LookupNames3 q;
1375 /* No policy handle on this call. Restrict to crypto connections. */
1376 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1377 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1378 get_remote_machine_name() ));
1379 return NT_STATUS_INVALID_PARAMETER;
1382 q.in.handle = NULL;
1383 q.in.num_names = r->in.num_names;
1384 q.in.names = r->in.names;
1385 q.in.level = r->in.level;
1386 q.in.lookup_options = r->in.lookup_options;
1387 q.in.client_revision = r->in.client_revision;
1388 q.in.sids = r->in.sids;
1389 q.in.count = r->in.count;
1391 q.out.domains = r->out.domains;
1392 q.out.sids = r->out.sids;
1393 q.out.count = r->out.count;
1395 return _lsa_LookupNames3(p, &q);
1398 /***************************************************************************
1399 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1400 ***************************************************************************/
1402 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1404 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1405 return NT_STATUS_INVALID_HANDLE;
1408 close_policy_hnd(p, r->in.handle);
1409 ZERO_STRUCTP(r->out.handle);
1410 return NT_STATUS_OK;
1413 /***************************************************************************
1414 ***************************************************************************/
1416 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1417 const struct dom_sid *sid,
1418 struct trustdom_info **info)
1420 NTSTATUS status;
1421 uint32_t num_domains = 0;
1422 struct trustdom_info **domains = NULL;
1423 int i;
1425 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1426 if (!NT_STATUS_IS_OK(status)) {
1427 return status;
1430 for (i=0; i < num_domains; i++) {
1431 if (dom_sid_equal(&domains[i]->sid, sid)) {
1432 break;
1436 if (i == num_domains) {
1437 return NT_STATUS_INVALID_PARAMETER;
1440 *info = domains[i];
1442 return NT_STATUS_OK;
1445 /***************************************************************************
1446 ***************************************************************************/
1448 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1449 const char *netbios_domain_name,
1450 struct trustdom_info **info_p)
1452 NTSTATUS status;
1453 struct trustdom_info *info;
1454 struct pdb_trusted_domain *td;
1456 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1457 if (!NT_STATUS_IS_OK(status)) {
1458 return status;
1461 info = talloc(mem_ctx, struct trustdom_info);
1462 if (!info) {
1463 return NT_STATUS_NO_MEMORY;
1466 info->name = talloc_strdup(info, netbios_domain_name);
1467 NT_STATUS_HAVE_NO_MEMORY(info->name);
1469 sid_copy(&info->sid, &td->security_identifier);
1471 *info_p = info;
1473 return NT_STATUS_OK;
1476 /***************************************************************************
1477 ***************************************************************************/
1479 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p, struct lsa_OpenSecret *r)
1481 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1484 /***************************************************************************
1485 _lsa_OpenTrustedDomain_base
1486 ***************************************************************************/
1488 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1489 uint32_t access_mask,
1490 struct trustdom_info *info,
1491 struct policy_handle *handle)
1493 struct security_descriptor *psd = NULL;
1494 size_t sd_size;
1495 uint32_t acc_granted;
1496 NTSTATUS status;
1498 /* des_access is for the account here, not the policy
1499 * handle - so don't check against policy handle. */
1501 /* Work out max allowed. */
1502 map_max_allowed_access(p->session_info->security_token,
1503 &p->session_info->utok,
1504 &access_mask);
1506 /* map the generic bits to the lsa account ones */
1507 se_map_generic(&access_mask, &lsa_account_mapping);
1509 /* get the generic lsa account SD until we store it */
1510 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1511 &lsa_trusted_domain_mapping,
1512 NULL, 0);
1513 if (!NT_STATUS_IS_OK(status)) {
1514 return status;
1517 status = access_check_object(psd, p->session_info->security_token,
1518 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1519 access_mask, &acc_granted,
1520 "_lsa_OpenTrustedDomain");
1521 if (!NT_STATUS_IS_OK(status)) {
1522 return status;
1525 status = create_lsa_policy_handle(p->mem_ctx, p,
1526 LSA_HANDLE_TRUST_TYPE,
1527 acc_granted,
1528 &info->sid,
1529 info->name,
1530 psd,
1531 handle);
1532 if (!NT_STATUS_IS_OK(status)) {
1533 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1536 return NT_STATUS_OK;
1539 /***************************************************************************
1540 _lsa_OpenTrustedDomain
1541 ***************************************************************************/
1543 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1544 struct lsa_OpenTrustedDomain *r)
1546 struct lsa_info *handle = NULL;
1547 struct trustdom_info *info = NULL;
1548 NTSTATUS status;
1550 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1551 return NT_STATUS_INVALID_HANDLE;
1554 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1555 return NT_STATUS_INVALID_HANDLE;
1558 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1559 r->in.sid,
1560 &info);
1561 if (!NT_STATUS_IS_OK(status)) {
1562 return status;
1565 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1566 r->out.trustdom_handle);
1569 /***************************************************************************
1570 _lsa_OpenTrustedDomainByName
1571 ***************************************************************************/
1573 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1574 struct lsa_OpenTrustedDomainByName *r)
1576 struct lsa_info *handle = NULL;
1577 struct trustdom_info *info = NULL;
1578 NTSTATUS status;
1580 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1581 return NT_STATUS_INVALID_HANDLE;
1584 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1585 return NT_STATUS_INVALID_HANDLE;
1588 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1589 r->in.name.string,
1590 &info);
1591 if (!NT_STATUS_IS_OK(status)) {
1592 return status;
1595 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1596 r->out.trustdom_handle);
1599 static NTSTATUS add_trusted_domain_user(TALLOC_CTX *mem_ctx,
1600 const char *netbios_name,
1601 const char *domain_name,
1602 struct trustDomainPasswords auth_struct)
1604 NTSTATUS status;
1605 struct samu *sam_acct;
1606 char *acct_name;
1607 uint32_t rid;
1608 struct dom_sid user_sid;
1609 int i;
1610 char *dummy;
1611 size_t dummy_size;
1613 sam_acct = samu_new(mem_ctx);
1614 if (sam_acct == NULL) {
1615 return NT_STATUS_NO_MEMORY;
1618 acct_name = talloc_asprintf(mem_ctx, "%s$", netbios_name);
1619 if (acct_name == NULL) {
1620 return NT_STATUS_NO_MEMORY;
1622 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1623 return NT_STATUS_UNSUCCESSFUL;
1626 if (!pdb_set_domain(sam_acct, domain_name, PDB_SET)) {
1627 return NT_STATUS_UNSUCCESSFUL;
1630 if (!pdb_set_acct_ctrl(sam_acct, ACB_DOMTRUST, PDB_SET)) {
1631 return NT_STATUS_UNSUCCESSFUL;
1634 if (!pdb_new_rid(&rid)) {
1635 return NT_STATUS_DS_NO_MORE_RIDS;
1637 sid_compose(&user_sid, get_global_sam_sid(), rid);
1638 if (!pdb_set_user_sid(sam_acct, &user_sid, PDB_SET)) {
1639 return NT_STATUS_UNSUCCESSFUL;
1642 for (i = 0; i < auth_struct.incoming.count; i++) {
1643 switch (auth_struct.incoming.current.array[i].AuthType) {
1644 case TRUST_AUTH_TYPE_CLEAR:
1645 if (!convert_string_talloc(mem_ctx,
1646 CH_UTF16LE,
1647 CH_UNIX,
1648 auth_struct.incoming.current.array[i].AuthInfo.clear.password,
1649 auth_struct.incoming.current.array[i].AuthInfo.clear.size,
1650 &dummy,
1651 &dummy_size,
1652 false)) {
1653 return NT_STATUS_UNSUCCESSFUL;
1655 if (!pdb_set_plaintext_passwd(sam_acct, dummy)) {
1656 return NT_STATUS_UNSUCCESSFUL;
1658 break;
1659 default:
1660 continue;
1664 status = pdb_add_sam_account(sam_acct);
1665 if (!NT_STATUS_IS_OK(status)) {
1666 return status;
1669 return NT_STATUS_OK;
1672 /***************************************************************************
1673 _lsa_CreateTrustedDomainEx2
1674 ***************************************************************************/
1676 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1677 struct lsa_CreateTrustedDomainEx2 *r)
1679 struct lsa_info *policy;
1680 NTSTATUS status;
1681 uint32_t acc_granted;
1682 struct security_descriptor *psd;
1683 size_t sd_size;
1684 struct pdb_trusted_domain td;
1685 struct trustDomainPasswords auth_struct;
1686 enum ndr_err_code ndr_err;
1687 DATA_BLOB auth_blob;
1689 if (!IS_DC) {
1690 return NT_STATUS_NOT_SUPPORTED;
1693 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1694 return NT_STATUS_INVALID_HANDLE;
1697 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1698 return NT_STATUS_ACCESS_DENIED;
1701 if (p->session_info->utok.uid != sec_initial_uid() &&
1702 !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1703 return NT_STATUS_ACCESS_DENIED;
1706 /* Work out max allowed. */
1707 map_max_allowed_access(p->session_info->security_token,
1708 &p->session_info->utok,
1709 &r->in.access_mask);
1711 /* map the generic bits to the lsa policy ones */
1712 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1714 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1715 &lsa_trusted_domain_mapping,
1716 NULL, 0);
1717 if (!NT_STATUS_IS_OK(status)) {
1718 return status;
1721 status = access_check_object(psd, p->session_info->security_token,
1722 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1723 r->in.access_mask, &acc_granted,
1724 "_lsa_CreateTrustedDomainEx2");
1725 if (!NT_STATUS_IS_OK(status)) {
1726 return status;
1729 ZERO_STRUCT(td);
1731 td.domain_name = talloc_strdup(p->mem_ctx,
1732 r->in.info->domain_name.string);
1733 if (td.domain_name == NULL) {
1734 return NT_STATUS_NO_MEMORY;
1736 td.netbios_name = talloc_strdup(p->mem_ctx,
1737 r->in.info->netbios_name.string);
1738 if (td.netbios_name == NULL) {
1739 return NT_STATUS_NO_MEMORY;
1741 sid_copy(&td.security_identifier, r->in.info->sid);
1742 td.trust_direction = r->in.info->trust_direction;
1743 td.trust_type = r->in.info->trust_type;
1744 td.trust_attributes = r->in.info->trust_attributes;
1746 if (r->in.auth_info->auth_blob.size != 0) {
1747 auth_blob.length = r->in.auth_info->auth_blob.size;
1748 auth_blob.data = r->in.auth_info->auth_blob.data;
1750 arcfour_crypt_blob(auth_blob.data, auth_blob.length,
1751 &p->session_info->user_session_key);
1753 ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
1754 &auth_struct,
1755 (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
1756 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1757 return NT_STATUS_UNSUCCESSFUL;
1760 ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
1761 &auth_struct.incoming,
1762 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1763 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1764 return NT_STATUS_UNSUCCESSFUL;
1767 ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
1768 &auth_struct.outgoing,
1769 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1770 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1771 return NT_STATUS_UNSUCCESSFUL;
1773 } else {
1774 td.trust_auth_incoming.data = NULL;
1775 td.trust_auth_incoming.length = 0;
1776 td.trust_auth_outgoing.data = NULL;
1777 td.trust_auth_outgoing.length = 0;
1780 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1781 if (!NT_STATUS_IS_OK(status)) {
1782 return status;
1785 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1786 status = add_trusted_domain_user(p->mem_ctx,
1787 r->in.info->netbios_name.string,
1788 r->in.info->domain_name.string,
1789 auth_struct);
1790 if (!NT_STATUS_IS_OK(status)) {
1791 return status;
1795 status = create_lsa_policy_handle(p->mem_ctx, p,
1796 LSA_HANDLE_TRUST_TYPE,
1797 acc_granted,
1798 r->in.info->sid,
1799 r->in.info->netbios_name.string,
1800 psd,
1801 r->out.trustdom_handle);
1802 if (!NT_STATUS_IS_OK(status)) {
1803 pdb_del_trusteddom_pw(r->in.info->netbios_name.string);
1804 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1807 return NT_STATUS_OK;
1810 /***************************************************************************
1811 _lsa_CreateTrustedDomainEx
1812 ***************************************************************************/
1814 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1815 struct lsa_CreateTrustedDomainEx *r)
1817 struct lsa_CreateTrustedDomainEx2 q;
1819 q.in.policy_handle = r->in.policy_handle;
1820 q.in.info = r->in.info;
1821 q.in.auth_info = r->in.auth_info;
1822 q.in.access_mask = r->in.access_mask;
1823 q.out.trustdom_handle = r->out.trustdom_handle;
1825 return _lsa_CreateTrustedDomainEx2(p, &q);
1828 /***************************************************************************
1829 _lsa_CreateTrustedDomain
1830 ***************************************************************************/
1832 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1833 struct lsa_CreateTrustedDomain *r)
1835 struct lsa_CreateTrustedDomainEx2 c;
1836 struct lsa_TrustDomainInfoInfoEx info;
1837 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1839 ZERO_STRUCT(auth_info);
1841 info.domain_name = r->in.info->name;
1842 info.netbios_name = r->in.info->name;
1843 info.sid = r->in.info->sid;
1844 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1845 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1846 info.trust_attributes = 0;
1848 c.in.policy_handle = r->in.policy_handle;
1849 c.in.info = &info;
1850 c.in.auth_info = &auth_info;
1851 c.in.access_mask = r->in.access_mask;
1852 c.out.trustdom_handle = r->out.trustdom_handle;
1854 return _lsa_CreateTrustedDomainEx2(p, &c);
1857 /***************************************************************************
1858 _lsa_DeleteTrustedDomain
1859 ***************************************************************************/
1861 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1862 struct lsa_DeleteTrustedDomain *r)
1864 NTSTATUS status;
1865 struct lsa_info *handle;
1866 struct pdb_trusted_domain *td;
1867 struct samu *sam_acct;
1868 char *acct_name;
1870 /* find the connection policy handle. */
1871 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1872 return NT_STATUS_INVALID_HANDLE;
1875 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1876 return NT_STATUS_INVALID_HANDLE;
1879 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1880 return NT_STATUS_ACCESS_DENIED;
1883 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1884 if (!NT_STATUS_IS_OK(status)) {
1885 return status;
1888 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1889 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1890 sid_string_tos(r->in.dom_sid)));
1891 return NT_STATUS_UNSUCCESSFUL;
1894 if (td->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1895 sam_acct = samu_new(p->mem_ctx);
1896 if (sam_acct == NULL) {
1897 return NT_STATUS_NO_MEMORY;
1900 acct_name = talloc_asprintf(p->mem_ctx, "%s$", td->netbios_name);
1901 if (acct_name == NULL) {
1902 return NT_STATUS_NO_MEMORY;
1904 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1905 return NT_STATUS_UNSUCCESSFUL;
1907 status = pdb_delete_sam_account(sam_acct);
1908 if (!NT_STATUS_IS_OK(status)) {
1909 return status;
1913 status = pdb_del_trusted_domain(td->netbios_name);
1914 if (!NT_STATUS_IS_OK(status)) {
1915 return status;
1918 return NT_STATUS_OK;
1921 /***************************************************************************
1922 _lsa_CloseTrustedDomainEx
1923 ***************************************************************************/
1925 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1926 struct lsa_CloseTrustedDomainEx *r)
1928 return NT_STATUS_NOT_IMPLEMENTED;
1931 /***************************************************************************
1932 _lsa_QueryTrustedDomainInfo
1933 ***************************************************************************/
1935 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
1936 struct lsa_QueryTrustedDomainInfo *r)
1938 NTSTATUS status;
1939 struct lsa_info *handle;
1940 union lsa_TrustedDomainInfo *info;
1941 struct pdb_trusted_domain *td;
1942 uint32_t acc_required;
1944 /* find the connection policy handle. */
1945 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
1946 return NT_STATUS_INVALID_HANDLE;
1949 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
1950 return NT_STATUS_INVALID_HANDLE;
1953 switch (r->in.level) {
1954 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1955 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1956 break;
1957 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1958 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
1959 break;
1960 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1961 acc_required = LSA_TRUSTED_QUERY_POSIX;
1962 break;
1963 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
1964 acc_required = LSA_TRUSTED_QUERY_AUTH;
1965 break;
1966 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1967 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1968 break;
1969 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1970 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1971 break;
1972 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1973 acc_required = LSA_TRUSTED_QUERY_AUTH;
1974 break;
1975 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1976 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1977 LSA_TRUSTED_QUERY_POSIX |
1978 LSA_TRUSTED_QUERY_AUTH;
1979 break;
1980 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1981 acc_required = LSA_TRUSTED_QUERY_AUTH;
1982 break;
1983 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1984 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1985 LSA_TRUSTED_QUERY_POSIX |
1986 LSA_TRUSTED_QUERY_AUTH;
1987 break;
1988 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1989 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1990 break;
1991 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1992 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1993 LSA_TRUSTED_QUERY_POSIX |
1994 LSA_TRUSTED_QUERY_AUTH;
1995 break;
1996 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1997 acc_required = LSA_TRUSTED_QUERY_POSIX;
1998 break;
1999 default:
2000 return NT_STATUS_INVALID_PARAMETER;
2003 if (!(handle->access & acc_required)) {
2004 return NT_STATUS_ACCESS_DENIED;
2007 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2008 if (!NT_STATUS_IS_OK(status)) {
2009 return status;
2012 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_TrustedDomainInfo);
2013 if (!info) {
2014 return NT_STATUS_NO_MEMORY;
2017 switch (r->in.level) {
2018 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2019 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2020 break;
2021 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2022 return NT_STATUS_INVALID_PARAMETER;
2023 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2024 break;
2025 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2026 return NT_STATUS_INVALID_INFO_CLASS;
2027 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2028 return NT_STATUS_INVALID_PARAMETER;
2029 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2030 init_lsa_StringLarge(&info->info_ex.domain_name, td->domain_name);
2031 init_lsa_StringLarge(&info->info_ex.netbios_name, td->netbios_name);
2032 info->info_ex.sid = dom_sid_dup(info, &td->security_identifier);
2033 if (!info->info_ex.sid) {
2034 return NT_STATUS_NO_MEMORY;
2036 info->info_ex.trust_direction = td->trust_direction;
2037 info->info_ex.trust_type = td->trust_type;
2038 info->info_ex.trust_attributes = td->trust_attributes;
2039 break;
2040 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2041 return NT_STATUS_INVALID_INFO_CLASS;
2042 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2043 break;
2044 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2045 return NT_STATUS_INVALID_INFO_CLASS;
2046 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2047 return NT_STATUS_INVALID_INFO_CLASS;
2048 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2049 return NT_STATUS_INVALID_PARAMETER;
2050 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2051 break;
2052 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2053 break;
2054 default:
2055 return NT_STATUS_INVALID_PARAMETER;
2058 *r->out.info = info;
2060 return NT_STATUS_OK;
2063 /***************************************************************************
2064 _lsa_QueryTrustedDomainInfoBySid
2065 ***************************************************************************/
2067 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2068 struct lsa_QueryTrustedDomainInfoBySid *r)
2070 NTSTATUS status;
2071 struct policy_handle trustdom_handle;
2072 struct lsa_OpenTrustedDomain o;
2073 struct lsa_QueryTrustedDomainInfo q;
2074 struct lsa_Close c;
2076 o.in.handle = r->in.handle;
2077 o.in.sid = r->in.dom_sid;
2078 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2079 o.out.trustdom_handle = &trustdom_handle;
2081 status = _lsa_OpenTrustedDomain(p, &o);
2082 if (!NT_STATUS_IS_OK(status)) {
2083 return status;
2086 q.in.trustdom_handle = &trustdom_handle;
2087 q.in.level = r->in.level;
2088 q.out.info = r->out.info;
2090 status = _lsa_QueryTrustedDomainInfo(p, &q);
2091 if (!NT_STATUS_IS_OK(status)) {
2092 return status;
2095 c.in.handle = &trustdom_handle;
2096 c.out.handle = &trustdom_handle;
2098 return _lsa_Close(p, &c);
2101 /***************************************************************************
2102 _lsa_QueryTrustedDomainInfoByName
2103 ***************************************************************************/
2105 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2106 struct lsa_QueryTrustedDomainInfoByName *r)
2108 NTSTATUS status;
2109 struct policy_handle trustdom_handle;
2110 struct lsa_OpenTrustedDomainByName o;
2111 struct lsa_QueryTrustedDomainInfo q;
2112 struct lsa_Close c;
2114 o.in.handle = r->in.handle;
2115 o.in.name.string = r->in.trusted_domain->string;
2116 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2117 o.out.trustdom_handle = &trustdom_handle;
2119 status = _lsa_OpenTrustedDomainByName(p, &o);
2120 if (!NT_STATUS_IS_OK(status)) {
2121 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2122 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2124 return status;
2127 q.in.trustdom_handle = &trustdom_handle;
2128 q.in.level = r->in.level;
2129 q.out.info = r->out.info;
2131 status = _lsa_QueryTrustedDomainInfo(p, &q);
2132 if (!NT_STATUS_IS_OK(status)) {
2133 return status;
2136 c.in.handle = &trustdom_handle;
2137 c.out.handle = &trustdom_handle;
2139 return _lsa_Close(p, &c);
2142 /***************************************************************************
2143 ***************************************************************************/
2145 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p, struct lsa_CreateSecret *r)
2147 return NT_STATUS_ACCESS_DENIED;
2150 /***************************************************************************
2151 ***************************************************************************/
2153 NTSTATUS _lsa_SetSecret(struct pipes_struct *p, struct lsa_SetSecret *r)
2155 return NT_STATUS_ACCESS_DENIED;
2158 /***************************************************************************
2159 _lsa_DeleteObject
2160 ***************************************************************************/
2162 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2163 struct lsa_DeleteObject *r)
2165 NTSTATUS status;
2166 struct lsa_info *info = NULL;
2168 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2169 return NT_STATUS_INVALID_HANDLE;
2172 if (!(info->access & SEC_STD_DELETE)) {
2173 return NT_STATUS_ACCESS_DENIED;
2176 switch (info->type) {
2177 case LSA_HANDLE_ACCOUNT_TYPE:
2178 status = privilege_delete_account(&info->sid);
2179 if (!NT_STATUS_IS_OK(status)) {
2180 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2181 nt_errstr(status)));
2182 return status;
2184 break;
2185 default:
2186 return NT_STATUS_INVALID_HANDLE;
2189 close_policy_hnd(p, r->in.handle);
2190 ZERO_STRUCTP(r->out.handle);
2192 return status;
2195 /***************************************************************************
2196 _lsa_EnumPrivs
2197 ***************************************************************************/
2199 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2200 struct lsa_EnumPrivs *r)
2202 struct lsa_info *handle;
2203 uint32 i;
2204 uint32 enum_context = *r->in.resume_handle;
2205 int num_privs = num_privileges_in_short_list();
2206 struct lsa_PrivEntry *entries = NULL;
2208 /* remember that the enum_context starts at 0 and not 1 */
2210 if ( enum_context >= num_privs )
2211 return NT_STATUS_NO_MORE_ENTRIES;
2213 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2214 enum_context, num_privs));
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 /* check if the user has enough rights
2224 I don't know if it's the right one. not documented. */
2226 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2227 return NT_STATUS_ACCESS_DENIED;
2229 if (num_privs) {
2230 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2231 if (!entries) {
2232 return NT_STATUS_NO_MEMORY;
2234 } else {
2235 entries = NULL;
2238 for (i = 0; i < num_privs; i++) {
2239 if( i < enum_context) {
2241 init_lsa_StringLarge(&entries[i].name, NULL);
2243 entries[i].luid.low = 0;
2244 entries[i].luid.high = 0;
2245 } else {
2247 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2249 entries[i].luid.low = sec_privilege_from_index(i);
2250 entries[i].luid.high = 0;
2254 enum_context = num_privs;
2256 *r->out.resume_handle = enum_context;
2257 r->out.privs->count = num_privs;
2258 r->out.privs->privs = entries;
2260 return NT_STATUS_OK;
2263 /***************************************************************************
2264 _lsa_LookupPrivDisplayName
2265 ***************************************************************************/
2267 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2268 struct lsa_LookupPrivDisplayName *r)
2270 struct lsa_info *handle;
2271 const char *description;
2272 struct lsa_StringLarge *lsa_name;
2274 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2275 return NT_STATUS_INVALID_HANDLE;
2277 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2278 return NT_STATUS_INVALID_HANDLE;
2281 /* check if the user has enough rights */
2284 * I don't know if it's the right one. not documented.
2286 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2287 return NT_STATUS_ACCESS_DENIED;
2289 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2291 description = get_privilege_dispname(r->in.name->string);
2292 if (!description) {
2293 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2294 return NT_STATUS_NO_SUCH_PRIVILEGE;
2297 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2299 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2300 if (!lsa_name) {
2301 return NT_STATUS_NO_MEMORY;
2304 init_lsa_StringLarge(lsa_name, description);
2306 *r->out.returned_language_id = r->in.language_id;
2307 *r->out.disp_name = lsa_name;
2309 return NT_STATUS_OK;
2312 /***************************************************************************
2313 _lsa_EnumAccounts
2314 ***************************************************************************/
2316 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2317 struct lsa_EnumAccounts *r)
2319 struct lsa_info *handle;
2320 struct dom_sid *sid_list;
2321 int i, j, num_entries;
2322 NTSTATUS status;
2323 struct lsa_SidPtr *sids = NULL;
2325 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2326 return NT_STATUS_INVALID_HANDLE;
2328 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2329 return NT_STATUS_INVALID_HANDLE;
2332 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2333 return NT_STATUS_ACCESS_DENIED;
2335 sid_list = NULL;
2336 num_entries = 0;
2338 /* The only way we can currently find out all the SIDs that have been
2339 privileged is to scan all privileges */
2341 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2342 if (!NT_STATUS_IS_OK(status)) {
2343 return status;
2346 if (*r->in.resume_handle >= num_entries) {
2347 return NT_STATUS_NO_MORE_ENTRIES;
2350 if (num_entries - *r->in.resume_handle) {
2351 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
2352 num_entries - *r->in.resume_handle);
2353 if (!sids) {
2354 talloc_free(sid_list);
2355 return NT_STATUS_NO_MEMORY;
2358 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2359 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2360 if (!sids[j].sid) {
2361 talloc_free(sid_list);
2362 return NT_STATUS_NO_MEMORY;
2367 talloc_free(sid_list);
2369 *r->out.resume_handle = num_entries;
2370 r->out.sids->num_sids = num_entries;
2371 r->out.sids->sids = sids;
2373 return NT_STATUS_OK;
2376 /***************************************************************************
2377 _lsa_GetUserName
2378 ***************************************************************************/
2380 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2381 struct lsa_GetUserName *r)
2383 const char *username, *domname;
2384 struct lsa_String *account_name = NULL;
2385 struct lsa_String *authority_name = NULL;
2387 if (r->in.account_name &&
2388 *r->in.account_name) {
2389 return NT_STATUS_INVALID_PARAMETER;
2392 if (r->in.authority_name &&
2393 *r->in.authority_name) {
2394 return NT_STATUS_INVALID_PARAMETER;
2397 if (p->session_info->guest) {
2399 * I'm 99% sure this is not the right place to do this,
2400 * global_sid_Anonymous should probably be put into the token
2401 * instead of the guest id -- vl
2403 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2404 &domname, &username, NULL)) {
2405 return NT_STATUS_NO_MEMORY;
2407 } else {
2408 username = p->session_info->sanitized_username;
2409 domname = p->session_info->info3->base.domain.string;
2412 account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2413 if (!account_name) {
2414 return NT_STATUS_NO_MEMORY;
2416 init_lsa_String(account_name, username);
2418 if (r->out.authority_name) {
2419 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2420 if (!authority_name) {
2421 return NT_STATUS_NO_MEMORY;
2423 init_lsa_String(authority_name, domname);
2426 *r->out.account_name = account_name;
2427 if (r->out.authority_name) {
2428 *r->out.authority_name = authority_name;
2431 return NT_STATUS_OK;
2434 /***************************************************************************
2435 _lsa_CreateAccount
2436 ***************************************************************************/
2438 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2439 struct lsa_CreateAccount *r)
2441 NTSTATUS status;
2442 struct lsa_info *handle;
2443 uint32_t acc_granted;
2444 struct security_descriptor *psd;
2445 size_t sd_size;
2447 /* find the connection policy handle. */
2448 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2449 return NT_STATUS_INVALID_HANDLE;
2451 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2452 return NT_STATUS_INVALID_HANDLE;
2455 /* check if the user has enough rights */
2457 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2458 return NT_STATUS_ACCESS_DENIED;
2461 /* Work out max allowed. */
2462 map_max_allowed_access(p->session_info->security_token,
2463 &p->session_info->utok,
2464 &r->in.access_mask);
2466 /* map the generic bits to the lsa policy ones */
2467 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2469 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2470 &lsa_account_mapping,
2471 r->in.sid, LSA_POLICY_ALL_ACCESS);
2472 if (!NT_STATUS_IS_OK(status)) {
2473 return status;
2476 status = access_check_object(psd, p->session_info->security_token,
2477 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2478 &acc_granted, "_lsa_CreateAccount");
2479 if (!NT_STATUS_IS_OK(status)) {
2480 return status;
2483 if ( is_privileged_sid( r->in.sid ) )
2484 return NT_STATUS_OBJECT_NAME_COLLISION;
2486 status = create_lsa_policy_handle(p->mem_ctx, p,
2487 LSA_HANDLE_ACCOUNT_TYPE,
2488 acc_granted,
2489 r->in.sid,
2490 NULL,
2491 psd,
2492 r->out.acct_handle);
2493 if (!NT_STATUS_IS_OK(status)) {
2494 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2497 return privilege_create_account(r->in.sid);
2500 /***************************************************************************
2501 _lsa_OpenAccount
2502 ***************************************************************************/
2504 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2505 struct lsa_OpenAccount *r)
2507 struct lsa_info *handle;
2508 struct security_descriptor *psd = NULL;
2509 size_t sd_size;
2510 uint32_t des_access = r->in.access_mask;
2511 uint32_t acc_granted;
2512 NTSTATUS status;
2514 /* find the connection policy handle. */
2515 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2516 return NT_STATUS_INVALID_HANDLE;
2518 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2519 return NT_STATUS_INVALID_HANDLE;
2522 /* des_access is for the account here, not the policy
2523 * handle - so don't check against policy handle. */
2525 /* Work out max allowed. */
2526 map_max_allowed_access(p->session_info->security_token,
2527 &p->session_info->utok,
2528 &des_access);
2530 /* map the generic bits to the lsa account ones */
2531 se_map_generic(&des_access, &lsa_account_mapping);
2533 /* get the generic lsa account SD until we store it */
2534 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2535 &lsa_account_mapping,
2536 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2537 if (!NT_STATUS_IS_OK(status)) {
2538 return status;
2541 status = access_check_object(psd, p->session_info->security_token,
2542 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2543 &acc_granted, "_lsa_OpenAccount" );
2544 if (!NT_STATUS_IS_OK(status)) {
2545 return status;
2548 /* TODO: Fis the parsing routine before reenabling this check! */
2549 #if 0
2550 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2551 return NT_STATUS_ACCESS_DENIED;
2552 #endif
2554 status = create_lsa_policy_handle(p->mem_ctx, p,
2555 LSA_HANDLE_ACCOUNT_TYPE,
2556 acc_granted,
2557 r->in.sid,
2558 NULL,
2559 psd,
2560 r->out.acct_handle);
2561 if (!NT_STATUS_IS_OK(status)) {
2562 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2565 return NT_STATUS_OK;
2568 /***************************************************************************
2569 _lsa_EnumPrivsAccount
2570 For a given SID, enumerate all the privilege this account has.
2571 ***************************************************************************/
2573 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2574 struct lsa_EnumPrivsAccount *r)
2576 NTSTATUS status = NT_STATUS_OK;
2577 struct lsa_info *info=NULL;
2578 PRIVILEGE_SET *privileges;
2579 struct lsa_PrivilegeSet *priv_set = NULL;
2581 /* find the connection policy handle. */
2582 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2583 return NT_STATUS_INVALID_HANDLE;
2585 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2586 return NT_STATUS_INVALID_HANDLE;
2589 if (!(info->access & LSA_ACCOUNT_VIEW))
2590 return NT_STATUS_ACCESS_DENIED;
2592 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2593 if (!NT_STATUS_IS_OK(status)) {
2594 return status;
2597 *r->out.privs = priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
2598 if (!priv_set) {
2599 return NT_STATUS_NO_MEMORY;
2602 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2603 sid_string_dbg(&info->sid),
2604 privileges->count));
2606 priv_set->count = privileges->count;
2607 priv_set->unknown = 0;
2608 priv_set->set = talloc_move(priv_set, &privileges->set);
2610 return status;
2613 /***************************************************************************
2614 _lsa_GetSystemAccessAccount
2615 ***************************************************************************/
2617 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2618 struct lsa_GetSystemAccessAccount *r)
2620 NTSTATUS status;
2621 struct lsa_info *info = NULL;
2622 struct lsa_EnumPrivsAccount e;
2623 struct lsa_PrivilegeSet *privset;
2625 /* find the connection policy handle. */
2627 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2628 return NT_STATUS_INVALID_HANDLE;
2630 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2631 return NT_STATUS_INVALID_HANDLE;
2634 if (!(info->access & LSA_ACCOUNT_VIEW))
2635 return NT_STATUS_ACCESS_DENIED;
2637 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2638 if (!privset) {
2639 return NT_STATUS_NO_MEMORY;
2642 e.in.handle = r->in.handle;
2643 e.out.privs = &privset;
2645 status = _lsa_EnumPrivsAccount(p, &e);
2646 if (!NT_STATUS_IS_OK(status)) {
2647 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2648 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2649 nt_errstr(status)));
2650 return status;
2653 /* Samba4 would iterate over the privset to merge the policy mode bits,
2654 * not sure samba3 can do the same here, so just return what we did in
2655 * the past - gd */
2658 0x01 -> Log on locally
2659 0x02 -> Access this computer from network
2660 0x04 -> Log on as a batch job
2661 0x10 -> Log on as a service
2663 they can be ORed together
2666 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2667 LSA_POLICY_MODE_NETWORK;
2669 return NT_STATUS_OK;
2672 /***************************************************************************
2673 update the systemaccount information
2674 ***************************************************************************/
2676 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2677 struct lsa_SetSystemAccessAccount *r)
2679 struct lsa_info *info=NULL;
2680 GROUP_MAP map;
2682 /* find the connection policy handle. */
2683 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2684 return NT_STATUS_INVALID_HANDLE;
2686 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2687 return NT_STATUS_INVALID_HANDLE;
2690 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2691 return NT_STATUS_ACCESS_DENIED;
2694 if (!pdb_getgrsid(&map, info->sid))
2695 return NT_STATUS_NO_SUCH_GROUP;
2697 return pdb_update_group_mapping_entry(&map);
2700 /***************************************************************************
2701 _lsa_AddPrivilegesToAccount
2702 For a given SID, add some privileges.
2703 ***************************************************************************/
2705 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
2706 struct lsa_AddPrivilegesToAccount *r)
2708 struct lsa_info *info = NULL;
2709 struct lsa_PrivilegeSet *set = NULL;
2711 /* find the connection policy handle. */
2712 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2713 return NT_STATUS_INVALID_HANDLE;
2715 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2716 return NT_STATUS_INVALID_HANDLE;
2719 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2720 return NT_STATUS_ACCESS_DENIED;
2723 set = r->in.privs;
2725 if ( !grant_privilege_set( &info->sid, set ) ) {
2726 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2727 sid_string_dbg(&info->sid) ));
2728 return NT_STATUS_NO_SUCH_PRIVILEGE;
2731 return NT_STATUS_OK;
2734 /***************************************************************************
2735 _lsa_RemovePrivilegesFromAccount
2736 For a given SID, remove some privileges.
2737 ***************************************************************************/
2739 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2740 struct lsa_RemovePrivilegesFromAccount *r)
2742 struct lsa_info *info = NULL;
2743 struct lsa_PrivilegeSet *set = NULL;
2745 /* find the connection policy handle. */
2746 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2747 return NT_STATUS_INVALID_HANDLE;
2749 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2750 return NT_STATUS_INVALID_HANDLE;
2753 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2754 return NT_STATUS_ACCESS_DENIED;
2757 set = r->in.privs;
2759 if ( !revoke_privilege_set( &info->sid, set) ) {
2760 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2761 sid_string_dbg(&info->sid) ));
2762 return NT_STATUS_NO_SUCH_PRIVILEGE;
2765 return NT_STATUS_OK;
2768 /***************************************************************************
2769 _lsa_LookupPrivName
2770 ***************************************************************************/
2772 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2773 struct lsa_LookupPrivName *r)
2775 struct lsa_info *info = NULL;
2776 const char *name;
2777 struct lsa_StringLarge *lsa_name;
2779 /* find the connection policy handle. */
2780 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2781 return NT_STATUS_INVALID_HANDLE;
2784 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2785 return NT_STATUS_INVALID_HANDLE;
2788 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2789 return NT_STATUS_ACCESS_DENIED;
2792 if (r->in.luid->high != 0) {
2793 return NT_STATUS_NO_SUCH_PRIVILEGE;
2796 name = sec_privilege_name(r->in.luid->low);
2797 if (!name) {
2798 return NT_STATUS_NO_SUCH_PRIVILEGE;
2801 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2802 if (!lsa_name) {
2803 return NT_STATUS_NO_MEMORY;
2806 lsa_name->string = talloc_strdup(lsa_name, name);
2807 if (!lsa_name->string) {
2808 TALLOC_FREE(lsa_name);
2809 return NT_STATUS_NO_MEMORY;
2812 *r->out.name = lsa_name;
2814 return NT_STATUS_OK;
2817 /***************************************************************************
2818 _lsa_QuerySecurity
2819 ***************************************************************************/
2821 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
2822 struct lsa_QuerySecurity *r)
2824 struct lsa_info *handle=NULL;
2825 struct security_descriptor *psd = NULL;
2826 size_t sd_size = 0;
2827 NTSTATUS status;
2829 /* find the connection policy handle. */
2830 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2831 return NT_STATUS_INVALID_HANDLE;
2833 switch (handle->type) {
2834 case LSA_HANDLE_POLICY_TYPE:
2835 case LSA_HANDLE_ACCOUNT_TYPE:
2836 case LSA_HANDLE_TRUST_TYPE:
2837 psd = handle->sd;
2838 sd_size = ndr_size_security_descriptor(psd, 0);
2839 status = NT_STATUS_OK;
2840 break;
2841 default:
2842 status = NT_STATUS_INVALID_HANDLE;
2843 break;
2846 if (!NT_STATUS_IS_OK(status)) {
2847 return status;
2850 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2851 if (!*r->out.sdbuf) {
2852 return NT_STATUS_NO_MEMORY;
2855 return status;
2858 /***************************************************************************
2859 _lsa_AddAccountRights
2860 ***************************************************************************/
2862 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
2863 struct lsa_AddAccountRights *r)
2865 struct lsa_info *info = NULL;
2866 int i = 0;
2867 uint32_t acc_granted = 0;
2868 struct security_descriptor *psd = NULL;
2869 size_t sd_size;
2870 struct dom_sid sid;
2871 NTSTATUS status;
2873 /* find the connection policy handle. */
2874 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2875 return NT_STATUS_INVALID_HANDLE;
2877 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2878 return NT_STATUS_INVALID_HANDLE;
2881 /* get the generic lsa account SD for this SID until we store it */
2882 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2883 &lsa_account_mapping,
2884 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2885 if (!NT_STATUS_IS_OK(status)) {
2886 return status;
2890 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2891 * on the policy handle. If it does, ask for
2892 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2893 * on the account sid. We don't check here so just use the latter. JRA.
2896 status = access_check_object(psd, p->session_info->security_token,
2897 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2898 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2899 &acc_granted, "_lsa_AddAccountRights" );
2900 if (!NT_STATUS_IS_OK(status)) {
2901 return status;
2904 /* according to an NT4 PDC, you can add privileges to SIDs even without
2905 call_lsa_create_account() first. And you can use any arbitrary SID. */
2907 sid_copy( &sid, r->in.sid );
2909 for ( i=0; i < r->in.rights->count; i++ ) {
2911 const char *privname = r->in.rights->names[i].string;
2913 /* only try to add non-null strings */
2915 if ( !privname )
2916 continue;
2918 if ( !grant_privilege_by_name( &sid, privname ) ) {
2919 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2920 privname ));
2921 return NT_STATUS_NO_SUCH_PRIVILEGE;
2925 return NT_STATUS_OK;
2928 /***************************************************************************
2929 _lsa_RemoveAccountRights
2930 ***************************************************************************/
2932 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
2933 struct lsa_RemoveAccountRights *r)
2935 struct lsa_info *info = NULL;
2936 int i = 0;
2937 struct security_descriptor *psd = NULL;
2938 size_t sd_size;
2939 struct dom_sid sid;
2940 const char *privname = NULL;
2941 uint32_t acc_granted = 0;
2942 NTSTATUS status;
2944 /* find the connection policy handle. */
2945 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2946 return NT_STATUS_INVALID_HANDLE;
2948 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2949 return NT_STATUS_INVALID_HANDLE;
2952 /* get the generic lsa account SD for this SID until we store it */
2953 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2954 &lsa_account_mapping,
2955 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2956 if (!NT_STATUS_IS_OK(status)) {
2957 return status;
2961 * From the MS DOCs. We need
2962 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2963 * and DELETE on the account sid.
2966 status = access_check_object(psd, p->session_info->security_token,
2967 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2968 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2969 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
2970 &acc_granted, "_lsa_RemoveAccountRights");
2971 if (!NT_STATUS_IS_OK(status)) {
2972 return status;
2975 sid_copy( &sid, r->in.sid );
2977 if ( r->in.remove_all ) {
2978 if ( !revoke_all_privileges( &sid ) )
2979 return NT_STATUS_ACCESS_DENIED;
2981 return NT_STATUS_OK;
2984 for ( i=0; i < r->in.rights->count; i++ ) {
2986 privname = r->in.rights->names[i].string;
2988 /* only try to add non-null strings */
2990 if ( !privname )
2991 continue;
2993 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2994 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
2995 privname ));
2996 return NT_STATUS_NO_SUCH_PRIVILEGE;
3000 return NT_STATUS_OK;
3003 /*******************************************************************
3004 ********************************************************************/
3006 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3007 struct lsa_RightSet *r,
3008 PRIVILEGE_SET *privileges)
3010 uint32 i;
3011 const char *privname;
3012 const char **privname_array = NULL;
3013 int num_priv = 0;
3015 for (i=0; i<privileges->count; i++) {
3016 if (privileges->set[i].luid.high) {
3017 continue;
3019 privname = sec_privilege_name(privileges->set[i].luid.low);
3020 if (privname) {
3021 if (!add_string_to_array(mem_ctx, privname,
3022 &privname_array, &num_priv)) {
3023 return NT_STATUS_NO_MEMORY;
3028 if (num_priv) {
3030 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
3031 num_priv);
3032 if (!r->names) {
3033 return NT_STATUS_NO_MEMORY;
3036 for (i=0; i<num_priv; i++) {
3037 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3040 r->count = num_priv;
3043 return NT_STATUS_OK;
3046 /***************************************************************************
3047 _lsa_EnumAccountRights
3048 ***************************************************************************/
3050 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3051 struct lsa_EnumAccountRights *r)
3053 NTSTATUS status;
3054 struct lsa_info *info = NULL;
3055 PRIVILEGE_SET *privileges;
3057 /* find the connection policy handle. */
3059 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3060 return NT_STATUS_INVALID_HANDLE;
3062 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3063 return NT_STATUS_INVALID_HANDLE;
3066 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3067 return NT_STATUS_ACCESS_DENIED;
3070 /* according to an NT4 PDC, you can add privileges to SIDs even without
3071 call_lsa_create_account() first. And you can use any arbitrary SID. */
3073 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3074 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3075 * the lsa database */
3077 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3078 if (!NT_STATUS_IS_OK(status)) {
3079 return status;
3082 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3083 sid_string_dbg(r->in.sid), privileges->count));
3085 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3087 return status;
3090 /***************************************************************************
3091 _lsa_LookupPrivValue
3092 ***************************************************************************/
3094 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3095 struct lsa_LookupPrivValue *r)
3097 struct lsa_info *info = NULL;
3098 const char *name = NULL;
3100 /* find the connection policy handle. */
3102 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3103 return NT_STATUS_INVALID_HANDLE;
3105 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3106 return NT_STATUS_INVALID_HANDLE;
3109 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3110 return NT_STATUS_ACCESS_DENIED;
3112 name = r->in.name->string;
3114 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3116 r->out.luid->low = sec_privilege_id(name);
3117 r->out.luid->high = 0;
3118 if (r->out.luid->low == SEC_PRIV_INVALID) {
3119 return NT_STATUS_NO_SUCH_PRIVILEGE;
3121 return NT_STATUS_OK;
3124 /***************************************************************************
3125 _lsa_EnumAccountsWithUserRight
3126 ***************************************************************************/
3128 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3129 struct lsa_EnumAccountsWithUserRight *r)
3131 NTSTATUS status;
3132 struct lsa_info *info = NULL;
3133 struct dom_sid *sids = NULL;
3134 int num_sids = 0;
3135 uint32_t i;
3136 enum sec_privilege privilege;
3138 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3139 return NT_STATUS_INVALID_HANDLE;
3142 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3143 return NT_STATUS_INVALID_HANDLE;
3146 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3147 return NT_STATUS_ACCESS_DENIED;
3150 if (!r->in.name || !r->in.name->string) {
3151 return NT_STATUS_NO_SUCH_PRIVILEGE;
3154 privilege = sec_privilege_id(r->in.name->string);
3155 if (privilege == SEC_PRIV_INVALID) {
3156 return NT_STATUS_NO_SUCH_PRIVILEGE;
3159 status = privilege_enum_sids(privilege, p->mem_ctx,
3160 &sids, &num_sids);
3161 if (!NT_STATUS_IS_OK(status)) {
3162 return status;
3165 r->out.sids->num_sids = num_sids;
3166 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3167 r->out.sids->num_sids);
3169 for (i=0; i < r->out.sids->num_sids; i++) {
3170 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3171 &sids[i]);
3172 if (!r->out.sids->sids[i].sid) {
3173 TALLOC_FREE(r->out.sids->sids);
3174 r->out.sids->num_sids = 0;
3175 return NT_STATUS_NO_MEMORY;
3179 return NT_STATUS_OK;
3182 /***************************************************************************
3183 _lsa_Delete
3184 ***************************************************************************/
3186 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3187 struct lsa_Delete *r)
3189 return NT_STATUS_NOT_SUPPORTED;
3193 * From here on the server routines are just dummy ones to make smbd link with
3194 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3195 * pulling the server stubs across one by one.
3198 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3200 p->rng_fault_state = True;
3201 return NT_STATUS_NOT_IMPLEMENTED;
3204 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3205 struct lsa_ChangePassword *r)
3207 p->rng_fault_state = True;
3208 return NT_STATUS_NOT_IMPLEMENTED;
3211 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3213 p->rng_fault_state = True;
3214 return NT_STATUS_NOT_IMPLEMENTED;
3217 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3219 p->rng_fault_state = True;
3220 return NT_STATUS_NOT_IMPLEMENTED;
3223 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3224 struct lsa_GetQuotasForAccount *r)
3226 p->rng_fault_state = True;
3227 return NT_STATUS_NOT_IMPLEMENTED;
3230 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3231 struct lsa_SetQuotasForAccount *r)
3233 p->rng_fault_state = True;
3234 return NT_STATUS_NOT_IMPLEMENTED;
3237 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3238 struct lsa_SetInformationTrustedDomain *r)
3240 p->rng_fault_state = True;
3241 return NT_STATUS_NOT_IMPLEMENTED;
3244 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
3246 p->rng_fault_state = True;
3247 return NT_STATUS_NOT_IMPLEMENTED;
3250 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3251 struct lsa_SetTrustedDomainInfo *r)
3253 p->rng_fault_state = True;
3254 return NT_STATUS_NOT_IMPLEMENTED;
3257 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3258 struct lsa_StorePrivateData *r)
3260 p->rng_fault_state = True;
3261 return NT_STATUS_NOT_IMPLEMENTED;
3264 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3265 struct lsa_RetrievePrivateData *r)
3267 p->rng_fault_state = True;
3268 return NT_STATUS_NOT_IMPLEMENTED;
3271 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3272 struct lsa_SetInfoPolicy2 *r)
3274 p->rng_fault_state = True;
3275 return NT_STATUS_NOT_IMPLEMENTED;
3278 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3279 struct lsa_SetTrustedDomainInfoByName *r)
3281 p->rng_fault_state = True;
3282 return NT_STATUS_NOT_IMPLEMENTED;
3285 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3286 struct lsa_EnumTrustedDomainsEx *r)
3288 struct lsa_info *info;
3289 uint32_t count;
3290 struct pdb_trusted_domain **domains;
3291 struct lsa_TrustDomainInfoInfoEx *entries;
3292 int i;
3293 NTSTATUS nt_status;
3295 /* bail out early if pdb backend is not capable of ex trusted domains,
3296 * if we dont do that, the client might not call
3297 * _lsa_EnumTrustedDomains() afterwards - gd */
3299 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3300 p->rng_fault_state = True;
3301 return NT_STATUS_NOT_IMPLEMENTED;
3304 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3305 return NT_STATUS_INVALID_HANDLE;
3307 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3308 return NT_STATUS_INVALID_HANDLE;
3311 /* check if the user has enough rights */
3312 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3313 return NT_STATUS_ACCESS_DENIED;
3315 become_root();
3316 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3317 unbecome_root();
3319 if (!NT_STATUS_IS_OK(nt_status)) {
3320 return nt_status;
3323 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3324 count);
3325 if (!entries) {
3326 return NT_STATUS_NO_MEMORY;
3329 for (i=0; i<count; i++) {
3330 init_lsa_StringLarge(&entries[i].netbios_name,
3331 domains[i]->netbios_name);
3332 entries[i].sid = &domains[i]->security_identifier;
3335 if (*r->in.resume_handle >= count) {
3336 *r->out.resume_handle = -1;
3337 TALLOC_FREE(entries);
3338 return NT_STATUS_NO_MORE_ENTRIES;
3341 /* return the rest, limit by max_size. Note that we
3342 use the w2k3 element size value of 60 */
3343 r->out.domains->count = count - *r->in.resume_handle;
3344 r->out.domains->count = MIN(r->out.domains->count,
3345 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3347 r->out.domains->domains = entries + *r->in.resume_handle;
3349 if (r->out.domains->count < count - *r->in.resume_handle) {
3350 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3351 return STATUS_MORE_ENTRIES;
3354 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3355 * always be larger than the previous input resume handle, in
3356 * particular when hitting the last query it is vital to set the
3357 * resume handle correctly to avoid infinite client loops, as
3358 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3359 * status is NT_STATUS_OK - gd */
3361 *r->out.resume_handle = (uint32_t)-1;
3363 return NT_STATUS_OK;
3366 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3367 struct lsa_QueryDomainInformationPolicy *r)
3369 p->rng_fault_state = True;
3370 return NT_STATUS_NOT_IMPLEMENTED;
3373 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3374 struct lsa_SetDomainInformationPolicy *r)
3376 p->rng_fault_state = True;
3377 return NT_STATUS_NOT_IMPLEMENTED;
3380 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3382 p->rng_fault_state = True;
3383 return NT_STATUS_NOT_IMPLEMENTED;
3386 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3388 p->rng_fault_state = True;
3389 return NT_STATUS_NOT_IMPLEMENTED;
3392 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3394 p->rng_fault_state = True;
3395 return NT_STATUS_NOT_IMPLEMENTED;
3398 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3400 p->rng_fault_state = True;
3401 return NT_STATUS_NOT_IMPLEMENTED;
3404 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3405 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3407 p->rng_fault_state = True;
3408 return NT_STATUS_NOT_IMPLEMENTED;
3411 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3412 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3414 p->rng_fault_state = True;
3415 return NT_STATUS_NOT_IMPLEMENTED;
3418 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3420 p->rng_fault_state = True;
3421 return NT_STATUS_NOT_IMPLEMENTED;
3424 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3425 struct lsa_CREDRGETTARGETINFO *r)
3427 p->rng_fault_state = True;
3428 return NT_STATUS_NOT_IMPLEMENTED;
3431 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3432 struct lsa_CREDRPROFILELOADED *r)
3434 p->rng_fault_state = True;
3435 return NT_STATUS_NOT_IMPLEMENTED;
3438 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3439 struct lsa_CREDRGETSESSIONTYPES *r)
3441 p->rng_fault_state = True;
3442 return NT_STATUS_NOT_IMPLEMENTED;
3445 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3446 struct lsa_LSARREGISTERAUDITEVENT *r)
3448 p->rng_fault_state = True;
3449 return NT_STATUS_NOT_IMPLEMENTED;
3452 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3453 struct lsa_LSARGENAUDITEVENT *r)
3455 p->rng_fault_state = True;
3456 return NT_STATUS_NOT_IMPLEMENTED;
3459 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3460 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3462 p->rng_fault_state = True;
3463 return NT_STATUS_NOT_IMPLEMENTED;
3466 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3467 struct lsa_lsaRQueryForestTrustInformation *r)
3469 p->rng_fault_state = True;
3470 return NT_STATUS_NOT_IMPLEMENTED;
3473 #define DNS_CMP_MATCH 0
3474 #define DNS_CMP_FIRST_IS_CHILD 1
3475 #define DNS_CMP_SECOND_IS_CHILD 2
3476 #define DNS_CMP_NO_MATCH 3
3478 /* this function assumes names are well formed DNS names.
3479 * it doesn't validate them */
3480 static int dns_cmp(const char *s1, size_t l1,
3481 const char *s2, size_t l2)
3483 const char *p1, *p2;
3484 size_t t1, t2;
3485 int cret;
3487 if (l1 == l2) {
3488 if (StrCaseCmp(s1, s2) == 0) {
3489 return DNS_CMP_MATCH;
3491 return DNS_CMP_NO_MATCH;
3494 if (l1 > l2) {
3495 p1 = s1;
3496 p2 = s2;
3497 t1 = l1;
3498 t2 = l2;
3499 cret = DNS_CMP_FIRST_IS_CHILD;
3500 } else {
3501 p1 = s2;
3502 p2 = s1;
3503 t1 = l2;
3504 t2 = l1;
3505 cret = DNS_CMP_SECOND_IS_CHILD;
3508 if (p1[t1 - t2 - 1] != '.') {
3509 return DNS_CMP_NO_MATCH;
3512 if (StrCaseCmp(&p1[t1 - t2], p2) == 0) {
3513 return cret;
3516 return DNS_CMP_NO_MATCH;
3519 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3520 struct lsa_ForestTrustInformation *lfti,
3521 struct ForestTrustInfo *fti)
3523 struct lsa_ForestTrustRecord *lrec;
3524 struct ForestTrustInfoRecord *rec;
3525 struct lsa_StringLarge *tln;
3526 struct lsa_ForestTrustDomainInfo *info;
3527 uint32_t i;
3529 fti->version = 1;
3530 fti->count = lfti->count;
3531 fti->records = talloc_array(mem_ctx,
3532 struct ForestTrustInfoRecordArmor,
3533 fti->count);
3534 if (!fti->records) {
3535 return NT_STATUS_NO_MEMORY;
3537 for (i = 0; i < fti->count; i++) {
3538 lrec = lfti->entries[i];
3539 rec = &fti->records[i].record;
3541 rec->flags = lrec->flags;
3542 rec->timestamp = lrec->time;
3543 rec->type = lrec->type;
3545 switch (lrec->type) {
3546 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3547 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3548 tln = &lrec->forest_trust_data.top_level_name;
3549 rec->data.name.string =
3550 talloc_strdup(mem_ctx, tln->string);
3551 if (!rec->data.name.string) {
3552 return NT_STATUS_NO_MEMORY;
3554 rec->data.name.size = strlen(rec->data.name.string);
3555 break;
3556 case LSA_FOREST_TRUST_DOMAIN_INFO:
3557 info = &lrec->forest_trust_data.domain_info;
3558 rec->data.info.sid = *info->domain_sid;
3559 rec->data.info.dns_name.string =
3560 talloc_strdup(mem_ctx,
3561 info->dns_domain_name.string);
3562 if (!rec->data.info.dns_name.string) {
3563 return NT_STATUS_NO_MEMORY;
3565 rec->data.info.dns_name.size =
3566 strlen(rec->data.info.dns_name.string);
3567 rec->data.info.netbios_name.string =
3568 talloc_strdup(mem_ctx,
3569 info->netbios_domain_name.string);
3570 if (!rec->data.info.netbios_name.string) {
3571 return NT_STATUS_NO_MEMORY;
3573 rec->data.info.netbios_name.size =
3574 strlen(rec->data.info.netbios_name.string);
3575 break;
3576 default:
3577 return NT_STATUS_INVALID_DOMAIN_STATE;
3581 return NT_STATUS_OK;
3584 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3585 uint32_t index, uint32_t collision_type,
3586 uint32_t conflict_type, const char *tdo_name);
3588 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
3589 const char *tdo_name,
3590 struct ForestTrustInfo *tdo_fti,
3591 struct ForestTrustInfo *new_fti,
3592 struct lsa_ForestTrustCollisionInfo *c_info)
3594 struct ForestTrustInfoRecord *nrec;
3595 struct ForestTrustInfoRecord *trec;
3596 const char *dns_name;
3597 const char *nb_name = NULL;
3598 struct dom_sid *sid = NULL;
3599 const char *tname = NULL;
3600 size_t dns_len = 0;
3601 size_t nb_len;
3602 size_t tlen = 0;
3603 NTSTATUS nt_status;
3604 uint32_t new_fti_idx;
3605 uint32_t i;
3606 /* use always TDO type, until we understand when Xref can be used */
3607 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
3608 bool tln_conflict;
3609 bool sid_conflict;
3610 bool nb_conflict;
3611 bool exclusion;
3612 bool ex_rule = false;
3613 int ret;
3615 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
3617 nrec = &new_fti->records[new_fti_idx].record;
3618 dns_name = NULL;
3619 tln_conflict = false;
3620 sid_conflict = false;
3621 nb_conflict = false;
3622 exclusion = false;
3624 switch (nrec->type) {
3625 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3626 /* exclusions do not conflict by definition */
3627 break;
3629 case FOREST_TRUST_TOP_LEVEL_NAME:
3630 dns_name = nrec->data.name.string;
3631 dns_len = nrec->data.name.size;
3632 break;
3634 case LSA_FOREST_TRUST_DOMAIN_INFO:
3635 dns_name = nrec->data.info.dns_name.string;
3636 dns_len = nrec->data.info.dns_name.size;
3637 nb_name = nrec->data.info.netbios_name.string;
3638 nb_len = nrec->data.info.netbios_name.size;
3639 sid = &nrec->data.info.sid;
3640 break;
3643 if (!dns_name) continue;
3645 /* check if this is already taken and not excluded */
3646 for (i = 0; i < tdo_fti->count; i++) {
3647 trec = &tdo_fti->records[i].record;
3649 switch (trec->type) {
3650 case FOREST_TRUST_TOP_LEVEL_NAME:
3651 ex_rule = false;
3652 tname = trec->data.name.string;
3653 tlen = trec->data.name.size;
3654 break;
3655 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
3656 ex_rule = true;
3657 tname = trec->data.name.string;
3658 tlen = trec->data.name.size;
3659 break;
3660 case FOREST_TRUST_DOMAIN_INFO:
3661 ex_rule = false;
3662 tname = trec->data.info.dns_name.string;
3663 tlen = trec->data.info.dns_name.size;
3665 ret = dns_cmp(dns_name, dns_len, tname, tlen);
3666 switch (ret) {
3667 case DNS_CMP_MATCH:
3668 /* if it matches exclusion,
3669 * it doesn't conflict */
3670 if (ex_rule) {
3671 exclusion = true;
3672 break;
3674 /* fall through */
3675 case DNS_CMP_FIRST_IS_CHILD:
3676 case DNS_CMP_SECOND_IS_CHILD:
3677 tln_conflict = true;
3678 /* fall through */
3679 default:
3680 break;
3683 /* explicit exclusion, no dns name conflict here */
3684 if (exclusion) {
3685 tln_conflict = false;
3688 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
3689 continue;
3692 /* also test for domain info */
3693 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
3694 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
3695 sid_conflict = true;
3697 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
3698 StrCaseCmp(trec->data.info.netbios_name.string,
3699 nb_name) == 0) {
3700 nb_conflict = true;
3704 if (tln_conflict) {
3705 nt_status = add_collision(c_info, new_fti_idx,
3706 collision_type,
3707 LSA_TLN_DISABLED_CONFLICT,
3708 tdo_name);
3710 if (sid_conflict) {
3711 nt_status = add_collision(c_info, new_fti_idx,
3712 collision_type,
3713 LSA_SID_DISABLED_CONFLICT,
3714 tdo_name);
3716 if (nb_conflict) {
3717 nt_status = add_collision(c_info, new_fti_idx,
3718 collision_type,
3719 LSA_NB_DISABLED_CONFLICT,
3720 tdo_name);
3724 return NT_STATUS_OK;
3727 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3728 uint32_t idx, uint32_t collision_type,
3729 uint32_t conflict_type, const char *tdo_name)
3731 struct lsa_ForestTrustCollisionRecord **es;
3732 uint32_t i = c_info->count;
3734 es = talloc_realloc(c_info, c_info->entries,
3735 struct lsa_ForestTrustCollisionRecord *, i + 1);
3736 if (!es) {
3737 return NT_STATUS_NO_MEMORY;
3739 c_info->entries = es;
3740 c_info->count = i + 1;
3742 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
3743 if (!es[i]) {
3744 return NT_STATUS_NO_MEMORY;
3747 es[i]->index = idx;
3748 es[i]->type = collision_type;
3749 es[i]->flags.flags = conflict_type;
3750 es[i]->name.string = talloc_strdup(es[i], tdo_name);
3751 if (!es[i]->name.string) {
3752 return NT_STATUS_NO_MEMORY;
3754 es[i]->name.size = strlen(es[i]->name.string);
3756 return NT_STATUS_OK;
3759 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3760 struct pdb_trusted_domain *td,
3761 struct ForestTrustInfo *info)
3763 enum ndr_err_code ndr_err;
3765 if (td->trust_forest_trust_info.length == 0 ||
3766 td->trust_forest_trust_info.data == NULL) {
3767 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3769 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
3770 info,
3771 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3772 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3773 return NT_STATUS_INVALID_DOMAIN_STATE;
3776 return NT_STATUS_OK;
3779 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
3780 struct ForestTrustInfo *fti)
3782 struct ForestTrustDataDomainInfo *info;
3783 struct ForestTrustInfoRecord *rec;
3785 fti->version = 1;
3786 fti->count = 2;
3787 fti->records = talloc_array(fti,
3788 struct ForestTrustInfoRecordArmor, 2);
3789 if (!fti->records) {
3790 return NT_STATUS_NO_MEMORY;
3793 /* TLN info */
3794 rec = &fti->records[0].record;
3796 rec->flags = 0;
3797 rec->timestamp = 0;
3798 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3800 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
3801 if (!rec->data.name.string) {
3802 return NT_STATUS_NO_MEMORY;
3804 rec->data.name.size = strlen(rec->data.name.string);
3806 /* DOMAIN info */
3807 rec = &fti->records[1].record;
3809 rec->flags = 0;
3810 rec->timestamp = 0;
3811 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3813 info = &rec->data.info;
3815 info->sid = dom_info->sid;
3816 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
3817 if (!info->dns_name.string) {
3818 return NT_STATUS_NO_MEMORY;
3820 info->dns_name.size = strlen(info->dns_name.string);
3821 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
3822 if (!info->netbios_name.string) {
3823 return NT_STATUS_NO_MEMORY;
3825 info->netbios_name.size = strlen(info->netbios_name.string);
3827 return NT_STATUS_OK;
3830 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
3831 struct lsa_lsaRSetForestTrustInformation *r)
3833 NTSTATUS status;
3834 int i;
3835 int j;
3836 struct lsa_info *handle;
3837 uint32_t num_domains;
3838 struct pdb_trusted_domain **domains;
3839 struct ForestTrustInfo *nfti;
3840 struct ForestTrustInfo *fti;
3841 struct lsa_ForestTrustCollisionInfo *c_info;
3842 struct pdb_domain_info *dom_info;
3843 enum ndr_err_code ndr_err;
3845 if (!IS_DC) {
3846 return NT_STATUS_NOT_SUPPORTED;
3849 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
3850 return NT_STATUS_INVALID_HANDLE;
3853 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
3854 return NT_STATUS_INVALID_HANDLE;
3857 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
3858 return NT_STATUS_ACCESS_DENIED;
3861 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
3862 if (!NT_STATUS_IS_OK(status)) {
3863 return status;
3865 if (num_domains == 0) {
3866 return NT_STATUS_NO_SUCH_DOMAIN;
3869 for (i = 0; i < num_domains; i++) {
3870 if (domains[i]->domain_name == NULL) {
3871 return NT_STATUS_INVALID_DOMAIN_STATE;
3873 if (StrCaseCmp(domains[i]->domain_name,
3874 r->in.trusted_domain_name->string) == 0) {
3875 break;
3878 if (i >= num_domains) {
3879 return NT_STATUS_NO_SUCH_DOMAIN;
3882 if (!(domains[i]->trust_attributes &
3883 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
3884 return NT_STATUS_INVALID_PARAMETER;
3887 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
3888 return NT_STATUS_INVALID_PARAMETER;
3891 /* The following section until COPY_END is a copy from
3892 * source4/rpmc_server/lsa/scesrc_lsa.c */
3893 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
3894 if (!nfti) {
3895 return NT_STATUS_NO_MEMORY;
3898 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
3899 if (!NT_STATUS_IS_OK(status)) {
3900 return status;
3903 c_info = talloc_zero(r->out.collision_info,
3904 struct lsa_ForestTrustCollisionInfo);
3905 if (!c_info) {
3906 return NT_STATUS_NO_MEMORY;
3909 /* first check own info, then other domains */
3910 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3911 if (!fti) {
3912 return NT_STATUS_NO_MEMORY;
3915 dom_info = pdb_get_domain_info(p->mem_ctx);
3917 status = own_ft_info(dom_info, fti);
3918 if (!NT_STATUS_IS_OK(status)) {
3919 return status;
3922 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
3923 if (!NT_STATUS_IS_OK(status)) {
3924 return status;
3927 for (j = 0; j < num_domains; j++) {
3928 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3929 if (!fti) {
3930 return NT_STATUS_NO_MEMORY;
3933 status = get_ft_info(p->mem_ctx, domains[j], fti);
3934 if (!NT_STATUS_IS_OK(status)) {
3935 if (NT_STATUS_EQUAL(status,
3936 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3937 continue;
3939 return status;
3942 if (domains[j]->domain_name == NULL) {
3943 return NT_STATUS_INVALID_DOMAIN_STATE;
3946 status = check_ft_info(c_info, domains[j]->domain_name,
3947 fti, nfti, c_info);
3948 if (!NT_STATUS_IS_OK(status)) {
3949 return status;
3953 *r->out.collision_info = c_info;
3955 if (r->in.check_only != 0) {
3956 return NT_STATUS_OK;
3959 /* COPY_END */
3961 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
3962 p->mem_ctx, nfti,
3963 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
3964 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3965 return NT_STATUS_INVALID_PARAMETER;
3968 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
3969 if (!NT_STATUS_IS_OK(status)) {
3970 return status;
3973 return NT_STATUS_OK;
3976 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
3977 struct lsa_CREDRRENAME *r)
3979 p->rng_fault_state = True;
3980 return NT_STATUS_NOT_IMPLEMENTED;
3983 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
3984 struct lsa_LSAROPENPOLICYSCE *r)
3986 p->rng_fault_state = True;
3987 return NT_STATUS_NOT_IMPLEMENTED;
3990 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
3991 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3993 p->rng_fault_state = True;
3994 return NT_STATUS_NOT_IMPLEMENTED;
3997 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
3998 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4000 p->rng_fault_state = True;
4001 return NT_STATUS_NOT_IMPLEMENTED;
4004 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4005 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4007 p->rng_fault_state = True;
4008 return NT_STATUS_NOT_IMPLEMENTED;