s3-lsa: support secret objects in _lsa_DeleteObject().
[Samba/gebeck_regimport.git] / source3 / rpc_server / lsa / srv_lsa_nt.c
bloba42a22d911842e9bac176476e76a1da232de3809
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 "ntdomain.h"
34 #include "../librpc/gen_ndr/srv_lsa.h"
35 #include "secrets.h"
36 #include "../librpc/gen_ndr/netlogon.h"
37 #include "rpc_client/init_lsa.h"
38 #include "../libcli/security/security.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../librpc/gen_ndr/drsblobs.h"
41 #include "../librpc/gen_ndr/ndr_drsblobs.h"
42 #include "../lib/crypto/arcfour.h"
43 #include "../libcli/security/dom_sid.h"
44 #include "../librpc/gen_ndr/ndr_security.h"
45 #include "passdb.h"
46 #include "auth.h"
47 #include "lib/privileges.h"
48 #include "rpc_server/srv_access_check.h"
49 #include "../librpc/gen_ndr/ndr_wkssvc.h"
50 #include "../libcli/auth/proto.h"
52 #undef DBGC_CLASS
53 #define DBGC_CLASS DBGC_RPC_SRV
55 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
57 enum lsa_handle_type {
58 LSA_HANDLE_POLICY_TYPE = 1,
59 LSA_HANDLE_ACCOUNT_TYPE = 2,
60 LSA_HANDLE_TRUST_TYPE = 3,
61 LSA_HANDLE_SECRET_TYPE = 4};
63 struct lsa_info {
64 struct dom_sid sid;
65 const char *name;
66 uint32 access;
67 enum lsa_handle_type type;
68 struct security_descriptor *sd;
71 const struct generic_mapping lsa_account_mapping = {
72 LSA_ACCOUNT_READ,
73 LSA_ACCOUNT_WRITE,
74 LSA_ACCOUNT_EXECUTE,
75 LSA_ACCOUNT_ALL_ACCESS
78 const struct generic_mapping lsa_policy_mapping = {
79 LSA_POLICY_READ,
80 LSA_POLICY_WRITE,
81 LSA_POLICY_EXECUTE,
82 LSA_POLICY_ALL_ACCESS
85 const struct generic_mapping lsa_secret_mapping = {
86 LSA_SECRET_READ,
87 LSA_SECRET_WRITE,
88 LSA_SECRET_EXECUTE,
89 LSA_SECRET_ALL_ACCESS
92 const struct generic_mapping lsa_trusted_domain_mapping = {
93 LSA_TRUSTED_DOMAIN_READ,
94 LSA_TRUSTED_DOMAIN_WRITE,
95 LSA_TRUSTED_DOMAIN_EXECUTE,
96 LSA_TRUSTED_DOMAIN_ALL_ACCESS
99 /***************************************************************************
100 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
101 ***************************************************************************/
103 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
104 struct lsa_RefDomainList *ref,
105 const char *dom_name,
106 struct dom_sid *dom_sid)
108 int num = 0;
110 if (dom_name != NULL) {
111 for (num = 0; num < ref->count; num++) {
112 if (dom_sid_equal(dom_sid, ref->domains[num].sid)) {
113 return num;
116 } else {
117 num = ref->count;
120 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
121 /* index not found, already at maximum domain limit */
122 return -1;
125 ref->count = num + 1;
126 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
128 ref->domains = talloc_realloc(mem_ctx, ref->domains,
129 struct lsa_DomainInfo, ref->count);
130 if (!ref->domains) {
131 return -1;
134 ZERO_STRUCT(ref->domains[num]);
136 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
137 ref->domains[num].sid = dom_sid_dup(mem_ctx, dom_sid);
138 if (!ref->domains[num].sid) {
139 return -1;
142 return num;
146 /***************************************************************************
147 initialize a lsa_DomainInfo structure.
148 ***************************************************************************/
150 static void init_dom_query_3(struct lsa_DomainInfo *r,
151 const char *name,
152 struct dom_sid *sid)
154 init_lsa_StringLarge(&r->name, name);
155 r->sid = sid;
158 /***************************************************************************
159 initialize a lsa_DomainInfo structure.
160 ***************************************************************************/
162 static void init_dom_query_5(struct lsa_DomainInfo *r,
163 const char *name,
164 struct dom_sid *sid)
166 init_lsa_StringLarge(&r->name, name);
167 r->sid = sid;
170 /***************************************************************************
171 lookup_lsa_rids. Must be called as root for lookup_name to work.
172 ***************************************************************************/
174 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
175 struct lsa_RefDomainList *ref,
176 struct lsa_TranslatedSid *prid,
177 uint32_t num_entries,
178 struct lsa_String *name,
179 int flags,
180 uint32_t *pmapped_count)
182 uint32 mapped_count, i;
184 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
186 mapped_count = 0;
187 *pmapped_count = 0;
189 for (i = 0; i < num_entries; i++) {
190 struct dom_sid sid;
191 uint32 rid;
192 int dom_idx;
193 const char *full_name;
194 const char *domain;
195 enum lsa_SidType type;
197 /* Split name into domain and user component */
199 /* follow w2k8 behavior and return the builtin domain when no
200 * input has been passed in */
202 if (name[i].string) {
203 full_name = name[i].string;
204 } else {
205 full_name = "BUILTIN";
208 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
210 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
211 &sid, &type)) {
212 type = SID_NAME_UNKNOWN;
215 switch (type) {
216 case SID_NAME_USER:
217 case SID_NAME_DOM_GRP:
218 case SID_NAME_DOMAIN:
219 case SID_NAME_ALIAS:
220 case SID_NAME_WKN_GRP:
221 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
222 /* Leave these unchanged */
223 break;
224 default:
225 /* Don't hand out anything but the list above */
226 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
227 type = SID_NAME_UNKNOWN;
228 break;
231 rid = 0;
232 dom_idx = -1;
234 if (type != SID_NAME_UNKNOWN) {
235 if (type == SID_NAME_DOMAIN) {
236 rid = (uint32_t)-1;
237 } else {
238 sid_split_rid(&sid, &rid);
240 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
241 mapped_count++;
244 prid[i].sid_type = type;
245 prid[i].rid = rid;
246 prid[i].sid_index = dom_idx;
249 *pmapped_count = mapped_count;
250 return NT_STATUS_OK;
253 /***************************************************************************
254 lookup_lsa_sids. Must be called as root for lookup_name to work.
255 ***************************************************************************/
257 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
258 struct lsa_RefDomainList *ref,
259 struct lsa_TranslatedSid3 *trans_sids,
260 uint32_t num_entries,
261 struct lsa_String *name,
262 int flags,
263 uint32 *pmapped_count)
265 uint32 mapped_count, i;
267 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
269 mapped_count = 0;
270 *pmapped_count = 0;
272 for (i = 0; i < num_entries; i++) {
273 struct dom_sid sid;
274 uint32 rid;
275 int dom_idx;
276 const char *full_name;
277 const char *domain;
278 enum lsa_SidType type;
280 ZERO_STRUCT(sid);
282 /* Split name into domain and user component */
284 full_name = name[i].string;
285 if (full_name == NULL) {
286 return NT_STATUS_NO_MEMORY;
289 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
291 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
292 &sid, &type)) {
293 type = SID_NAME_UNKNOWN;
296 switch (type) {
297 case SID_NAME_USER:
298 case SID_NAME_DOM_GRP:
299 case SID_NAME_DOMAIN:
300 case SID_NAME_ALIAS:
301 case SID_NAME_WKN_GRP:
302 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
303 /* Leave these unchanged */
304 break;
305 default:
306 /* Don't hand out anything but the list above */
307 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
308 type = SID_NAME_UNKNOWN;
309 break;
312 rid = 0;
313 dom_idx = -1;
315 if (type != SID_NAME_UNKNOWN) {
316 struct dom_sid domain_sid;
317 sid_copy(&domain_sid, &sid);
318 sid_split_rid(&domain_sid, &rid);
319 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
320 mapped_count++;
323 /* Initialize the lsa_TranslatedSid3 return. */
324 trans_sids[i].sid_type = type;
325 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
326 trans_sids[i].sid_index = dom_idx;
329 *pmapped_count = mapped_count;
330 return NT_STATUS_OK;
333 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
334 const struct generic_mapping *map,
335 struct dom_sid *sid, uint32_t sid_access)
337 struct dom_sid adm_sid;
338 struct security_ace ace[5];
339 size_t i = 0;
341 struct security_acl *psa = NULL;
343 /* READ|EXECUTE access for Everyone */
345 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
346 map->generic_execute | map->generic_read, 0);
348 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
350 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
351 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
352 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
353 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
355 /* Add Full Access for Domain Admins */
356 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
357 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
358 map->generic_all, 0);
360 /* If we have a sid, give it some special access */
362 if (sid) {
363 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
364 sid_access, 0);
367 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
368 return NT_STATUS_NO_MEMORY;
370 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
371 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
372 psa, sd_size)) == NULL)
373 return NT_STATUS_NO_MEMORY;
375 return NT_STATUS_OK;
378 /***************************************************************************
379 ***************************************************************************/
381 static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
382 struct pipes_struct *p,
383 enum lsa_handle_type type,
384 uint32_t acc_granted,
385 struct dom_sid *sid,
386 const char *name,
387 const struct security_descriptor *sd,
388 struct policy_handle *handle)
390 struct lsa_info *info;
392 ZERO_STRUCTP(handle);
394 info = talloc_zero(mem_ctx, struct lsa_info);
395 if (!info) {
396 return NT_STATUS_NO_MEMORY;
399 info->type = type;
400 info->access = acc_granted;
402 if (sid) {
403 sid_copy(&info->sid, sid);
406 info->name = talloc_strdup(info, name);
408 if (sd) {
409 info->sd = dup_sec_desc(info, sd);
410 if (!info->sd) {
411 talloc_free(info);
412 return NT_STATUS_NO_MEMORY;
416 if (!create_policy_hnd(p, handle, info)) {
417 talloc_free(info);
418 ZERO_STRUCTP(handle);
419 return NT_STATUS_NO_MEMORY;
422 return NT_STATUS_OK;
425 /***************************************************************************
426 _lsa_OpenPolicy2
427 ***************************************************************************/
429 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
430 struct lsa_OpenPolicy2 *r)
432 struct security_descriptor *psd = NULL;
433 size_t sd_size;
434 uint32 des_access = r->in.access_mask;
435 uint32 acc_granted;
436 NTSTATUS status;
438 /* Work out max allowed. */
439 map_max_allowed_access(p->session_info->security_token,
440 p->session_info->unix_token,
441 &des_access);
443 /* map the generic bits to the lsa policy ones */
444 se_map_generic(&des_access, &lsa_policy_mapping);
446 /* get the generic lsa policy SD until we store it */
447 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
448 NULL, 0);
449 if (!NT_STATUS_IS_OK(status)) {
450 return status;
453 status = access_check_object(psd, p->session_info->security_token,
454 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
455 &acc_granted, "_lsa_OpenPolicy2" );
456 if (!NT_STATUS_IS_OK(status)) {
457 return status;
460 status = create_lsa_policy_handle(p->mem_ctx, p,
461 LSA_HANDLE_POLICY_TYPE,
462 acc_granted,
463 get_global_sam_sid(),
464 NULL,
465 psd,
466 r->out.handle);
467 if (!NT_STATUS_IS_OK(status)) {
468 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
471 return NT_STATUS_OK;
474 /***************************************************************************
475 _lsa_OpenPolicy
476 ***************************************************************************/
478 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
479 struct lsa_OpenPolicy *r)
481 struct lsa_OpenPolicy2 o;
483 o.in.system_name = NULL; /* should be ignored */
484 o.in.attr = r->in.attr;
485 o.in.access_mask = r->in.access_mask;
487 o.out.handle = r->out.handle;
489 return _lsa_OpenPolicy2(p, &o);
492 /***************************************************************************
493 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
494 ufff, done :) mimir
495 ***************************************************************************/
497 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
498 struct lsa_EnumTrustDom *r)
500 struct lsa_info *info;
501 uint32_t count;
502 struct trustdom_info **domains;
503 struct lsa_DomainInfo *entries;
504 int i;
505 NTSTATUS nt_status;
507 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
508 return NT_STATUS_INVALID_HANDLE;
510 if (info->type != LSA_HANDLE_POLICY_TYPE) {
511 return NT_STATUS_INVALID_HANDLE;
514 /* check if the user has enough rights */
515 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
516 return NT_STATUS_ACCESS_DENIED;
518 become_root();
519 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
520 unbecome_root();
522 if (!NT_STATUS_IS_OK(nt_status)) {
523 return nt_status;
526 entries = talloc_zero_array(p->mem_ctx, struct lsa_DomainInfo, count);
527 if (!entries) {
528 return NT_STATUS_NO_MEMORY;
531 for (i=0; i<count; i++) {
532 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
533 entries[i].sid = &domains[i]->sid;
536 if (*r->in.resume_handle >= count) {
537 *r->out.resume_handle = -1;
538 TALLOC_FREE(entries);
539 return NT_STATUS_NO_MORE_ENTRIES;
542 /* return the rest, limit by max_size. Note that we
543 use the w2k3 element size value of 60 */
544 r->out.domains->count = count - *r->in.resume_handle;
545 r->out.domains->count = MIN(r->out.domains->count,
546 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
548 r->out.domains->domains = entries + *r->in.resume_handle;
550 if (r->out.domains->count < count - *r->in.resume_handle) {
551 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
552 return STATUS_MORE_ENTRIES;
555 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
556 * always be larger than the previous input resume handle, in
557 * particular when hitting the last query it is vital to set the
558 * resume handle correctly to avoid infinite client loops, as
559 * seen e.g. with Windows XP SP3 when resume handle is 0 and
560 * status is NT_STATUS_OK - gd */
562 *r->out.resume_handle = (uint32_t)-1;
564 return NT_STATUS_OK;
567 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
568 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
569 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
571 /***************************************************************************
572 _lsa_QueryInfoPolicy
573 ***************************************************************************/
575 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
576 struct lsa_QueryInfoPolicy *r)
578 NTSTATUS status = NT_STATUS_OK;
579 struct lsa_info *handle;
580 struct dom_sid domain_sid;
581 const char *name;
582 struct dom_sid *sid = NULL;
583 union lsa_PolicyInformation *info = NULL;
584 uint32_t acc_required = 0;
586 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
587 return NT_STATUS_INVALID_HANDLE;
589 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
590 return NT_STATUS_INVALID_HANDLE;
593 switch (r->in.level) {
594 case LSA_POLICY_INFO_AUDIT_LOG:
595 case LSA_POLICY_INFO_AUDIT_EVENTS:
596 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
597 break;
598 case LSA_POLICY_INFO_DOMAIN:
599 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
600 break;
601 case LSA_POLICY_INFO_PD:
602 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
603 break;
604 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
605 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
606 break;
607 case LSA_POLICY_INFO_ROLE:
608 case LSA_POLICY_INFO_REPLICA:
609 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
610 break;
611 case LSA_POLICY_INFO_QUOTA:
612 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
613 break;
614 case LSA_POLICY_INFO_MOD:
615 case LSA_POLICY_INFO_AUDIT_FULL_SET:
616 /* according to MS-LSAD 3.1.4.4.3 */
617 return NT_STATUS_INVALID_PARAMETER;
618 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
619 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
620 break;
621 case LSA_POLICY_INFO_DNS:
622 case LSA_POLICY_INFO_DNS_INT:
623 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
624 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
625 break;
626 default:
627 break;
630 if (!(handle->access & acc_required)) {
631 /* return NT_STATUS_ACCESS_DENIED; */
634 info = talloc_zero(p->mem_ctx, union lsa_PolicyInformation);
635 if (!info) {
636 return NT_STATUS_NO_MEMORY;
639 switch (r->in.level) {
640 /* according to MS-LSAD 3.1.4.4.3 */
641 case LSA_POLICY_INFO_MOD:
642 case LSA_POLICY_INFO_AUDIT_FULL_SET:
643 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
644 return NT_STATUS_INVALID_PARAMETER;
645 case LSA_POLICY_INFO_AUDIT_LOG:
646 info->audit_log.percent_full = 0;
647 info->audit_log.maximum_log_size = 0;
648 info->audit_log.retention_time = 0;
649 info->audit_log.shutdown_in_progress = 0;
650 info->audit_log.time_to_shutdown = 0;
651 info->audit_log.next_audit_record = 0;
652 status = NT_STATUS_OK;
653 break;
654 case LSA_POLICY_INFO_PD:
655 info->pd.name.string = NULL;
656 status = NT_STATUS_OK;
657 break;
658 case LSA_POLICY_INFO_REPLICA:
659 info->replica.source.string = NULL;
660 info->replica.account.string = NULL;
661 status = NT_STATUS_OK;
662 break;
663 case LSA_POLICY_INFO_QUOTA:
664 info->quota.paged_pool = 0;
665 info->quota.non_paged_pool = 0;
666 info->quota.min_wss = 0;
667 info->quota.max_wss = 0;
668 info->quota.pagefile = 0;
669 info->quota.unknown = 0;
670 status = NT_STATUS_OK;
671 break;
672 case LSA_POLICY_INFO_AUDIT_EVENTS:
675 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
677 /* check if the user has enough rights */
678 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
679 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
680 return NT_STATUS_ACCESS_DENIED;
683 /* fake info: We audit everything. ;) */
685 info->audit_events.auditing_mode = true;
686 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
687 info->audit_events.settings = talloc_zero_array(p->mem_ctx,
688 enum lsa_PolicyAuditPolicy,
689 info->audit_events.count);
690 if (!info->audit_events.settings) {
691 return NT_STATUS_NO_MEMORY;
694 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
695 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
696 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
697 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
698 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
699 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
700 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
702 break;
704 case LSA_POLICY_INFO_DOMAIN:
705 /* check if the user has enough rights */
706 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
707 return NT_STATUS_ACCESS_DENIED;
709 /* Request PolicyPrimaryDomainInformation. */
710 switch (lp_server_role()) {
711 case ROLE_DOMAIN_PDC:
712 case ROLE_DOMAIN_BDC:
713 name = get_global_sam_name();
714 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
715 if (!sid) {
716 return NT_STATUS_NO_MEMORY;
718 break;
719 case ROLE_DOMAIN_MEMBER:
720 name = lp_workgroup();
721 /* We need to return the Domain SID here. */
722 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
723 sid = dom_sid_dup(p->mem_ctx, &domain_sid);
724 if (!sid) {
725 return NT_STATUS_NO_MEMORY;
727 } else {
728 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
730 break;
731 case ROLE_STANDALONE:
732 name = lp_workgroup();
733 sid = NULL;
734 break;
735 default:
736 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
738 init_dom_query_3(&info->domain, name, sid);
739 break;
740 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
741 /* check if the user has enough rights */
742 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
743 return NT_STATUS_ACCESS_DENIED;
745 /* Request PolicyAccountDomainInformation. */
746 name = get_global_sam_name();
747 sid = get_global_sam_sid();
749 init_dom_query_5(&info->account_domain, name, sid);
750 break;
751 case LSA_POLICY_INFO_ROLE:
752 /* check if the user has enough rights */
753 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
754 return NT_STATUS_ACCESS_DENIED;
756 switch (lp_server_role()) {
757 case ROLE_DOMAIN_BDC:
759 * only a BDC is a backup controller
760 * of the domain, it controls.
762 info->role.role = LSA_ROLE_BACKUP;
763 break;
764 default:
766 * any other role is a primary
767 * of the domain, it controls.
769 info->role.role = LSA_ROLE_PRIMARY;
770 break;
772 break;
773 case LSA_POLICY_INFO_DNS:
774 case LSA_POLICY_INFO_DNS_INT: {
775 struct pdb_domain_info *dominfo;
777 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
778 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
779 "without ADS passdb backend\n"));
780 status = NT_STATUS_INVALID_INFO_CLASS;
781 break;
784 dominfo = pdb_get_domain_info(info);
785 if (dominfo == NULL) {
786 status = NT_STATUS_NO_MEMORY;
787 break;
790 init_lsa_StringLarge(&info->dns.name,
791 dominfo->name);
792 init_lsa_StringLarge(&info->dns.dns_domain,
793 dominfo->dns_domain);
794 init_lsa_StringLarge(&info->dns.dns_forest,
795 dominfo->dns_forest);
796 info->dns.domain_guid = dominfo->guid;
797 info->dns.sid = &dominfo->sid;
798 break;
800 default:
801 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
802 r->in.level));
803 status = NT_STATUS_INVALID_INFO_CLASS;
804 break;
807 *r->out.info = info;
809 return status;
812 /***************************************************************************
813 _lsa_QueryInfoPolicy2
814 ***************************************************************************/
816 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
817 struct lsa_QueryInfoPolicy2 *r2)
819 struct lsa_QueryInfoPolicy r;
821 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
822 p->rng_fault_state = True;
823 return NT_STATUS_NOT_IMPLEMENTED;
826 ZERO_STRUCT(r);
827 r.in.handle = r2->in.handle;
828 r.in.level = r2->in.level;
829 r.out.info = r2->out.info;
831 return _lsa_QueryInfoPolicy(p, &r);
834 /***************************************************************************
835 _lsa_lookup_sids_internal
836 ***************************************************************************/
838 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
839 TALLOC_CTX *mem_ctx,
840 uint16_t level, /* input */
841 int num_sids, /* input */
842 struct lsa_SidPtr *sid, /* input */
843 struct lsa_RefDomainList **pp_ref, /* input/output */
844 struct lsa_TranslatedName2 **pp_names,/* input/output */
845 uint32_t *pp_mapped_count) /* input/output */
847 NTSTATUS status;
848 int i;
849 const struct dom_sid **sids = NULL;
850 struct lsa_RefDomainList *ref = NULL;
851 uint32 mapped_count = 0;
852 struct lsa_dom_info *dom_infos = NULL;
853 struct lsa_name_info *name_infos = NULL;
854 struct lsa_TranslatedName2 *names = NULL;
856 *pp_mapped_count = 0;
857 *pp_names = NULL;
858 *pp_ref = NULL;
860 if (num_sids == 0) {
861 return NT_STATUS_OK;
864 sids = talloc_array(p->mem_ctx, const struct dom_sid *, num_sids);
865 ref = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
867 if (sids == NULL || ref == NULL) {
868 return NT_STATUS_NO_MEMORY;
871 for (i=0; i<num_sids; i++) {
872 sids[i] = sid[i].sid;
875 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
876 &dom_infos, &name_infos);
878 if (!NT_STATUS_IS_OK(status)) {
879 return status;
882 names = talloc_array(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
883 if (names == NULL) {
884 return NT_STATUS_NO_MEMORY;
887 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
889 if (!dom_infos[i].valid) {
890 break;
893 if (init_lsa_ref_domain_list(mem_ctx, ref,
894 dom_infos[i].name,
895 &dom_infos[i].sid) != i) {
896 DEBUG(0, ("Domain %s mentioned twice??\n",
897 dom_infos[i].name));
898 return NT_STATUS_INTERNAL_ERROR;
902 for (i=0; i<num_sids; i++) {
903 struct lsa_name_info *name = &name_infos[i];
905 if (name->type == SID_NAME_UNKNOWN) {
906 name->dom_idx = -1;
907 /* Unknown sids should return the string
908 * representation of the SID. Windows 2003 behaves
909 * rather erratic here, in many cases it returns the
910 * RID as 8 bytes hex, in others it returns the full
911 * SID. We (Jerry/VL) could not figure out which the
912 * hard cases are, so leave it with the SID. */
913 name->name = dom_sid_string(p->mem_ctx, sids[i]);
914 if (name->name == NULL) {
915 return NT_STATUS_NO_MEMORY;
917 } else {
918 mapped_count += 1;
921 names[i].sid_type = name->type;
922 names[i].name.string = name->name;
923 names[i].sid_index = name->dom_idx;
924 names[i].unknown = 0;
927 status = NT_STATUS_NONE_MAPPED;
928 if (mapped_count > 0) {
929 status = (mapped_count < num_sids) ?
930 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
933 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
934 num_sids, mapped_count, nt_errstr(status)));
936 *pp_mapped_count = mapped_count;
937 *pp_names = names;
938 *pp_ref = ref;
940 return status;
943 /***************************************************************************
944 _lsa_LookupSids
945 ***************************************************************************/
947 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
948 struct lsa_LookupSids *r)
950 NTSTATUS status;
951 struct lsa_info *handle;
952 int num_sids = r->in.sids->num_sids;
953 uint32 mapped_count = 0;
954 struct lsa_RefDomainList *domains = NULL;
955 struct lsa_TranslatedName *names_out = NULL;
956 struct lsa_TranslatedName2 *names = NULL;
957 int i;
959 if ((r->in.level < 1) || (r->in.level > 6)) {
960 return NT_STATUS_INVALID_PARAMETER;
963 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
964 return NT_STATUS_INVALID_HANDLE;
967 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
968 return NT_STATUS_INVALID_HANDLE;
971 /* check if the user has enough rights */
972 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
973 return NT_STATUS_ACCESS_DENIED;
976 if (num_sids > MAX_LOOKUP_SIDS) {
977 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
978 MAX_LOOKUP_SIDS, num_sids));
979 return NT_STATUS_NONE_MAPPED;
982 status = _lsa_lookup_sids_internal(p,
983 p->mem_ctx,
984 r->in.level,
985 num_sids,
986 r->in.sids->sids,
987 &domains,
988 &names,
989 &mapped_count);
991 /* Only return here when there is a real error.
992 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
993 the requested sids could be resolved. Older versions of XP (pre SP3)
994 rely that we return with the string representations of those SIDs in
995 that case. If we don't, XP crashes - Guenther
998 if (NT_STATUS_IS_ERR(status) &&
999 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1000 return status;
1003 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
1004 names_out = talloc_array(p->mem_ctx, struct lsa_TranslatedName,
1005 num_sids);
1006 if (!names_out) {
1007 return NT_STATUS_NO_MEMORY;
1010 for (i=0; i<num_sids; i++) {
1011 names_out[i].sid_type = names[i].sid_type;
1012 names_out[i].name = names[i].name;
1013 names_out[i].sid_index = names[i].sid_index;
1016 *r->out.domains = domains;
1017 r->out.names->count = num_sids;
1018 r->out.names->names = names_out;
1019 *r->out.count = mapped_count;
1021 return status;
1024 /***************************************************************************
1025 _lsa_LookupSids2
1026 ***************************************************************************/
1028 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1029 struct lsa_LookupSids2 *r)
1031 NTSTATUS status;
1032 struct lsa_info *handle;
1033 int num_sids = r->in.sids->num_sids;
1034 uint32 mapped_count = 0;
1035 struct lsa_RefDomainList *domains = NULL;
1036 struct lsa_TranslatedName2 *names = NULL;
1037 bool check_policy = true;
1039 switch (p->opnum) {
1040 case NDR_LSA_LOOKUPSIDS3:
1041 check_policy = false;
1042 break;
1043 case NDR_LSA_LOOKUPSIDS2:
1044 default:
1045 check_policy = true;
1048 if ((r->in.level < 1) || (r->in.level > 6)) {
1049 return NT_STATUS_INVALID_PARAMETER;
1052 if (check_policy) {
1053 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1054 return NT_STATUS_INVALID_HANDLE;
1057 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1058 return NT_STATUS_INVALID_HANDLE;
1061 /* check if the user has enough rights */
1062 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1063 return NT_STATUS_ACCESS_DENIED;
1067 if (num_sids > MAX_LOOKUP_SIDS) {
1068 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1069 MAX_LOOKUP_SIDS, num_sids));
1070 return NT_STATUS_NONE_MAPPED;
1073 status = _lsa_lookup_sids_internal(p,
1074 p->mem_ctx,
1075 r->in.level,
1076 num_sids,
1077 r->in.sids->sids,
1078 &domains,
1079 &names,
1080 &mapped_count);
1082 *r->out.domains = domains;
1083 r->out.names->count = num_sids;
1084 r->out.names->names = names;
1085 *r->out.count = mapped_count;
1087 return status;
1090 /***************************************************************************
1091 _lsa_LookupSids3
1092 ***************************************************************************/
1094 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1095 struct lsa_LookupSids3 *r)
1097 struct lsa_LookupSids2 q;
1099 /* No policy handle on this call. Restrict to crypto connections. */
1100 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1101 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1102 get_remote_machine_name() ));
1103 return NT_STATUS_INVALID_PARAMETER;
1106 q.in.handle = NULL;
1107 q.in.sids = r->in.sids;
1108 q.in.level = r->in.level;
1109 q.in.lookup_options = r->in.lookup_options;
1110 q.in.client_revision = r->in.client_revision;
1111 q.in.names = r->in.names;
1112 q.in.count = r->in.count;
1114 q.out.domains = r->out.domains;
1115 q.out.names = r->out.names;
1116 q.out.count = r->out.count;
1118 return _lsa_LookupSids2(p, &q);
1121 /***************************************************************************
1122 ***************************************************************************/
1124 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1126 int flags;
1128 switch (level) {
1129 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1130 flags = LOOKUP_NAME_ALL;
1131 break;
1132 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1133 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1134 break;
1135 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1136 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1137 break;
1138 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1139 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1140 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1141 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1142 default:
1143 flags = LOOKUP_NAME_NONE;
1144 break;
1147 return flags;
1150 /***************************************************************************
1151 _lsa_LookupNames
1152 ***************************************************************************/
1154 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1155 struct lsa_LookupNames *r)
1157 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1158 struct lsa_info *handle;
1159 struct lsa_String *names = r->in.names;
1160 uint32 num_entries = r->in.num_names;
1161 struct lsa_RefDomainList *domains = NULL;
1162 struct lsa_TranslatedSid *rids = NULL;
1163 uint32 mapped_count = 0;
1164 int flags = 0;
1166 if (num_entries > MAX_LOOKUP_SIDS) {
1167 num_entries = MAX_LOOKUP_SIDS;
1168 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1169 num_entries));
1172 flags = lsa_lookup_level_to_flags(r->in.level);
1174 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1175 if (!domains) {
1176 return NT_STATUS_NO_MEMORY;
1179 if (num_entries) {
1180 rids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid,
1181 num_entries);
1182 if (!rids) {
1183 return NT_STATUS_NO_MEMORY;
1185 } else {
1186 rids = NULL;
1189 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1190 status = NT_STATUS_INVALID_HANDLE;
1191 goto done;
1194 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1195 return NT_STATUS_INVALID_HANDLE;
1198 /* check if the user has enough rights */
1199 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1200 status = NT_STATUS_ACCESS_DENIED;
1201 goto done;
1204 /* set up the LSA Lookup RIDs response */
1205 become_root(); /* lookup_name can require root privs */
1206 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1207 names, flags, &mapped_count);
1208 unbecome_root();
1210 done:
1212 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1213 if (mapped_count == 0) {
1214 status = NT_STATUS_NONE_MAPPED;
1215 } else if (mapped_count != num_entries) {
1216 status = STATUS_SOME_UNMAPPED;
1220 *r->out.count = mapped_count;
1221 *r->out.domains = domains;
1222 r->out.sids->sids = rids;
1223 r->out.sids->count = num_entries;
1225 return status;
1228 /***************************************************************************
1229 _lsa_LookupNames2
1230 ***************************************************************************/
1232 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1233 struct lsa_LookupNames2 *r)
1235 NTSTATUS status;
1236 struct lsa_LookupNames q;
1237 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1238 struct lsa_TransSidArray *sid_array = NULL;
1239 uint32_t i;
1241 sid_array = talloc_zero(p->mem_ctx, struct lsa_TransSidArray);
1242 if (!sid_array) {
1243 return NT_STATUS_NO_MEMORY;
1246 q.in.handle = r->in.handle;
1247 q.in.num_names = r->in.num_names;
1248 q.in.names = r->in.names;
1249 q.in.level = r->in.level;
1250 q.in.sids = sid_array;
1251 q.in.count = r->in.count;
1252 /* we do not know what this is for */
1253 /* = r->in.unknown1; */
1254 /* = r->in.unknown2; */
1256 q.out.domains = r->out.domains;
1257 q.out.sids = sid_array;
1258 q.out.count = r->out.count;
1260 status = _lsa_LookupNames(p, &q);
1262 sid_array2->count = sid_array->count;
1263 sid_array2->sids = talloc_array(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1264 if (!sid_array2->sids) {
1265 return NT_STATUS_NO_MEMORY;
1268 for (i=0; i<sid_array->count; i++) {
1269 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1270 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1271 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1272 sid_array2->sids[i].unknown = 0;
1275 r->out.sids = sid_array2;
1277 return status;
1280 /***************************************************************************
1281 _lsa_LookupNames3
1282 ***************************************************************************/
1284 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1285 struct lsa_LookupNames3 *r)
1287 NTSTATUS status;
1288 struct lsa_info *handle;
1289 struct lsa_String *names = r->in.names;
1290 uint32 num_entries = r->in.num_names;
1291 struct lsa_RefDomainList *domains = NULL;
1292 struct lsa_TranslatedSid3 *trans_sids = NULL;
1293 uint32 mapped_count = 0;
1294 int flags = 0;
1295 bool check_policy = true;
1297 switch (p->opnum) {
1298 case NDR_LSA_LOOKUPNAMES4:
1299 check_policy = false;
1300 break;
1301 case NDR_LSA_LOOKUPNAMES3:
1302 default:
1303 check_policy = true;
1306 if (num_entries > MAX_LOOKUP_SIDS) {
1307 num_entries = MAX_LOOKUP_SIDS;
1308 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1311 /* Probably the lookup_level is some sort of bitmask. */
1312 if (r->in.level == 1) {
1313 flags = LOOKUP_NAME_ALL;
1316 domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1317 if (!domains) {
1318 return NT_STATUS_NO_MEMORY;
1321 if (num_entries) {
1322 trans_sids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid3,
1323 num_entries);
1324 if (!trans_sids) {
1325 return NT_STATUS_NO_MEMORY;
1327 } else {
1328 trans_sids = NULL;
1331 if (check_policy) {
1333 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1334 status = NT_STATUS_INVALID_HANDLE;
1335 goto done;
1338 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1339 return NT_STATUS_INVALID_HANDLE;
1342 /* check if the user has enough rights */
1343 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1344 status = NT_STATUS_ACCESS_DENIED;
1345 goto done;
1349 /* set up the LSA Lookup SIDs response */
1350 become_root(); /* lookup_name can require root privs */
1351 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1352 names, flags, &mapped_count);
1353 unbecome_root();
1355 done:
1357 if (NT_STATUS_IS_OK(status)) {
1358 if (mapped_count == 0) {
1359 status = NT_STATUS_NONE_MAPPED;
1360 } else if (mapped_count != num_entries) {
1361 status = STATUS_SOME_UNMAPPED;
1365 *r->out.count = mapped_count;
1366 *r->out.domains = domains;
1367 r->out.sids->sids = trans_sids;
1368 r->out.sids->count = num_entries;
1370 return status;
1373 /***************************************************************************
1374 _lsa_LookupNames4
1375 ***************************************************************************/
1377 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1378 struct lsa_LookupNames4 *r)
1380 struct lsa_LookupNames3 q;
1382 /* No policy handle on this call. Restrict to crypto connections. */
1383 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1384 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1385 get_remote_machine_name() ));
1386 return NT_STATUS_INVALID_PARAMETER;
1389 q.in.handle = NULL;
1390 q.in.num_names = r->in.num_names;
1391 q.in.names = r->in.names;
1392 q.in.level = r->in.level;
1393 q.in.lookup_options = r->in.lookup_options;
1394 q.in.client_revision = r->in.client_revision;
1395 q.in.sids = r->in.sids;
1396 q.in.count = r->in.count;
1398 q.out.domains = r->out.domains;
1399 q.out.sids = r->out.sids;
1400 q.out.count = r->out.count;
1402 return _lsa_LookupNames3(p, &q);
1405 /***************************************************************************
1406 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1407 ***************************************************************************/
1409 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1411 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1412 return NT_STATUS_INVALID_HANDLE;
1415 close_policy_hnd(p, r->in.handle);
1416 ZERO_STRUCTP(r->out.handle);
1417 return NT_STATUS_OK;
1420 /***************************************************************************
1421 ***************************************************************************/
1423 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1424 const struct dom_sid *sid,
1425 struct trustdom_info **info)
1427 NTSTATUS status;
1428 uint32_t num_domains = 0;
1429 struct trustdom_info **domains = NULL;
1430 int i;
1432 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1433 if (!NT_STATUS_IS_OK(status)) {
1434 return status;
1437 for (i=0; i < num_domains; i++) {
1438 if (dom_sid_equal(&domains[i]->sid, sid)) {
1439 break;
1443 if (i == num_domains) {
1444 return NT_STATUS_INVALID_PARAMETER;
1447 *info = domains[i];
1449 return NT_STATUS_OK;
1452 /***************************************************************************
1453 ***************************************************************************/
1455 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1456 const char *netbios_domain_name,
1457 struct trustdom_info **info_p)
1459 NTSTATUS status;
1460 struct trustdom_info *info;
1461 struct pdb_trusted_domain *td;
1463 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1464 if (!NT_STATUS_IS_OK(status)) {
1465 return status;
1468 info = talloc(mem_ctx, struct trustdom_info);
1469 if (!info) {
1470 return NT_STATUS_NO_MEMORY;
1473 info->name = talloc_strdup(info, netbios_domain_name);
1474 NT_STATUS_HAVE_NO_MEMORY(info->name);
1476 sid_copy(&info->sid, &td->security_identifier);
1478 *info_p = info;
1480 return NT_STATUS_OK;
1483 /***************************************************************************
1484 _lsa_OpenSecret
1485 ***************************************************************************/
1487 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p,
1488 struct lsa_OpenSecret *r)
1490 struct lsa_info *handle;
1491 struct security_descriptor *psd;
1492 NTSTATUS status;
1493 uint32_t acc_granted;
1495 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1496 return NT_STATUS_INVALID_HANDLE;
1499 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1500 return NT_STATUS_INVALID_HANDLE;
1503 if (!r->in.name.string) {
1504 return NT_STATUS_INVALID_PARAMETER;
1507 /* Work out max allowed. */
1508 map_max_allowed_access(p->session_info->security_token,
1509 p->session_info->unix_token,
1510 &r->in.access_mask);
1512 /* map the generic bits to the lsa policy ones */
1513 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
1515 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
1516 NULL,
1517 NULL,
1518 NULL,
1519 NULL,
1520 &psd);
1521 if (!NT_STATUS_IS_OK(status)) {
1522 return status;
1525 status = access_check_object(psd, p->session_info->security_token,
1526 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1527 r->in.access_mask,
1528 &acc_granted, "_lsa_OpenSecret");
1529 if (!NT_STATUS_IS_OK(status)) {
1530 return status;
1533 status = create_lsa_policy_handle(p->mem_ctx, p,
1534 LSA_HANDLE_SECRET_TYPE,
1535 acc_granted,
1536 NULL,
1537 r->in.name.string,
1538 psd,
1539 r->out.sec_handle);
1540 if (!NT_STATUS_IS_OK(status)) {
1541 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1544 return NT_STATUS_OK;
1547 /***************************************************************************
1548 _lsa_OpenTrustedDomain_base
1549 ***************************************************************************/
1551 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1552 uint32_t access_mask,
1553 struct trustdom_info *info,
1554 struct policy_handle *handle)
1556 struct security_descriptor *psd = NULL;
1557 size_t sd_size;
1558 uint32_t acc_granted;
1559 NTSTATUS status;
1561 /* des_access is for the account here, not the policy
1562 * handle - so don't check against policy handle. */
1564 /* Work out max allowed. */
1565 map_max_allowed_access(p->session_info->security_token,
1566 p->session_info->unix_token,
1567 &access_mask);
1569 /* map the generic bits to the lsa account ones */
1570 se_map_generic(&access_mask, &lsa_account_mapping);
1572 /* get the generic lsa account SD until we store it */
1573 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1574 &lsa_trusted_domain_mapping,
1575 NULL, 0);
1576 if (!NT_STATUS_IS_OK(status)) {
1577 return status;
1580 status = access_check_object(psd, p->session_info->security_token,
1581 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1582 access_mask, &acc_granted,
1583 "_lsa_OpenTrustedDomain");
1584 if (!NT_STATUS_IS_OK(status)) {
1585 return status;
1588 status = create_lsa_policy_handle(p->mem_ctx, p,
1589 LSA_HANDLE_TRUST_TYPE,
1590 acc_granted,
1591 &info->sid,
1592 info->name,
1593 psd,
1594 handle);
1595 if (!NT_STATUS_IS_OK(status)) {
1596 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1599 return NT_STATUS_OK;
1602 /***************************************************************************
1603 _lsa_OpenTrustedDomain
1604 ***************************************************************************/
1606 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1607 struct lsa_OpenTrustedDomain *r)
1609 struct lsa_info *handle = NULL;
1610 struct trustdom_info *info = NULL;
1611 NTSTATUS status;
1613 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1614 return NT_STATUS_INVALID_HANDLE;
1617 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1618 return NT_STATUS_INVALID_HANDLE;
1621 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1622 r->in.sid,
1623 &info);
1624 if (!NT_STATUS_IS_OK(status)) {
1625 return status;
1628 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1629 r->out.trustdom_handle);
1632 /***************************************************************************
1633 _lsa_OpenTrustedDomainByName
1634 ***************************************************************************/
1636 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1637 struct lsa_OpenTrustedDomainByName *r)
1639 struct lsa_info *handle = NULL;
1640 struct trustdom_info *info = NULL;
1641 NTSTATUS status;
1643 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1644 return NT_STATUS_INVALID_HANDLE;
1647 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1648 return NT_STATUS_INVALID_HANDLE;
1651 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1652 r->in.name.string,
1653 &info);
1654 if (!NT_STATUS_IS_OK(status)) {
1655 return status;
1658 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1659 r->out.trustdom_handle);
1662 static NTSTATUS add_trusted_domain_user(TALLOC_CTX *mem_ctx,
1663 const char *netbios_name,
1664 const char *domain_name,
1665 const struct trustDomainPasswords *auth_struct)
1667 NTSTATUS status;
1668 struct samu *sam_acct;
1669 char *acct_name;
1670 uint32_t rid;
1671 struct dom_sid user_sid;
1672 int i;
1673 char *dummy;
1674 size_t dummy_size;
1676 sam_acct = samu_new(mem_ctx);
1677 if (sam_acct == NULL) {
1678 return NT_STATUS_NO_MEMORY;
1681 acct_name = talloc_asprintf(mem_ctx, "%s$", netbios_name);
1682 if (acct_name == NULL) {
1683 return NT_STATUS_NO_MEMORY;
1685 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1686 return NT_STATUS_UNSUCCESSFUL;
1689 if (!pdb_set_domain(sam_acct, domain_name, PDB_SET)) {
1690 return NT_STATUS_UNSUCCESSFUL;
1693 if (!pdb_set_acct_ctrl(sam_acct, ACB_DOMTRUST, PDB_SET)) {
1694 return NT_STATUS_UNSUCCESSFUL;
1697 if (!pdb_new_rid(&rid)) {
1698 return NT_STATUS_DS_NO_MORE_RIDS;
1700 sid_compose(&user_sid, get_global_sam_sid(), rid);
1701 if (!pdb_set_user_sid(sam_acct, &user_sid, PDB_SET)) {
1702 return NT_STATUS_UNSUCCESSFUL;
1705 for (i = 0; i < auth_struct->incoming.count; i++) {
1706 switch (auth_struct->incoming.current.array[i].AuthType) {
1707 case TRUST_AUTH_TYPE_CLEAR:
1708 if (!convert_string_talloc(mem_ctx,
1709 CH_UTF16LE,
1710 CH_UNIX,
1711 auth_struct->incoming.current.array[i].AuthInfo.clear.password,
1712 auth_struct->incoming.current.array[i].AuthInfo.clear.size,
1713 &dummy,
1714 &dummy_size)) {
1715 return NT_STATUS_UNSUCCESSFUL;
1717 if (!pdb_set_plaintext_passwd(sam_acct, dummy)) {
1718 return NT_STATUS_UNSUCCESSFUL;
1720 break;
1721 default:
1722 continue;
1726 status = pdb_add_sam_account(sam_acct);
1727 if (!NT_STATUS_IS_OK(status)) {
1728 return status;
1731 return NT_STATUS_OK;
1734 /***************************************************************************
1735 _lsa_CreateTrustedDomainEx2
1736 ***************************************************************************/
1738 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1739 struct lsa_CreateTrustedDomainEx2 *r)
1741 struct lsa_info *policy;
1742 NTSTATUS status;
1743 uint32_t acc_granted;
1744 struct security_descriptor *psd;
1745 size_t sd_size;
1746 struct pdb_trusted_domain td;
1747 struct trustDomainPasswords auth_struct;
1748 enum ndr_err_code ndr_err;
1749 DATA_BLOB auth_blob;
1751 if (!IS_DC) {
1752 return NT_STATUS_NOT_SUPPORTED;
1755 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1756 return NT_STATUS_INVALID_HANDLE;
1759 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1760 return NT_STATUS_ACCESS_DENIED;
1763 if (p->session_info->unix_token->uid != sec_initial_uid() &&
1764 !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1765 return NT_STATUS_ACCESS_DENIED;
1768 /* Work out max allowed. */
1769 map_max_allowed_access(p->session_info->security_token,
1770 p->session_info->unix_token,
1771 &r->in.access_mask);
1773 /* map the generic bits to the lsa policy ones */
1774 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1776 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1777 &lsa_trusted_domain_mapping,
1778 NULL, 0);
1779 if (!NT_STATUS_IS_OK(status)) {
1780 return status;
1783 status = access_check_object(psd, p->session_info->security_token,
1784 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1785 r->in.access_mask, &acc_granted,
1786 "_lsa_CreateTrustedDomainEx2");
1787 if (!NT_STATUS_IS_OK(status)) {
1788 return status;
1791 ZERO_STRUCT(td);
1793 td.domain_name = talloc_strdup(p->mem_ctx,
1794 r->in.info->domain_name.string);
1795 if (td.domain_name == NULL) {
1796 return NT_STATUS_NO_MEMORY;
1798 td.netbios_name = talloc_strdup(p->mem_ctx,
1799 r->in.info->netbios_name.string);
1800 if (td.netbios_name == NULL) {
1801 return NT_STATUS_NO_MEMORY;
1803 sid_copy(&td.security_identifier, r->in.info->sid);
1804 td.trust_direction = r->in.info->trust_direction;
1805 td.trust_type = r->in.info->trust_type;
1806 td.trust_attributes = r->in.info->trust_attributes;
1808 if (r->in.auth_info_internal->auth_blob.size != 0) {
1809 auth_blob.length = r->in.auth_info_internal->auth_blob.size;
1810 auth_blob.data = r->in.auth_info_internal->auth_blob.data;
1812 arcfour_crypt_blob(auth_blob.data, auth_blob.length,
1813 &p->session_info->session_key);
1815 ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
1816 &auth_struct,
1817 (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
1818 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1819 return NT_STATUS_UNSUCCESSFUL;
1822 ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
1823 &auth_struct.incoming,
1824 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1825 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1826 return NT_STATUS_UNSUCCESSFUL;
1829 ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
1830 &auth_struct.outgoing,
1831 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1832 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1833 return NT_STATUS_UNSUCCESSFUL;
1835 } else {
1836 td.trust_auth_incoming.data = NULL;
1837 td.trust_auth_incoming.length = 0;
1838 td.trust_auth_outgoing.data = NULL;
1839 td.trust_auth_outgoing.length = 0;
1842 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1843 if (!NT_STATUS_IS_OK(status)) {
1844 return status;
1847 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1848 status = add_trusted_domain_user(p->mem_ctx,
1849 r->in.info->netbios_name.string,
1850 r->in.info->domain_name.string,
1851 &auth_struct);
1852 if (!NT_STATUS_IS_OK(status)) {
1853 return status;
1857 status = create_lsa_policy_handle(p->mem_ctx, p,
1858 LSA_HANDLE_TRUST_TYPE,
1859 acc_granted,
1860 r->in.info->sid,
1861 r->in.info->netbios_name.string,
1862 psd,
1863 r->out.trustdom_handle);
1864 if (!NT_STATUS_IS_OK(status)) {
1865 pdb_del_trusteddom_pw(r->in.info->netbios_name.string);
1866 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1869 return NT_STATUS_OK;
1872 /***************************************************************************
1873 _lsa_CreateTrustedDomainEx
1874 ***************************************************************************/
1876 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1877 struct lsa_CreateTrustedDomainEx *r)
1879 struct lsa_CreateTrustedDomainEx2 q;
1880 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1882 ZERO_STRUCT(auth_info);
1884 q.in.policy_handle = r->in.policy_handle;
1885 q.in.info = r->in.info;
1886 q.in.auth_info_internal = &auth_info;
1887 q.in.access_mask = r->in.access_mask;
1888 q.out.trustdom_handle = r->out.trustdom_handle;
1890 return _lsa_CreateTrustedDomainEx2(p, &q);
1893 /***************************************************************************
1894 _lsa_CreateTrustedDomain
1895 ***************************************************************************/
1897 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1898 struct lsa_CreateTrustedDomain *r)
1900 struct lsa_CreateTrustedDomainEx2 c;
1901 struct lsa_TrustDomainInfoInfoEx info;
1902 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1904 ZERO_STRUCT(auth_info);
1906 info.domain_name = r->in.info->name;
1907 info.netbios_name = r->in.info->name;
1908 info.sid = r->in.info->sid;
1909 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1910 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1911 info.trust_attributes = 0;
1913 c.in.policy_handle = r->in.policy_handle;
1914 c.in.info = &info;
1915 c.in.auth_info_internal = &auth_info;
1916 c.in.access_mask = r->in.access_mask;
1917 c.out.trustdom_handle = r->out.trustdom_handle;
1919 return _lsa_CreateTrustedDomainEx2(p, &c);
1922 /***************************************************************************
1923 _lsa_DeleteTrustedDomain
1924 ***************************************************************************/
1926 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1927 struct lsa_DeleteTrustedDomain *r)
1929 NTSTATUS status;
1930 struct lsa_info *handle;
1931 struct pdb_trusted_domain *td;
1932 struct samu *sam_acct;
1933 char *acct_name;
1935 /* find the connection policy handle. */
1936 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1937 return NT_STATUS_INVALID_HANDLE;
1940 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1941 return NT_STATUS_INVALID_HANDLE;
1944 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1945 return NT_STATUS_ACCESS_DENIED;
1948 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1949 if (!NT_STATUS_IS_OK(status)) {
1950 return status;
1953 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1954 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1955 sid_string_tos(r->in.dom_sid)));
1956 return NT_STATUS_UNSUCCESSFUL;
1959 if (td->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1960 sam_acct = samu_new(p->mem_ctx);
1961 if (sam_acct == NULL) {
1962 return NT_STATUS_NO_MEMORY;
1965 acct_name = talloc_asprintf(p->mem_ctx, "%s$", td->netbios_name);
1966 if (acct_name == NULL) {
1967 return NT_STATUS_NO_MEMORY;
1969 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1970 return NT_STATUS_UNSUCCESSFUL;
1972 status = pdb_delete_sam_account(sam_acct);
1973 if (!NT_STATUS_IS_OK(status)) {
1974 return status;
1978 status = pdb_del_trusted_domain(td->netbios_name);
1979 if (!NT_STATUS_IS_OK(status)) {
1980 return status;
1983 return NT_STATUS_OK;
1986 /***************************************************************************
1987 _lsa_CloseTrustedDomainEx
1988 ***************************************************************************/
1990 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1991 struct lsa_CloseTrustedDomainEx *r)
1993 return NT_STATUS_NOT_IMPLEMENTED;
1996 /***************************************************************************
1997 _lsa_QueryTrustedDomainInfo
1998 ***************************************************************************/
2000 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
2001 struct lsa_QueryTrustedDomainInfo *r)
2003 NTSTATUS status;
2004 struct lsa_info *handle;
2005 union lsa_TrustedDomainInfo *info;
2006 struct pdb_trusted_domain *td;
2007 uint32_t acc_required;
2009 /* find the connection policy handle. */
2010 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
2011 return NT_STATUS_INVALID_HANDLE;
2014 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
2015 return NT_STATUS_INVALID_HANDLE;
2018 switch (r->in.level) {
2019 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2020 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2021 break;
2022 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2023 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
2024 break;
2025 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2026 acc_required = LSA_TRUSTED_QUERY_POSIX;
2027 break;
2028 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2029 acc_required = LSA_TRUSTED_QUERY_AUTH;
2030 break;
2031 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2032 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2033 break;
2034 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2035 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2036 break;
2037 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2038 acc_required = LSA_TRUSTED_QUERY_AUTH;
2039 break;
2040 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2041 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2042 LSA_TRUSTED_QUERY_POSIX |
2043 LSA_TRUSTED_QUERY_AUTH;
2044 break;
2045 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2046 acc_required = LSA_TRUSTED_QUERY_AUTH;
2047 break;
2048 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2049 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2050 LSA_TRUSTED_QUERY_POSIX |
2051 LSA_TRUSTED_QUERY_AUTH;
2052 break;
2053 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2054 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2055 break;
2056 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2057 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2058 LSA_TRUSTED_QUERY_POSIX |
2059 LSA_TRUSTED_QUERY_AUTH;
2060 break;
2061 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2062 acc_required = LSA_TRUSTED_QUERY_POSIX;
2063 break;
2064 default:
2065 return NT_STATUS_INVALID_PARAMETER;
2068 if (!(handle->access & acc_required)) {
2069 return NT_STATUS_ACCESS_DENIED;
2072 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2073 if (!NT_STATUS_IS_OK(status)) {
2074 return status;
2077 info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
2078 if (!info) {
2079 return NT_STATUS_NO_MEMORY;
2082 switch (r->in.level) {
2083 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2084 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2085 break;
2086 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2087 return NT_STATUS_INVALID_PARAMETER;
2088 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2089 break;
2090 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2091 return NT_STATUS_INVALID_INFO_CLASS;
2092 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2093 return NT_STATUS_INVALID_PARAMETER;
2094 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2095 init_lsa_StringLarge(&info->info_ex.domain_name, td->domain_name);
2096 init_lsa_StringLarge(&info->info_ex.netbios_name, td->netbios_name);
2097 info->info_ex.sid = dom_sid_dup(info, &td->security_identifier);
2098 if (!info->info_ex.sid) {
2099 return NT_STATUS_NO_MEMORY;
2101 info->info_ex.trust_direction = td->trust_direction;
2102 info->info_ex.trust_type = td->trust_type;
2103 info->info_ex.trust_attributes = td->trust_attributes;
2104 break;
2105 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2106 return NT_STATUS_INVALID_INFO_CLASS;
2107 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2108 break;
2109 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2110 return NT_STATUS_INVALID_INFO_CLASS;
2111 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2112 return NT_STATUS_INVALID_INFO_CLASS;
2113 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2114 return NT_STATUS_INVALID_PARAMETER;
2115 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2116 break;
2117 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2118 break;
2119 default:
2120 return NT_STATUS_INVALID_PARAMETER;
2123 *r->out.info = info;
2125 return NT_STATUS_OK;
2128 /***************************************************************************
2129 _lsa_QueryTrustedDomainInfoBySid
2130 ***************************************************************************/
2132 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2133 struct lsa_QueryTrustedDomainInfoBySid *r)
2135 NTSTATUS status;
2136 struct policy_handle trustdom_handle;
2137 struct lsa_OpenTrustedDomain o;
2138 struct lsa_QueryTrustedDomainInfo q;
2139 struct lsa_Close c;
2141 o.in.handle = r->in.handle;
2142 o.in.sid = r->in.dom_sid;
2143 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2144 o.out.trustdom_handle = &trustdom_handle;
2146 status = _lsa_OpenTrustedDomain(p, &o);
2147 if (!NT_STATUS_IS_OK(status)) {
2148 return status;
2151 q.in.trustdom_handle = &trustdom_handle;
2152 q.in.level = r->in.level;
2153 q.out.info = r->out.info;
2155 status = _lsa_QueryTrustedDomainInfo(p, &q);
2156 if (!NT_STATUS_IS_OK(status)) {
2157 return status;
2160 c.in.handle = &trustdom_handle;
2161 c.out.handle = &trustdom_handle;
2163 return _lsa_Close(p, &c);
2166 /***************************************************************************
2167 _lsa_QueryTrustedDomainInfoByName
2168 ***************************************************************************/
2170 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2171 struct lsa_QueryTrustedDomainInfoByName *r)
2173 NTSTATUS status;
2174 struct policy_handle trustdom_handle;
2175 struct lsa_OpenTrustedDomainByName o;
2176 struct lsa_QueryTrustedDomainInfo q;
2177 struct lsa_Close c;
2179 o.in.handle = r->in.handle;
2180 o.in.name.string = r->in.trusted_domain->string;
2181 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2182 o.out.trustdom_handle = &trustdom_handle;
2184 status = _lsa_OpenTrustedDomainByName(p, &o);
2185 if (!NT_STATUS_IS_OK(status)) {
2186 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2187 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2189 return status;
2192 q.in.trustdom_handle = &trustdom_handle;
2193 q.in.level = r->in.level;
2194 q.out.info = r->out.info;
2196 status = _lsa_QueryTrustedDomainInfo(p, &q);
2197 if (!NT_STATUS_IS_OK(status)) {
2198 return status;
2201 c.in.handle = &trustdom_handle;
2202 c.out.handle = &trustdom_handle;
2204 return _lsa_Close(p, &c);
2207 /***************************************************************************
2208 _lsa_CreateSecret
2209 ***************************************************************************/
2211 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p,
2212 struct lsa_CreateSecret *r)
2214 NTSTATUS status;
2215 struct lsa_info *handle;
2216 uint32_t acc_granted;
2217 struct security_descriptor *psd;
2218 size_t sd_size;
2220 /* find the connection policy handle. */
2221 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
2222 return NT_STATUS_INVALID_HANDLE;
2225 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2226 return NT_STATUS_INVALID_HANDLE;
2229 /* check if the user has enough rights */
2231 if (!(handle->access & LSA_POLICY_CREATE_SECRET)) {
2232 return NT_STATUS_ACCESS_DENIED;
2235 /* Work out max allowed. */
2236 map_max_allowed_access(p->session_info->security_token,
2237 p->session_info->unix_token,
2238 &r->in.access_mask);
2240 /* map the generic bits to the lsa policy ones */
2241 se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
2243 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2244 &lsa_secret_mapping,
2245 NULL, 0);
2246 if (!NT_STATUS_IS_OK(status)) {
2247 return status;
2250 status = access_check_object(psd, p->session_info->security_token,
2251 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2252 r->in.access_mask,
2253 &acc_granted, "_lsa_CreateSecret");
2254 if (!NT_STATUS_IS_OK(status)) {
2255 return status;
2258 if (!r->in.name.string) {
2259 return NT_STATUS_INVALID_PARAMETER;
2262 if (strlen(r->in.name.string) > 128) {
2263 return NT_STATUS_NAME_TOO_LONG;
2266 status = pdb_get_secret(p->mem_ctx, r->in.name.string,
2267 NULL, NULL, NULL, NULL, NULL);
2268 if (NT_STATUS_IS_OK(status)) {
2269 return NT_STATUS_OBJECT_NAME_COLLISION;
2272 status = pdb_set_secret(r->in.name.string, NULL, NULL, psd);
2273 if (!NT_STATUS_IS_OK(status)) {
2274 return status;
2277 status = create_lsa_policy_handle(p->mem_ctx, p,
2278 LSA_HANDLE_SECRET_TYPE,
2279 acc_granted,
2280 NULL,
2281 r->in.name.string,
2282 psd,
2283 r->out.sec_handle);
2284 if (!NT_STATUS_IS_OK(status)) {
2285 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2288 return NT_STATUS_OK;
2291 /***************************************************************************
2292 _lsa_SetSecret
2293 ***************************************************************************/
2295 NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
2296 struct lsa_SetSecret *r)
2298 NTSTATUS status;
2299 struct lsa_info *info = NULL;
2300 DATA_BLOB blob_new, blob_old;
2301 DATA_BLOB cleartext_blob_new = data_blob_null;
2302 DATA_BLOB cleartext_blob_old = data_blob_null;
2303 DATA_BLOB *cleartext_blob_new_p = NULL;
2304 DATA_BLOB *cleartext_blob_old_p = NULL;
2306 if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
2307 return NT_STATUS_INVALID_HANDLE;
2310 if (info->type != LSA_HANDLE_SECRET_TYPE) {
2311 return NT_STATUS_INVALID_HANDLE;
2314 if (!(info->access & LSA_SECRET_SET_VALUE)) {
2315 return NT_STATUS_ACCESS_DENIED;
2318 if (r->in.new_val) {
2319 blob_new = data_blob_const(r->in.new_val->data,
2320 r->in.new_val->length);
2322 status = sess_decrypt_blob(p->mem_ctx, &blob_new,
2323 &p->session_info->session_key,
2324 &cleartext_blob_new);
2325 if (!NT_STATUS_IS_OK(status)) {
2326 return status;
2329 cleartext_blob_new_p = &cleartext_blob_new;
2332 if (r->in.old_val) {
2333 blob_old = data_blob_const(r->in.old_val->data,
2334 r->in.old_val->length);
2336 status = sess_decrypt_blob(p->mem_ctx, &blob_old,
2337 &p->session_info->session_key,
2338 &cleartext_blob_old);
2339 if (!NT_STATUS_IS_OK(status)) {
2340 return status;
2343 cleartext_blob_old_p = &cleartext_blob_old;
2346 status = pdb_set_secret(info->name, cleartext_blob_new_p, cleartext_blob_old_p, NULL);
2347 if (!NT_STATUS_IS_OK(status)) {
2348 return status;
2351 #ifdef DEBUG_PASSWORD
2352 DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
2353 dump_data(10, cleartext_blob_new.data, cleartext_blob_new.length);
2354 DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
2355 dump_data(10, cleartext_blob_old.data, cleartext_blob_old.length);
2356 #endif
2358 return NT_STATUS_OK;
2361 /***************************************************************************
2362 _lsa_QuerySecret
2363 ***************************************************************************/
2365 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
2366 struct lsa_QuerySecret *r)
2368 struct lsa_info *info = NULL;
2369 DATA_BLOB blob_new, blob_old;
2370 DATA_BLOB blob_new_crypt, blob_old_crypt;
2371 NTTIME nttime_new, nttime_old;
2372 NTSTATUS status;
2374 if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
2375 return NT_STATUS_INVALID_HANDLE;
2378 if (info->type != LSA_HANDLE_SECRET_TYPE) {
2379 return NT_STATUS_INVALID_HANDLE;
2382 if (!(info->access & LSA_SECRET_QUERY_VALUE)) {
2383 return NT_STATUS_ACCESS_DENIED;
2386 status = pdb_get_secret(p->mem_ctx, info->name,
2387 &blob_new, &nttime_new,
2388 &blob_old, &nttime_old,
2389 NULL);
2390 if (!NT_STATUS_IS_OK(status)) {
2391 return status;
2394 if (r->in.new_val) {
2395 if (blob_new.length) {
2396 if (!r->out.new_val->buf) {
2397 r->out.new_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2399 if (!r->out.new_val->buf) {
2400 return NT_STATUS_NO_MEMORY;
2403 blob_new_crypt = sess_encrypt_blob(p->mem_ctx, &blob_new,
2404 &p->session_info->session_key);
2405 if (!blob_new_crypt.length) {
2406 return NT_STATUS_NO_MEMORY;
2409 r->out.new_val->buf->data = blob_new_crypt.data;
2410 r->out.new_val->buf->length = blob_new_crypt.length;
2411 r->out.new_val->buf->size = blob_new_crypt.length;
2415 if (r->in.old_val) {
2416 if (blob_old.length) {
2417 if (!r->out.old_val->buf) {
2418 r->out.old_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2420 if (!r->out.old_val->buf) {
2421 return NT_STATUS_NO_MEMORY;
2424 blob_old_crypt = sess_encrypt_blob(p->mem_ctx, &blob_old,
2425 &p->session_info->session_key);
2426 if (!blob_old_crypt.length) {
2427 return NT_STATUS_NO_MEMORY;
2430 r->out.old_val->buf->data = blob_old_crypt.data;
2431 r->out.old_val->buf->length = blob_old_crypt.length;
2432 r->out.old_val->buf->size = blob_old_crypt.length;
2436 if (r->out.new_mtime) {
2437 *r->out.new_mtime = nttime_new;
2440 if (r->out.old_mtime) {
2441 *r->out.old_mtime = nttime_old;
2444 return NT_STATUS_OK;
2447 /***************************************************************************
2448 _lsa_DeleteObject
2449 ***************************************************************************/
2451 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2452 struct lsa_DeleteObject *r)
2454 NTSTATUS status;
2455 struct lsa_info *info = NULL;
2457 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2458 return NT_STATUS_INVALID_HANDLE;
2461 if (!(info->access & SEC_STD_DELETE)) {
2462 return NT_STATUS_ACCESS_DENIED;
2465 switch (info->type) {
2466 case LSA_HANDLE_ACCOUNT_TYPE:
2467 status = privilege_delete_account(&info->sid);
2468 if (!NT_STATUS_IS_OK(status)) {
2469 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2470 nt_errstr(status)));
2471 return status;
2473 break;
2474 case LSA_HANDLE_TRUST_TYPE:
2475 if (!pdb_del_trusteddom_pw(info->name)) {
2476 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2478 status = NT_STATUS_OK;
2479 break;
2480 case LSA_HANDLE_SECRET_TYPE:
2481 status = pdb_delete_secret(info->name);
2482 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2483 return NT_STATUS_INVALID_HANDLE;
2485 break;
2486 default:
2487 return NT_STATUS_INVALID_HANDLE;
2490 close_policy_hnd(p, r->in.handle);
2491 ZERO_STRUCTP(r->out.handle);
2493 return status;
2496 /***************************************************************************
2497 _lsa_EnumPrivs
2498 ***************************************************************************/
2500 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2501 struct lsa_EnumPrivs *r)
2503 struct lsa_info *handle;
2504 uint32 i;
2505 uint32 enum_context = *r->in.resume_handle;
2506 int num_privs = num_privileges_in_short_list();
2507 struct lsa_PrivEntry *entries = NULL;
2509 /* remember that the enum_context starts at 0 and not 1 */
2511 if ( enum_context >= num_privs )
2512 return NT_STATUS_NO_MORE_ENTRIES;
2514 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2515 enum_context, num_privs));
2517 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2518 return NT_STATUS_INVALID_HANDLE;
2520 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2521 return NT_STATUS_INVALID_HANDLE;
2524 /* check if the user has enough rights
2525 I don't know if it's the right one. not documented. */
2527 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2528 return NT_STATUS_ACCESS_DENIED;
2530 if (num_privs) {
2531 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2532 if (!entries) {
2533 return NT_STATUS_NO_MEMORY;
2535 } else {
2536 entries = NULL;
2539 for (i = 0; i < num_privs; i++) {
2540 if( i < enum_context) {
2542 init_lsa_StringLarge(&entries[i].name, NULL);
2544 entries[i].luid.low = 0;
2545 entries[i].luid.high = 0;
2546 } else {
2548 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2550 entries[i].luid.low = sec_privilege_from_index(i);
2551 entries[i].luid.high = 0;
2555 enum_context = num_privs;
2557 *r->out.resume_handle = enum_context;
2558 r->out.privs->count = num_privs;
2559 r->out.privs->privs = entries;
2561 return NT_STATUS_OK;
2564 /***************************************************************************
2565 _lsa_LookupPrivDisplayName
2566 ***************************************************************************/
2568 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2569 struct lsa_LookupPrivDisplayName *r)
2571 struct lsa_info *handle;
2572 const char *description;
2573 struct lsa_StringLarge *lsa_name;
2575 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2576 return NT_STATUS_INVALID_HANDLE;
2578 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2579 return NT_STATUS_INVALID_HANDLE;
2582 /* check if the user has enough rights */
2585 * I don't know if it's the right one. not documented.
2587 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2588 return NT_STATUS_ACCESS_DENIED;
2590 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2592 description = get_privilege_dispname(r->in.name->string);
2593 if (!description) {
2594 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2595 return NT_STATUS_NO_SUCH_PRIVILEGE;
2598 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2600 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2601 if (!lsa_name) {
2602 return NT_STATUS_NO_MEMORY;
2605 init_lsa_StringLarge(lsa_name, description);
2607 *r->out.returned_language_id = r->in.language_id;
2608 *r->out.disp_name = lsa_name;
2610 return NT_STATUS_OK;
2613 /***************************************************************************
2614 _lsa_EnumAccounts
2615 ***************************************************************************/
2617 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2618 struct lsa_EnumAccounts *r)
2620 struct lsa_info *handle;
2621 struct dom_sid *sid_list;
2622 int i, j, num_entries;
2623 NTSTATUS status;
2624 struct lsa_SidPtr *sids = NULL;
2626 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2627 return NT_STATUS_INVALID_HANDLE;
2629 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2630 return NT_STATUS_INVALID_HANDLE;
2633 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2634 return NT_STATUS_ACCESS_DENIED;
2636 sid_list = NULL;
2637 num_entries = 0;
2639 /* The only way we can currently find out all the SIDs that have been
2640 privileged is to scan all privileges */
2642 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2643 if (!NT_STATUS_IS_OK(status)) {
2644 return status;
2647 if (*r->in.resume_handle >= num_entries) {
2648 return NT_STATUS_NO_MORE_ENTRIES;
2651 if (num_entries - *r->in.resume_handle) {
2652 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2653 num_entries - *r->in.resume_handle);
2654 if (!sids) {
2655 talloc_free(sid_list);
2656 return NT_STATUS_NO_MEMORY;
2659 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2660 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2661 if (!sids[j].sid) {
2662 talloc_free(sid_list);
2663 return NT_STATUS_NO_MEMORY;
2668 talloc_free(sid_list);
2670 *r->out.resume_handle = num_entries;
2671 r->out.sids->num_sids = num_entries;
2672 r->out.sids->sids = sids;
2674 return NT_STATUS_OK;
2677 /***************************************************************************
2678 _lsa_GetUserName
2679 ***************************************************************************/
2681 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2682 struct lsa_GetUserName *r)
2684 const char *username, *domname;
2685 struct lsa_String *account_name = NULL;
2686 struct lsa_String *authority_name = NULL;
2688 if (r->in.account_name &&
2689 *r->in.account_name) {
2690 return NT_STATUS_INVALID_PARAMETER;
2693 if (r->in.authority_name &&
2694 *r->in.authority_name) {
2695 return NT_STATUS_INVALID_PARAMETER;
2698 if (security_session_user_level(p->session_info, NULL) < SECURITY_USER) {
2700 * I'm 99% sure this is not the right place to do this,
2701 * global_sid_Anonymous should probably be put into the token
2702 * instead of the guest id -- vl
2704 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2705 &domname, &username, NULL)) {
2706 return NT_STATUS_NO_MEMORY;
2708 } else {
2709 username = p->session_info->unix_info->sanitized_username;
2710 domname = p->session_info->info->domain_name;
2713 account_name = talloc(p->mem_ctx, struct lsa_String);
2714 if (!account_name) {
2715 return NT_STATUS_NO_MEMORY;
2717 init_lsa_String(account_name, username);
2719 if (r->out.authority_name) {
2720 authority_name = talloc(p->mem_ctx, struct lsa_String);
2721 if (!authority_name) {
2722 return NT_STATUS_NO_MEMORY;
2724 init_lsa_String(authority_name, domname);
2727 *r->out.account_name = account_name;
2728 if (r->out.authority_name) {
2729 *r->out.authority_name = authority_name;
2732 return NT_STATUS_OK;
2735 /***************************************************************************
2736 _lsa_CreateAccount
2737 ***************************************************************************/
2739 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2740 struct lsa_CreateAccount *r)
2742 NTSTATUS status;
2743 struct lsa_info *handle;
2744 uint32_t acc_granted;
2745 struct security_descriptor *psd;
2746 size_t sd_size;
2748 /* find the connection policy handle. */
2749 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2750 return NT_STATUS_INVALID_HANDLE;
2752 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2753 return NT_STATUS_INVALID_HANDLE;
2756 /* check if the user has enough rights */
2758 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2759 return NT_STATUS_ACCESS_DENIED;
2762 /* Work out max allowed. */
2763 map_max_allowed_access(p->session_info->security_token,
2764 p->session_info->unix_token,
2765 &r->in.access_mask);
2767 /* map the generic bits to the lsa policy ones */
2768 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2770 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2771 &lsa_account_mapping,
2772 r->in.sid, LSA_POLICY_ALL_ACCESS);
2773 if (!NT_STATUS_IS_OK(status)) {
2774 return status;
2777 status = access_check_object(psd, p->session_info->security_token,
2778 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2779 &acc_granted, "_lsa_CreateAccount");
2780 if (!NT_STATUS_IS_OK(status)) {
2781 return status;
2784 if ( is_privileged_sid( r->in.sid ) )
2785 return NT_STATUS_OBJECT_NAME_COLLISION;
2787 status = create_lsa_policy_handle(p->mem_ctx, p,
2788 LSA_HANDLE_ACCOUNT_TYPE,
2789 acc_granted,
2790 r->in.sid,
2791 NULL,
2792 psd,
2793 r->out.acct_handle);
2794 if (!NT_STATUS_IS_OK(status)) {
2795 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2798 return privilege_create_account(r->in.sid);
2801 /***************************************************************************
2802 _lsa_OpenAccount
2803 ***************************************************************************/
2805 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2806 struct lsa_OpenAccount *r)
2808 struct lsa_info *handle;
2809 struct security_descriptor *psd = NULL;
2810 size_t sd_size;
2811 uint32_t des_access = r->in.access_mask;
2812 uint32_t acc_granted;
2813 NTSTATUS status;
2815 /* find the connection policy handle. */
2816 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2817 return NT_STATUS_INVALID_HANDLE;
2819 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2820 return NT_STATUS_INVALID_HANDLE;
2823 /* des_access is for the account here, not the policy
2824 * handle - so don't check against policy handle. */
2826 /* Work out max allowed. */
2827 map_max_allowed_access(p->session_info->security_token,
2828 p->session_info->unix_token,
2829 &des_access);
2831 /* map the generic bits to the lsa account ones */
2832 se_map_generic(&des_access, &lsa_account_mapping);
2834 /* get the generic lsa account SD until we store it */
2835 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2836 &lsa_account_mapping,
2837 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2838 if (!NT_STATUS_IS_OK(status)) {
2839 return status;
2842 status = access_check_object(psd, p->session_info->security_token,
2843 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2844 &acc_granted, "_lsa_OpenAccount" );
2845 if (!NT_STATUS_IS_OK(status)) {
2846 return status;
2849 /* TODO: Fis the parsing routine before reenabling this check! */
2850 #if 0
2851 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2852 return NT_STATUS_ACCESS_DENIED;
2853 #endif
2855 status = create_lsa_policy_handle(p->mem_ctx, p,
2856 LSA_HANDLE_ACCOUNT_TYPE,
2857 acc_granted,
2858 r->in.sid,
2859 NULL,
2860 psd,
2861 r->out.acct_handle);
2862 if (!NT_STATUS_IS_OK(status)) {
2863 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2866 return NT_STATUS_OK;
2869 /***************************************************************************
2870 _lsa_EnumPrivsAccount
2871 For a given SID, enumerate all the privilege this account has.
2872 ***************************************************************************/
2874 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2875 struct lsa_EnumPrivsAccount *r)
2877 NTSTATUS status = NT_STATUS_OK;
2878 struct lsa_info *info=NULL;
2879 PRIVILEGE_SET *privileges;
2880 struct lsa_PrivilegeSet *priv_set = NULL;
2882 /* find the connection policy handle. */
2883 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2884 return NT_STATUS_INVALID_HANDLE;
2886 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2887 return NT_STATUS_INVALID_HANDLE;
2890 if (!(info->access & LSA_ACCOUNT_VIEW))
2891 return NT_STATUS_ACCESS_DENIED;
2893 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2894 if (!NT_STATUS_IS_OK(status)) {
2895 return status;
2898 *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2899 if (!priv_set) {
2900 return NT_STATUS_NO_MEMORY;
2903 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2904 sid_string_dbg(&info->sid),
2905 privileges->count));
2907 priv_set->count = privileges->count;
2908 priv_set->unknown = 0;
2909 priv_set->set = talloc_move(priv_set, &privileges->set);
2911 return status;
2914 /***************************************************************************
2915 _lsa_GetSystemAccessAccount
2916 ***************************************************************************/
2918 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2919 struct lsa_GetSystemAccessAccount *r)
2921 NTSTATUS status;
2922 struct lsa_info *info = NULL;
2923 struct lsa_EnumPrivsAccount e;
2924 struct lsa_PrivilegeSet *privset;
2926 /* find the connection policy handle. */
2928 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2929 return NT_STATUS_INVALID_HANDLE;
2931 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2932 return NT_STATUS_INVALID_HANDLE;
2935 if (!(info->access & LSA_ACCOUNT_VIEW))
2936 return NT_STATUS_ACCESS_DENIED;
2938 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2939 if (!privset) {
2940 return NT_STATUS_NO_MEMORY;
2943 e.in.handle = r->in.handle;
2944 e.out.privs = &privset;
2946 status = _lsa_EnumPrivsAccount(p, &e);
2947 if (!NT_STATUS_IS_OK(status)) {
2948 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2949 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2950 nt_errstr(status)));
2951 return status;
2954 /* Samba4 would iterate over the privset to merge the policy mode bits,
2955 * not sure samba3 can do the same here, so just return what we did in
2956 * the past - gd */
2959 0x01 -> Log on locally
2960 0x02 -> Access this computer from network
2961 0x04 -> Log on as a batch job
2962 0x10 -> Log on as a service
2964 they can be ORed together
2967 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2968 LSA_POLICY_MODE_NETWORK;
2970 return NT_STATUS_OK;
2973 /***************************************************************************
2974 update the systemaccount information
2975 ***************************************************************************/
2977 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2978 struct lsa_SetSystemAccessAccount *r)
2980 struct lsa_info *info=NULL;
2981 GROUP_MAP map;
2983 /* find the connection policy handle. */
2984 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2985 return NT_STATUS_INVALID_HANDLE;
2987 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2988 return NT_STATUS_INVALID_HANDLE;
2991 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2992 return NT_STATUS_ACCESS_DENIED;
2995 if (!pdb_getgrsid(&map, info->sid))
2996 return NT_STATUS_NO_SUCH_GROUP;
2998 return pdb_update_group_mapping_entry(&map);
3001 /***************************************************************************
3002 _lsa_AddPrivilegesToAccount
3003 For a given SID, add some privileges.
3004 ***************************************************************************/
3006 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
3007 struct lsa_AddPrivilegesToAccount *r)
3009 struct lsa_info *info = NULL;
3010 struct lsa_PrivilegeSet *set = NULL;
3012 /* find the connection policy handle. */
3013 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3014 return NT_STATUS_INVALID_HANDLE;
3016 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3017 return NT_STATUS_INVALID_HANDLE;
3020 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3021 return NT_STATUS_ACCESS_DENIED;
3024 set = r->in.privs;
3026 if ( !grant_privilege_set( &info->sid, set ) ) {
3027 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
3028 sid_string_dbg(&info->sid) ));
3029 return NT_STATUS_NO_SUCH_PRIVILEGE;
3032 return NT_STATUS_OK;
3035 /***************************************************************************
3036 _lsa_RemovePrivilegesFromAccount
3037 For a given SID, remove some privileges.
3038 ***************************************************************************/
3040 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
3041 struct lsa_RemovePrivilegesFromAccount *r)
3043 struct lsa_info *info = NULL;
3044 struct lsa_PrivilegeSet *set = NULL;
3046 /* find the connection policy handle. */
3047 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3048 return NT_STATUS_INVALID_HANDLE;
3050 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3051 return NT_STATUS_INVALID_HANDLE;
3054 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3055 return NT_STATUS_ACCESS_DENIED;
3058 set = r->in.privs;
3060 if ( !revoke_privilege_set( &info->sid, set) ) {
3061 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
3062 sid_string_dbg(&info->sid) ));
3063 return NT_STATUS_NO_SUCH_PRIVILEGE;
3066 return NT_STATUS_OK;
3069 /***************************************************************************
3070 _lsa_LookupPrivName
3071 ***************************************************************************/
3073 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
3074 struct lsa_LookupPrivName *r)
3076 struct lsa_info *info = NULL;
3077 const char *name;
3078 struct lsa_StringLarge *lsa_name;
3080 /* find the connection policy handle. */
3081 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3082 return NT_STATUS_INVALID_HANDLE;
3085 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3086 return NT_STATUS_INVALID_HANDLE;
3089 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
3090 return NT_STATUS_ACCESS_DENIED;
3093 if (r->in.luid->high != 0) {
3094 return NT_STATUS_NO_SUCH_PRIVILEGE;
3097 name = sec_privilege_name(r->in.luid->low);
3098 if (!name) {
3099 return NT_STATUS_NO_SUCH_PRIVILEGE;
3102 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
3103 if (!lsa_name) {
3104 return NT_STATUS_NO_MEMORY;
3107 lsa_name->string = talloc_strdup(lsa_name, name);
3108 if (!lsa_name->string) {
3109 TALLOC_FREE(lsa_name);
3110 return NT_STATUS_NO_MEMORY;
3113 *r->out.name = lsa_name;
3115 return NT_STATUS_OK;
3118 /***************************************************************************
3119 _lsa_QuerySecurity
3120 ***************************************************************************/
3122 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
3123 struct lsa_QuerySecurity *r)
3125 struct lsa_info *handle=NULL;
3126 struct security_descriptor *psd = NULL;
3127 size_t sd_size = 0;
3128 NTSTATUS status;
3130 /* find the connection policy handle. */
3131 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
3132 return NT_STATUS_INVALID_HANDLE;
3134 switch (handle->type) {
3135 case LSA_HANDLE_POLICY_TYPE:
3136 case LSA_HANDLE_ACCOUNT_TYPE:
3137 case LSA_HANDLE_TRUST_TYPE:
3138 psd = handle->sd;
3139 sd_size = ndr_size_security_descriptor(psd, 0);
3140 status = NT_STATUS_OK;
3141 break;
3142 default:
3143 status = NT_STATUS_INVALID_HANDLE;
3144 break;
3147 if (!NT_STATUS_IS_OK(status)) {
3148 return status;
3151 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
3152 if (!*r->out.sdbuf) {
3153 return NT_STATUS_NO_MEMORY;
3156 return status;
3159 /***************************************************************************
3160 _lsa_AddAccountRights
3161 ***************************************************************************/
3163 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
3164 struct lsa_AddAccountRights *r)
3166 struct lsa_info *info = NULL;
3167 int i = 0;
3168 uint32_t acc_granted = 0;
3169 struct security_descriptor *psd = NULL;
3170 size_t sd_size;
3171 struct dom_sid sid;
3172 NTSTATUS status;
3174 /* find the connection policy handle. */
3175 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3176 return NT_STATUS_INVALID_HANDLE;
3178 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3179 return NT_STATUS_INVALID_HANDLE;
3182 /* get the generic lsa account SD for this SID until we store it */
3183 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3184 &lsa_account_mapping,
3185 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
3186 if (!NT_STATUS_IS_OK(status)) {
3187 return status;
3191 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3192 * on the policy handle. If it does, ask for
3193 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3194 * on the account sid. We don't check here so just use the latter. JRA.
3197 status = access_check_object(psd, p->session_info->security_token,
3198 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3199 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3200 &acc_granted, "_lsa_AddAccountRights" );
3201 if (!NT_STATUS_IS_OK(status)) {
3202 return status;
3205 /* according to an NT4 PDC, you can add privileges to SIDs even without
3206 call_lsa_create_account() first. And you can use any arbitrary SID. */
3208 sid_copy( &sid, r->in.sid );
3210 for ( i=0; i < r->in.rights->count; i++ ) {
3212 const char *privname = r->in.rights->names[i].string;
3214 /* only try to add non-null strings */
3216 if ( !privname )
3217 continue;
3219 if ( !grant_privilege_by_name( &sid, privname ) ) {
3220 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3221 privname ));
3222 return NT_STATUS_NO_SUCH_PRIVILEGE;
3226 return NT_STATUS_OK;
3229 /***************************************************************************
3230 _lsa_RemoveAccountRights
3231 ***************************************************************************/
3233 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
3234 struct lsa_RemoveAccountRights *r)
3236 struct lsa_info *info = NULL;
3237 int i = 0;
3238 struct security_descriptor *psd = NULL;
3239 size_t sd_size;
3240 struct dom_sid sid;
3241 const char *privname = NULL;
3242 uint32_t acc_granted = 0;
3243 NTSTATUS status;
3245 /* find the connection policy handle. */
3246 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3247 return NT_STATUS_INVALID_HANDLE;
3249 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3250 return NT_STATUS_INVALID_HANDLE;
3253 /* get the generic lsa account SD for this SID until we store it */
3254 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3255 &lsa_account_mapping,
3256 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
3257 if (!NT_STATUS_IS_OK(status)) {
3258 return status;
3262 * From the MS DOCs. We need
3263 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3264 * and DELETE on the account sid.
3267 status = access_check_object(psd, p->session_info->security_token,
3268 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3269 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3270 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
3271 &acc_granted, "_lsa_RemoveAccountRights");
3272 if (!NT_STATUS_IS_OK(status)) {
3273 return status;
3276 sid_copy( &sid, r->in.sid );
3278 if ( r->in.remove_all ) {
3279 if ( !revoke_all_privileges( &sid ) )
3280 return NT_STATUS_ACCESS_DENIED;
3282 return NT_STATUS_OK;
3285 for ( i=0; i < r->in.rights->count; i++ ) {
3287 privname = r->in.rights->names[i].string;
3289 /* only try to add non-null strings */
3291 if ( !privname )
3292 continue;
3294 if ( !revoke_privilege_by_name( &sid, privname ) ) {
3295 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3296 privname ));
3297 return NT_STATUS_NO_SUCH_PRIVILEGE;
3301 return NT_STATUS_OK;
3304 /*******************************************************************
3305 ********************************************************************/
3307 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3308 struct lsa_RightSet *r,
3309 PRIVILEGE_SET *privileges)
3311 uint32 i;
3312 const char *privname;
3313 const char **privname_array = NULL;
3314 int num_priv = 0;
3316 for (i=0; i<privileges->count; i++) {
3317 if (privileges->set[i].luid.high) {
3318 continue;
3320 privname = sec_privilege_name(privileges->set[i].luid.low);
3321 if (privname) {
3322 if (!add_string_to_array(mem_ctx, privname,
3323 &privname_array, &num_priv)) {
3324 return NT_STATUS_NO_MEMORY;
3329 if (num_priv) {
3331 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3332 num_priv);
3333 if (!r->names) {
3334 return NT_STATUS_NO_MEMORY;
3337 for (i=0; i<num_priv; i++) {
3338 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3341 r->count = num_priv;
3344 return NT_STATUS_OK;
3347 /***************************************************************************
3348 _lsa_EnumAccountRights
3349 ***************************************************************************/
3351 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3352 struct lsa_EnumAccountRights *r)
3354 NTSTATUS status;
3355 struct lsa_info *info = NULL;
3356 PRIVILEGE_SET *privileges;
3358 /* find the connection policy handle. */
3360 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3361 return NT_STATUS_INVALID_HANDLE;
3363 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3364 return NT_STATUS_INVALID_HANDLE;
3367 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3368 return NT_STATUS_ACCESS_DENIED;
3371 /* according to an NT4 PDC, you can add privileges to SIDs even without
3372 call_lsa_create_account() first. And you can use any arbitrary SID. */
3374 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3375 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3376 * the lsa database */
3378 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3379 if (!NT_STATUS_IS_OK(status)) {
3380 return status;
3383 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3384 sid_string_dbg(r->in.sid), privileges->count));
3386 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3388 return status;
3391 /***************************************************************************
3392 _lsa_LookupPrivValue
3393 ***************************************************************************/
3395 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3396 struct lsa_LookupPrivValue *r)
3398 struct lsa_info *info = NULL;
3399 const char *name = NULL;
3401 /* find the connection policy handle. */
3403 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3404 return NT_STATUS_INVALID_HANDLE;
3406 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3407 return NT_STATUS_INVALID_HANDLE;
3410 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3411 return NT_STATUS_ACCESS_DENIED;
3413 name = r->in.name->string;
3415 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3417 r->out.luid->low = sec_privilege_id(name);
3418 r->out.luid->high = 0;
3419 if (r->out.luid->low == SEC_PRIV_INVALID) {
3420 return NT_STATUS_NO_SUCH_PRIVILEGE;
3422 return NT_STATUS_OK;
3425 /***************************************************************************
3426 _lsa_EnumAccountsWithUserRight
3427 ***************************************************************************/
3429 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3430 struct lsa_EnumAccountsWithUserRight *r)
3432 NTSTATUS status;
3433 struct lsa_info *info = NULL;
3434 struct dom_sid *sids = NULL;
3435 int num_sids = 0;
3436 uint32_t i;
3437 enum sec_privilege privilege;
3439 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3440 return NT_STATUS_INVALID_HANDLE;
3443 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3444 return NT_STATUS_INVALID_HANDLE;
3447 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3448 return NT_STATUS_ACCESS_DENIED;
3451 if (!r->in.name || !r->in.name->string) {
3452 return NT_STATUS_NO_SUCH_PRIVILEGE;
3455 privilege = sec_privilege_id(r->in.name->string);
3456 if (privilege == SEC_PRIV_INVALID) {
3457 return NT_STATUS_NO_SUCH_PRIVILEGE;
3460 status = privilege_enum_sids(privilege, p->mem_ctx,
3461 &sids, &num_sids);
3462 if (!NT_STATUS_IS_OK(status)) {
3463 return status;
3466 r->out.sids->num_sids = num_sids;
3467 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3468 r->out.sids->num_sids);
3470 for (i=0; i < r->out.sids->num_sids; i++) {
3471 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3472 &sids[i]);
3473 if (!r->out.sids->sids[i].sid) {
3474 TALLOC_FREE(r->out.sids->sids);
3475 r->out.sids->num_sids = 0;
3476 return NT_STATUS_NO_MEMORY;
3480 return NT_STATUS_OK;
3483 /***************************************************************************
3484 _lsa_Delete
3485 ***************************************************************************/
3487 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3488 struct lsa_Delete *r)
3490 return NT_STATUS_NOT_SUPPORTED;
3494 * From here on the server routines are just dummy ones to make smbd link with
3495 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3496 * pulling the server stubs across one by one.
3499 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3501 p->rng_fault_state = True;
3502 return NT_STATUS_NOT_IMPLEMENTED;
3505 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3506 struct lsa_ChangePassword *r)
3508 p->rng_fault_state = True;
3509 return NT_STATUS_NOT_IMPLEMENTED;
3512 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3514 p->rng_fault_state = True;
3515 return NT_STATUS_NOT_IMPLEMENTED;
3518 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3520 p->rng_fault_state = True;
3521 return NT_STATUS_NOT_IMPLEMENTED;
3524 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3525 struct lsa_GetQuotasForAccount *r)
3527 p->rng_fault_state = True;
3528 return NT_STATUS_NOT_IMPLEMENTED;
3531 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3532 struct lsa_SetQuotasForAccount *r)
3534 p->rng_fault_state = True;
3535 return NT_STATUS_NOT_IMPLEMENTED;
3538 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3539 struct lsa_SetInformationTrustedDomain *r)
3541 p->rng_fault_state = True;
3542 return NT_STATUS_NOT_IMPLEMENTED;
3545 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3546 struct lsa_SetTrustedDomainInfo *r)
3548 p->rng_fault_state = True;
3549 return NT_STATUS_NOT_IMPLEMENTED;
3552 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3553 struct lsa_StorePrivateData *r)
3555 p->rng_fault_state = True;
3556 return NT_STATUS_NOT_IMPLEMENTED;
3559 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3560 struct lsa_RetrievePrivateData *r)
3562 p->rng_fault_state = True;
3563 return NT_STATUS_NOT_IMPLEMENTED;
3566 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3567 struct lsa_SetInfoPolicy2 *r)
3569 p->rng_fault_state = True;
3570 return NT_STATUS_NOT_IMPLEMENTED;
3573 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3574 struct lsa_SetTrustedDomainInfoByName *r)
3576 p->rng_fault_state = True;
3577 return NT_STATUS_NOT_IMPLEMENTED;
3580 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3581 struct lsa_EnumTrustedDomainsEx *r)
3583 struct lsa_info *info;
3584 uint32_t count;
3585 struct pdb_trusted_domain **domains;
3586 struct lsa_TrustDomainInfoInfoEx *entries;
3587 int i;
3588 NTSTATUS nt_status;
3590 /* bail out early if pdb backend is not capable of ex trusted domains,
3591 * if we dont do that, the client might not call
3592 * _lsa_EnumTrustedDomains() afterwards - gd */
3594 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3595 p->rng_fault_state = True;
3596 return NT_STATUS_NOT_IMPLEMENTED;
3599 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3600 return NT_STATUS_INVALID_HANDLE;
3602 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3603 return NT_STATUS_INVALID_HANDLE;
3606 /* check if the user has enough rights */
3607 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3608 return NT_STATUS_ACCESS_DENIED;
3610 become_root();
3611 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3612 unbecome_root();
3614 if (!NT_STATUS_IS_OK(nt_status)) {
3615 return nt_status;
3618 entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3619 count);
3620 if (!entries) {
3621 return NT_STATUS_NO_MEMORY;
3624 for (i=0; i<count; i++) {
3625 init_lsa_StringLarge(&entries[i].netbios_name,
3626 domains[i]->netbios_name);
3627 entries[i].sid = &domains[i]->security_identifier;
3630 if (*r->in.resume_handle >= count) {
3631 *r->out.resume_handle = -1;
3632 TALLOC_FREE(entries);
3633 return NT_STATUS_NO_MORE_ENTRIES;
3636 /* return the rest, limit by max_size. Note that we
3637 use the w2k3 element size value of 60 */
3638 r->out.domains->count = count - *r->in.resume_handle;
3639 r->out.domains->count = MIN(r->out.domains->count,
3640 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3642 r->out.domains->domains = entries + *r->in.resume_handle;
3644 if (r->out.domains->count < count - *r->in.resume_handle) {
3645 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3646 return STATUS_MORE_ENTRIES;
3649 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3650 * always be larger than the previous input resume handle, in
3651 * particular when hitting the last query it is vital to set the
3652 * resume handle correctly to avoid infinite client loops, as
3653 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3654 * status is NT_STATUS_OK - gd */
3656 *r->out.resume_handle = (uint32_t)-1;
3658 return NT_STATUS_OK;
3661 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3662 struct lsa_QueryDomainInformationPolicy *r)
3664 p->rng_fault_state = True;
3665 return NT_STATUS_NOT_IMPLEMENTED;
3668 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3669 struct lsa_SetDomainInformationPolicy *r)
3671 p->rng_fault_state = True;
3672 return NT_STATUS_NOT_IMPLEMENTED;
3675 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3677 p->rng_fault_state = True;
3678 return NT_STATUS_NOT_IMPLEMENTED;
3681 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3683 p->rng_fault_state = True;
3684 return NT_STATUS_NOT_IMPLEMENTED;
3687 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3689 p->rng_fault_state = True;
3690 return NT_STATUS_NOT_IMPLEMENTED;
3693 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3695 p->rng_fault_state = True;
3696 return NT_STATUS_NOT_IMPLEMENTED;
3699 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3700 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3702 p->rng_fault_state = True;
3703 return NT_STATUS_NOT_IMPLEMENTED;
3706 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3707 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3709 p->rng_fault_state = True;
3710 return NT_STATUS_NOT_IMPLEMENTED;
3713 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3715 p->rng_fault_state = True;
3716 return NT_STATUS_NOT_IMPLEMENTED;
3719 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3720 struct lsa_CREDRGETTARGETINFO *r)
3722 p->rng_fault_state = True;
3723 return NT_STATUS_NOT_IMPLEMENTED;
3726 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3727 struct lsa_CREDRPROFILELOADED *r)
3729 p->rng_fault_state = True;
3730 return NT_STATUS_NOT_IMPLEMENTED;
3733 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3734 struct lsa_CREDRGETSESSIONTYPES *r)
3736 p->rng_fault_state = True;
3737 return NT_STATUS_NOT_IMPLEMENTED;
3740 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3741 struct lsa_LSARREGISTERAUDITEVENT *r)
3743 p->rng_fault_state = True;
3744 return NT_STATUS_NOT_IMPLEMENTED;
3747 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3748 struct lsa_LSARGENAUDITEVENT *r)
3750 p->rng_fault_state = True;
3751 return NT_STATUS_NOT_IMPLEMENTED;
3754 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3755 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3757 p->rng_fault_state = True;
3758 return NT_STATUS_NOT_IMPLEMENTED;
3761 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3762 struct lsa_lsaRQueryForestTrustInformation *r)
3764 p->rng_fault_state = True;
3765 return NT_STATUS_NOT_IMPLEMENTED;
3768 #define DNS_CMP_MATCH 0
3769 #define DNS_CMP_FIRST_IS_CHILD 1
3770 #define DNS_CMP_SECOND_IS_CHILD 2
3771 #define DNS_CMP_NO_MATCH 3
3773 /* this function assumes names are well formed DNS names.
3774 * it doesn't validate them */
3775 static int dns_cmp(const char *s1, size_t l1,
3776 const char *s2, size_t l2)
3778 const char *p1, *p2;
3779 size_t t1, t2;
3780 int cret;
3782 if (l1 == l2) {
3783 if (strcasecmp_m(s1, s2) == 0) {
3784 return DNS_CMP_MATCH;
3786 return DNS_CMP_NO_MATCH;
3789 if (l1 > l2) {
3790 p1 = s1;
3791 p2 = s2;
3792 t1 = l1;
3793 t2 = l2;
3794 cret = DNS_CMP_FIRST_IS_CHILD;
3795 } else {
3796 p1 = s2;
3797 p2 = s1;
3798 t1 = l2;
3799 t2 = l1;
3800 cret = DNS_CMP_SECOND_IS_CHILD;
3803 if (p1[t1 - t2 - 1] != '.') {
3804 return DNS_CMP_NO_MATCH;
3807 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
3808 return cret;
3811 return DNS_CMP_NO_MATCH;
3814 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3815 struct lsa_ForestTrustInformation *lfti,
3816 struct ForestTrustInfo *fti)
3818 struct lsa_ForestTrustRecord *lrec;
3819 struct ForestTrustInfoRecord *rec;
3820 struct lsa_StringLarge *tln;
3821 struct lsa_ForestTrustDomainInfo *info;
3822 uint32_t i;
3824 fti->version = 1;
3825 fti->count = lfti->count;
3826 fti->records = talloc_array(mem_ctx,
3827 struct ForestTrustInfoRecordArmor,
3828 fti->count);
3829 if (!fti->records) {
3830 return NT_STATUS_NO_MEMORY;
3832 for (i = 0; i < fti->count; i++) {
3833 lrec = lfti->entries[i];
3834 rec = &fti->records[i].record;
3836 rec->flags = lrec->flags;
3837 rec->timestamp = lrec->time;
3838 rec->type = lrec->type;
3840 switch (lrec->type) {
3841 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3842 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3843 tln = &lrec->forest_trust_data.top_level_name;
3844 rec->data.name.string =
3845 talloc_strdup(mem_ctx, tln->string);
3846 if (!rec->data.name.string) {
3847 return NT_STATUS_NO_MEMORY;
3849 rec->data.name.size = strlen(rec->data.name.string);
3850 break;
3851 case LSA_FOREST_TRUST_DOMAIN_INFO:
3852 info = &lrec->forest_trust_data.domain_info;
3853 rec->data.info.sid = *info->domain_sid;
3854 rec->data.info.dns_name.string =
3855 talloc_strdup(mem_ctx,
3856 info->dns_domain_name.string);
3857 if (!rec->data.info.dns_name.string) {
3858 return NT_STATUS_NO_MEMORY;
3860 rec->data.info.dns_name.size =
3861 strlen(rec->data.info.dns_name.string);
3862 rec->data.info.netbios_name.string =
3863 talloc_strdup(mem_ctx,
3864 info->netbios_domain_name.string);
3865 if (!rec->data.info.netbios_name.string) {
3866 return NT_STATUS_NO_MEMORY;
3868 rec->data.info.netbios_name.size =
3869 strlen(rec->data.info.netbios_name.string);
3870 break;
3871 default:
3872 return NT_STATUS_INVALID_DOMAIN_STATE;
3876 return NT_STATUS_OK;
3879 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3880 uint32_t index, uint32_t collision_type,
3881 uint32_t conflict_type, const char *tdo_name);
3883 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
3884 const char *tdo_name,
3885 struct ForestTrustInfo *tdo_fti,
3886 struct ForestTrustInfo *new_fti,
3887 struct lsa_ForestTrustCollisionInfo *c_info)
3889 struct ForestTrustInfoRecord *nrec;
3890 struct ForestTrustInfoRecord *trec;
3891 const char *dns_name;
3892 const char *nb_name = NULL;
3893 struct dom_sid *sid = NULL;
3894 const char *tname = NULL;
3895 size_t dns_len = 0;
3896 size_t nb_len;
3897 size_t tlen = 0;
3898 NTSTATUS nt_status;
3899 uint32_t new_fti_idx;
3900 uint32_t i;
3901 /* use always TDO type, until we understand when Xref can be used */
3902 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
3903 bool tln_conflict;
3904 bool sid_conflict;
3905 bool nb_conflict;
3906 bool exclusion;
3907 bool ex_rule = false;
3908 int ret;
3910 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
3912 nrec = &new_fti->records[new_fti_idx].record;
3913 dns_name = NULL;
3914 tln_conflict = false;
3915 sid_conflict = false;
3916 nb_conflict = false;
3917 exclusion = false;
3919 switch (nrec->type) {
3920 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3921 /* exclusions do not conflict by definition */
3922 break;
3924 case FOREST_TRUST_TOP_LEVEL_NAME:
3925 dns_name = nrec->data.name.string;
3926 dns_len = nrec->data.name.size;
3927 break;
3929 case LSA_FOREST_TRUST_DOMAIN_INFO:
3930 dns_name = nrec->data.info.dns_name.string;
3931 dns_len = nrec->data.info.dns_name.size;
3932 nb_name = nrec->data.info.netbios_name.string;
3933 nb_len = nrec->data.info.netbios_name.size;
3934 sid = &nrec->data.info.sid;
3935 break;
3938 if (!dns_name) continue;
3940 /* check if this is already taken and not excluded */
3941 for (i = 0; i < tdo_fti->count; i++) {
3942 trec = &tdo_fti->records[i].record;
3944 switch (trec->type) {
3945 case FOREST_TRUST_TOP_LEVEL_NAME:
3946 ex_rule = false;
3947 tname = trec->data.name.string;
3948 tlen = trec->data.name.size;
3949 break;
3950 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
3951 ex_rule = true;
3952 tname = trec->data.name.string;
3953 tlen = trec->data.name.size;
3954 break;
3955 case FOREST_TRUST_DOMAIN_INFO:
3956 ex_rule = false;
3957 tname = trec->data.info.dns_name.string;
3958 tlen = trec->data.info.dns_name.size;
3959 break;
3960 default:
3961 return NT_STATUS_INVALID_PARAMETER;
3963 ret = dns_cmp(dns_name, dns_len, tname, tlen);
3964 switch (ret) {
3965 case DNS_CMP_MATCH:
3966 /* if it matches exclusion,
3967 * it doesn't conflict */
3968 if (ex_rule) {
3969 exclusion = true;
3970 break;
3972 /* fall through */
3973 case DNS_CMP_FIRST_IS_CHILD:
3974 case DNS_CMP_SECOND_IS_CHILD:
3975 tln_conflict = true;
3976 /* fall through */
3977 default:
3978 break;
3981 /* explicit exclusion, no dns name conflict here */
3982 if (exclusion) {
3983 tln_conflict = false;
3986 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
3987 continue;
3990 /* also test for domain info */
3991 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
3992 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
3993 sid_conflict = true;
3995 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
3996 strcasecmp_m(trec->data.info.netbios_name.string,
3997 nb_name) == 0) {
3998 nb_conflict = true;
4002 if (tln_conflict) {
4003 nt_status = add_collision(c_info, new_fti_idx,
4004 collision_type,
4005 LSA_TLN_DISABLED_CONFLICT,
4006 tdo_name);
4008 if (sid_conflict) {
4009 nt_status = add_collision(c_info, new_fti_idx,
4010 collision_type,
4011 LSA_SID_DISABLED_CONFLICT,
4012 tdo_name);
4014 if (nb_conflict) {
4015 nt_status = add_collision(c_info, new_fti_idx,
4016 collision_type,
4017 LSA_NB_DISABLED_CONFLICT,
4018 tdo_name);
4022 return NT_STATUS_OK;
4025 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4026 uint32_t idx, uint32_t collision_type,
4027 uint32_t conflict_type, const char *tdo_name)
4029 struct lsa_ForestTrustCollisionRecord **es;
4030 uint32_t i = c_info->count;
4032 es = talloc_realloc(c_info, c_info->entries,
4033 struct lsa_ForestTrustCollisionRecord *, i + 1);
4034 if (!es) {
4035 return NT_STATUS_NO_MEMORY;
4037 c_info->entries = es;
4038 c_info->count = i + 1;
4040 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4041 if (!es[i]) {
4042 return NT_STATUS_NO_MEMORY;
4045 es[i]->index = idx;
4046 es[i]->type = collision_type;
4047 es[i]->flags.flags = conflict_type;
4048 es[i]->name.string = talloc_strdup(es[i], tdo_name);
4049 if (!es[i]->name.string) {
4050 return NT_STATUS_NO_MEMORY;
4052 es[i]->name.size = strlen(es[i]->name.string);
4054 return NT_STATUS_OK;
4057 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
4058 struct pdb_trusted_domain *td,
4059 struct ForestTrustInfo *info)
4061 enum ndr_err_code ndr_err;
4063 if (td->trust_forest_trust_info.length == 0 ||
4064 td->trust_forest_trust_info.data == NULL) {
4065 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4067 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
4068 info,
4069 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
4070 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4071 return NT_STATUS_INVALID_DOMAIN_STATE;
4074 return NT_STATUS_OK;
4077 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
4078 struct ForestTrustInfo *fti)
4080 struct ForestTrustDataDomainInfo *info;
4081 struct ForestTrustInfoRecord *rec;
4083 fti->version = 1;
4084 fti->count = 2;
4085 fti->records = talloc_array(fti,
4086 struct ForestTrustInfoRecordArmor, 2);
4087 if (!fti->records) {
4088 return NT_STATUS_NO_MEMORY;
4091 /* TLN info */
4092 rec = &fti->records[0].record;
4094 rec->flags = 0;
4095 rec->timestamp = 0;
4096 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
4098 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
4099 if (!rec->data.name.string) {
4100 return NT_STATUS_NO_MEMORY;
4102 rec->data.name.size = strlen(rec->data.name.string);
4104 /* DOMAIN info */
4105 rec = &fti->records[1].record;
4107 rec->flags = 0;
4108 rec->timestamp = 0;
4109 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
4111 info = &rec->data.info;
4113 info->sid = dom_info->sid;
4114 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
4115 if (!info->dns_name.string) {
4116 return NT_STATUS_NO_MEMORY;
4118 info->dns_name.size = strlen(info->dns_name.string);
4119 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
4120 if (!info->netbios_name.string) {
4121 return NT_STATUS_NO_MEMORY;
4123 info->netbios_name.size = strlen(info->netbios_name.string);
4125 return NT_STATUS_OK;
4128 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
4129 struct lsa_lsaRSetForestTrustInformation *r)
4131 NTSTATUS status;
4132 int i;
4133 int j;
4134 struct lsa_info *handle;
4135 uint32_t num_domains;
4136 struct pdb_trusted_domain **domains;
4137 struct ForestTrustInfo *nfti;
4138 struct ForestTrustInfo *fti;
4139 struct lsa_ForestTrustCollisionInfo *c_info;
4140 struct pdb_domain_info *dom_info;
4141 enum ndr_err_code ndr_err;
4143 if (!IS_DC) {
4144 return NT_STATUS_NOT_SUPPORTED;
4147 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
4148 return NT_STATUS_INVALID_HANDLE;
4151 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
4152 return NT_STATUS_INVALID_HANDLE;
4155 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
4156 return NT_STATUS_ACCESS_DENIED;
4159 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
4160 if (!NT_STATUS_IS_OK(status)) {
4161 return status;
4163 if (num_domains == 0) {
4164 return NT_STATUS_NO_SUCH_DOMAIN;
4167 for (i = 0; i < num_domains; i++) {
4168 if (domains[i]->domain_name == NULL) {
4169 return NT_STATUS_INVALID_DOMAIN_STATE;
4171 if (strcasecmp_m(domains[i]->domain_name,
4172 r->in.trusted_domain_name->string) == 0) {
4173 break;
4176 if (i >= num_domains) {
4177 return NT_STATUS_NO_SUCH_DOMAIN;
4180 if (!(domains[i]->trust_attributes &
4181 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4182 return NT_STATUS_INVALID_PARAMETER;
4185 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4186 return NT_STATUS_INVALID_PARAMETER;
4189 /* The following section until COPY_END is a copy from
4190 * source4/rpmc_server/lsa/scesrc_lsa.c */
4191 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
4192 if (!nfti) {
4193 return NT_STATUS_NO_MEMORY;
4196 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4197 if (!NT_STATUS_IS_OK(status)) {
4198 return status;
4201 c_info = talloc_zero(r->out.collision_info,
4202 struct lsa_ForestTrustCollisionInfo);
4203 if (!c_info) {
4204 return NT_STATUS_NO_MEMORY;
4207 /* first check own info, then other domains */
4208 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4209 if (!fti) {
4210 return NT_STATUS_NO_MEMORY;
4213 dom_info = pdb_get_domain_info(p->mem_ctx);
4215 status = own_ft_info(dom_info, fti);
4216 if (!NT_STATUS_IS_OK(status)) {
4217 return status;
4220 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
4221 if (!NT_STATUS_IS_OK(status)) {
4222 return status;
4225 for (j = 0; j < num_domains; j++) {
4226 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4227 if (!fti) {
4228 return NT_STATUS_NO_MEMORY;
4231 status = get_ft_info(p->mem_ctx, domains[j], fti);
4232 if (!NT_STATUS_IS_OK(status)) {
4233 if (NT_STATUS_EQUAL(status,
4234 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4235 continue;
4237 return status;
4240 if (domains[j]->domain_name == NULL) {
4241 return NT_STATUS_INVALID_DOMAIN_STATE;
4244 status = check_ft_info(c_info, domains[j]->domain_name,
4245 fti, nfti, c_info);
4246 if (!NT_STATUS_IS_OK(status)) {
4247 return status;
4251 *r->out.collision_info = c_info;
4253 if (r->in.check_only != 0) {
4254 return NT_STATUS_OK;
4257 /* COPY_END */
4259 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
4260 p->mem_ctx, nfti,
4261 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4262 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4263 return NT_STATUS_INVALID_PARAMETER;
4266 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
4267 if (!NT_STATUS_IS_OK(status)) {
4268 return status;
4271 return NT_STATUS_OK;
4274 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
4275 struct lsa_CREDRRENAME *r)
4277 p->rng_fault_state = True;
4278 return NT_STATUS_NOT_IMPLEMENTED;
4281 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
4282 struct lsa_LSAROPENPOLICYSCE *r)
4284 p->rng_fault_state = True;
4285 return NT_STATUS_NOT_IMPLEMENTED;
4288 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4289 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4291 p->rng_fault_state = True;
4292 return NT_STATUS_NOT_IMPLEMENTED;
4295 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4296 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4298 p->rng_fault_state = True;
4299 return NT_STATUS_NOT_IMPLEMENTED;
4302 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4303 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4305 p->rng_fault_state = True;
4306 return NT_STATUS_NOT_IMPLEMENTED;