s3-lsa: implement _lsa_QuerySecret().
[Samba/gebeck_regimport.git] / source3 / rpc_server / lsa / srv_lsa_nt.c
blob32ea8526298bad5abd5baa5018f05576d0b7ff30
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 default:
2481 return NT_STATUS_INVALID_HANDLE;
2484 close_policy_hnd(p, r->in.handle);
2485 ZERO_STRUCTP(r->out.handle);
2487 return status;
2490 /***************************************************************************
2491 _lsa_EnumPrivs
2492 ***************************************************************************/
2494 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2495 struct lsa_EnumPrivs *r)
2497 struct lsa_info *handle;
2498 uint32 i;
2499 uint32 enum_context = *r->in.resume_handle;
2500 int num_privs = num_privileges_in_short_list();
2501 struct lsa_PrivEntry *entries = NULL;
2503 /* remember that the enum_context starts at 0 and not 1 */
2505 if ( enum_context >= num_privs )
2506 return NT_STATUS_NO_MORE_ENTRIES;
2508 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2509 enum_context, num_privs));
2511 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2512 return NT_STATUS_INVALID_HANDLE;
2514 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2515 return NT_STATUS_INVALID_HANDLE;
2518 /* check if the user has enough rights
2519 I don't know if it's the right one. not documented. */
2521 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2522 return NT_STATUS_ACCESS_DENIED;
2524 if (num_privs) {
2525 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2526 if (!entries) {
2527 return NT_STATUS_NO_MEMORY;
2529 } else {
2530 entries = NULL;
2533 for (i = 0; i < num_privs; i++) {
2534 if( i < enum_context) {
2536 init_lsa_StringLarge(&entries[i].name, NULL);
2538 entries[i].luid.low = 0;
2539 entries[i].luid.high = 0;
2540 } else {
2542 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2544 entries[i].luid.low = sec_privilege_from_index(i);
2545 entries[i].luid.high = 0;
2549 enum_context = num_privs;
2551 *r->out.resume_handle = enum_context;
2552 r->out.privs->count = num_privs;
2553 r->out.privs->privs = entries;
2555 return NT_STATUS_OK;
2558 /***************************************************************************
2559 _lsa_LookupPrivDisplayName
2560 ***************************************************************************/
2562 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2563 struct lsa_LookupPrivDisplayName *r)
2565 struct lsa_info *handle;
2566 const char *description;
2567 struct lsa_StringLarge *lsa_name;
2569 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2570 return NT_STATUS_INVALID_HANDLE;
2572 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2573 return NT_STATUS_INVALID_HANDLE;
2576 /* check if the user has enough rights */
2579 * I don't know if it's the right one. not documented.
2581 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2582 return NT_STATUS_ACCESS_DENIED;
2584 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2586 description = get_privilege_dispname(r->in.name->string);
2587 if (!description) {
2588 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2589 return NT_STATUS_NO_SUCH_PRIVILEGE;
2592 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2594 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2595 if (!lsa_name) {
2596 return NT_STATUS_NO_MEMORY;
2599 init_lsa_StringLarge(lsa_name, description);
2601 *r->out.returned_language_id = r->in.language_id;
2602 *r->out.disp_name = lsa_name;
2604 return NT_STATUS_OK;
2607 /***************************************************************************
2608 _lsa_EnumAccounts
2609 ***************************************************************************/
2611 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2612 struct lsa_EnumAccounts *r)
2614 struct lsa_info *handle;
2615 struct dom_sid *sid_list;
2616 int i, j, num_entries;
2617 NTSTATUS status;
2618 struct lsa_SidPtr *sids = NULL;
2620 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2621 return NT_STATUS_INVALID_HANDLE;
2623 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2624 return NT_STATUS_INVALID_HANDLE;
2627 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2628 return NT_STATUS_ACCESS_DENIED;
2630 sid_list = NULL;
2631 num_entries = 0;
2633 /* The only way we can currently find out all the SIDs that have been
2634 privileged is to scan all privileges */
2636 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2637 if (!NT_STATUS_IS_OK(status)) {
2638 return status;
2641 if (*r->in.resume_handle >= num_entries) {
2642 return NT_STATUS_NO_MORE_ENTRIES;
2645 if (num_entries - *r->in.resume_handle) {
2646 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2647 num_entries - *r->in.resume_handle);
2648 if (!sids) {
2649 talloc_free(sid_list);
2650 return NT_STATUS_NO_MEMORY;
2653 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2654 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2655 if (!sids[j].sid) {
2656 talloc_free(sid_list);
2657 return NT_STATUS_NO_MEMORY;
2662 talloc_free(sid_list);
2664 *r->out.resume_handle = num_entries;
2665 r->out.sids->num_sids = num_entries;
2666 r->out.sids->sids = sids;
2668 return NT_STATUS_OK;
2671 /***************************************************************************
2672 _lsa_GetUserName
2673 ***************************************************************************/
2675 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2676 struct lsa_GetUserName *r)
2678 const char *username, *domname;
2679 struct lsa_String *account_name = NULL;
2680 struct lsa_String *authority_name = NULL;
2682 if (r->in.account_name &&
2683 *r->in.account_name) {
2684 return NT_STATUS_INVALID_PARAMETER;
2687 if (r->in.authority_name &&
2688 *r->in.authority_name) {
2689 return NT_STATUS_INVALID_PARAMETER;
2692 if (security_session_user_level(p->session_info, NULL) < SECURITY_USER) {
2694 * I'm 99% sure this is not the right place to do this,
2695 * global_sid_Anonymous should probably be put into the token
2696 * instead of the guest id -- vl
2698 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2699 &domname, &username, NULL)) {
2700 return NT_STATUS_NO_MEMORY;
2702 } else {
2703 username = p->session_info->unix_info->sanitized_username;
2704 domname = p->session_info->info->domain_name;
2707 account_name = talloc(p->mem_ctx, struct lsa_String);
2708 if (!account_name) {
2709 return NT_STATUS_NO_MEMORY;
2711 init_lsa_String(account_name, username);
2713 if (r->out.authority_name) {
2714 authority_name = talloc(p->mem_ctx, struct lsa_String);
2715 if (!authority_name) {
2716 return NT_STATUS_NO_MEMORY;
2718 init_lsa_String(authority_name, domname);
2721 *r->out.account_name = account_name;
2722 if (r->out.authority_name) {
2723 *r->out.authority_name = authority_name;
2726 return NT_STATUS_OK;
2729 /***************************************************************************
2730 _lsa_CreateAccount
2731 ***************************************************************************/
2733 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2734 struct lsa_CreateAccount *r)
2736 NTSTATUS status;
2737 struct lsa_info *handle;
2738 uint32_t acc_granted;
2739 struct security_descriptor *psd;
2740 size_t sd_size;
2742 /* find the connection policy handle. */
2743 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2744 return NT_STATUS_INVALID_HANDLE;
2746 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2747 return NT_STATUS_INVALID_HANDLE;
2750 /* check if the user has enough rights */
2752 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2753 return NT_STATUS_ACCESS_DENIED;
2756 /* Work out max allowed. */
2757 map_max_allowed_access(p->session_info->security_token,
2758 p->session_info->unix_token,
2759 &r->in.access_mask);
2761 /* map the generic bits to the lsa policy ones */
2762 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2764 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2765 &lsa_account_mapping,
2766 r->in.sid, LSA_POLICY_ALL_ACCESS);
2767 if (!NT_STATUS_IS_OK(status)) {
2768 return status;
2771 status = access_check_object(psd, p->session_info->security_token,
2772 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2773 &acc_granted, "_lsa_CreateAccount");
2774 if (!NT_STATUS_IS_OK(status)) {
2775 return status;
2778 if ( is_privileged_sid( r->in.sid ) )
2779 return NT_STATUS_OBJECT_NAME_COLLISION;
2781 status = create_lsa_policy_handle(p->mem_ctx, p,
2782 LSA_HANDLE_ACCOUNT_TYPE,
2783 acc_granted,
2784 r->in.sid,
2785 NULL,
2786 psd,
2787 r->out.acct_handle);
2788 if (!NT_STATUS_IS_OK(status)) {
2789 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2792 return privilege_create_account(r->in.sid);
2795 /***************************************************************************
2796 _lsa_OpenAccount
2797 ***************************************************************************/
2799 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2800 struct lsa_OpenAccount *r)
2802 struct lsa_info *handle;
2803 struct security_descriptor *psd = NULL;
2804 size_t sd_size;
2805 uint32_t des_access = r->in.access_mask;
2806 uint32_t acc_granted;
2807 NTSTATUS status;
2809 /* find the connection policy handle. */
2810 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2811 return NT_STATUS_INVALID_HANDLE;
2813 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2814 return NT_STATUS_INVALID_HANDLE;
2817 /* des_access is for the account here, not the policy
2818 * handle - so don't check against policy handle. */
2820 /* Work out max allowed. */
2821 map_max_allowed_access(p->session_info->security_token,
2822 p->session_info->unix_token,
2823 &des_access);
2825 /* map the generic bits to the lsa account ones */
2826 se_map_generic(&des_access, &lsa_account_mapping);
2828 /* get the generic lsa account SD until we store it */
2829 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2830 &lsa_account_mapping,
2831 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2832 if (!NT_STATUS_IS_OK(status)) {
2833 return status;
2836 status = access_check_object(psd, p->session_info->security_token,
2837 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2838 &acc_granted, "_lsa_OpenAccount" );
2839 if (!NT_STATUS_IS_OK(status)) {
2840 return status;
2843 /* TODO: Fis the parsing routine before reenabling this check! */
2844 #if 0
2845 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2846 return NT_STATUS_ACCESS_DENIED;
2847 #endif
2849 status = create_lsa_policy_handle(p->mem_ctx, p,
2850 LSA_HANDLE_ACCOUNT_TYPE,
2851 acc_granted,
2852 r->in.sid,
2853 NULL,
2854 psd,
2855 r->out.acct_handle);
2856 if (!NT_STATUS_IS_OK(status)) {
2857 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2860 return NT_STATUS_OK;
2863 /***************************************************************************
2864 _lsa_EnumPrivsAccount
2865 For a given SID, enumerate all the privilege this account has.
2866 ***************************************************************************/
2868 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2869 struct lsa_EnumPrivsAccount *r)
2871 NTSTATUS status = NT_STATUS_OK;
2872 struct lsa_info *info=NULL;
2873 PRIVILEGE_SET *privileges;
2874 struct lsa_PrivilegeSet *priv_set = NULL;
2876 /* find the connection policy handle. */
2877 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2878 return NT_STATUS_INVALID_HANDLE;
2880 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2881 return NT_STATUS_INVALID_HANDLE;
2884 if (!(info->access & LSA_ACCOUNT_VIEW))
2885 return NT_STATUS_ACCESS_DENIED;
2887 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2888 if (!NT_STATUS_IS_OK(status)) {
2889 return status;
2892 *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2893 if (!priv_set) {
2894 return NT_STATUS_NO_MEMORY;
2897 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2898 sid_string_dbg(&info->sid),
2899 privileges->count));
2901 priv_set->count = privileges->count;
2902 priv_set->unknown = 0;
2903 priv_set->set = talloc_move(priv_set, &privileges->set);
2905 return status;
2908 /***************************************************************************
2909 _lsa_GetSystemAccessAccount
2910 ***************************************************************************/
2912 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2913 struct lsa_GetSystemAccessAccount *r)
2915 NTSTATUS status;
2916 struct lsa_info *info = NULL;
2917 struct lsa_EnumPrivsAccount e;
2918 struct lsa_PrivilegeSet *privset;
2920 /* find the connection policy handle. */
2922 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2923 return NT_STATUS_INVALID_HANDLE;
2925 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2926 return NT_STATUS_INVALID_HANDLE;
2929 if (!(info->access & LSA_ACCOUNT_VIEW))
2930 return NT_STATUS_ACCESS_DENIED;
2932 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2933 if (!privset) {
2934 return NT_STATUS_NO_MEMORY;
2937 e.in.handle = r->in.handle;
2938 e.out.privs = &privset;
2940 status = _lsa_EnumPrivsAccount(p, &e);
2941 if (!NT_STATUS_IS_OK(status)) {
2942 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2943 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2944 nt_errstr(status)));
2945 return status;
2948 /* Samba4 would iterate over the privset to merge the policy mode bits,
2949 * not sure samba3 can do the same here, so just return what we did in
2950 * the past - gd */
2953 0x01 -> Log on locally
2954 0x02 -> Access this computer from network
2955 0x04 -> Log on as a batch job
2956 0x10 -> Log on as a service
2958 they can be ORed together
2961 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2962 LSA_POLICY_MODE_NETWORK;
2964 return NT_STATUS_OK;
2967 /***************************************************************************
2968 update the systemaccount information
2969 ***************************************************************************/
2971 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2972 struct lsa_SetSystemAccessAccount *r)
2974 struct lsa_info *info=NULL;
2975 GROUP_MAP map;
2977 /* find the connection policy handle. */
2978 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2979 return NT_STATUS_INVALID_HANDLE;
2981 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2982 return NT_STATUS_INVALID_HANDLE;
2985 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2986 return NT_STATUS_ACCESS_DENIED;
2989 if (!pdb_getgrsid(&map, info->sid))
2990 return NT_STATUS_NO_SUCH_GROUP;
2992 return pdb_update_group_mapping_entry(&map);
2995 /***************************************************************************
2996 _lsa_AddPrivilegesToAccount
2997 For a given SID, add some privileges.
2998 ***************************************************************************/
3000 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
3001 struct lsa_AddPrivilegesToAccount *r)
3003 struct lsa_info *info = NULL;
3004 struct lsa_PrivilegeSet *set = NULL;
3006 /* find the connection policy handle. */
3007 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3008 return NT_STATUS_INVALID_HANDLE;
3010 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3011 return NT_STATUS_INVALID_HANDLE;
3014 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3015 return NT_STATUS_ACCESS_DENIED;
3018 set = r->in.privs;
3020 if ( !grant_privilege_set( &info->sid, set ) ) {
3021 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
3022 sid_string_dbg(&info->sid) ));
3023 return NT_STATUS_NO_SUCH_PRIVILEGE;
3026 return NT_STATUS_OK;
3029 /***************************************************************************
3030 _lsa_RemovePrivilegesFromAccount
3031 For a given SID, remove some privileges.
3032 ***************************************************************************/
3034 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
3035 struct lsa_RemovePrivilegesFromAccount *r)
3037 struct lsa_info *info = NULL;
3038 struct lsa_PrivilegeSet *set = NULL;
3040 /* find the connection policy handle. */
3041 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3042 return NT_STATUS_INVALID_HANDLE;
3044 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
3045 return NT_STATUS_INVALID_HANDLE;
3048 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3049 return NT_STATUS_ACCESS_DENIED;
3052 set = r->in.privs;
3054 if ( !revoke_privilege_set( &info->sid, set) ) {
3055 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
3056 sid_string_dbg(&info->sid) ));
3057 return NT_STATUS_NO_SUCH_PRIVILEGE;
3060 return NT_STATUS_OK;
3063 /***************************************************************************
3064 _lsa_LookupPrivName
3065 ***************************************************************************/
3067 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
3068 struct lsa_LookupPrivName *r)
3070 struct lsa_info *info = NULL;
3071 const char *name;
3072 struct lsa_StringLarge *lsa_name;
3074 /* find the connection policy handle. */
3075 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3076 return NT_STATUS_INVALID_HANDLE;
3079 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3080 return NT_STATUS_INVALID_HANDLE;
3083 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
3084 return NT_STATUS_ACCESS_DENIED;
3087 if (r->in.luid->high != 0) {
3088 return NT_STATUS_NO_SUCH_PRIVILEGE;
3091 name = sec_privilege_name(r->in.luid->low);
3092 if (!name) {
3093 return NT_STATUS_NO_SUCH_PRIVILEGE;
3096 lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
3097 if (!lsa_name) {
3098 return NT_STATUS_NO_MEMORY;
3101 lsa_name->string = talloc_strdup(lsa_name, name);
3102 if (!lsa_name->string) {
3103 TALLOC_FREE(lsa_name);
3104 return NT_STATUS_NO_MEMORY;
3107 *r->out.name = lsa_name;
3109 return NT_STATUS_OK;
3112 /***************************************************************************
3113 _lsa_QuerySecurity
3114 ***************************************************************************/
3116 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
3117 struct lsa_QuerySecurity *r)
3119 struct lsa_info *handle=NULL;
3120 struct security_descriptor *psd = NULL;
3121 size_t sd_size = 0;
3122 NTSTATUS status;
3124 /* find the connection policy handle. */
3125 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
3126 return NT_STATUS_INVALID_HANDLE;
3128 switch (handle->type) {
3129 case LSA_HANDLE_POLICY_TYPE:
3130 case LSA_HANDLE_ACCOUNT_TYPE:
3131 case LSA_HANDLE_TRUST_TYPE:
3132 psd = handle->sd;
3133 sd_size = ndr_size_security_descriptor(psd, 0);
3134 status = NT_STATUS_OK;
3135 break;
3136 default:
3137 status = NT_STATUS_INVALID_HANDLE;
3138 break;
3141 if (!NT_STATUS_IS_OK(status)) {
3142 return status;
3145 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
3146 if (!*r->out.sdbuf) {
3147 return NT_STATUS_NO_MEMORY;
3150 return status;
3153 /***************************************************************************
3154 _lsa_AddAccountRights
3155 ***************************************************************************/
3157 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
3158 struct lsa_AddAccountRights *r)
3160 struct lsa_info *info = NULL;
3161 int i = 0;
3162 uint32_t acc_granted = 0;
3163 struct security_descriptor *psd = NULL;
3164 size_t sd_size;
3165 struct dom_sid sid;
3166 NTSTATUS status;
3168 /* find the connection policy handle. */
3169 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3170 return NT_STATUS_INVALID_HANDLE;
3172 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3173 return NT_STATUS_INVALID_HANDLE;
3176 /* get the generic lsa account SD for this SID until we store it */
3177 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3178 &lsa_account_mapping,
3179 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
3180 if (!NT_STATUS_IS_OK(status)) {
3181 return status;
3185 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3186 * on the policy handle. If it does, ask for
3187 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3188 * on the account sid. We don't check here so just use the latter. JRA.
3191 status = access_check_object(psd, p->session_info->security_token,
3192 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3193 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3194 &acc_granted, "_lsa_AddAccountRights" );
3195 if (!NT_STATUS_IS_OK(status)) {
3196 return status;
3199 /* according to an NT4 PDC, you can add privileges to SIDs even without
3200 call_lsa_create_account() first. And you can use any arbitrary SID. */
3202 sid_copy( &sid, r->in.sid );
3204 for ( i=0; i < r->in.rights->count; i++ ) {
3206 const char *privname = r->in.rights->names[i].string;
3208 /* only try to add non-null strings */
3210 if ( !privname )
3211 continue;
3213 if ( !grant_privilege_by_name( &sid, privname ) ) {
3214 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3215 privname ));
3216 return NT_STATUS_NO_SUCH_PRIVILEGE;
3220 return NT_STATUS_OK;
3223 /***************************************************************************
3224 _lsa_RemoveAccountRights
3225 ***************************************************************************/
3227 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
3228 struct lsa_RemoveAccountRights *r)
3230 struct lsa_info *info = NULL;
3231 int i = 0;
3232 struct security_descriptor *psd = NULL;
3233 size_t sd_size;
3234 struct dom_sid sid;
3235 const char *privname = NULL;
3236 uint32_t acc_granted = 0;
3237 NTSTATUS status;
3239 /* find the connection policy handle. */
3240 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3241 return NT_STATUS_INVALID_HANDLE;
3243 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3244 return NT_STATUS_INVALID_HANDLE;
3247 /* get the generic lsa account SD for this SID until we store it */
3248 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3249 &lsa_account_mapping,
3250 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
3251 if (!NT_STATUS_IS_OK(status)) {
3252 return status;
3256 * From the MS DOCs. We need
3257 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3258 * and DELETE on the account sid.
3261 status = access_check_object(psd, p->session_info->security_token,
3262 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3263 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3264 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
3265 &acc_granted, "_lsa_RemoveAccountRights");
3266 if (!NT_STATUS_IS_OK(status)) {
3267 return status;
3270 sid_copy( &sid, r->in.sid );
3272 if ( r->in.remove_all ) {
3273 if ( !revoke_all_privileges( &sid ) )
3274 return NT_STATUS_ACCESS_DENIED;
3276 return NT_STATUS_OK;
3279 for ( i=0; i < r->in.rights->count; i++ ) {
3281 privname = r->in.rights->names[i].string;
3283 /* only try to add non-null strings */
3285 if ( !privname )
3286 continue;
3288 if ( !revoke_privilege_by_name( &sid, privname ) ) {
3289 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3290 privname ));
3291 return NT_STATUS_NO_SUCH_PRIVILEGE;
3295 return NT_STATUS_OK;
3298 /*******************************************************************
3299 ********************************************************************/
3301 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3302 struct lsa_RightSet *r,
3303 PRIVILEGE_SET *privileges)
3305 uint32 i;
3306 const char *privname;
3307 const char **privname_array = NULL;
3308 int num_priv = 0;
3310 for (i=0; i<privileges->count; i++) {
3311 if (privileges->set[i].luid.high) {
3312 continue;
3314 privname = sec_privilege_name(privileges->set[i].luid.low);
3315 if (privname) {
3316 if (!add_string_to_array(mem_ctx, privname,
3317 &privname_array, &num_priv)) {
3318 return NT_STATUS_NO_MEMORY;
3323 if (num_priv) {
3325 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3326 num_priv);
3327 if (!r->names) {
3328 return NT_STATUS_NO_MEMORY;
3331 for (i=0; i<num_priv; i++) {
3332 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3335 r->count = num_priv;
3338 return NT_STATUS_OK;
3341 /***************************************************************************
3342 _lsa_EnumAccountRights
3343 ***************************************************************************/
3345 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3346 struct lsa_EnumAccountRights *r)
3348 NTSTATUS status;
3349 struct lsa_info *info = NULL;
3350 PRIVILEGE_SET *privileges;
3352 /* find the connection policy handle. */
3354 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3355 return NT_STATUS_INVALID_HANDLE;
3357 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3358 return NT_STATUS_INVALID_HANDLE;
3361 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3362 return NT_STATUS_ACCESS_DENIED;
3365 /* according to an NT4 PDC, you can add privileges to SIDs even without
3366 call_lsa_create_account() first. And you can use any arbitrary SID. */
3368 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3369 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3370 * the lsa database */
3372 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3373 if (!NT_STATUS_IS_OK(status)) {
3374 return status;
3377 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3378 sid_string_dbg(r->in.sid), privileges->count));
3380 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3382 return status;
3385 /***************************************************************************
3386 _lsa_LookupPrivValue
3387 ***************************************************************************/
3389 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3390 struct lsa_LookupPrivValue *r)
3392 struct lsa_info *info = NULL;
3393 const char *name = NULL;
3395 /* find the connection policy handle. */
3397 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3398 return NT_STATUS_INVALID_HANDLE;
3400 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3401 return NT_STATUS_INVALID_HANDLE;
3404 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3405 return NT_STATUS_ACCESS_DENIED;
3407 name = r->in.name->string;
3409 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3411 r->out.luid->low = sec_privilege_id(name);
3412 r->out.luid->high = 0;
3413 if (r->out.luid->low == SEC_PRIV_INVALID) {
3414 return NT_STATUS_NO_SUCH_PRIVILEGE;
3416 return NT_STATUS_OK;
3419 /***************************************************************************
3420 _lsa_EnumAccountsWithUserRight
3421 ***************************************************************************/
3423 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3424 struct lsa_EnumAccountsWithUserRight *r)
3426 NTSTATUS status;
3427 struct lsa_info *info = NULL;
3428 struct dom_sid *sids = NULL;
3429 int num_sids = 0;
3430 uint32_t i;
3431 enum sec_privilege privilege;
3433 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3434 return NT_STATUS_INVALID_HANDLE;
3437 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3438 return NT_STATUS_INVALID_HANDLE;
3441 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3442 return NT_STATUS_ACCESS_DENIED;
3445 if (!r->in.name || !r->in.name->string) {
3446 return NT_STATUS_NO_SUCH_PRIVILEGE;
3449 privilege = sec_privilege_id(r->in.name->string);
3450 if (privilege == SEC_PRIV_INVALID) {
3451 return NT_STATUS_NO_SUCH_PRIVILEGE;
3454 status = privilege_enum_sids(privilege, p->mem_ctx,
3455 &sids, &num_sids);
3456 if (!NT_STATUS_IS_OK(status)) {
3457 return status;
3460 r->out.sids->num_sids = num_sids;
3461 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3462 r->out.sids->num_sids);
3464 for (i=0; i < r->out.sids->num_sids; i++) {
3465 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3466 &sids[i]);
3467 if (!r->out.sids->sids[i].sid) {
3468 TALLOC_FREE(r->out.sids->sids);
3469 r->out.sids->num_sids = 0;
3470 return NT_STATUS_NO_MEMORY;
3474 return NT_STATUS_OK;
3477 /***************************************************************************
3478 _lsa_Delete
3479 ***************************************************************************/
3481 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3482 struct lsa_Delete *r)
3484 return NT_STATUS_NOT_SUPPORTED;
3488 * From here on the server routines are just dummy ones to make smbd link with
3489 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3490 * pulling the server stubs across one by one.
3493 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3495 p->rng_fault_state = True;
3496 return NT_STATUS_NOT_IMPLEMENTED;
3499 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3500 struct lsa_ChangePassword *r)
3502 p->rng_fault_state = True;
3503 return NT_STATUS_NOT_IMPLEMENTED;
3506 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3508 p->rng_fault_state = True;
3509 return NT_STATUS_NOT_IMPLEMENTED;
3512 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3514 p->rng_fault_state = True;
3515 return NT_STATUS_NOT_IMPLEMENTED;
3518 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3519 struct lsa_GetQuotasForAccount *r)
3521 p->rng_fault_state = True;
3522 return NT_STATUS_NOT_IMPLEMENTED;
3525 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3526 struct lsa_SetQuotasForAccount *r)
3528 p->rng_fault_state = True;
3529 return NT_STATUS_NOT_IMPLEMENTED;
3532 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3533 struct lsa_SetInformationTrustedDomain *r)
3535 p->rng_fault_state = True;
3536 return NT_STATUS_NOT_IMPLEMENTED;
3539 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3540 struct lsa_SetTrustedDomainInfo *r)
3542 p->rng_fault_state = True;
3543 return NT_STATUS_NOT_IMPLEMENTED;
3546 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3547 struct lsa_StorePrivateData *r)
3549 p->rng_fault_state = True;
3550 return NT_STATUS_NOT_IMPLEMENTED;
3553 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3554 struct lsa_RetrievePrivateData *r)
3556 p->rng_fault_state = True;
3557 return NT_STATUS_NOT_IMPLEMENTED;
3560 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3561 struct lsa_SetInfoPolicy2 *r)
3563 p->rng_fault_state = True;
3564 return NT_STATUS_NOT_IMPLEMENTED;
3567 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3568 struct lsa_SetTrustedDomainInfoByName *r)
3570 p->rng_fault_state = True;
3571 return NT_STATUS_NOT_IMPLEMENTED;
3574 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3575 struct lsa_EnumTrustedDomainsEx *r)
3577 struct lsa_info *info;
3578 uint32_t count;
3579 struct pdb_trusted_domain **domains;
3580 struct lsa_TrustDomainInfoInfoEx *entries;
3581 int i;
3582 NTSTATUS nt_status;
3584 /* bail out early if pdb backend is not capable of ex trusted domains,
3585 * if we dont do that, the client might not call
3586 * _lsa_EnumTrustedDomains() afterwards - gd */
3588 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3589 p->rng_fault_state = True;
3590 return NT_STATUS_NOT_IMPLEMENTED;
3593 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3594 return NT_STATUS_INVALID_HANDLE;
3596 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3597 return NT_STATUS_INVALID_HANDLE;
3600 /* check if the user has enough rights */
3601 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3602 return NT_STATUS_ACCESS_DENIED;
3604 become_root();
3605 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3606 unbecome_root();
3608 if (!NT_STATUS_IS_OK(nt_status)) {
3609 return nt_status;
3612 entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3613 count);
3614 if (!entries) {
3615 return NT_STATUS_NO_MEMORY;
3618 for (i=0; i<count; i++) {
3619 init_lsa_StringLarge(&entries[i].netbios_name,
3620 domains[i]->netbios_name);
3621 entries[i].sid = &domains[i]->security_identifier;
3624 if (*r->in.resume_handle >= count) {
3625 *r->out.resume_handle = -1;
3626 TALLOC_FREE(entries);
3627 return NT_STATUS_NO_MORE_ENTRIES;
3630 /* return the rest, limit by max_size. Note that we
3631 use the w2k3 element size value of 60 */
3632 r->out.domains->count = count - *r->in.resume_handle;
3633 r->out.domains->count = MIN(r->out.domains->count,
3634 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3636 r->out.domains->domains = entries + *r->in.resume_handle;
3638 if (r->out.domains->count < count - *r->in.resume_handle) {
3639 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3640 return STATUS_MORE_ENTRIES;
3643 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3644 * always be larger than the previous input resume handle, in
3645 * particular when hitting the last query it is vital to set the
3646 * resume handle correctly to avoid infinite client loops, as
3647 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3648 * status is NT_STATUS_OK - gd */
3650 *r->out.resume_handle = (uint32_t)-1;
3652 return NT_STATUS_OK;
3655 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3656 struct lsa_QueryDomainInformationPolicy *r)
3658 p->rng_fault_state = True;
3659 return NT_STATUS_NOT_IMPLEMENTED;
3662 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3663 struct lsa_SetDomainInformationPolicy *r)
3665 p->rng_fault_state = True;
3666 return NT_STATUS_NOT_IMPLEMENTED;
3669 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3671 p->rng_fault_state = True;
3672 return NT_STATUS_NOT_IMPLEMENTED;
3675 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3677 p->rng_fault_state = True;
3678 return NT_STATUS_NOT_IMPLEMENTED;
3681 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3683 p->rng_fault_state = True;
3684 return NT_STATUS_NOT_IMPLEMENTED;
3687 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3689 p->rng_fault_state = True;
3690 return NT_STATUS_NOT_IMPLEMENTED;
3693 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3694 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3696 p->rng_fault_state = True;
3697 return NT_STATUS_NOT_IMPLEMENTED;
3700 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3701 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3703 p->rng_fault_state = True;
3704 return NT_STATUS_NOT_IMPLEMENTED;
3707 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3709 p->rng_fault_state = True;
3710 return NT_STATUS_NOT_IMPLEMENTED;
3713 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3714 struct lsa_CREDRGETTARGETINFO *r)
3716 p->rng_fault_state = True;
3717 return NT_STATUS_NOT_IMPLEMENTED;
3720 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3721 struct lsa_CREDRPROFILELOADED *r)
3723 p->rng_fault_state = True;
3724 return NT_STATUS_NOT_IMPLEMENTED;
3727 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3728 struct lsa_CREDRGETSESSIONTYPES *r)
3730 p->rng_fault_state = True;
3731 return NT_STATUS_NOT_IMPLEMENTED;
3734 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3735 struct lsa_LSARREGISTERAUDITEVENT *r)
3737 p->rng_fault_state = True;
3738 return NT_STATUS_NOT_IMPLEMENTED;
3741 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3742 struct lsa_LSARGENAUDITEVENT *r)
3744 p->rng_fault_state = True;
3745 return NT_STATUS_NOT_IMPLEMENTED;
3748 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3749 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3751 p->rng_fault_state = True;
3752 return NT_STATUS_NOT_IMPLEMENTED;
3755 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3756 struct lsa_lsaRQueryForestTrustInformation *r)
3758 p->rng_fault_state = True;
3759 return NT_STATUS_NOT_IMPLEMENTED;
3762 #define DNS_CMP_MATCH 0
3763 #define DNS_CMP_FIRST_IS_CHILD 1
3764 #define DNS_CMP_SECOND_IS_CHILD 2
3765 #define DNS_CMP_NO_MATCH 3
3767 /* this function assumes names are well formed DNS names.
3768 * it doesn't validate them */
3769 static int dns_cmp(const char *s1, size_t l1,
3770 const char *s2, size_t l2)
3772 const char *p1, *p2;
3773 size_t t1, t2;
3774 int cret;
3776 if (l1 == l2) {
3777 if (strcasecmp_m(s1, s2) == 0) {
3778 return DNS_CMP_MATCH;
3780 return DNS_CMP_NO_MATCH;
3783 if (l1 > l2) {
3784 p1 = s1;
3785 p2 = s2;
3786 t1 = l1;
3787 t2 = l2;
3788 cret = DNS_CMP_FIRST_IS_CHILD;
3789 } else {
3790 p1 = s2;
3791 p2 = s1;
3792 t1 = l2;
3793 t2 = l1;
3794 cret = DNS_CMP_SECOND_IS_CHILD;
3797 if (p1[t1 - t2 - 1] != '.') {
3798 return DNS_CMP_NO_MATCH;
3801 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
3802 return cret;
3805 return DNS_CMP_NO_MATCH;
3808 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3809 struct lsa_ForestTrustInformation *lfti,
3810 struct ForestTrustInfo *fti)
3812 struct lsa_ForestTrustRecord *lrec;
3813 struct ForestTrustInfoRecord *rec;
3814 struct lsa_StringLarge *tln;
3815 struct lsa_ForestTrustDomainInfo *info;
3816 uint32_t i;
3818 fti->version = 1;
3819 fti->count = lfti->count;
3820 fti->records = talloc_array(mem_ctx,
3821 struct ForestTrustInfoRecordArmor,
3822 fti->count);
3823 if (!fti->records) {
3824 return NT_STATUS_NO_MEMORY;
3826 for (i = 0; i < fti->count; i++) {
3827 lrec = lfti->entries[i];
3828 rec = &fti->records[i].record;
3830 rec->flags = lrec->flags;
3831 rec->timestamp = lrec->time;
3832 rec->type = lrec->type;
3834 switch (lrec->type) {
3835 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3836 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3837 tln = &lrec->forest_trust_data.top_level_name;
3838 rec->data.name.string =
3839 talloc_strdup(mem_ctx, tln->string);
3840 if (!rec->data.name.string) {
3841 return NT_STATUS_NO_MEMORY;
3843 rec->data.name.size = strlen(rec->data.name.string);
3844 break;
3845 case LSA_FOREST_TRUST_DOMAIN_INFO:
3846 info = &lrec->forest_trust_data.domain_info;
3847 rec->data.info.sid = *info->domain_sid;
3848 rec->data.info.dns_name.string =
3849 talloc_strdup(mem_ctx,
3850 info->dns_domain_name.string);
3851 if (!rec->data.info.dns_name.string) {
3852 return NT_STATUS_NO_MEMORY;
3854 rec->data.info.dns_name.size =
3855 strlen(rec->data.info.dns_name.string);
3856 rec->data.info.netbios_name.string =
3857 talloc_strdup(mem_ctx,
3858 info->netbios_domain_name.string);
3859 if (!rec->data.info.netbios_name.string) {
3860 return NT_STATUS_NO_MEMORY;
3862 rec->data.info.netbios_name.size =
3863 strlen(rec->data.info.netbios_name.string);
3864 break;
3865 default:
3866 return NT_STATUS_INVALID_DOMAIN_STATE;
3870 return NT_STATUS_OK;
3873 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3874 uint32_t index, uint32_t collision_type,
3875 uint32_t conflict_type, const char *tdo_name);
3877 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
3878 const char *tdo_name,
3879 struct ForestTrustInfo *tdo_fti,
3880 struct ForestTrustInfo *new_fti,
3881 struct lsa_ForestTrustCollisionInfo *c_info)
3883 struct ForestTrustInfoRecord *nrec;
3884 struct ForestTrustInfoRecord *trec;
3885 const char *dns_name;
3886 const char *nb_name = NULL;
3887 struct dom_sid *sid = NULL;
3888 const char *tname = NULL;
3889 size_t dns_len = 0;
3890 size_t nb_len;
3891 size_t tlen = 0;
3892 NTSTATUS nt_status;
3893 uint32_t new_fti_idx;
3894 uint32_t i;
3895 /* use always TDO type, until we understand when Xref can be used */
3896 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
3897 bool tln_conflict;
3898 bool sid_conflict;
3899 bool nb_conflict;
3900 bool exclusion;
3901 bool ex_rule = false;
3902 int ret;
3904 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
3906 nrec = &new_fti->records[new_fti_idx].record;
3907 dns_name = NULL;
3908 tln_conflict = false;
3909 sid_conflict = false;
3910 nb_conflict = false;
3911 exclusion = false;
3913 switch (nrec->type) {
3914 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3915 /* exclusions do not conflict by definition */
3916 break;
3918 case FOREST_TRUST_TOP_LEVEL_NAME:
3919 dns_name = nrec->data.name.string;
3920 dns_len = nrec->data.name.size;
3921 break;
3923 case LSA_FOREST_TRUST_DOMAIN_INFO:
3924 dns_name = nrec->data.info.dns_name.string;
3925 dns_len = nrec->data.info.dns_name.size;
3926 nb_name = nrec->data.info.netbios_name.string;
3927 nb_len = nrec->data.info.netbios_name.size;
3928 sid = &nrec->data.info.sid;
3929 break;
3932 if (!dns_name) continue;
3934 /* check if this is already taken and not excluded */
3935 for (i = 0; i < tdo_fti->count; i++) {
3936 trec = &tdo_fti->records[i].record;
3938 switch (trec->type) {
3939 case FOREST_TRUST_TOP_LEVEL_NAME:
3940 ex_rule = false;
3941 tname = trec->data.name.string;
3942 tlen = trec->data.name.size;
3943 break;
3944 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
3945 ex_rule = true;
3946 tname = trec->data.name.string;
3947 tlen = trec->data.name.size;
3948 break;
3949 case FOREST_TRUST_DOMAIN_INFO:
3950 ex_rule = false;
3951 tname = trec->data.info.dns_name.string;
3952 tlen = trec->data.info.dns_name.size;
3953 break;
3954 default:
3955 return NT_STATUS_INVALID_PARAMETER;
3957 ret = dns_cmp(dns_name, dns_len, tname, tlen);
3958 switch (ret) {
3959 case DNS_CMP_MATCH:
3960 /* if it matches exclusion,
3961 * it doesn't conflict */
3962 if (ex_rule) {
3963 exclusion = true;
3964 break;
3966 /* fall through */
3967 case DNS_CMP_FIRST_IS_CHILD:
3968 case DNS_CMP_SECOND_IS_CHILD:
3969 tln_conflict = true;
3970 /* fall through */
3971 default:
3972 break;
3975 /* explicit exclusion, no dns name conflict here */
3976 if (exclusion) {
3977 tln_conflict = false;
3980 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
3981 continue;
3984 /* also test for domain info */
3985 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
3986 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
3987 sid_conflict = true;
3989 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
3990 strcasecmp_m(trec->data.info.netbios_name.string,
3991 nb_name) == 0) {
3992 nb_conflict = true;
3996 if (tln_conflict) {
3997 nt_status = add_collision(c_info, new_fti_idx,
3998 collision_type,
3999 LSA_TLN_DISABLED_CONFLICT,
4000 tdo_name);
4002 if (sid_conflict) {
4003 nt_status = add_collision(c_info, new_fti_idx,
4004 collision_type,
4005 LSA_SID_DISABLED_CONFLICT,
4006 tdo_name);
4008 if (nb_conflict) {
4009 nt_status = add_collision(c_info, new_fti_idx,
4010 collision_type,
4011 LSA_NB_DISABLED_CONFLICT,
4012 tdo_name);
4016 return NT_STATUS_OK;
4019 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4020 uint32_t idx, uint32_t collision_type,
4021 uint32_t conflict_type, const char *tdo_name)
4023 struct lsa_ForestTrustCollisionRecord **es;
4024 uint32_t i = c_info->count;
4026 es = talloc_realloc(c_info, c_info->entries,
4027 struct lsa_ForestTrustCollisionRecord *, i + 1);
4028 if (!es) {
4029 return NT_STATUS_NO_MEMORY;
4031 c_info->entries = es;
4032 c_info->count = i + 1;
4034 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4035 if (!es[i]) {
4036 return NT_STATUS_NO_MEMORY;
4039 es[i]->index = idx;
4040 es[i]->type = collision_type;
4041 es[i]->flags.flags = conflict_type;
4042 es[i]->name.string = talloc_strdup(es[i], tdo_name);
4043 if (!es[i]->name.string) {
4044 return NT_STATUS_NO_MEMORY;
4046 es[i]->name.size = strlen(es[i]->name.string);
4048 return NT_STATUS_OK;
4051 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
4052 struct pdb_trusted_domain *td,
4053 struct ForestTrustInfo *info)
4055 enum ndr_err_code ndr_err;
4057 if (td->trust_forest_trust_info.length == 0 ||
4058 td->trust_forest_trust_info.data == NULL) {
4059 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4061 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
4062 info,
4063 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
4064 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4065 return NT_STATUS_INVALID_DOMAIN_STATE;
4068 return NT_STATUS_OK;
4071 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
4072 struct ForestTrustInfo *fti)
4074 struct ForestTrustDataDomainInfo *info;
4075 struct ForestTrustInfoRecord *rec;
4077 fti->version = 1;
4078 fti->count = 2;
4079 fti->records = talloc_array(fti,
4080 struct ForestTrustInfoRecordArmor, 2);
4081 if (!fti->records) {
4082 return NT_STATUS_NO_MEMORY;
4085 /* TLN info */
4086 rec = &fti->records[0].record;
4088 rec->flags = 0;
4089 rec->timestamp = 0;
4090 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
4092 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
4093 if (!rec->data.name.string) {
4094 return NT_STATUS_NO_MEMORY;
4096 rec->data.name.size = strlen(rec->data.name.string);
4098 /* DOMAIN info */
4099 rec = &fti->records[1].record;
4101 rec->flags = 0;
4102 rec->timestamp = 0;
4103 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
4105 info = &rec->data.info;
4107 info->sid = dom_info->sid;
4108 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
4109 if (!info->dns_name.string) {
4110 return NT_STATUS_NO_MEMORY;
4112 info->dns_name.size = strlen(info->dns_name.string);
4113 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
4114 if (!info->netbios_name.string) {
4115 return NT_STATUS_NO_MEMORY;
4117 info->netbios_name.size = strlen(info->netbios_name.string);
4119 return NT_STATUS_OK;
4122 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
4123 struct lsa_lsaRSetForestTrustInformation *r)
4125 NTSTATUS status;
4126 int i;
4127 int j;
4128 struct lsa_info *handle;
4129 uint32_t num_domains;
4130 struct pdb_trusted_domain **domains;
4131 struct ForestTrustInfo *nfti;
4132 struct ForestTrustInfo *fti;
4133 struct lsa_ForestTrustCollisionInfo *c_info;
4134 struct pdb_domain_info *dom_info;
4135 enum ndr_err_code ndr_err;
4137 if (!IS_DC) {
4138 return NT_STATUS_NOT_SUPPORTED;
4141 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
4142 return NT_STATUS_INVALID_HANDLE;
4145 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
4146 return NT_STATUS_INVALID_HANDLE;
4149 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
4150 return NT_STATUS_ACCESS_DENIED;
4153 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
4154 if (!NT_STATUS_IS_OK(status)) {
4155 return status;
4157 if (num_domains == 0) {
4158 return NT_STATUS_NO_SUCH_DOMAIN;
4161 for (i = 0; i < num_domains; i++) {
4162 if (domains[i]->domain_name == NULL) {
4163 return NT_STATUS_INVALID_DOMAIN_STATE;
4165 if (strcasecmp_m(domains[i]->domain_name,
4166 r->in.trusted_domain_name->string) == 0) {
4167 break;
4170 if (i >= num_domains) {
4171 return NT_STATUS_NO_SUCH_DOMAIN;
4174 if (!(domains[i]->trust_attributes &
4175 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4176 return NT_STATUS_INVALID_PARAMETER;
4179 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4180 return NT_STATUS_INVALID_PARAMETER;
4183 /* The following section until COPY_END is a copy from
4184 * source4/rpmc_server/lsa/scesrc_lsa.c */
4185 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
4186 if (!nfti) {
4187 return NT_STATUS_NO_MEMORY;
4190 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4191 if (!NT_STATUS_IS_OK(status)) {
4192 return status;
4195 c_info = talloc_zero(r->out.collision_info,
4196 struct lsa_ForestTrustCollisionInfo);
4197 if (!c_info) {
4198 return NT_STATUS_NO_MEMORY;
4201 /* first check own info, then other domains */
4202 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4203 if (!fti) {
4204 return NT_STATUS_NO_MEMORY;
4207 dom_info = pdb_get_domain_info(p->mem_ctx);
4209 status = own_ft_info(dom_info, fti);
4210 if (!NT_STATUS_IS_OK(status)) {
4211 return status;
4214 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
4215 if (!NT_STATUS_IS_OK(status)) {
4216 return status;
4219 for (j = 0; j < num_domains; j++) {
4220 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4221 if (!fti) {
4222 return NT_STATUS_NO_MEMORY;
4225 status = get_ft_info(p->mem_ctx, domains[j], fti);
4226 if (!NT_STATUS_IS_OK(status)) {
4227 if (NT_STATUS_EQUAL(status,
4228 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4229 continue;
4231 return status;
4234 if (domains[j]->domain_name == NULL) {
4235 return NT_STATUS_INVALID_DOMAIN_STATE;
4238 status = check_ft_info(c_info, domains[j]->domain_name,
4239 fti, nfti, c_info);
4240 if (!NT_STATUS_IS_OK(status)) {
4241 return status;
4245 *r->out.collision_info = c_info;
4247 if (r->in.check_only != 0) {
4248 return NT_STATUS_OK;
4251 /* COPY_END */
4253 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
4254 p->mem_ctx, nfti,
4255 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4256 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4257 return NT_STATUS_INVALID_PARAMETER;
4260 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
4261 if (!NT_STATUS_IS_OK(status)) {
4262 return status;
4265 return NT_STATUS_OK;
4268 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
4269 struct lsa_CREDRRENAME *r)
4271 p->rng_fault_state = True;
4272 return NT_STATUS_NOT_IMPLEMENTED;
4275 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
4276 struct lsa_LSAROPENPOLICYSCE *r)
4278 p->rng_fault_state = True;
4279 return NT_STATUS_NOT_IMPLEMENTED;
4282 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4283 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4285 p->rng_fault_state = True;
4286 return NT_STATUS_NOT_IMPLEMENTED;
4289 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4290 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4292 p->rng_fault_state = True;
4293 return NT_STATUS_NOT_IMPLEMENTED;
4296 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4297 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4299 p->rng_fault_state = True;
4300 return NT_STATUS_NOT_IMPLEMENTED;