s3:registry: add a warning debug message when the sorted subkeys is created from...
[Samba.git] / source3 / rpc_server / lsa / srv_lsa_nt.c
blob69cf52b2c842f821ae78b3763fb5ca029d7e130a
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Jeremy Allison 2001, 2006.
8 * Copyright (C) Rafal Szczesniak 2002,
9 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
10 * Copyright (C) Simo Sorce 2003.
11 * Copyright (C) Gerald (Jerry) Carter 2005.
12 * Copyright (C) Volker Lendecke 2005.
13 * Copyright (C) Guenther Deschner 2008.
14 * Copyright (C) Andrew Bartlett 2010.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
30 /* This is the implementation of the lsa server code. */
32 #include "includes.h"
33 #include "../librpc/gen_ndr/srv_lsa.h"
34 #include "secrets.h"
35 #include "../librpc/gen_ndr/netlogon.h"
36 #include "rpc_client/init_lsa.h"
37 #include "../libcli/security/security.h"
38 #include "../libcli/security/dom_sid.h"
39 #include "../librpc/gen_ndr/drsblobs.h"
40 #include "../librpc/gen_ndr/ndr_drsblobs.h"
41 #include "../lib/crypto/arcfour.h"
42 #include "../libcli/security/dom_sid.h"
43 #include "../librpc/gen_ndr/ndr_security.h"
44 #include "passdb.h"
45 #include "auth.h"
46 #include "ntdomain.h"
47 #include "lib/privileges.h"
48 #include "rpc_server/srv_access_check.h"
50 #undef DBGC_CLASS
51 #define DBGC_CLASS DBGC_RPC_SRV
53 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
55 enum lsa_handle_type {
56 LSA_HANDLE_POLICY_TYPE = 1,
57 LSA_HANDLE_ACCOUNT_TYPE = 2,
58 LSA_HANDLE_TRUST_TYPE = 3};
60 struct lsa_info {
61 struct dom_sid sid;
62 const char *name;
63 uint32 access;
64 enum lsa_handle_type type;
65 struct security_descriptor *sd;
68 const struct generic_mapping lsa_account_mapping = {
69 LSA_ACCOUNT_READ,
70 LSA_ACCOUNT_WRITE,
71 LSA_ACCOUNT_EXECUTE,
72 LSA_ACCOUNT_ALL_ACCESS
75 const struct generic_mapping lsa_policy_mapping = {
76 LSA_POLICY_READ,
77 LSA_POLICY_WRITE,
78 LSA_POLICY_EXECUTE,
79 LSA_POLICY_ALL_ACCESS
82 const struct generic_mapping lsa_secret_mapping = {
83 LSA_SECRET_READ,
84 LSA_SECRET_WRITE,
85 LSA_SECRET_EXECUTE,
86 LSA_SECRET_ALL_ACCESS
89 const struct generic_mapping lsa_trusted_domain_mapping = {
90 LSA_TRUSTED_DOMAIN_READ,
91 LSA_TRUSTED_DOMAIN_WRITE,
92 LSA_TRUSTED_DOMAIN_EXECUTE,
93 LSA_TRUSTED_DOMAIN_ALL_ACCESS
96 /***************************************************************************
97 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
98 ***************************************************************************/
100 static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
101 struct lsa_RefDomainList *ref,
102 const char *dom_name,
103 struct dom_sid *dom_sid)
105 int num = 0;
107 if (dom_name != NULL) {
108 for (num = 0; num < ref->count; num++) {
109 if (dom_sid_equal(dom_sid, ref->domains[num].sid)) {
110 return num;
113 } else {
114 num = ref->count;
117 if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
118 /* index not found, already at maximum domain limit */
119 return -1;
122 ref->count = num + 1;
123 ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
125 ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains,
126 struct lsa_DomainInfo, ref->count);
127 if (!ref->domains) {
128 return -1;
131 ZERO_STRUCT(ref->domains[num]);
133 init_lsa_StringLarge(&ref->domains[num].name, dom_name);
134 ref->domains[num].sid = dom_sid_dup(mem_ctx, dom_sid);
135 if (!ref->domains[num].sid) {
136 return -1;
139 return num;
143 /***************************************************************************
144 initialize a lsa_DomainInfo structure.
145 ***************************************************************************/
147 static void init_dom_query_3(struct lsa_DomainInfo *r,
148 const char *name,
149 struct dom_sid *sid)
151 init_lsa_StringLarge(&r->name, name);
152 r->sid = sid;
155 /***************************************************************************
156 initialize a lsa_DomainInfo structure.
157 ***************************************************************************/
159 static void init_dom_query_5(struct lsa_DomainInfo *r,
160 const char *name,
161 struct dom_sid *sid)
163 init_lsa_StringLarge(&r->name, name);
164 r->sid = sid;
167 /***************************************************************************
168 lookup_lsa_rids. Must be called as root for lookup_name to work.
169 ***************************************************************************/
171 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
172 struct lsa_RefDomainList *ref,
173 struct lsa_TranslatedSid *prid,
174 uint32_t num_entries,
175 struct lsa_String *name,
176 int flags,
177 uint32_t *pmapped_count)
179 uint32 mapped_count, i;
181 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
183 mapped_count = 0;
184 *pmapped_count = 0;
186 for (i = 0; i < num_entries; i++) {
187 struct dom_sid sid;
188 uint32 rid;
189 int dom_idx;
190 const char *full_name;
191 const char *domain;
192 enum lsa_SidType type = SID_NAME_UNKNOWN;
194 /* Split name into domain and user component */
196 /* follow w2k8 behavior and return the builtin domain when no
197 * input has been passed in */
199 if (name[i].string) {
200 full_name = name[i].string;
201 } else {
202 full_name = "BUILTIN";
205 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
207 /* We can ignore the result of lookup_name, it will not touch
208 "type" if it's not successful */
210 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
211 &sid, &type);
213 switch (type) {
214 case SID_NAME_USER:
215 case SID_NAME_DOM_GRP:
216 case SID_NAME_DOMAIN:
217 case SID_NAME_ALIAS:
218 case SID_NAME_WKN_GRP:
219 DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
220 /* Leave these unchanged */
221 break;
222 default:
223 /* Don't hand out anything but the list above */
224 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
225 type = SID_NAME_UNKNOWN;
226 break;
229 rid = 0;
230 dom_idx = -1;
232 if (type != SID_NAME_UNKNOWN) {
233 if (type == SID_NAME_DOMAIN) {
234 rid = (uint32_t)-1;
235 } else {
236 sid_split_rid(&sid, &rid);
238 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
239 mapped_count++;
242 prid[i].sid_type = type;
243 prid[i].rid = rid;
244 prid[i].sid_index = dom_idx;
247 *pmapped_count = mapped_count;
248 return NT_STATUS_OK;
251 /***************************************************************************
252 lookup_lsa_sids. Must be called as root for lookup_name to work.
253 ***************************************************************************/
255 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
256 struct lsa_RefDomainList *ref,
257 struct lsa_TranslatedSid3 *trans_sids,
258 uint32_t num_entries,
259 struct lsa_String *name,
260 int flags,
261 uint32 *pmapped_count)
263 uint32 mapped_count, i;
265 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
267 mapped_count = 0;
268 *pmapped_count = 0;
270 for (i = 0; i < num_entries; i++) {
271 struct dom_sid sid;
272 uint32 rid;
273 int dom_idx;
274 const char *full_name;
275 const char *domain;
276 enum lsa_SidType type;
278 ZERO_STRUCT(sid);
280 /* Split name into domain and user component */
282 full_name = name[i].string;
283 if (full_name == NULL) {
284 return NT_STATUS_NO_MEMORY;
287 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
289 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
290 &sid, &type)) {
291 type = SID_NAME_UNKNOWN;
294 switch (type) {
295 case SID_NAME_USER:
296 case SID_NAME_DOM_GRP:
297 case SID_NAME_DOMAIN:
298 case SID_NAME_ALIAS:
299 case SID_NAME_WKN_GRP:
300 DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
301 /* Leave these unchanged */
302 break;
303 default:
304 /* Don't hand out anything but the list above */
305 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
306 type = SID_NAME_UNKNOWN;
307 break;
310 rid = 0;
311 dom_idx = -1;
313 if (type != SID_NAME_UNKNOWN) {
314 struct dom_sid domain_sid;
315 sid_copy(&domain_sid, &sid);
316 sid_split_rid(&domain_sid, &rid);
317 dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
318 mapped_count++;
321 /* Initialize the lsa_TranslatedSid3 return. */
322 trans_sids[i].sid_type = type;
323 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
324 trans_sids[i].sid_index = dom_idx;
327 *pmapped_count = mapped_count;
328 return NT_STATUS_OK;
331 static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
332 const struct generic_mapping *map,
333 struct dom_sid *sid, uint32_t sid_access)
335 struct dom_sid adm_sid;
336 struct security_ace ace[5];
337 size_t i = 0;
339 struct security_acl *psa = NULL;
341 /* READ|EXECUTE access for Everyone */
343 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
344 map->generic_execute | map->generic_read, 0);
346 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
348 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
349 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
350 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
351 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
353 /* Add Full Access for Domain Admins */
354 sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
355 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
356 map->generic_all, 0);
358 /* If we have a sid, give it some special access */
360 if (sid) {
361 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
362 sid_access, 0);
365 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
366 return NT_STATUS_NO_MEMORY;
368 if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
369 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
370 psa, sd_size)) == NULL)
371 return NT_STATUS_NO_MEMORY;
373 return NT_STATUS_OK;
376 /***************************************************************************
377 ***************************************************************************/
379 static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
380 struct pipes_struct *p,
381 enum lsa_handle_type type,
382 uint32_t acc_granted,
383 struct dom_sid *sid,
384 const char *name,
385 const struct security_descriptor *sd,
386 struct policy_handle *handle)
388 struct lsa_info *info;
390 ZERO_STRUCTP(handle);
392 info = talloc_zero(mem_ctx, struct lsa_info);
393 if (!info) {
394 return NT_STATUS_NO_MEMORY;
397 info->type = type;
398 info->access = acc_granted;
400 if (sid) {
401 sid_copy(&info->sid, sid);
404 info->name = talloc_strdup(info, name);
406 if (sd) {
407 info->sd = dup_sec_desc(info, sd);
408 if (!info->sd) {
409 talloc_free(info);
410 return NT_STATUS_NO_MEMORY;
414 if (!create_policy_hnd(p, handle, info)) {
415 talloc_free(info);
416 ZERO_STRUCTP(handle);
417 return NT_STATUS_NO_MEMORY;
420 return NT_STATUS_OK;
423 /***************************************************************************
424 _lsa_OpenPolicy2
425 ***************************************************************************/
427 NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
428 struct lsa_OpenPolicy2 *r)
430 struct security_descriptor *psd = NULL;
431 size_t sd_size;
432 uint32 des_access = r->in.access_mask;
433 uint32 acc_granted;
434 NTSTATUS status;
436 /* Work out max allowed. */
437 map_max_allowed_access(p->session_info->security_token,
438 &p->session_info->utok,
439 &des_access);
441 /* map the generic bits to the lsa policy ones */
442 se_map_generic(&des_access, &lsa_policy_mapping);
444 /* get the generic lsa policy SD until we store it */
445 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
446 NULL, 0);
447 if (!NT_STATUS_IS_OK(status)) {
448 return status;
451 status = access_check_object(psd, p->session_info->security_token,
452 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
453 &acc_granted, "_lsa_OpenPolicy2" );
454 if (!NT_STATUS_IS_OK(status)) {
455 return status;
458 status = create_lsa_policy_handle(p->mem_ctx, p,
459 LSA_HANDLE_POLICY_TYPE,
460 acc_granted,
461 get_global_sam_sid(),
462 NULL,
463 psd,
464 r->out.handle);
465 if (!NT_STATUS_IS_OK(status)) {
466 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
469 return NT_STATUS_OK;
472 /***************************************************************************
473 _lsa_OpenPolicy
474 ***************************************************************************/
476 NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
477 struct lsa_OpenPolicy *r)
479 struct lsa_OpenPolicy2 o;
481 o.in.system_name = NULL; /* should be ignored */
482 o.in.attr = r->in.attr;
483 o.in.access_mask = r->in.access_mask;
485 o.out.handle = r->out.handle;
487 return _lsa_OpenPolicy2(p, &o);
490 /***************************************************************************
491 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
492 ufff, done :) mimir
493 ***************************************************************************/
495 NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
496 struct lsa_EnumTrustDom *r)
498 struct lsa_info *info;
499 uint32_t count;
500 struct trustdom_info **domains;
501 struct lsa_DomainInfo *entries;
502 int i;
503 NTSTATUS nt_status;
505 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
506 return NT_STATUS_INVALID_HANDLE;
508 if (info->type != LSA_HANDLE_POLICY_TYPE) {
509 return NT_STATUS_INVALID_HANDLE;
512 /* check if the user has enough rights */
513 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
514 return NT_STATUS_ACCESS_DENIED;
516 become_root();
517 nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
518 unbecome_root();
520 if (!NT_STATUS_IS_OK(nt_status)) {
521 return nt_status;
524 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo, count);
525 if (!entries) {
526 return NT_STATUS_NO_MEMORY;
529 for (i=0; i<count; i++) {
530 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
531 entries[i].sid = &domains[i]->sid;
534 if (*r->in.resume_handle >= count) {
535 *r->out.resume_handle = -1;
536 TALLOC_FREE(entries);
537 return NT_STATUS_NO_MORE_ENTRIES;
540 /* return the rest, limit by max_size. Note that we
541 use the w2k3 element size value of 60 */
542 r->out.domains->count = count - *r->in.resume_handle;
543 r->out.domains->count = MIN(r->out.domains->count,
544 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
546 r->out.domains->domains = entries + *r->in.resume_handle;
548 if (r->out.domains->count < count - *r->in.resume_handle) {
549 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
550 return STATUS_MORE_ENTRIES;
553 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
554 * always be larger than the previous input resume handle, in
555 * particular when hitting the last query it is vital to set the
556 * resume handle correctly to avoid infinite client loops, as
557 * seen e.g. with Windows XP SP3 when resume handle is 0 and
558 * status is NT_STATUS_OK - gd */
560 *r->out.resume_handle = (uint32_t)-1;
562 return NT_STATUS_OK;
565 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
566 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
567 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
569 /***************************************************************************
570 _lsa_QueryInfoPolicy
571 ***************************************************************************/
573 NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
574 struct lsa_QueryInfoPolicy *r)
576 NTSTATUS status = NT_STATUS_OK;
577 struct lsa_info *handle;
578 struct dom_sid domain_sid;
579 const char *name;
580 struct dom_sid *sid = NULL;
581 union lsa_PolicyInformation *info = NULL;
582 uint32_t acc_required = 0;
584 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
585 return NT_STATUS_INVALID_HANDLE;
587 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
588 return NT_STATUS_INVALID_HANDLE;
591 switch (r->in.level) {
592 case LSA_POLICY_INFO_AUDIT_LOG:
593 case LSA_POLICY_INFO_AUDIT_EVENTS:
594 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
595 break;
596 case LSA_POLICY_INFO_DOMAIN:
597 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
598 break;
599 case LSA_POLICY_INFO_PD:
600 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
601 break;
602 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
603 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
604 break;
605 case LSA_POLICY_INFO_ROLE:
606 case LSA_POLICY_INFO_REPLICA:
607 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
608 break;
609 case LSA_POLICY_INFO_QUOTA:
610 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
611 break;
612 case LSA_POLICY_INFO_MOD:
613 case LSA_POLICY_INFO_AUDIT_FULL_SET:
614 /* according to MS-LSAD 3.1.4.4.3 */
615 return NT_STATUS_INVALID_PARAMETER;
616 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
617 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
618 break;
619 case LSA_POLICY_INFO_DNS:
620 case LSA_POLICY_INFO_DNS_INT:
621 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
622 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
623 break;
624 default:
625 break;
628 if (!(handle->access & acc_required)) {
629 /* return NT_STATUS_ACCESS_DENIED; */
632 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
633 if (!info) {
634 return NT_STATUS_NO_MEMORY;
637 switch (r->in.level) {
638 /* according to MS-LSAD 3.1.4.4.3 */
639 case LSA_POLICY_INFO_MOD:
640 case LSA_POLICY_INFO_AUDIT_FULL_SET:
641 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
642 return NT_STATUS_INVALID_PARAMETER;
643 case LSA_POLICY_INFO_AUDIT_LOG:
644 info->audit_log.percent_full = 0;
645 info->audit_log.maximum_log_size = 0;
646 info->audit_log.retention_time = 0;
647 info->audit_log.shutdown_in_progress = 0;
648 info->audit_log.time_to_shutdown = 0;
649 info->audit_log.next_audit_record = 0;
650 status = NT_STATUS_OK;
651 break;
652 case LSA_POLICY_INFO_PD:
653 info->pd.name.string = NULL;
654 status = NT_STATUS_OK;
655 break;
656 case LSA_POLICY_INFO_REPLICA:
657 info->replica.source.string = NULL;
658 info->replica.account.string = NULL;
659 status = NT_STATUS_OK;
660 break;
661 case LSA_POLICY_INFO_QUOTA:
662 info->quota.paged_pool = 0;
663 info->quota.non_paged_pool = 0;
664 info->quota.min_wss = 0;
665 info->quota.max_wss = 0;
666 info->quota.pagefile = 0;
667 info->quota.unknown = 0;
668 status = NT_STATUS_OK;
669 break;
670 case LSA_POLICY_INFO_AUDIT_EVENTS:
673 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
675 /* check if the user has enough rights */
676 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
677 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
678 return NT_STATUS_ACCESS_DENIED;
681 /* fake info: We audit everything. ;) */
683 info->audit_events.auditing_mode = true;
684 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
685 info->audit_events.settings = TALLOC_ZERO_ARRAY(p->mem_ctx,
686 enum lsa_PolicyAuditPolicy,
687 info->audit_events.count);
688 if (!info->audit_events.settings) {
689 return NT_STATUS_NO_MEMORY;
692 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
693 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
694 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
695 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
696 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
697 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
698 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
700 break;
702 case LSA_POLICY_INFO_DOMAIN:
703 /* check if the user has enough rights */
704 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
705 return NT_STATUS_ACCESS_DENIED;
707 /* Request PolicyPrimaryDomainInformation. */
708 switch (lp_server_role()) {
709 case ROLE_DOMAIN_PDC:
710 case ROLE_DOMAIN_BDC:
711 name = get_global_sam_name();
712 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
713 if (!sid) {
714 return NT_STATUS_NO_MEMORY;
716 break;
717 case ROLE_DOMAIN_MEMBER:
718 name = lp_workgroup();
719 /* We need to return the Domain SID here. */
720 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
721 sid = dom_sid_dup(p->mem_ctx, &domain_sid);
722 if (!sid) {
723 return NT_STATUS_NO_MEMORY;
725 } else {
726 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
728 break;
729 case ROLE_STANDALONE:
730 name = lp_workgroup();
731 sid = NULL;
732 break;
733 default:
734 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
736 init_dom_query_3(&info->domain, name, sid);
737 break;
738 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
739 /* check if the user has enough rights */
740 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
741 return NT_STATUS_ACCESS_DENIED;
743 /* Request PolicyAccountDomainInformation. */
744 name = get_global_sam_name();
745 sid = get_global_sam_sid();
747 init_dom_query_5(&info->account_domain, name, sid);
748 break;
749 case LSA_POLICY_INFO_ROLE:
750 /* check if the user has enough rights */
751 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
752 return NT_STATUS_ACCESS_DENIED;
754 switch (lp_server_role()) {
755 case ROLE_DOMAIN_BDC:
757 * only a BDC is a backup controller
758 * of the domain, it controls.
760 info->role.role = LSA_ROLE_BACKUP;
761 break;
762 default:
764 * any other role is a primary
765 * of the domain, it controls.
767 info->role.role = LSA_ROLE_PRIMARY;
768 break;
770 break;
771 case LSA_POLICY_INFO_DNS:
772 case LSA_POLICY_INFO_DNS_INT: {
773 struct pdb_domain_info *dominfo;
775 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
776 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
777 "without ADS passdb backend\n"));
778 status = NT_STATUS_INVALID_INFO_CLASS;
779 break;
782 dominfo = pdb_get_domain_info(info);
783 if (dominfo == NULL) {
784 status = NT_STATUS_NO_MEMORY;
785 break;
788 init_lsa_StringLarge(&info->dns.name,
789 dominfo->name);
790 init_lsa_StringLarge(&info->dns.dns_domain,
791 dominfo->dns_domain);
792 init_lsa_StringLarge(&info->dns.dns_forest,
793 dominfo->dns_forest);
794 info->dns.domain_guid = dominfo->guid;
795 info->dns.sid = &dominfo->sid;
796 break;
798 default:
799 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
800 r->in.level));
801 status = NT_STATUS_INVALID_INFO_CLASS;
802 break;
805 *r->out.info = info;
807 return status;
810 /***************************************************************************
811 _lsa_QueryInfoPolicy2
812 ***************************************************************************/
814 NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
815 struct lsa_QueryInfoPolicy2 *r2)
817 struct lsa_QueryInfoPolicy r;
819 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
820 p->rng_fault_state = True;
821 return NT_STATUS_NOT_IMPLEMENTED;
824 ZERO_STRUCT(r);
825 r.in.handle = r2->in.handle;
826 r.in.level = r2->in.level;
827 r.out.info = r2->out.info;
829 return _lsa_QueryInfoPolicy(p, &r);
832 /***************************************************************************
833 _lsa_lookup_sids_internal
834 ***************************************************************************/
836 static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
837 TALLOC_CTX *mem_ctx,
838 uint16_t level, /* input */
839 int num_sids, /* input */
840 struct lsa_SidPtr *sid, /* input */
841 struct lsa_RefDomainList **pp_ref, /* input/output */
842 struct lsa_TranslatedName2 **pp_names,/* input/output */
843 uint32_t *pp_mapped_count) /* input/output */
845 NTSTATUS status;
846 int i;
847 const struct dom_sid **sids = NULL;
848 struct lsa_RefDomainList *ref = NULL;
849 uint32 mapped_count = 0;
850 struct lsa_dom_info *dom_infos = NULL;
851 struct lsa_name_info *name_infos = NULL;
852 struct lsa_TranslatedName2 *names = NULL;
854 *pp_mapped_count = 0;
855 *pp_names = NULL;
856 *pp_ref = NULL;
858 if (num_sids == 0) {
859 return NT_STATUS_OK;
862 sids = TALLOC_ARRAY(p->mem_ctx, const struct dom_sid *, num_sids);
863 ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
865 if (sids == NULL || ref == NULL) {
866 return NT_STATUS_NO_MEMORY;
869 for (i=0; i<num_sids; i++) {
870 sids[i] = sid[i].sid;
873 status = lookup_sids(p->mem_ctx, num_sids, sids, level,
874 &dom_infos, &name_infos);
876 if (!NT_STATUS_IS_OK(status)) {
877 return status;
880 names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
881 if (names == NULL) {
882 return NT_STATUS_NO_MEMORY;
885 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
887 if (!dom_infos[i].valid) {
888 break;
891 if (init_lsa_ref_domain_list(mem_ctx, ref,
892 dom_infos[i].name,
893 &dom_infos[i].sid) != i) {
894 DEBUG(0, ("Domain %s mentioned twice??\n",
895 dom_infos[i].name));
896 return NT_STATUS_INTERNAL_ERROR;
900 for (i=0; i<num_sids; i++) {
901 struct lsa_name_info *name = &name_infos[i];
903 if (name->type == SID_NAME_UNKNOWN) {
904 name->dom_idx = -1;
905 /* Unknown sids should return the string
906 * representation of the SID. Windows 2003 behaves
907 * rather erratic here, in many cases it returns the
908 * RID as 8 bytes hex, in others it returns the full
909 * SID. We (Jerry/VL) could not figure out which the
910 * hard cases are, so leave it with the SID. */
911 name->name = dom_sid_string(p->mem_ctx, sids[i]);
912 if (name->name == NULL) {
913 return NT_STATUS_NO_MEMORY;
915 } else {
916 mapped_count += 1;
919 names[i].sid_type = name->type;
920 names[i].name.string = name->name;
921 names[i].sid_index = name->dom_idx;
922 names[i].unknown = 0;
925 status = NT_STATUS_NONE_MAPPED;
926 if (mapped_count > 0) {
927 status = (mapped_count < num_sids) ?
928 STATUS_SOME_UNMAPPED : NT_STATUS_OK;
931 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
932 num_sids, mapped_count, nt_errstr(status)));
934 *pp_mapped_count = mapped_count;
935 *pp_names = names;
936 *pp_ref = ref;
938 return status;
941 /***************************************************************************
942 _lsa_LookupSids
943 ***************************************************************************/
945 NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
946 struct lsa_LookupSids *r)
948 NTSTATUS status;
949 struct lsa_info *handle;
950 int num_sids = r->in.sids->num_sids;
951 uint32 mapped_count = 0;
952 struct lsa_RefDomainList *domains = NULL;
953 struct lsa_TranslatedName *names_out = NULL;
954 struct lsa_TranslatedName2 *names = NULL;
955 int i;
957 if ((r->in.level < 1) || (r->in.level > 6)) {
958 return NT_STATUS_INVALID_PARAMETER;
961 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
962 return NT_STATUS_INVALID_HANDLE;
965 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
966 return NT_STATUS_INVALID_HANDLE;
969 /* check if the user has enough rights */
970 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
971 return NT_STATUS_ACCESS_DENIED;
974 if (num_sids > MAX_LOOKUP_SIDS) {
975 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
976 MAX_LOOKUP_SIDS, num_sids));
977 return NT_STATUS_NONE_MAPPED;
980 status = _lsa_lookup_sids_internal(p,
981 p->mem_ctx,
982 r->in.level,
983 num_sids,
984 r->in.sids->sids,
985 &domains,
986 &names,
987 &mapped_count);
989 /* Only return here when there is a real error.
990 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
991 the requested sids could be resolved. Older versions of XP (pre SP3)
992 rely that we return with the string representations of those SIDs in
993 that case. If we don't, XP crashes - Guenther
996 if (NT_STATUS_IS_ERR(status) &&
997 !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
998 return status;
1001 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
1002 names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
1003 num_sids);
1004 if (!names_out) {
1005 return NT_STATUS_NO_MEMORY;
1008 for (i=0; i<num_sids; i++) {
1009 names_out[i].sid_type = names[i].sid_type;
1010 names_out[i].name = names[i].name;
1011 names_out[i].sid_index = names[i].sid_index;
1014 *r->out.domains = domains;
1015 r->out.names->count = num_sids;
1016 r->out.names->names = names_out;
1017 *r->out.count = mapped_count;
1019 return status;
1022 /***************************************************************************
1023 _lsa_LookupSids2
1024 ***************************************************************************/
1026 NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1027 struct lsa_LookupSids2 *r)
1029 NTSTATUS status;
1030 struct lsa_info *handle;
1031 int num_sids = r->in.sids->num_sids;
1032 uint32 mapped_count = 0;
1033 struct lsa_RefDomainList *domains = NULL;
1034 struct lsa_TranslatedName2 *names = NULL;
1035 bool check_policy = true;
1037 switch (p->opnum) {
1038 case NDR_LSA_LOOKUPSIDS3:
1039 check_policy = false;
1040 break;
1041 case NDR_LSA_LOOKUPSIDS2:
1042 default:
1043 check_policy = true;
1046 if ((r->in.level < 1) || (r->in.level > 6)) {
1047 return NT_STATUS_INVALID_PARAMETER;
1050 if (check_policy) {
1051 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1052 return NT_STATUS_INVALID_HANDLE;
1055 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1056 return NT_STATUS_INVALID_HANDLE;
1059 /* check if the user has enough rights */
1060 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1061 return NT_STATUS_ACCESS_DENIED;
1065 if (num_sids > MAX_LOOKUP_SIDS) {
1066 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1067 MAX_LOOKUP_SIDS, num_sids));
1068 return NT_STATUS_NONE_MAPPED;
1071 status = _lsa_lookup_sids_internal(p,
1072 p->mem_ctx,
1073 r->in.level,
1074 num_sids,
1075 r->in.sids->sids,
1076 &domains,
1077 &names,
1078 &mapped_count);
1080 *r->out.domains = domains;
1081 r->out.names->count = num_sids;
1082 r->out.names->names = names;
1083 *r->out.count = mapped_count;
1085 return status;
1088 /***************************************************************************
1089 _lsa_LookupSids3
1090 ***************************************************************************/
1092 NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1093 struct lsa_LookupSids3 *r)
1095 struct lsa_LookupSids2 q;
1097 /* No policy handle on this call. Restrict to crypto connections. */
1098 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1099 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1100 get_remote_machine_name() ));
1101 return NT_STATUS_INVALID_PARAMETER;
1104 q.in.handle = NULL;
1105 q.in.sids = r->in.sids;
1106 q.in.level = r->in.level;
1107 q.in.lookup_options = r->in.lookup_options;
1108 q.in.client_revision = r->in.client_revision;
1109 q.in.names = r->in.names;
1110 q.in.count = r->in.count;
1112 q.out.domains = r->out.domains;
1113 q.out.names = r->out.names;
1114 q.out.count = r->out.count;
1116 return _lsa_LookupSids2(p, &q);
1119 /***************************************************************************
1120 ***************************************************************************/
1122 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1124 int flags;
1126 switch (level) {
1127 case LSA_LOOKUP_NAMES_ALL: /* 1 */
1128 flags = LOOKUP_NAME_ALL;
1129 break;
1130 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1131 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1132 break;
1133 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1134 flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1135 break;
1136 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1137 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1138 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1139 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1140 default:
1141 flags = LOOKUP_NAME_NONE;
1142 break;
1145 return flags;
1148 /***************************************************************************
1149 _lsa_LookupNames
1150 ***************************************************************************/
1152 NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1153 struct lsa_LookupNames *r)
1155 NTSTATUS status = NT_STATUS_NONE_MAPPED;
1156 struct lsa_info *handle;
1157 struct lsa_String *names = r->in.names;
1158 uint32 num_entries = r->in.num_names;
1159 struct lsa_RefDomainList *domains = NULL;
1160 struct lsa_TranslatedSid *rids = NULL;
1161 uint32 mapped_count = 0;
1162 int flags = 0;
1164 if (num_entries > MAX_LOOKUP_SIDS) {
1165 num_entries = MAX_LOOKUP_SIDS;
1166 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1167 num_entries));
1170 flags = lsa_lookup_level_to_flags(r->in.level);
1172 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1173 if (!domains) {
1174 return NT_STATUS_NO_MEMORY;
1177 if (num_entries) {
1178 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid,
1179 num_entries);
1180 if (!rids) {
1181 return NT_STATUS_NO_MEMORY;
1183 } else {
1184 rids = NULL;
1187 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1188 status = NT_STATUS_INVALID_HANDLE;
1189 goto done;
1192 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1193 return NT_STATUS_INVALID_HANDLE;
1196 /* check if the user has enough rights */
1197 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1198 status = NT_STATUS_ACCESS_DENIED;
1199 goto done;
1202 /* set up the LSA Lookup RIDs response */
1203 become_root(); /* lookup_name can require root privs */
1204 status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1205 names, flags, &mapped_count);
1206 unbecome_root();
1208 done:
1210 if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1211 if (mapped_count == 0) {
1212 status = NT_STATUS_NONE_MAPPED;
1213 } else if (mapped_count != num_entries) {
1214 status = STATUS_SOME_UNMAPPED;
1218 *r->out.count = mapped_count;
1219 *r->out.domains = domains;
1220 r->out.sids->sids = rids;
1221 r->out.sids->count = num_entries;
1223 return status;
1226 /***************************************************************************
1227 _lsa_LookupNames2
1228 ***************************************************************************/
1230 NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1231 struct lsa_LookupNames2 *r)
1233 NTSTATUS status;
1234 struct lsa_LookupNames q;
1235 struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1236 struct lsa_TransSidArray *sid_array = NULL;
1237 uint32_t i;
1239 sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray);
1240 if (!sid_array) {
1241 return NT_STATUS_NO_MEMORY;
1244 q.in.handle = r->in.handle;
1245 q.in.num_names = r->in.num_names;
1246 q.in.names = r->in.names;
1247 q.in.level = r->in.level;
1248 q.in.sids = sid_array;
1249 q.in.count = r->in.count;
1250 /* we do not know what this is for */
1251 /* = r->in.unknown1; */
1252 /* = r->in.unknown2; */
1254 q.out.domains = r->out.domains;
1255 q.out.sids = sid_array;
1256 q.out.count = r->out.count;
1258 status = _lsa_LookupNames(p, &q);
1260 sid_array2->count = sid_array->count;
1261 sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1262 if (!sid_array2->sids) {
1263 return NT_STATUS_NO_MEMORY;
1266 for (i=0; i<sid_array->count; i++) {
1267 sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1268 sid_array2->sids[i].rid = sid_array->sids[i].rid;
1269 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1270 sid_array2->sids[i].unknown = 0;
1273 r->out.sids = sid_array2;
1275 return status;
1278 /***************************************************************************
1279 _lsa_LookupNames3
1280 ***************************************************************************/
1282 NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1283 struct lsa_LookupNames3 *r)
1285 NTSTATUS status;
1286 struct lsa_info *handle;
1287 struct lsa_String *names = r->in.names;
1288 uint32 num_entries = r->in.num_names;
1289 struct lsa_RefDomainList *domains = NULL;
1290 struct lsa_TranslatedSid3 *trans_sids = NULL;
1291 uint32 mapped_count = 0;
1292 int flags = 0;
1293 bool check_policy = true;
1295 switch (p->opnum) {
1296 case NDR_LSA_LOOKUPNAMES4:
1297 check_policy = false;
1298 break;
1299 case NDR_LSA_LOOKUPNAMES3:
1300 default:
1301 check_policy = true;
1304 if (num_entries > MAX_LOOKUP_SIDS) {
1305 num_entries = MAX_LOOKUP_SIDS;
1306 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1309 /* Probably the lookup_level is some sort of bitmask. */
1310 if (r->in.level == 1) {
1311 flags = LOOKUP_NAME_ALL;
1314 domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList);
1315 if (!domains) {
1316 return NT_STATUS_NO_MEMORY;
1319 if (num_entries) {
1320 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3,
1321 num_entries);
1322 if (!trans_sids) {
1323 return NT_STATUS_NO_MEMORY;
1325 } else {
1326 trans_sids = NULL;
1329 if (check_policy) {
1331 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1332 status = NT_STATUS_INVALID_HANDLE;
1333 goto done;
1336 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1337 return NT_STATUS_INVALID_HANDLE;
1340 /* check if the user has enough rights */
1341 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1342 status = NT_STATUS_ACCESS_DENIED;
1343 goto done;
1347 /* set up the LSA Lookup SIDs response */
1348 become_root(); /* lookup_name can require root privs */
1349 status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1350 names, flags, &mapped_count);
1351 unbecome_root();
1353 done:
1355 if (NT_STATUS_IS_OK(status)) {
1356 if (mapped_count == 0) {
1357 status = NT_STATUS_NONE_MAPPED;
1358 } else if (mapped_count != num_entries) {
1359 status = STATUS_SOME_UNMAPPED;
1363 *r->out.count = mapped_count;
1364 *r->out.domains = domains;
1365 r->out.sids->sids = trans_sids;
1366 r->out.sids->count = num_entries;
1368 return status;
1371 /***************************************************************************
1372 _lsa_LookupNames4
1373 ***************************************************************************/
1375 NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1376 struct lsa_LookupNames4 *r)
1378 struct lsa_LookupNames3 q;
1380 /* No policy handle on this call. Restrict to crypto connections. */
1381 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1382 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1383 get_remote_machine_name() ));
1384 return NT_STATUS_INVALID_PARAMETER;
1387 q.in.handle = NULL;
1388 q.in.num_names = r->in.num_names;
1389 q.in.names = r->in.names;
1390 q.in.level = r->in.level;
1391 q.in.lookup_options = r->in.lookup_options;
1392 q.in.client_revision = r->in.client_revision;
1393 q.in.sids = r->in.sids;
1394 q.in.count = r->in.count;
1396 q.out.domains = r->out.domains;
1397 q.out.sids = r->out.sids;
1398 q.out.count = r->out.count;
1400 return _lsa_LookupNames3(p, &q);
1403 /***************************************************************************
1404 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1405 ***************************************************************************/
1407 NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1409 if (!find_policy_by_hnd(p, r->in.handle, NULL)) {
1410 return NT_STATUS_INVALID_HANDLE;
1413 close_policy_hnd(p, r->in.handle);
1414 ZERO_STRUCTP(r->out.handle);
1415 return NT_STATUS_OK;
1418 /***************************************************************************
1419 ***************************************************************************/
1421 static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1422 const struct dom_sid *sid,
1423 struct trustdom_info **info)
1425 NTSTATUS status;
1426 uint32_t num_domains = 0;
1427 struct trustdom_info **domains = NULL;
1428 int i;
1430 status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1431 if (!NT_STATUS_IS_OK(status)) {
1432 return status;
1435 for (i=0; i < num_domains; i++) {
1436 if (dom_sid_equal(&domains[i]->sid, sid)) {
1437 break;
1441 if (i == num_domains) {
1442 return NT_STATUS_INVALID_PARAMETER;
1445 *info = domains[i];
1447 return NT_STATUS_OK;
1450 /***************************************************************************
1451 ***************************************************************************/
1453 static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1454 const char *netbios_domain_name,
1455 struct trustdom_info **info_p)
1457 NTSTATUS status;
1458 struct trustdom_info *info;
1459 struct pdb_trusted_domain *td;
1461 status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1462 if (!NT_STATUS_IS_OK(status)) {
1463 return status;
1466 info = talloc(mem_ctx, struct trustdom_info);
1467 if (!info) {
1468 return NT_STATUS_NO_MEMORY;
1471 info->name = talloc_strdup(info, netbios_domain_name);
1472 NT_STATUS_HAVE_NO_MEMORY(info->name);
1474 sid_copy(&info->sid, &td->security_identifier);
1476 *info_p = info;
1478 return NT_STATUS_OK;
1481 /***************************************************************************
1482 ***************************************************************************/
1484 NTSTATUS _lsa_OpenSecret(struct pipes_struct *p, struct lsa_OpenSecret *r)
1486 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1489 /***************************************************************************
1490 _lsa_OpenTrustedDomain_base
1491 ***************************************************************************/
1493 static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1494 uint32_t access_mask,
1495 struct trustdom_info *info,
1496 struct policy_handle *handle)
1498 struct security_descriptor *psd = NULL;
1499 size_t sd_size;
1500 uint32_t acc_granted;
1501 NTSTATUS status;
1503 /* des_access is for the account here, not the policy
1504 * handle - so don't check against policy handle. */
1506 /* Work out max allowed. */
1507 map_max_allowed_access(p->session_info->security_token,
1508 &p->session_info->utok,
1509 &access_mask);
1511 /* map the generic bits to the lsa account ones */
1512 se_map_generic(&access_mask, &lsa_account_mapping);
1514 /* get the generic lsa account SD until we store it */
1515 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1516 &lsa_trusted_domain_mapping,
1517 NULL, 0);
1518 if (!NT_STATUS_IS_OK(status)) {
1519 return status;
1522 status = access_check_object(psd, p->session_info->security_token,
1523 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1524 access_mask, &acc_granted,
1525 "_lsa_OpenTrustedDomain");
1526 if (!NT_STATUS_IS_OK(status)) {
1527 return status;
1530 status = create_lsa_policy_handle(p->mem_ctx, p,
1531 LSA_HANDLE_TRUST_TYPE,
1532 acc_granted,
1533 &info->sid,
1534 info->name,
1535 psd,
1536 handle);
1537 if (!NT_STATUS_IS_OK(status)) {
1538 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1541 return NT_STATUS_OK;
1544 /***************************************************************************
1545 _lsa_OpenTrustedDomain
1546 ***************************************************************************/
1548 NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1549 struct lsa_OpenTrustedDomain *r)
1551 struct lsa_info *handle = NULL;
1552 struct trustdom_info *info = NULL;
1553 NTSTATUS status;
1555 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1556 return NT_STATUS_INVALID_HANDLE;
1559 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1560 return NT_STATUS_INVALID_HANDLE;
1563 status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1564 r->in.sid,
1565 &info);
1566 if (!NT_STATUS_IS_OK(status)) {
1567 return status;
1570 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1571 r->out.trustdom_handle);
1574 /***************************************************************************
1575 _lsa_OpenTrustedDomainByName
1576 ***************************************************************************/
1578 NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1579 struct lsa_OpenTrustedDomainByName *r)
1581 struct lsa_info *handle = NULL;
1582 struct trustdom_info *info = NULL;
1583 NTSTATUS status;
1585 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1586 return NT_STATUS_INVALID_HANDLE;
1589 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1590 return NT_STATUS_INVALID_HANDLE;
1593 status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1594 r->in.name.string,
1595 &info);
1596 if (!NT_STATUS_IS_OK(status)) {
1597 return status;
1600 return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1601 r->out.trustdom_handle);
1604 static NTSTATUS add_trusted_domain_user(TALLOC_CTX *mem_ctx,
1605 const char *netbios_name,
1606 const char *domain_name,
1607 struct trustDomainPasswords auth_struct)
1609 NTSTATUS status;
1610 struct samu *sam_acct;
1611 char *acct_name;
1612 uint32_t rid;
1613 struct dom_sid user_sid;
1614 int i;
1615 char *dummy;
1616 size_t dummy_size;
1618 sam_acct = samu_new(mem_ctx);
1619 if (sam_acct == NULL) {
1620 return NT_STATUS_NO_MEMORY;
1623 acct_name = talloc_asprintf(mem_ctx, "%s$", netbios_name);
1624 if (acct_name == NULL) {
1625 return NT_STATUS_NO_MEMORY;
1627 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1628 return NT_STATUS_UNSUCCESSFUL;
1631 if (!pdb_set_domain(sam_acct, domain_name, PDB_SET)) {
1632 return NT_STATUS_UNSUCCESSFUL;
1635 if (!pdb_set_acct_ctrl(sam_acct, ACB_DOMTRUST, PDB_SET)) {
1636 return NT_STATUS_UNSUCCESSFUL;
1639 if (!pdb_new_rid(&rid)) {
1640 return NT_STATUS_DS_NO_MORE_RIDS;
1642 sid_compose(&user_sid, get_global_sam_sid(), rid);
1643 if (!pdb_set_user_sid(sam_acct, &user_sid, PDB_SET)) {
1644 return NT_STATUS_UNSUCCESSFUL;
1647 for (i = 0; i < auth_struct.incoming.count; i++) {
1648 switch (auth_struct.incoming.current.array[i].AuthType) {
1649 case TRUST_AUTH_TYPE_CLEAR:
1650 if (!convert_string_talloc(mem_ctx,
1651 CH_UTF16LE,
1652 CH_UNIX,
1653 auth_struct.incoming.current.array[i].AuthInfo.clear.password,
1654 auth_struct.incoming.current.array[i].AuthInfo.clear.size,
1655 &dummy,
1656 &dummy_size,
1657 false)) {
1658 return NT_STATUS_UNSUCCESSFUL;
1660 if (!pdb_set_plaintext_passwd(sam_acct, dummy)) {
1661 return NT_STATUS_UNSUCCESSFUL;
1663 break;
1664 default:
1665 continue;
1669 status = pdb_add_sam_account(sam_acct);
1670 if (!NT_STATUS_IS_OK(status)) {
1671 return status;
1674 return NT_STATUS_OK;
1677 /***************************************************************************
1678 _lsa_CreateTrustedDomainEx2
1679 ***************************************************************************/
1681 NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1682 struct lsa_CreateTrustedDomainEx2 *r)
1684 struct lsa_info *policy;
1685 NTSTATUS status;
1686 uint32_t acc_granted;
1687 struct security_descriptor *psd;
1688 size_t sd_size;
1689 struct pdb_trusted_domain td;
1690 struct trustDomainPasswords auth_struct;
1691 enum ndr_err_code ndr_err;
1692 DATA_BLOB auth_blob;
1694 if (!IS_DC) {
1695 return NT_STATUS_NOT_SUPPORTED;
1698 if (!find_policy_by_hnd(p, r->in.policy_handle, (void **)(void *)&policy)) {
1699 return NT_STATUS_INVALID_HANDLE;
1702 if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1703 return NT_STATUS_ACCESS_DENIED;
1706 if (p->session_info->utok.uid != sec_initial_uid() &&
1707 !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
1708 return NT_STATUS_ACCESS_DENIED;
1711 /* Work out max allowed. */
1712 map_max_allowed_access(p->session_info->security_token,
1713 &p->session_info->utok,
1714 &r->in.access_mask);
1716 /* map the generic bits to the lsa policy ones */
1717 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1719 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1720 &lsa_trusted_domain_mapping,
1721 NULL, 0);
1722 if (!NT_STATUS_IS_OK(status)) {
1723 return status;
1726 status = access_check_object(psd, p->session_info->security_token,
1727 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1728 r->in.access_mask, &acc_granted,
1729 "_lsa_CreateTrustedDomainEx2");
1730 if (!NT_STATUS_IS_OK(status)) {
1731 return status;
1734 ZERO_STRUCT(td);
1736 td.domain_name = talloc_strdup(p->mem_ctx,
1737 r->in.info->domain_name.string);
1738 if (td.domain_name == NULL) {
1739 return NT_STATUS_NO_MEMORY;
1741 td.netbios_name = talloc_strdup(p->mem_ctx,
1742 r->in.info->netbios_name.string);
1743 if (td.netbios_name == NULL) {
1744 return NT_STATUS_NO_MEMORY;
1746 sid_copy(&td.security_identifier, r->in.info->sid);
1747 td.trust_direction = r->in.info->trust_direction;
1748 td.trust_type = r->in.info->trust_type;
1749 td.trust_attributes = r->in.info->trust_attributes;
1751 if (r->in.auth_info->auth_blob.size != 0) {
1752 auth_blob.length = r->in.auth_info->auth_blob.size;
1753 auth_blob.data = r->in.auth_info->auth_blob.data;
1755 arcfour_crypt_blob(auth_blob.data, auth_blob.length,
1756 &p->session_info->user_session_key);
1758 ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
1759 &auth_struct,
1760 (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
1761 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1762 return NT_STATUS_UNSUCCESSFUL;
1765 ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
1766 &auth_struct.incoming,
1767 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1768 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1769 return NT_STATUS_UNSUCCESSFUL;
1772 ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
1773 &auth_struct.outgoing,
1774 (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
1775 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1776 return NT_STATUS_UNSUCCESSFUL;
1778 } else {
1779 td.trust_auth_incoming.data = NULL;
1780 td.trust_auth_incoming.length = 0;
1781 td.trust_auth_outgoing.data = NULL;
1782 td.trust_auth_outgoing.length = 0;
1785 status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1786 if (!NT_STATUS_IS_OK(status)) {
1787 return status;
1790 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1791 status = add_trusted_domain_user(p->mem_ctx,
1792 r->in.info->netbios_name.string,
1793 r->in.info->domain_name.string,
1794 auth_struct);
1795 if (!NT_STATUS_IS_OK(status)) {
1796 return status;
1800 status = create_lsa_policy_handle(p->mem_ctx, p,
1801 LSA_HANDLE_TRUST_TYPE,
1802 acc_granted,
1803 r->in.info->sid,
1804 r->in.info->netbios_name.string,
1805 psd,
1806 r->out.trustdom_handle);
1807 if (!NT_STATUS_IS_OK(status)) {
1808 pdb_del_trusteddom_pw(r->in.info->netbios_name.string);
1809 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1812 return NT_STATUS_OK;
1815 /***************************************************************************
1816 _lsa_CreateTrustedDomainEx
1817 ***************************************************************************/
1819 NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1820 struct lsa_CreateTrustedDomainEx *r)
1822 struct lsa_CreateTrustedDomainEx2 q;
1824 q.in.policy_handle = r->in.policy_handle;
1825 q.in.info = r->in.info;
1826 q.in.auth_info = r->in.auth_info;
1827 q.in.access_mask = r->in.access_mask;
1828 q.out.trustdom_handle = r->out.trustdom_handle;
1830 return _lsa_CreateTrustedDomainEx2(p, &q);
1833 /***************************************************************************
1834 _lsa_CreateTrustedDomain
1835 ***************************************************************************/
1837 NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1838 struct lsa_CreateTrustedDomain *r)
1840 struct lsa_CreateTrustedDomainEx2 c;
1841 struct lsa_TrustDomainInfoInfoEx info;
1842 struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
1844 ZERO_STRUCT(auth_info);
1846 info.domain_name = r->in.info->name;
1847 info.netbios_name = r->in.info->name;
1848 info.sid = r->in.info->sid;
1849 info.trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1850 info.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1851 info.trust_attributes = 0;
1853 c.in.policy_handle = r->in.policy_handle;
1854 c.in.info = &info;
1855 c.in.auth_info = &auth_info;
1856 c.in.access_mask = r->in.access_mask;
1857 c.out.trustdom_handle = r->out.trustdom_handle;
1859 return _lsa_CreateTrustedDomainEx2(p, &c);
1862 /***************************************************************************
1863 _lsa_DeleteTrustedDomain
1864 ***************************************************************************/
1866 NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
1867 struct lsa_DeleteTrustedDomain *r)
1869 NTSTATUS status;
1870 struct lsa_info *handle;
1871 struct pdb_trusted_domain *td;
1872 struct samu *sam_acct;
1873 char *acct_name;
1875 /* find the connection policy handle. */
1876 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
1877 return NT_STATUS_INVALID_HANDLE;
1880 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
1881 return NT_STATUS_INVALID_HANDLE;
1884 if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
1885 return NT_STATUS_ACCESS_DENIED;
1888 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
1889 if (!NT_STATUS_IS_OK(status)) {
1890 return status;
1893 if (td->netbios_name == NULL || *td->netbios_name == '\0') {
1894 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1895 sid_string_tos(r->in.dom_sid)));
1896 return NT_STATUS_UNSUCCESSFUL;
1899 if (td->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1900 sam_acct = samu_new(p->mem_ctx);
1901 if (sam_acct == NULL) {
1902 return NT_STATUS_NO_MEMORY;
1905 acct_name = talloc_asprintf(p->mem_ctx, "%s$", td->netbios_name);
1906 if (acct_name == NULL) {
1907 return NT_STATUS_NO_MEMORY;
1909 if (!pdb_set_username(sam_acct, acct_name, PDB_SET)) {
1910 return NT_STATUS_UNSUCCESSFUL;
1912 status = pdb_delete_sam_account(sam_acct);
1913 if (!NT_STATUS_IS_OK(status)) {
1914 return status;
1918 status = pdb_del_trusted_domain(td->netbios_name);
1919 if (!NT_STATUS_IS_OK(status)) {
1920 return status;
1923 return NT_STATUS_OK;
1926 /***************************************************************************
1927 _lsa_CloseTrustedDomainEx
1928 ***************************************************************************/
1930 NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
1931 struct lsa_CloseTrustedDomainEx *r)
1933 return NT_STATUS_NOT_IMPLEMENTED;
1936 /***************************************************************************
1937 _lsa_QueryTrustedDomainInfo
1938 ***************************************************************************/
1940 NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
1941 struct lsa_QueryTrustedDomainInfo *r)
1943 NTSTATUS status;
1944 struct lsa_info *handle;
1945 union lsa_TrustedDomainInfo *info;
1946 struct pdb_trusted_domain *td;
1947 uint32_t acc_required;
1949 /* find the connection policy handle. */
1950 if (!find_policy_by_hnd(p, r->in.trustdom_handle, (void **)(void *)&handle)) {
1951 return NT_STATUS_INVALID_HANDLE;
1954 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
1955 return NT_STATUS_INVALID_HANDLE;
1958 switch (r->in.level) {
1959 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1960 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1961 break;
1962 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
1963 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
1964 break;
1965 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1966 acc_required = LSA_TRUSTED_QUERY_POSIX;
1967 break;
1968 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
1969 acc_required = LSA_TRUSTED_QUERY_AUTH;
1970 break;
1971 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1972 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1973 break;
1974 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1975 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1976 break;
1977 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1978 acc_required = LSA_TRUSTED_QUERY_AUTH;
1979 break;
1980 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1981 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1982 LSA_TRUSTED_QUERY_POSIX |
1983 LSA_TRUSTED_QUERY_AUTH;
1984 break;
1985 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1986 acc_required = LSA_TRUSTED_QUERY_AUTH;
1987 break;
1988 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1989 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1990 LSA_TRUSTED_QUERY_POSIX |
1991 LSA_TRUSTED_QUERY_AUTH;
1992 break;
1993 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
1994 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
1995 break;
1996 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
1997 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
1998 LSA_TRUSTED_QUERY_POSIX |
1999 LSA_TRUSTED_QUERY_AUTH;
2000 break;
2001 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2002 acc_required = LSA_TRUSTED_QUERY_POSIX;
2003 break;
2004 default:
2005 return NT_STATUS_INVALID_PARAMETER;
2008 if (!(handle->access & acc_required)) {
2009 return NT_STATUS_ACCESS_DENIED;
2012 status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2013 if (!NT_STATUS_IS_OK(status)) {
2014 return status;
2017 info = TALLOC_ZERO_P(p->mem_ctx, union lsa_TrustedDomainInfo);
2018 if (!info) {
2019 return NT_STATUS_NO_MEMORY;
2022 switch (r->in.level) {
2023 case LSA_TRUSTED_DOMAIN_INFO_NAME:
2024 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2025 break;
2026 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2027 return NT_STATUS_INVALID_PARAMETER;
2028 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2029 break;
2030 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2031 return NT_STATUS_INVALID_INFO_CLASS;
2032 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2033 return NT_STATUS_INVALID_PARAMETER;
2034 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2035 init_lsa_StringLarge(&info->info_ex.domain_name, td->domain_name);
2036 init_lsa_StringLarge(&info->info_ex.netbios_name, td->netbios_name);
2037 info->info_ex.sid = dom_sid_dup(info, &td->security_identifier);
2038 if (!info->info_ex.sid) {
2039 return NT_STATUS_NO_MEMORY;
2041 info->info_ex.trust_direction = td->trust_direction;
2042 info->info_ex.trust_type = td->trust_type;
2043 info->info_ex.trust_attributes = td->trust_attributes;
2044 break;
2045 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2046 return NT_STATUS_INVALID_INFO_CLASS;
2047 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2048 break;
2049 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2050 return NT_STATUS_INVALID_INFO_CLASS;
2051 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2052 return NT_STATUS_INVALID_INFO_CLASS;
2053 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2054 return NT_STATUS_INVALID_PARAMETER;
2055 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2056 break;
2057 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2058 break;
2059 default:
2060 return NT_STATUS_INVALID_PARAMETER;
2063 *r->out.info = info;
2065 return NT_STATUS_OK;
2068 /***************************************************************************
2069 _lsa_QueryTrustedDomainInfoBySid
2070 ***************************************************************************/
2072 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2073 struct lsa_QueryTrustedDomainInfoBySid *r)
2075 NTSTATUS status;
2076 struct policy_handle trustdom_handle;
2077 struct lsa_OpenTrustedDomain o;
2078 struct lsa_QueryTrustedDomainInfo q;
2079 struct lsa_Close c;
2081 o.in.handle = r->in.handle;
2082 o.in.sid = r->in.dom_sid;
2083 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2084 o.out.trustdom_handle = &trustdom_handle;
2086 status = _lsa_OpenTrustedDomain(p, &o);
2087 if (!NT_STATUS_IS_OK(status)) {
2088 return status;
2091 q.in.trustdom_handle = &trustdom_handle;
2092 q.in.level = r->in.level;
2093 q.out.info = r->out.info;
2095 status = _lsa_QueryTrustedDomainInfo(p, &q);
2096 if (!NT_STATUS_IS_OK(status)) {
2097 return status;
2100 c.in.handle = &trustdom_handle;
2101 c.out.handle = &trustdom_handle;
2103 return _lsa_Close(p, &c);
2106 /***************************************************************************
2107 _lsa_QueryTrustedDomainInfoByName
2108 ***************************************************************************/
2110 NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2111 struct lsa_QueryTrustedDomainInfoByName *r)
2113 NTSTATUS status;
2114 struct policy_handle trustdom_handle;
2115 struct lsa_OpenTrustedDomainByName o;
2116 struct lsa_QueryTrustedDomainInfo q;
2117 struct lsa_Close c;
2119 o.in.handle = r->in.handle;
2120 o.in.name.string = r->in.trusted_domain->string;
2121 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2122 o.out.trustdom_handle = &trustdom_handle;
2124 status = _lsa_OpenTrustedDomainByName(p, &o);
2125 if (!NT_STATUS_IS_OK(status)) {
2126 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2127 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2129 return status;
2132 q.in.trustdom_handle = &trustdom_handle;
2133 q.in.level = r->in.level;
2134 q.out.info = r->out.info;
2136 status = _lsa_QueryTrustedDomainInfo(p, &q);
2137 if (!NT_STATUS_IS_OK(status)) {
2138 return status;
2141 c.in.handle = &trustdom_handle;
2142 c.out.handle = &trustdom_handle;
2144 return _lsa_Close(p, &c);
2147 /***************************************************************************
2148 ***************************************************************************/
2150 NTSTATUS _lsa_CreateSecret(struct pipes_struct *p, struct lsa_CreateSecret *r)
2152 return NT_STATUS_ACCESS_DENIED;
2155 /***************************************************************************
2156 ***************************************************************************/
2158 NTSTATUS _lsa_SetSecret(struct pipes_struct *p, struct lsa_SetSecret *r)
2160 return NT_STATUS_ACCESS_DENIED;
2163 /***************************************************************************
2164 _lsa_DeleteObject
2165 ***************************************************************************/
2167 NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2168 struct lsa_DeleteObject *r)
2170 NTSTATUS status;
2171 struct lsa_info *info = NULL;
2173 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2174 return NT_STATUS_INVALID_HANDLE;
2177 if (!(info->access & SEC_STD_DELETE)) {
2178 return NT_STATUS_ACCESS_DENIED;
2181 switch (info->type) {
2182 case LSA_HANDLE_ACCOUNT_TYPE:
2183 status = privilege_delete_account(&info->sid);
2184 if (!NT_STATUS_IS_OK(status)) {
2185 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2186 nt_errstr(status)));
2187 return status;
2189 break;
2190 default:
2191 return NT_STATUS_INVALID_HANDLE;
2194 close_policy_hnd(p, r->in.handle);
2195 ZERO_STRUCTP(r->out.handle);
2197 return status;
2200 /***************************************************************************
2201 _lsa_EnumPrivs
2202 ***************************************************************************/
2204 NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2205 struct lsa_EnumPrivs *r)
2207 struct lsa_info *handle;
2208 uint32 i;
2209 uint32 enum_context = *r->in.resume_handle;
2210 int num_privs = num_privileges_in_short_list();
2211 struct lsa_PrivEntry *entries = NULL;
2213 /* remember that the enum_context starts at 0 and not 1 */
2215 if ( enum_context >= num_privs )
2216 return NT_STATUS_NO_MORE_ENTRIES;
2218 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2219 enum_context, num_privs));
2221 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2222 return NT_STATUS_INVALID_HANDLE;
2224 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2225 return NT_STATUS_INVALID_HANDLE;
2228 /* check if the user has enough rights
2229 I don't know if it's the right one. not documented. */
2231 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2232 return NT_STATUS_ACCESS_DENIED;
2234 if (num_privs) {
2235 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2236 if (!entries) {
2237 return NT_STATUS_NO_MEMORY;
2239 } else {
2240 entries = NULL;
2243 for (i = 0; i < num_privs; i++) {
2244 if( i < enum_context) {
2246 init_lsa_StringLarge(&entries[i].name, NULL);
2248 entries[i].luid.low = 0;
2249 entries[i].luid.high = 0;
2250 } else {
2252 init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2254 entries[i].luid.low = sec_privilege_from_index(i);
2255 entries[i].luid.high = 0;
2259 enum_context = num_privs;
2261 *r->out.resume_handle = enum_context;
2262 r->out.privs->count = num_privs;
2263 r->out.privs->privs = entries;
2265 return NT_STATUS_OK;
2268 /***************************************************************************
2269 _lsa_LookupPrivDisplayName
2270 ***************************************************************************/
2272 NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2273 struct lsa_LookupPrivDisplayName *r)
2275 struct lsa_info *handle;
2276 const char *description;
2277 struct lsa_StringLarge *lsa_name;
2279 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2280 return NT_STATUS_INVALID_HANDLE;
2282 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2283 return NT_STATUS_INVALID_HANDLE;
2286 /* check if the user has enough rights */
2289 * I don't know if it's the right one. not documented.
2291 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2292 return NT_STATUS_ACCESS_DENIED;
2294 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2296 description = get_privilege_dispname(r->in.name->string);
2297 if (!description) {
2298 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2299 return NT_STATUS_NO_SUCH_PRIVILEGE;
2302 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2304 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2305 if (!lsa_name) {
2306 return NT_STATUS_NO_MEMORY;
2309 init_lsa_StringLarge(lsa_name, description);
2311 *r->out.returned_language_id = r->in.language_id;
2312 *r->out.disp_name = lsa_name;
2314 return NT_STATUS_OK;
2317 /***************************************************************************
2318 _lsa_EnumAccounts
2319 ***************************************************************************/
2321 NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2322 struct lsa_EnumAccounts *r)
2324 struct lsa_info *handle;
2325 struct dom_sid *sid_list;
2326 int i, j, num_entries;
2327 NTSTATUS status;
2328 struct lsa_SidPtr *sids = NULL;
2330 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2331 return NT_STATUS_INVALID_HANDLE;
2333 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2334 return NT_STATUS_INVALID_HANDLE;
2337 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2338 return NT_STATUS_ACCESS_DENIED;
2340 sid_list = NULL;
2341 num_entries = 0;
2343 /* The only way we can currently find out all the SIDs that have been
2344 privileged is to scan all privileges */
2346 status = privilege_enumerate_accounts(&sid_list, &num_entries);
2347 if (!NT_STATUS_IS_OK(status)) {
2348 return status;
2351 if (*r->in.resume_handle >= num_entries) {
2352 return NT_STATUS_NO_MORE_ENTRIES;
2355 if (num_entries - *r->in.resume_handle) {
2356 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
2357 num_entries - *r->in.resume_handle);
2358 if (!sids) {
2359 talloc_free(sid_list);
2360 return NT_STATUS_NO_MEMORY;
2363 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2364 sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2365 if (!sids[j].sid) {
2366 talloc_free(sid_list);
2367 return NT_STATUS_NO_MEMORY;
2372 talloc_free(sid_list);
2374 *r->out.resume_handle = num_entries;
2375 r->out.sids->num_sids = num_entries;
2376 r->out.sids->sids = sids;
2378 return NT_STATUS_OK;
2381 /***************************************************************************
2382 _lsa_GetUserName
2383 ***************************************************************************/
2385 NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2386 struct lsa_GetUserName *r)
2388 const char *username, *domname;
2389 struct lsa_String *account_name = NULL;
2390 struct lsa_String *authority_name = NULL;
2392 if (r->in.account_name &&
2393 *r->in.account_name) {
2394 return NT_STATUS_INVALID_PARAMETER;
2397 if (r->in.authority_name &&
2398 *r->in.authority_name) {
2399 return NT_STATUS_INVALID_PARAMETER;
2402 if (p->session_info->guest) {
2404 * I'm 99% sure this is not the right place to do this,
2405 * global_sid_Anonymous should probably be put into the token
2406 * instead of the guest id -- vl
2408 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2409 &domname, &username, NULL)) {
2410 return NT_STATUS_NO_MEMORY;
2412 } else {
2413 username = p->session_info->sanitized_username;
2414 domname = p->session_info->info3->base.domain.string;
2417 account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2418 if (!account_name) {
2419 return NT_STATUS_NO_MEMORY;
2421 init_lsa_String(account_name, username);
2423 if (r->out.authority_name) {
2424 authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
2425 if (!authority_name) {
2426 return NT_STATUS_NO_MEMORY;
2428 init_lsa_String(authority_name, domname);
2431 *r->out.account_name = account_name;
2432 if (r->out.authority_name) {
2433 *r->out.authority_name = authority_name;
2436 return NT_STATUS_OK;
2439 /***************************************************************************
2440 _lsa_CreateAccount
2441 ***************************************************************************/
2443 NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2444 struct lsa_CreateAccount *r)
2446 NTSTATUS status;
2447 struct lsa_info *handle;
2448 uint32_t acc_granted;
2449 struct security_descriptor *psd;
2450 size_t sd_size;
2452 /* find the connection policy handle. */
2453 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2454 return NT_STATUS_INVALID_HANDLE;
2456 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2457 return NT_STATUS_INVALID_HANDLE;
2460 /* check if the user has enough rights */
2462 if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2463 return NT_STATUS_ACCESS_DENIED;
2466 /* Work out max allowed. */
2467 map_max_allowed_access(p->session_info->security_token,
2468 &p->session_info->utok,
2469 &r->in.access_mask);
2471 /* map the generic bits to the lsa policy ones */
2472 se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2474 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2475 &lsa_account_mapping,
2476 r->in.sid, LSA_POLICY_ALL_ACCESS);
2477 if (!NT_STATUS_IS_OK(status)) {
2478 return status;
2481 status = access_check_object(psd, p->session_info->security_token,
2482 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2483 &acc_granted, "_lsa_CreateAccount");
2484 if (!NT_STATUS_IS_OK(status)) {
2485 return status;
2488 if ( is_privileged_sid( r->in.sid ) )
2489 return NT_STATUS_OBJECT_NAME_COLLISION;
2491 status = create_lsa_policy_handle(p->mem_ctx, p,
2492 LSA_HANDLE_ACCOUNT_TYPE,
2493 acc_granted,
2494 r->in.sid,
2495 NULL,
2496 psd,
2497 r->out.acct_handle);
2498 if (!NT_STATUS_IS_OK(status)) {
2499 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2502 return privilege_create_account(r->in.sid);
2505 /***************************************************************************
2506 _lsa_OpenAccount
2507 ***************************************************************************/
2509 NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2510 struct lsa_OpenAccount *r)
2512 struct lsa_info *handle;
2513 struct security_descriptor *psd = NULL;
2514 size_t sd_size;
2515 uint32_t des_access = r->in.access_mask;
2516 uint32_t acc_granted;
2517 NTSTATUS status;
2519 /* find the connection policy handle. */
2520 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2521 return NT_STATUS_INVALID_HANDLE;
2523 if (handle->type != LSA_HANDLE_POLICY_TYPE) {
2524 return NT_STATUS_INVALID_HANDLE;
2527 /* des_access is for the account here, not the policy
2528 * handle - so don't check against policy handle. */
2530 /* Work out max allowed. */
2531 map_max_allowed_access(p->session_info->security_token,
2532 &p->session_info->utok,
2533 &des_access);
2535 /* map the generic bits to the lsa account ones */
2536 se_map_generic(&des_access, &lsa_account_mapping);
2538 /* get the generic lsa account SD until we store it */
2539 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2540 &lsa_account_mapping,
2541 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2542 if (!NT_STATUS_IS_OK(status)) {
2543 return status;
2546 status = access_check_object(psd, p->session_info->security_token,
2547 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
2548 &acc_granted, "_lsa_OpenAccount" );
2549 if (!NT_STATUS_IS_OK(status)) {
2550 return status;
2553 /* TODO: Fis the parsing routine before reenabling this check! */
2554 #if 0
2555 if (!lookup_sid(&handle->sid, dom_name, name, &type))
2556 return NT_STATUS_ACCESS_DENIED;
2557 #endif
2559 status = create_lsa_policy_handle(p->mem_ctx, p,
2560 LSA_HANDLE_ACCOUNT_TYPE,
2561 acc_granted,
2562 r->in.sid,
2563 NULL,
2564 psd,
2565 r->out.acct_handle);
2566 if (!NT_STATUS_IS_OK(status)) {
2567 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2570 return NT_STATUS_OK;
2573 /***************************************************************************
2574 _lsa_EnumPrivsAccount
2575 For a given SID, enumerate all the privilege this account has.
2576 ***************************************************************************/
2578 NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
2579 struct lsa_EnumPrivsAccount *r)
2581 NTSTATUS status = NT_STATUS_OK;
2582 struct lsa_info *info=NULL;
2583 PRIVILEGE_SET *privileges;
2584 struct lsa_PrivilegeSet *priv_set = NULL;
2586 /* find the connection policy handle. */
2587 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2588 return NT_STATUS_INVALID_HANDLE;
2590 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2591 return NT_STATUS_INVALID_HANDLE;
2594 if (!(info->access & LSA_ACCOUNT_VIEW))
2595 return NT_STATUS_ACCESS_DENIED;
2597 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
2598 if (!NT_STATUS_IS_OK(status)) {
2599 return status;
2602 *r->out.privs = priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet);
2603 if (!priv_set) {
2604 return NT_STATUS_NO_MEMORY;
2607 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2608 sid_string_dbg(&info->sid),
2609 privileges->count));
2611 priv_set->count = privileges->count;
2612 priv_set->unknown = 0;
2613 priv_set->set = talloc_move(priv_set, &privileges->set);
2615 return status;
2618 /***************************************************************************
2619 _lsa_GetSystemAccessAccount
2620 ***************************************************************************/
2622 NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
2623 struct lsa_GetSystemAccessAccount *r)
2625 NTSTATUS status;
2626 struct lsa_info *info = NULL;
2627 struct lsa_EnumPrivsAccount e;
2628 struct lsa_PrivilegeSet *privset;
2630 /* find the connection policy handle. */
2632 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2633 return NT_STATUS_INVALID_HANDLE;
2635 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2636 return NT_STATUS_INVALID_HANDLE;
2639 if (!(info->access & LSA_ACCOUNT_VIEW))
2640 return NT_STATUS_ACCESS_DENIED;
2642 privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
2643 if (!privset) {
2644 return NT_STATUS_NO_MEMORY;
2647 e.in.handle = r->in.handle;
2648 e.out.privs = &privset;
2650 status = _lsa_EnumPrivsAccount(p, &e);
2651 if (!NT_STATUS_IS_OK(status)) {
2652 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2653 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2654 nt_errstr(status)));
2655 return status;
2658 /* Samba4 would iterate over the privset to merge the policy mode bits,
2659 * not sure samba3 can do the same here, so just return what we did in
2660 * the past - gd */
2663 0x01 -> Log on locally
2664 0x02 -> Access this computer from network
2665 0x04 -> Log on as a batch job
2666 0x10 -> Log on as a service
2668 they can be ORed together
2671 *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
2672 LSA_POLICY_MODE_NETWORK;
2674 return NT_STATUS_OK;
2677 /***************************************************************************
2678 update the systemaccount information
2679 ***************************************************************************/
2681 NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
2682 struct lsa_SetSystemAccessAccount *r)
2684 struct lsa_info *info=NULL;
2685 GROUP_MAP map;
2687 /* find the connection policy handle. */
2688 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2689 return NT_STATUS_INVALID_HANDLE;
2691 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2692 return NT_STATUS_INVALID_HANDLE;
2695 if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
2696 return NT_STATUS_ACCESS_DENIED;
2699 if (!pdb_getgrsid(&map, info->sid))
2700 return NT_STATUS_NO_SUCH_GROUP;
2702 return pdb_update_group_mapping_entry(&map);
2705 /***************************************************************************
2706 _lsa_AddPrivilegesToAccount
2707 For a given SID, add some privileges.
2708 ***************************************************************************/
2710 NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
2711 struct lsa_AddPrivilegesToAccount *r)
2713 struct lsa_info *info = NULL;
2714 struct lsa_PrivilegeSet *set = NULL;
2716 /* find the connection policy handle. */
2717 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2718 return NT_STATUS_INVALID_HANDLE;
2720 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2721 return NT_STATUS_INVALID_HANDLE;
2724 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2725 return NT_STATUS_ACCESS_DENIED;
2728 set = r->in.privs;
2730 if ( !grant_privilege_set( &info->sid, set ) ) {
2731 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2732 sid_string_dbg(&info->sid) ));
2733 return NT_STATUS_NO_SUCH_PRIVILEGE;
2736 return NT_STATUS_OK;
2739 /***************************************************************************
2740 _lsa_RemovePrivilegesFromAccount
2741 For a given SID, remove some privileges.
2742 ***************************************************************************/
2744 NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
2745 struct lsa_RemovePrivilegesFromAccount *r)
2747 struct lsa_info *info = NULL;
2748 struct lsa_PrivilegeSet *set = NULL;
2750 /* find the connection policy handle. */
2751 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2752 return NT_STATUS_INVALID_HANDLE;
2754 if (info->type != LSA_HANDLE_ACCOUNT_TYPE) {
2755 return NT_STATUS_INVALID_HANDLE;
2758 if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
2759 return NT_STATUS_ACCESS_DENIED;
2762 set = r->in.privs;
2764 if ( !revoke_privilege_set( &info->sid, set) ) {
2765 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2766 sid_string_dbg(&info->sid) ));
2767 return NT_STATUS_NO_SUCH_PRIVILEGE;
2770 return NT_STATUS_OK;
2773 /***************************************************************************
2774 _lsa_LookupPrivName
2775 ***************************************************************************/
2777 NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
2778 struct lsa_LookupPrivName *r)
2780 struct lsa_info *info = NULL;
2781 const char *name;
2782 struct lsa_StringLarge *lsa_name;
2784 /* find the connection policy handle. */
2785 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
2786 return NT_STATUS_INVALID_HANDLE;
2789 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2790 return NT_STATUS_INVALID_HANDLE;
2793 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
2794 return NT_STATUS_ACCESS_DENIED;
2797 if (r->in.luid->high != 0) {
2798 return NT_STATUS_NO_SUCH_PRIVILEGE;
2801 name = sec_privilege_name(r->in.luid->low);
2802 if (!name) {
2803 return NT_STATUS_NO_SUCH_PRIVILEGE;
2806 lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
2807 if (!lsa_name) {
2808 return NT_STATUS_NO_MEMORY;
2811 lsa_name->string = talloc_strdup(lsa_name, name);
2812 if (!lsa_name->string) {
2813 TALLOC_FREE(lsa_name);
2814 return NT_STATUS_NO_MEMORY;
2817 *r->out.name = lsa_name;
2819 return NT_STATUS_OK;
2822 /***************************************************************************
2823 _lsa_QuerySecurity
2824 ***************************************************************************/
2826 NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
2827 struct lsa_QuerySecurity *r)
2829 struct lsa_info *handle=NULL;
2830 struct security_descriptor *psd = NULL;
2831 size_t sd_size = 0;
2832 NTSTATUS status;
2834 /* find the connection policy handle. */
2835 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
2836 return NT_STATUS_INVALID_HANDLE;
2838 switch (handle->type) {
2839 case LSA_HANDLE_POLICY_TYPE:
2840 case LSA_HANDLE_ACCOUNT_TYPE:
2841 case LSA_HANDLE_TRUST_TYPE:
2842 psd = handle->sd;
2843 sd_size = ndr_size_security_descriptor(psd, 0);
2844 status = NT_STATUS_OK;
2845 break;
2846 default:
2847 status = NT_STATUS_INVALID_HANDLE;
2848 break;
2851 if (!NT_STATUS_IS_OK(status)) {
2852 return status;
2855 *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
2856 if (!*r->out.sdbuf) {
2857 return NT_STATUS_NO_MEMORY;
2860 return status;
2863 /***************************************************************************
2864 _lsa_AddAccountRights
2865 ***************************************************************************/
2867 NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
2868 struct lsa_AddAccountRights *r)
2870 struct lsa_info *info = NULL;
2871 int i = 0;
2872 uint32_t acc_granted = 0;
2873 struct security_descriptor *psd = NULL;
2874 size_t sd_size;
2875 struct dom_sid sid;
2876 NTSTATUS status;
2878 /* find the connection policy handle. */
2879 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2880 return NT_STATUS_INVALID_HANDLE;
2882 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2883 return NT_STATUS_INVALID_HANDLE;
2886 /* get the generic lsa account SD for this SID until we store it */
2887 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2888 &lsa_account_mapping,
2889 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2890 if (!NT_STATUS_IS_OK(status)) {
2891 return status;
2895 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
2896 * on the policy handle. If it does, ask for
2897 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2898 * on the account sid. We don't check here so just use the latter. JRA.
2901 status = access_check_object(psd, p->session_info->security_token,
2902 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2903 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
2904 &acc_granted, "_lsa_AddAccountRights" );
2905 if (!NT_STATUS_IS_OK(status)) {
2906 return status;
2909 /* according to an NT4 PDC, you can add privileges to SIDs even without
2910 call_lsa_create_account() first. And you can use any arbitrary SID. */
2912 sid_copy( &sid, r->in.sid );
2914 for ( i=0; i < r->in.rights->count; i++ ) {
2916 const char *privname = r->in.rights->names[i].string;
2918 /* only try to add non-null strings */
2920 if ( !privname )
2921 continue;
2923 if ( !grant_privilege_by_name( &sid, privname ) ) {
2924 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
2925 privname ));
2926 return NT_STATUS_NO_SUCH_PRIVILEGE;
2930 return NT_STATUS_OK;
2933 /***************************************************************************
2934 _lsa_RemoveAccountRights
2935 ***************************************************************************/
2937 NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
2938 struct lsa_RemoveAccountRights *r)
2940 struct lsa_info *info = NULL;
2941 int i = 0;
2942 struct security_descriptor *psd = NULL;
2943 size_t sd_size;
2944 struct dom_sid sid;
2945 const char *privname = NULL;
2946 uint32_t acc_granted = 0;
2947 NTSTATUS status;
2949 /* find the connection policy handle. */
2950 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
2951 return NT_STATUS_INVALID_HANDLE;
2953 if (info->type != LSA_HANDLE_POLICY_TYPE) {
2954 return NT_STATUS_INVALID_HANDLE;
2957 /* get the generic lsa account SD for this SID until we store it */
2958 status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2959 &lsa_account_mapping,
2960 r->in.sid, LSA_ACCOUNT_ALL_ACCESS);
2961 if (!NT_STATUS_IS_OK(status)) {
2962 return status;
2966 * From the MS DOCs. We need
2967 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
2968 * and DELETE on the account sid.
2971 status = access_check_object(psd, p->session_info->security_token,
2972 SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2973 LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2974 LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
2975 &acc_granted, "_lsa_RemoveAccountRights");
2976 if (!NT_STATUS_IS_OK(status)) {
2977 return status;
2980 sid_copy( &sid, r->in.sid );
2982 if ( r->in.remove_all ) {
2983 if ( !revoke_all_privileges( &sid ) )
2984 return NT_STATUS_ACCESS_DENIED;
2986 return NT_STATUS_OK;
2989 for ( i=0; i < r->in.rights->count; i++ ) {
2991 privname = r->in.rights->names[i].string;
2993 /* only try to add non-null strings */
2995 if ( !privname )
2996 continue;
2998 if ( !revoke_privilege_by_name( &sid, privname ) ) {
2999 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3000 privname ));
3001 return NT_STATUS_NO_SUCH_PRIVILEGE;
3005 return NT_STATUS_OK;
3008 /*******************************************************************
3009 ********************************************************************/
3011 static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3012 struct lsa_RightSet *r,
3013 PRIVILEGE_SET *privileges)
3015 uint32 i;
3016 const char *privname;
3017 const char **privname_array = NULL;
3018 int num_priv = 0;
3020 for (i=0; i<privileges->count; i++) {
3021 if (privileges->set[i].luid.high) {
3022 continue;
3024 privname = sec_privilege_name(privileges->set[i].luid.low);
3025 if (privname) {
3026 if (!add_string_to_array(mem_ctx, privname,
3027 &privname_array, &num_priv)) {
3028 return NT_STATUS_NO_MEMORY;
3033 if (num_priv) {
3035 r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge,
3036 num_priv);
3037 if (!r->names) {
3038 return NT_STATUS_NO_MEMORY;
3041 for (i=0; i<num_priv; i++) {
3042 init_lsa_StringLarge(&r->names[i], privname_array[i]);
3045 r->count = num_priv;
3048 return NT_STATUS_OK;
3051 /***************************************************************************
3052 _lsa_EnumAccountRights
3053 ***************************************************************************/
3055 NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3056 struct lsa_EnumAccountRights *r)
3058 NTSTATUS status;
3059 struct lsa_info *info = NULL;
3060 PRIVILEGE_SET *privileges;
3062 /* find the connection policy handle. */
3064 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3065 return NT_STATUS_INVALID_HANDLE;
3067 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3068 return NT_STATUS_INVALID_HANDLE;
3071 if (!(info->access & LSA_ACCOUNT_VIEW)) {
3072 return NT_STATUS_ACCESS_DENIED;
3075 /* according to an NT4 PDC, you can add privileges to SIDs even without
3076 call_lsa_create_account() first. And you can use any arbitrary SID. */
3078 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3079 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3080 * the lsa database */
3082 status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3083 if (!NT_STATUS_IS_OK(status)) {
3084 return status;
3087 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3088 sid_string_dbg(r->in.sid), privileges->count));
3090 status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3092 return status;
3095 /***************************************************************************
3096 _lsa_LookupPrivValue
3097 ***************************************************************************/
3099 NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3100 struct lsa_LookupPrivValue *r)
3102 struct lsa_info *info = NULL;
3103 const char *name = NULL;
3105 /* find the connection policy handle. */
3107 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3108 return NT_STATUS_INVALID_HANDLE;
3110 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3111 return NT_STATUS_INVALID_HANDLE;
3114 if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3115 return NT_STATUS_ACCESS_DENIED;
3117 name = r->in.name->string;
3119 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3121 r->out.luid->low = sec_privilege_id(name);
3122 r->out.luid->high = 0;
3123 if (r->out.luid->low == SEC_PRIV_INVALID) {
3124 return NT_STATUS_NO_SUCH_PRIVILEGE;
3126 return NT_STATUS_OK;
3129 /***************************************************************************
3130 _lsa_EnumAccountsWithUserRight
3131 ***************************************************************************/
3133 NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3134 struct lsa_EnumAccountsWithUserRight *r)
3136 NTSTATUS status;
3137 struct lsa_info *info = NULL;
3138 struct dom_sid *sids = NULL;
3139 int num_sids = 0;
3140 uint32_t i;
3141 enum sec_privilege privilege;
3143 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
3144 return NT_STATUS_INVALID_HANDLE;
3147 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3148 return NT_STATUS_INVALID_HANDLE;
3151 if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3152 return NT_STATUS_ACCESS_DENIED;
3155 if (!r->in.name || !r->in.name->string) {
3156 return NT_STATUS_NO_SUCH_PRIVILEGE;
3159 privilege = sec_privilege_id(r->in.name->string);
3160 if (privilege == SEC_PRIV_INVALID) {
3161 return NT_STATUS_NO_SUCH_PRIVILEGE;
3164 status = privilege_enum_sids(privilege, p->mem_ctx,
3165 &sids, &num_sids);
3166 if (!NT_STATUS_IS_OK(status)) {
3167 return status;
3170 r->out.sids->num_sids = num_sids;
3171 r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3172 r->out.sids->num_sids);
3174 for (i=0; i < r->out.sids->num_sids; i++) {
3175 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3176 &sids[i]);
3177 if (!r->out.sids->sids[i].sid) {
3178 TALLOC_FREE(r->out.sids->sids);
3179 r->out.sids->num_sids = 0;
3180 return NT_STATUS_NO_MEMORY;
3184 return NT_STATUS_OK;
3187 /***************************************************************************
3188 _lsa_Delete
3189 ***************************************************************************/
3191 NTSTATUS _lsa_Delete(struct pipes_struct *p,
3192 struct lsa_Delete *r)
3194 return NT_STATUS_NOT_SUPPORTED;
3198 * From here on the server routines are just dummy ones to make smbd link with
3199 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3200 * pulling the server stubs across one by one.
3203 NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3205 p->rng_fault_state = True;
3206 return NT_STATUS_NOT_IMPLEMENTED;
3209 NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3210 struct lsa_ChangePassword *r)
3212 p->rng_fault_state = True;
3213 return NT_STATUS_NOT_IMPLEMENTED;
3216 NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
3218 p->rng_fault_state = True;
3219 return NT_STATUS_NOT_IMPLEMENTED;
3222 NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
3224 p->rng_fault_state = True;
3225 return NT_STATUS_NOT_IMPLEMENTED;
3228 NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
3229 struct lsa_GetQuotasForAccount *r)
3231 p->rng_fault_state = True;
3232 return NT_STATUS_NOT_IMPLEMENTED;
3235 NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
3236 struct lsa_SetQuotasForAccount *r)
3238 p->rng_fault_state = True;
3239 return NT_STATUS_NOT_IMPLEMENTED;
3242 NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3243 struct lsa_SetInformationTrustedDomain *r)
3245 p->rng_fault_state = True;
3246 return NT_STATUS_NOT_IMPLEMENTED;
3249 NTSTATUS _lsa_QuerySecret(struct pipes_struct *p, struct lsa_QuerySecret *r)
3251 p->rng_fault_state = True;
3252 return NT_STATUS_NOT_IMPLEMENTED;
3255 NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3256 struct lsa_SetTrustedDomainInfo *r)
3258 p->rng_fault_state = True;
3259 return NT_STATUS_NOT_IMPLEMENTED;
3262 NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
3263 struct lsa_StorePrivateData *r)
3265 p->rng_fault_state = True;
3266 return NT_STATUS_NOT_IMPLEMENTED;
3269 NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
3270 struct lsa_RetrievePrivateData *r)
3272 p->rng_fault_state = True;
3273 return NT_STATUS_NOT_IMPLEMENTED;
3276 NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
3277 struct lsa_SetInfoPolicy2 *r)
3279 p->rng_fault_state = True;
3280 return NT_STATUS_NOT_IMPLEMENTED;
3283 NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3284 struct lsa_SetTrustedDomainInfoByName *r)
3286 p->rng_fault_state = True;
3287 return NT_STATUS_NOT_IMPLEMENTED;
3290 NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
3291 struct lsa_EnumTrustedDomainsEx *r)
3293 struct lsa_info *info;
3294 uint32_t count;
3295 struct pdb_trusted_domain **domains;
3296 struct lsa_TrustDomainInfoInfoEx *entries;
3297 int i;
3298 NTSTATUS nt_status;
3300 /* bail out early if pdb backend is not capable of ex trusted domains,
3301 * if we dont do that, the client might not call
3302 * _lsa_EnumTrustedDomains() afterwards - gd */
3304 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
3305 p->rng_fault_state = True;
3306 return NT_STATUS_NOT_IMPLEMENTED;
3309 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
3310 return NT_STATUS_INVALID_HANDLE;
3312 if (info->type != LSA_HANDLE_POLICY_TYPE) {
3313 return NT_STATUS_INVALID_HANDLE;
3316 /* check if the user has enough rights */
3317 if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
3318 return NT_STATUS_ACCESS_DENIED;
3320 become_root();
3321 nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
3322 unbecome_root();
3324 if (!NT_STATUS_IS_OK(nt_status)) {
3325 return nt_status;
3328 entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
3329 count);
3330 if (!entries) {
3331 return NT_STATUS_NO_MEMORY;
3334 for (i=0; i<count; i++) {
3335 init_lsa_StringLarge(&entries[i].netbios_name,
3336 domains[i]->netbios_name);
3337 entries[i].sid = &domains[i]->security_identifier;
3340 if (*r->in.resume_handle >= count) {
3341 *r->out.resume_handle = -1;
3342 TALLOC_FREE(entries);
3343 return NT_STATUS_NO_MORE_ENTRIES;
3346 /* return the rest, limit by max_size. Note that we
3347 use the w2k3 element size value of 60 */
3348 r->out.domains->count = count - *r->in.resume_handle;
3349 r->out.domains->count = MIN(r->out.domains->count,
3350 (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
3352 r->out.domains->domains = entries + *r->in.resume_handle;
3354 if (r->out.domains->count < count - *r->in.resume_handle) {
3355 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
3356 return STATUS_MORE_ENTRIES;
3359 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3360 * always be larger than the previous input resume handle, in
3361 * particular when hitting the last query it is vital to set the
3362 * resume handle correctly to avoid infinite client loops, as
3363 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3364 * status is NT_STATUS_OK - gd */
3366 *r->out.resume_handle = (uint32_t)-1;
3368 return NT_STATUS_OK;
3371 NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
3372 struct lsa_QueryDomainInformationPolicy *r)
3374 p->rng_fault_state = True;
3375 return NT_STATUS_NOT_IMPLEMENTED;
3378 NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
3379 struct lsa_SetDomainInformationPolicy *r)
3381 p->rng_fault_state = True;
3382 return NT_STATUS_NOT_IMPLEMENTED;
3385 NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
3387 p->rng_fault_state = True;
3388 return NT_STATUS_NOT_IMPLEMENTED;
3391 NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
3393 p->rng_fault_state = True;
3394 return NT_STATUS_NOT_IMPLEMENTED;
3397 NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
3399 p->rng_fault_state = True;
3400 return NT_STATUS_NOT_IMPLEMENTED;
3403 NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
3405 p->rng_fault_state = True;
3406 return NT_STATUS_NOT_IMPLEMENTED;
3409 NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
3410 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3412 p->rng_fault_state = True;
3413 return NT_STATUS_NOT_IMPLEMENTED;
3416 NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
3417 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3419 p->rng_fault_state = True;
3420 return NT_STATUS_NOT_IMPLEMENTED;
3423 NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
3425 p->rng_fault_state = True;
3426 return NT_STATUS_NOT_IMPLEMENTED;
3429 NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
3430 struct lsa_CREDRGETTARGETINFO *r)
3432 p->rng_fault_state = True;
3433 return NT_STATUS_NOT_IMPLEMENTED;
3436 NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
3437 struct lsa_CREDRPROFILELOADED *r)
3439 p->rng_fault_state = True;
3440 return NT_STATUS_NOT_IMPLEMENTED;
3443 NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
3444 struct lsa_CREDRGETSESSIONTYPES *r)
3446 p->rng_fault_state = True;
3447 return NT_STATUS_NOT_IMPLEMENTED;
3450 NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
3451 struct lsa_LSARREGISTERAUDITEVENT *r)
3453 p->rng_fault_state = True;
3454 return NT_STATUS_NOT_IMPLEMENTED;
3457 NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
3458 struct lsa_LSARGENAUDITEVENT *r)
3460 p->rng_fault_state = True;
3461 return NT_STATUS_NOT_IMPLEMENTED;
3464 NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
3465 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3467 p->rng_fault_state = True;
3468 return NT_STATUS_NOT_IMPLEMENTED;
3471 NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
3472 struct lsa_lsaRQueryForestTrustInformation *r)
3474 p->rng_fault_state = True;
3475 return NT_STATUS_NOT_IMPLEMENTED;
3478 #define DNS_CMP_MATCH 0
3479 #define DNS_CMP_FIRST_IS_CHILD 1
3480 #define DNS_CMP_SECOND_IS_CHILD 2
3481 #define DNS_CMP_NO_MATCH 3
3483 /* this function assumes names are well formed DNS names.
3484 * it doesn't validate them */
3485 static int dns_cmp(const char *s1, size_t l1,
3486 const char *s2, size_t l2)
3488 const char *p1, *p2;
3489 size_t t1, t2;
3490 int cret;
3492 if (l1 == l2) {
3493 if (StrCaseCmp(s1, s2) == 0) {
3494 return DNS_CMP_MATCH;
3496 return DNS_CMP_NO_MATCH;
3499 if (l1 > l2) {
3500 p1 = s1;
3501 p2 = s2;
3502 t1 = l1;
3503 t2 = l2;
3504 cret = DNS_CMP_FIRST_IS_CHILD;
3505 } else {
3506 p1 = s2;
3507 p2 = s1;
3508 t1 = l2;
3509 t2 = l1;
3510 cret = DNS_CMP_SECOND_IS_CHILD;
3513 if (p1[t1 - t2 - 1] != '.') {
3514 return DNS_CMP_NO_MATCH;
3517 if (StrCaseCmp(&p1[t1 - t2], p2) == 0) {
3518 return cret;
3521 return DNS_CMP_NO_MATCH;
3524 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
3525 struct lsa_ForestTrustInformation *lfti,
3526 struct ForestTrustInfo *fti)
3528 struct lsa_ForestTrustRecord *lrec;
3529 struct ForestTrustInfoRecord *rec;
3530 struct lsa_StringLarge *tln;
3531 struct lsa_ForestTrustDomainInfo *info;
3532 uint32_t i;
3534 fti->version = 1;
3535 fti->count = lfti->count;
3536 fti->records = talloc_array(mem_ctx,
3537 struct ForestTrustInfoRecordArmor,
3538 fti->count);
3539 if (!fti->records) {
3540 return NT_STATUS_NO_MEMORY;
3542 for (i = 0; i < fti->count; i++) {
3543 lrec = lfti->entries[i];
3544 rec = &fti->records[i].record;
3546 rec->flags = lrec->flags;
3547 rec->timestamp = lrec->time;
3548 rec->type = lrec->type;
3550 switch (lrec->type) {
3551 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
3552 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3553 tln = &lrec->forest_trust_data.top_level_name;
3554 rec->data.name.string =
3555 talloc_strdup(mem_ctx, tln->string);
3556 if (!rec->data.name.string) {
3557 return NT_STATUS_NO_MEMORY;
3559 rec->data.name.size = strlen(rec->data.name.string);
3560 break;
3561 case LSA_FOREST_TRUST_DOMAIN_INFO:
3562 info = &lrec->forest_trust_data.domain_info;
3563 rec->data.info.sid = *info->domain_sid;
3564 rec->data.info.dns_name.string =
3565 talloc_strdup(mem_ctx,
3566 info->dns_domain_name.string);
3567 if (!rec->data.info.dns_name.string) {
3568 return NT_STATUS_NO_MEMORY;
3570 rec->data.info.dns_name.size =
3571 strlen(rec->data.info.dns_name.string);
3572 rec->data.info.netbios_name.string =
3573 talloc_strdup(mem_ctx,
3574 info->netbios_domain_name.string);
3575 if (!rec->data.info.netbios_name.string) {
3576 return NT_STATUS_NO_MEMORY;
3578 rec->data.info.netbios_name.size =
3579 strlen(rec->data.info.netbios_name.string);
3580 break;
3581 default:
3582 return NT_STATUS_INVALID_DOMAIN_STATE;
3586 return NT_STATUS_OK;
3589 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3590 uint32_t index, uint32_t collision_type,
3591 uint32_t conflict_type, const char *tdo_name);
3593 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
3594 const char *tdo_name,
3595 struct ForestTrustInfo *tdo_fti,
3596 struct ForestTrustInfo *new_fti,
3597 struct lsa_ForestTrustCollisionInfo *c_info)
3599 struct ForestTrustInfoRecord *nrec;
3600 struct ForestTrustInfoRecord *trec;
3601 const char *dns_name;
3602 const char *nb_name = NULL;
3603 struct dom_sid *sid = NULL;
3604 const char *tname = NULL;
3605 size_t dns_len = 0;
3606 size_t nb_len;
3607 size_t tlen = 0;
3608 NTSTATUS nt_status;
3609 uint32_t new_fti_idx;
3610 uint32_t i;
3611 /* use always TDO type, until we understand when Xref can be used */
3612 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
3613 bool tln_conflict;
3614 bool sid_conflict;
3615 bool nb_conflict;
3616 bool exclusion;
3617 bool ex_rule = false;
3618 int ret;
3620 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
3622 nrec = &new_fti->records[new_fti_idx].record;
3623 dns_name = NULL;
3624 tln_conflict = false;
3625 sid_conflict = false;
3626 nb_conflict = false;
3627 exclusion = false;
3629 switch (nrec->type) {
3630 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
3631 /* exclusions do not conflict by definition */
3632 break;
3634 case FOREST_TRUST_TOP_LEVEL_NAME:
3635 dns_name = nrec->data.name.string;
3636 dns_len = nrec->data.name.size;
3637 break;
3639 case LSA_FOREST_TRUST_DOMAIN_INFO:
3640 dns_name = nrec->data.info.dns_name.string;
3641 dns_len = nrec->data.info.dns_name.size;
3642 nb_name = nrec->data.info.netbios_name.string;
3643 nb_len = nrec->data.info.netbios_name.size;
3644 sid = &nrec->data.info.sid;
3645 break;
3648 if (!dns_name) continue;
3650 /* check if this is already taken and not excluded */
3651 for (i = 0; i < tdo_fti->count; i++) {
3652 trec = &tdo_fti->records[i].record;
3654 switch (trec->type) {
3655 case FOREST_TRUST_TOP_LEVEL_NAME:
3656 ex_rule = false;
3657 tname = trec->data.name.string;
3658 tlen = trec->data.name.size;
3659 break;
3660 case FOREST_TRUST_TOP_LEVEL_NAME_EX:
3661 ex_rule = true;
3662 tname = trec->data.name.string;
3663 tlen = trec->data.name.size;
3664 break;
3665 case FOREST_TRUST_DOMAIN_INFO:
3666 ex_rule = false;
3667 tname = trec->data.info.dns_name.string;
3668 tlen = trec->data.info.dns_name.size;
3669 break;
3670 default:
3671 return NT_STATUS_INVALID_PARAMETER;
3673 ret = dns_cmp(dns_name, dns_len, tname, tlen);
3674 switch (ret) {
3675 case DNS_CMP_MATCH:
3676 /* if it matches exclusion,
3677 * it doesn't conflict */
3678 if (ex_rule) {
3679 exclusion = true;
3680 break;
3682 /* fall through */
3683 case DNS_CMP_FIRST_IS_CHILD:
3684 case DNS_CMP_SECOND_IS_CHILD:
3685 tln_conflict = true;
3686 /* fall through */
3687 default:
3688 break;
3691 /* explicit exclusion, no dns name conflict here */
3692 if (exclusion) {
3693 tln_conflict = false;
3696 if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
3697 continue;
3700 /* also test for domain info */
3701 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
3702 dom_sid_compare(&trec->data.info.sid, sid) == 0) {
3703 sid_conflict = true;
3705 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
3706 StrCaseCmp(trec->data.info.netbios_name.string,
3707 nb_name) == 0) {
3708 nb_conflict = true;
3712 if (tln_conflict) {
3713 nt_status = add_collision(c_info, new_fti_idx,
3714 collision_type,
3715 LSA_TLN_DISABLED_CONFLICT,
3716 tdo_name);
3718 if (sid_conflict) {
3719 nt_status = add_collision(c_info, new_fti_idx,
3720 collision_type,
3721 LSA_SID_DISABLED_CONFLICT,
3722 tdo_name);
3724 if (nb_conflict) {
3725 nt_status = add_collision(c_info, new_fti_idx,
3726 collision_type,
3727 LSA_NB_DISABLED_CONFLICT,
3728 tdo_name);
3732 return NT_STATUS_OK;
3735 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
3736 uint32_t idx, uint32_t collision_type,
3737 uint32_t conflict_type, const char *tdo_name)
3739 struct lsa_ForestTrustCollisionRecord **es;
3740 uint32_t i = c_info->count;
3742 es = talloc_realloc(c_info, c_info->entries,
3743 struct lsa_ForestTrustCollisionRecord *, i + 1);
3744 if (!es) {
3745 return NT_STATUS_NO_MEMORY;
3747 c_info->entries = es;
3748 c_info->count = i + 1;
3750 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
3751 if (!es[i]) {
3752 return NT_STATUS_NO_MEMORY;
3755 es[i]->index = idx;
3756 es[i]->type = collision_type;
3757 es[i]->flags.flags = conflict_type;
3758 es[i]->name.string = talloc_strdup(es[i], tdo_name);
3759 if (!es[i]->name.string) {
3760 return NT_STATUS_NO_MEMORY;
3762 es[i]->name.size = strlen(es[i]->name.string);
3764 return NT_STATUS_OK;
3767 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
3768 struct pdb_trusted_domain *td,
3769 struct ForestTrustInfo *info)
3771 enum ndr_err_code ndr_err;
3773 if (td->trust_forest_trust_info.length == 0 ||
3774 td->trust_forest_trust_info.data == NULL) {
3775 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3777 ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
3778 info,
3779 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
3780 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3781 return NT_STATUS_INVALID_DOMAIN_STATE;
3784 return NT_STATUS_OK;
3787 static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
3788 struct ForestTrustInfo *fti)
3790 struct ForestTrustDataDomainInfo *info;
3791 struct ForestTrustInfoRecord *rec;
3793 fti->version = 1;
3794 fti->count = 2;
3795 fti->records = talloc_array(fti,
3796 struct ForestTrustInfoRecordArmor, 2);
3797 if (!fti->records) {
3798 return NT_STATUS_NO_MEMORY;
3801 /* TLN info */
3802 rec = &fti->records[0].record;
3804 rec->flags = 0;
3805 rec->timestamp = 0;
3806 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
3808 rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
3809 if (!rec->data.name.string) {
3810 return NT_STATUS_NO_MEMORY;
3812 rec->data.name.size = strlen(rec->data.name.string);
3814 /* DOMAIN info */
3815 rec = &fti->records[1].record;
3817 rec->flags = 0;
3818 rec->timestamp = 0;
3819 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO;
3821 info = &rec->data.info;
3823 info->sid = dom_info->sid;
3824 info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
3825 if (!info->dns_name.string) {
3826 return NT_STATUS_NO_MEMORY;
3828 info->dns_name.size = strlen(info->dns_name.string);
3829 info->netbios_name.string = talloc_strdup(fti, dom_info->name);
3830 if (!info->netbios_name.string) {
3831 return NT_STATUS_NO_MEMORY;
3833 info->netbios_name.size = strlen(info->netbios_name.string);
3835 return NT_STATUS_OK;
3838 NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
3839 struct lsa_lsaRSetForestTrustInformation *r)
3841 NTSTATUS status;
3842 int i;
3843 int j;
3844 struct lsa_info *handle;
3845 uint32_t num_domains;
3846 struct pdb_trusted_domain **domains;
3847 struct ForestTrustInfo *nfti;
3848 struct ForestTrustInfo *fti;
3849 struct lsa_ForestTrustCollisionInfo *c_info;
3850 struct pdb_domain_info *dom_info;
3851 enum ndr_err_code ndr_err;
3853 if (!IS_DC) {
3854 return NT_STATUS_NOT_SUPPORTED;
3857 if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) {
3858 return NT_STATUS_INVALID_HANDLE;
3861 if (handle->type != LSA_HANDLE_TRUST_TYPE) {
3862 return NT_STATUS_INVALID_HANDLE;
3865 if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
3866 return NT_STATUS_ACCESS_DENIED;
3869 status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
3870 if (!NT_STATUS_IS_OK(status)) {
3871 return status;
3873 if (num_domains == 0) {
3874 return NT_STATUS_NO_SUCH_DOMAIN;
3877 for (i = 0; i < num_domains; i++) {
3878 if (domains[i]->domain_name == NULL) {
3879 return NT_STATUS_INVALID_DOMAIN_STATE;
3881 if (StrCaseCmp(domains[i]->domain_name,
3882 r->in.trusted_domain_name->string) == 0) {
3883 break;
3886 if (i >= num_domains) {
3887 return NT_STATUS_NO_SUCH_DOMAIN;
3890 if (!(domains[i]->trust_attributes &
3891 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
3892 return NT_STATUS_INVALID_PARAMETER;
3895 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
3896 return NT_STATUS_INVALID_PARAMETER;
3899 /* The following section until COPY_END is a copy from
3900 * source4/rpmc_server/lsa/scesrc_lsa.c */
3901 nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
3902 if (!nfti) {
3903 return NT_STATUS_NO_MEMORY;
3906 status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
3907 if (!NT_STATUS_IS_OK(status)) {
3908 return status;
3911 c_info = talloc_zero(r->out.collision_info,
3912 struct lsa_ForestTrustCollisionInfo);
3913 if (!c_info) {
3914 return NT_STATUS_NO_MEMORY;
3917 /* first check own info, then other domains */
3918 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3919 if (!fti) {
3920 return NT_STATUS_NO_MEMORY;
3923 dom_info = pdb_get_domain_info(p->mem_ctx);
3925 status = own_ft_info(dom_info, fti);
3926 if (!NT_STATUS_IS_OK(status)) {
3927 return status;
3930 status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
3931 if (!NT_STATUS_IS_OK(status)) {
3932 return status;
3935 for (j = 0; j < num_domains; j++) {
3936 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
3937 if (!fti) {
3938 return NT_STATUS_NO_MEMORY;
3941 status = get_ft_info(p->mem_ctx, domains[j], fti);
3942 if (!NT_STATUS_IS_OK(status)) {
3943 if (NT_STATUS_EQUAL(status,
3944 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3945 continue;
3947 return status;
3950 if (domains[j]->domain_name == NULL) {
3951 return NT_STATUS_INVALID_DOMAIN_STATE;
3954 status = check_ft_info(c_info, domains[j]->domain_name,
3955 fti, nfti, c_info);
3956 if (!NT_STATUS_IS_OK(status)) {
3957 return status;
3961 *r->out.collision_info = c_info;
3963 if (r->in.check_only != 0) {
3964 return NT_STATUS_OK;
3967 /* COPY_END */
3969 ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
3970 p->mem_ctx, nfti,
3971 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
3972 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3973 return NT_STATUS_INVALID_PARAMETER;
3976 status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
3977 if (!NT_STATUS_IS_OK(status)) {
3978 return status;
3981 return NT_STATUS_OK;
3984 NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
3985 struct lsa_CREDRRENAME *r)
3987 p->rng_fault_state = True;
3988 return NT_STATUS_NOT_IMPLEMENTED;
3991 NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
3992 struct lsa_LSAROPENPOLICYSCE *r)
3994 p->rng_fault_state = True;
3995 return NT_STATUS_NOT_IMPLEMENTED;
3998 NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
3999 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4001 p->rng_fault_state = True;
4002 return NT_STATUS_NOT_IMPLEMENTED;
4005 NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4006 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4008 p->rng_fault_state = True;
4009 return NT_STATUS_NOT_IMPLEMENTED;
4012 NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4013 struct lsa_LSARADTREPORTSECURITYEVENT *r)
4015 p->rng_fault_state = True;
4016 return NT_STATUS_NOT_IMPLEMENTED;