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. */
34 #include "../librpc/gen_ndr/srv_lsa.h"
36 #include "../librpc/gen_ndr/netlogon.h"
37 #include "rpc_client/init_lsa.h"
38 #include "../libcli/security/security.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../librpc/gen_ndr/drsblobs.h"
41 #include "../librpc/gen_ndr/ndr_drsblobs.h"
42 #include "../lib/crypto/arcfour.h"
43 #include "../libcli/security/dom_sid.h"
44 #include "../librpc/gen_ndr/ndr_security.h"
47 #include "lib/privileges.h"
48 #include "rpc_server/srv_access_check.h"
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};
64 enum lsa_handle_type type
;
65 struct security_descriptor
*sd
;
68 const struct generic_mapping lsa_account_mapping
= {
72 LSA_ACCOUNT_ALL_ACCESS
75 const struct generic_mapping lsa_policy_mapping
= {
82 const struct generic_mapping lsa_secret_mapping
= {
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
)
107 if (dom_name
!= NULL
) {
108 for (num
= 0; num
< ref
->count
; num
++) {
109 if (dom_sid_equal(dom_sid
, ref
->domains
[num
].sid
)) {
117 if (num
>= LSA_REF_DOMAIN_LIST_MULTIPLIER
) {
118 /* index not found, already at maximum domain limit */
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
);
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
) {
143 /***************************************************************************
144 initialize a lsa_DomainInfo structure.
145 ***************************************************************************/
147 static void init_dom_query_3(struct lsa_DomainInfo
*r
,
151 init_lsa_StringLarge(&r
->name
, name
);
155 /***************************************************************************
156 initialize a lsa_DomainInfo structure.
157 ***************************************************************************/
159 static void init_dom_query_5(struct lsa_DomainInfo
*r
,
163 init_lsa_StringLarge(&r
->name
, name
);
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
,
177 uint32_t *pmapped_count
)
179 uint32 mapped_count
, i
;
181 SMB_ASSERT(num_entries
<= MAX_LOOKUP_SIDS
);
186 for (i
= 0; i
< num_entries
; i
++) {
190 const char *full_name
;
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
;
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
,
215 case SID_NAME_DOM_GRP
:
216 case SID_NAME_DOMAIN
:
218 case SID_NAME_WKN_GRP
:
219 DEBUG(5, ("init_lsa_rids: %s found\n", full_name
));
220 /* Leave these unchanged */
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
;
232 if (type
!= SID_NAME_UNKNOWN
) {
233 if (type
== SID_NAME_DOMAIN
) {
236 sid_split_rid(&sid
, &rid
);
238 dom_idx
= init_lsa_ref_domain_list(mem_ctx
, ref
, domain
, &sid
);
242 prid
[i
].sid_type
= type
;
244 prid
[i
].sid_index
= dom_idx
;
247 *pmapped_count
= mapped_count
;
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
,
261 uint32
*pmapped_count
)
263 uint32 mapped_count
, i
;
265 SMB_ASSERT(num_entries
<= MAX_LOOKUP_SIDS
);
270 for (i
= 0; i
< num_entries
; i
++) {
274 const char *full_name
;
276 enum lsa_SidType type
;
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
,
291 type
= SID_NAME_UNKNOWN
;
296 case SID_NAME_DOM_GRP
:
297 case SID_NAME_DOMAIN
:
299 case SID_NAME_WKN_GRP
:
300 DEBUG(5, ("init_lsa_sids: %s found\n", full_name
));
301 /* Leave these unchanged */
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
;
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
);
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
;
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];
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 */
361 init_sec_ace(&ace
[i
++], sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
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
;
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
,
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
);
394 return NT_STATUS_NO_MEMORY
;
398 info
->access
= acc_granted
;
401 sid_copy(&info
->sid
, sid
);
404 info
->name
= talloc_strdup(info
, name
);
407 info
->sd
= dup_sec_desc(info
, sd
);
410 return NT_STATUS_NO_MEMORY
;
414 if (!create_policy_hnd(p
, handle
, info
)) {
416 ZERO_STRUCTP(handle
);
417 return NT_STATUS_NO_MEMORY
;
423 /***************************************************************************
425 ***************************************************************************/
427 NTSTATUS
_lsa_OpenPolicy2(struct pipes_struct
*p
,
428 struct lsa_OpenPolicy2
*r
)
430 struct security_descriptor
*psd
= NULL
;
432 uint32 des_access
= r
->in
.access_mask
;
436 /* Work out max allowed. */
437 map_max_allowed_access(p
->session_info
->security_token
,
438 &p
->session_info
->utok
,
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
,
447 if (!NT_STATUS_IS_OK(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
)) {
458 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
459 LSA_HANDLE_POLICY_TYPE
,
461 get_global_sam_sid(),
465 if (!NT_STATUS_IS_OK(status
)) {
466 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
472 /***************************************************************************
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.
493 ***************************************************************************/
495 NTSTATUS
_lsa_EnumTrustDom(struct pipes_struct
*p
,
496 struct lsa_EnumTrustDom
*r
)
498 struct lsa_info
*info
;
500 struct trustdom_info
**domains
;
501 struct lsa_DomainInfo
*entries
;
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
;
517 nt_status
= pdb_enum_trusteddoms(p
->mem_ctx
, &count
, &domains
);
520 if (!NT_STATUS_IS_OK(nt_status
)) {
524 entries
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, struct lsa_DomainInfo
, count
);
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;
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 /***************************************************************************
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
;
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
;
596 case LSA_POLICY_INFO_DOMAIN
:
597 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
599 case LSA_POLICY_INFO_PD
:
600 acc_required
= LSA_POLICY_GET_PRIVATE_INFORMATION
;
602 case LSA_POLICY_INFO_ACCOUNT_DOMAIN
:
603 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
605 case LSA_POLICY_INFO_ROLE
:
606 case LSA_POLICY_INFO_REPLICA
:
607 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
609 case LSA_POLICY_INFO_QUOTA
:
610 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
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
;
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
;
628 if (!(handle
->access
& acc_required
)) {
629 /* return NT_STATUS_ACCESS_DENIED; */
632 info
= TALLOC_ZERO_P(p
->mem_ctx
, union lsa_PolicyInformation
);
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
;
652 case LSA_POLICY_INFO_PD
:
653 info
->pd
.name
.string
= NULL
;
654 status
= NT_STATUS_OK
;
656 case LSA_POLICY_INFO_REPLICA
:
657 info
->replica
.source
.string
= NULL
;
658 info
->replica
.account
.string
= NULL
;
659 status
= NT_STATUS_OK
;
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
;
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
;
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());
714 return NT_STATUS_NO_MEMORY
;
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
);
723 return NT_STATUS_NO_MEMORY
;
726 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
729 case ROLE_STANDALONE
:
730 name
= lp_workgroup();
734 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
736 init_dom_query_3(&info
->domain
, name
, sid
);
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
);
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
;
764 * any other role is a primary
765 * of the domain, it controls.
767 info
->role
.role
= LSA_ROLE_PRIMARY
;
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
;
782 dominfo
= pdb_get_domain_info(info
);
783 if (dominfo
== NULL
) {
784 status
= NT_STATUS_NO_MEMORY
;
788 init_lsa_StringLarge(&info
->dns
.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
;
799 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
801 status
= NT_STATUS_INVALID_INFO_CLASS
;
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
;
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
,
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 */
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;
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
)) {
880 names
= TALLOC_ARRAY(p
->mem_ctx
, struct lsa_TranslatedName2
, num_sids
);
882 return NT_STATUS_NO_MEMORY
;
885 for (i
=0; i
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; i
++) {
887 if (!dom_infos
[i
].valid
) {
891 if (init_lsa_ref_domain_list(mem_ctx
, ref
,
893 &dom_infos
[i
].sid
) != i
) {
894 DEBUG(0, ("Domain %s mentioned twice??\n",
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
) {
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
;
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
;
941 /***************************************************************************
943 ***************************************************************************/
945 NTSTATUS
_lsa_LookupSids(struct pipes_struct
*p
,
946 struct lsa_LookupSids
*r
)
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
;
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
,
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
)) {
1001 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
1002 names_out
= TALLOC_ARRAY(p
->mem_ctx
, struct lsa_TranslatedName
,
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
;
1022 /***************************************************************************
1024 ***************************************************************************/
1026 NTSTATUS
_lsa_LookupSids2(struct pipes_struct
*p
,
1027 struct lsa_LookupSids2
*r
)
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;
1038 case NDR_LSA_LOOKUPSIDS3
:
1039 check_policy
= false;
1041 case NDR_LSA_LOOKUPSIDS2
:
1043 check_policy
= true;
1046 if ((r
->in
.level
< 1) || (r
->in
.level
> 6)) {
1047 return NT_STATUS_INVALID_PARAMETER
;
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
,
1080 *r
->out
.domains
= domains
;
1081 r
->out
.names
->count
= num_sids
;
1082 r
->out
.names
->names
= names
;
1083 *r
->out
.count
= mapped_count
;
1088 /***************************************************************************
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
;
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
)
1127 case LSA_LOOKUP_NAMES_ALL
: /* 1 */
1128 flags
= LOOKUP_NAME_ALL
;
1130 case LSA_LOOKUP_NAMES_DOMAINS_ONLY
: /* 2 */
1131 flags
= LOOKUP_NAME_DOMAIN
|LOOKUP_NAME_REMOTE
|LOOKUP_NAME_ISOLATED
;
1133 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY
: /* 3 */
1134 flags
= LOOKUP_NAME_DOMAIN
|LOOKUP_NAME_ISOLATED
;
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 */
1141 flags
= LOOKUP_NAME_NONE
;
1148 /***************************************************************************
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;
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",
1170 flags
= lsa_lookup_level_to_flags(r
->in
.level
);
1172 domains
= TALLOC_ZERO_P(p
->mem_ctx
, struct lsa_RefDomainList
);
1174 return NT_STATUS_NO_MEMORY
;
1178 rids
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, struct lsa_TranslatedSid
,
1181 return NT_STATUS_NO_MEMORY
;
1187 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1188 status
= NT_STATUS_INVALID_HANDLE
;
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
;
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
);
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
;
1226 /***************************************************************************
1228 ***************************************************************************/
1230 NTSTATUS
_lsa_LookupNames2(struct pipes_struct
*p
,
1231 struct lsa_LookupNames2
*r
)
1234 struct lsa_LookupNames q
;
1235 struct lsa_TransSidArray2
*sid_array2
= r
->in
.sids
;
1236 struct lsa_TransSidArray
*sid_array
= NULL
;
1239 sid_array
= TALLOC_ZERO_P(p
->mem_ctx
, struct lsa_TransSidArray
);
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
;
1278 /***************************************************************************
1280 ***************************************************************************/
1282 NTSTATUS
_lsa_LookupNames3(struct pipes_struct
*p
,
1283 struct lsa_LookupNames3
*r
)
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;
1293 bool check_policy
= true;
1296 case NDR_LSA_LOOKUPNAMES4
:
1297 check_policy
= false;
1299 case NDR_LSA_LOOKUPNAMES3
:
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
);
1316 return NT_STATUS_NO_MEMORY
;
1320 trans_sids
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, struct lsa_TranslatedSid3
,
1323 return NT_STATUS_NO_MEMORY
;
1331 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1332 status
= NT_STATUS_INVALID_HANDLE
;
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
;
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
);
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
;
1371 /***************************************************************************
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
;
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
)
1426 uint32_t num_domains
= 0;
1427 struct trustdom_info
**domains
= NULL
;
1430 status
= pdb_enum_trusteddoms(mem_ctx
, &num_domains
, &domains
);
1431 if (!NT_STATUS_IS_OK(status
)) {
1435 for (i
=0; i
< num_domains
; i
++) {
1436 if (dom_sid_equal(&domains
[i
]->sid
, sid
)) {
1441 if (i
== num_domains
) {
1442 return NT_STATUS_INVALID_PARAMETER
;
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
)
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
)) {
1466 info
= talloc(mem_ctx
, struct trustdom_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
);
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
;
1500 uint32_t acc_granted
;
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
,
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
,
1518 if (!NT_STATUS_IS_OK(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
)) {
1530 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
1531 LSA_HANDLE_TRUST_TYPE
,
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
;
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
,
1566 if (!NT_STATUS_IS_OK(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
;
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
,
1596 if (!NT_STATUS_IS_OK(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
)
1610 struct samu
*sam_acct
;
1613 struct dom_sid user_sid
;
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
,
1653 auth_struct
.incoming
.current
.array
[i
].AuthInfo
.clear
.password
,
1654 auth_struct
.incoming
.current
.array
[i
].AuthInfo
.clear
.size
,
1658 return NT_STATUS_UNSUCCESSFUL
;
1660 if (!pdb_set_plaintext_passwd(sam_acct
, dummy
)) {
1661 return NT_STATUS_UNSUCCESSFUL
;
1669 status
= pdb_add_sam_account(sam_acct
);
1670 if (!NT_STATUS_IS_OK(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
;
1686 uint32_t acc_granted
;
1687 struct security_descriptor
*psd
;
1689 struct pdb_trusted_domain td
;
1690 struct trustDomainPasswords auth_struct
;
1691 enum ndr_err_code ndr_err
;
1692 DATA_BLOB auth_blob
;
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
,
1722 if (!NT_STATUS_IS_OK(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
)) {
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
,
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
;
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
)) {
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
,
1795 if (!NT_STATUS_IS_OK(status
)) {
1800 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
1801 LSA_HANDLE_TRUST_TYPE
,
1804 r
->in
.info
->netbios_name
.string
,
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
;
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
)
1870 struct lsa_info
*handle
;
1871 struct pdb_trusted_domain
*td
;
1872 struct samu
*sam_acct
;
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
)) {
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
)) {
1918 status
= pdb_del_trusted_domain(td
->netbios_name
);
1919 if (!NT_STATUS_IS_OK(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
)
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
;
1962 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS
:
1963 acc_required
= LSA_TRUSTED_QUERY_CONTROLLERS
;
1965 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET
:
1966 acc_required
= LSA_TRUSTED_QUERY_POSIX
;
1968 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD
:
1969 acc_required
= LSA_TRUSTED_QUERY_AUTH
;
1971 case LSA_TRUSTED_DOMAIN_INFO_BASIC
:
1972 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
1974 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX
:
1975 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
1977 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO
:
1978 acc_required
= LSA_TRUSTED_QUERY_AUTH
;
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
;
1985 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL
:
1986 acc_required
= LSA_TRUSTED_QUERY_AUTH
;
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
;
1993 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL
:
1994 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
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
;
2001 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES
:
2002 acc_required
= LSA_TRUSTED_QUERY_POSIX
;
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
)) {
2017 info
= TALLOC_ZERO_P(p
->mem_ctx
, union lsa_TrustedDomainInfo
);
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
);
2026 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS
:
2027 return NT_STATUS_INVALID_PARAMETER
;
2028 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET
:
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
;
2045 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO
:
2046 return NT_STATUS_INVALID_INFO_CLASS
;
2047 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
:
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
:
2057 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES
:
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
)
2076 struct policy_handle trustdom_handle
;
2077 struct lsa_OpenTrustedDomain o
;
2078 struct lsa_QueryTrustedDomainInfo q
;
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
)) {
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
)) {
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
)
2114 struct policy_handle trustdom_handle
;
2115 struct lsa_OpenTrustedDomainByName o
;
2116 struct lsa_QueryTrustedDomainInfo q
;
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
;
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
)) {
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 /***************************************************************************
2165 ***************************************************************************/
2167 NTSTATUS
_lsa_DeleteObject(struct pipes_struct
*p
,
2168 struct lsa_DeleteObject
*r
)
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
)));
2191 return NT_STATUS_INVALID_HANDLE
;
2194 close_policy_hnd(p
, r
->in
.handle
);
2195 ZERO_STRUCTP(r
->out
.handle
);
2200 /***************************************************************************
2202 ***************************************************************************/
2204 NTSTATUS
_lsa_EnumPrivs(struct pipes_struct
*p
,
2205 struct lsa_EnumPrivs
*r
)
2207 struct lsa_info
*handle
;
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
;
2235 entries
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, struct lsa_PrivEntry
, num_privs
);
2237 return NT_STATUS_NO_MEMORY
;
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;
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
);
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
);
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 /***************************************************************************
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
;
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
;
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
)) {
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
);
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
]);
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 /***************************************************************************
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
;
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 /***************************************************************************
2441 ***************************************************************************/
2443 NTSTATUS
_lsa_CreateAccount(struct pipes_struct
*p
,
2444 struct lsa_CreateAccount
*r
)
2447 struct lsa_info
*handle
;
2448 uint32_t acc_granted
;
2449 struct security_descriptor
*psd
;
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
)) {
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
)) {
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
,
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 /***************************************************************************
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
;
2515 uint32_t des_access
= r
->in
.access_mask
;
2516 uint32_t acc_granted
;
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
,
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
)) {
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
)) {
2553 /* TODO: Fis the parsing routine before reenabling this check! */
2555 if (!lookup_sid(&handle
->sid
, dom_name
, name
, &type
))
2556 return NT_STATUS_ACCESS_DENIED
;
2559 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
2560 LSA_HANDLE_ACCOUNT_TYPE
,
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
)) {
2602 *r
->out
.privs
= priv_set
= TALLOC_ZERO_P(p
->mem_ctx
, struct lsa_PrivilegeSet
);
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
);
2618 /***************************************************************************
2619 _lsa_GetSystemAccessAccount
2620 ***************************************************************************/
2622 NTSTATUS
_lsa_GetSystemAccessAccount(struct pipes_struct
*p
,
2623 struct lsa_GetSystemAccessAccount
*r
)
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
);
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
)));
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
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
;
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
;
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
;
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 /***************************************************************************
2775 ***************************************************************************/
2777 NTSTATUS
_lsa_LookupPrivName(struct pipes_struct
*p
,
2778 struct lsa_LookupPrivName
*r
)
2780 struct lsa_info
*info
= NULL
;
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
);
2803 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2806 lsa_name
= TALLOC_ZERO_P(p
->mem_ctx
, struct lsa_StringLarge
);
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 /***************************************************************************
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
;
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
:
2843 sd_size
= ndr_size_security_descriptor(psd
, 0);
2844 status
= NT_STATUS_OK
;
2847 status
= NT_STATUS_INVALID_HANDLE
;
2851 if (!NT_STATUS_IS_OK(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
;
2863 /***************************************************************************
2864 _lsa_AddAccountRights
2865 ***************************************************************************/
2867 NTSTATUS
_lsa_AddAccountRights(struct pipes_struct
*p
,
2868 struct lsa_AddAccountRights
*r
)
2870 struct lsa_info
*info
= NULL
;
2872 uint32_t acc_granted
= 0;
2873 struct security_descriptor
*psd
= NULL
;
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
)) {
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
)) {
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 */
2923 if ( !grant_privilege_by_name( &sid
, privname
) ) {
2924 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
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
;
2942 struct security_descriptor
*psd
= NULL
;
2945 const char *privname
= NULL
;
2946 uint32_t acc_granted
= 0;
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
)) {
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
)) {
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 */
2998 if ( !revoke_privilege_by_name( &sid
, privname
) ) {
2999 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
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
)
3016 const char *privname
;
3017 const char **privname_array
= NULL
;
3020 for (i
=0; i
<privileges
->count
; i
++) {
3021 if (privileges
->set
[i
].luid
.high
) {
3024 privname
= sec_privilege_name(privileges
->set
[i
].luid
.low
);
3026 if (!add_string_to_array(mem_ctx
, privname
,
3027 &privname_array
, &num_priv
)) {
3028 return NT_STATUS_NO_MEMORY
;
3035 r
->names
= TALLOC_ZERO_ARRAY(mem_ctx
, struct lsa_StringLarge
,
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
)
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
)) {
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
);
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
)
3137 struct lsa_info
*info
= NULL
;
3138 struct dom_sid
*sids
= NULL
;
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
,
3166 if (!NT_STATUS_IS_OK(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
,
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 /***************************************************************************
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
;
3295 struct pdb_trusted_domain
**domains
;
3296 struct lsa_TrustDomainInfoInfoEx
*entries
;
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
;
3321 nt_status
= pdb_enum_trusted_domains(p
->mem_ctx
, &count
, &domains
);
3324 if (!NT_STATUS_IS_OK(nt_status
)) {
3328 entries
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, struct lsa_TrustDomainInfoInfoEx
,
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
;
3493 if (StrCaseCmp(s1
, s2
) == 0) {
3494 return DNS_CMP_MATCH
;
3496 return DNS_CMP_NO_MATCH
;
3504 cret
= DNS_CMP_FIRST_IS_CHILD
;
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) {
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
;
3535 fti
->count
= lfti
->count
;
3536 fti
->records
= talloc_array(mem_ctx
,
3537 struct ForestTrustInfoRecordArmor
,
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
);
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
);
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
;
3609 uint32_t new_fti_idx
;
3611 /* use always TDO type, until we understand when Xref can be used */
3612 uint32_t collision_type
= LSA_FOREST_TRUST_COLLISION_TDO
;
3617 bool ex_rule
= false;
3620 for (new_fti_idx
= 0; new_fti_idx
< new_fti
->count
; new_fti_idx
++) {
3622 nrec
= &new_fti
->records
[new_fti_idx
].record
;
3624 tln_conflict
= false;
3625 sid_conflict
= false;
3626 nb_conflict
= false;
3629 switch (nrec
->type
) {
3630 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX
:
3631 /* exclusions do not conflict by definition */
3634 case FOREST_TRUST_TOP_LEVEL_NAME
:
3635 dns_name
= nrec
->data
.name
.string
;
3636 dns_len
= nrec
->data
.name
.size
;
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
;
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
:
3657 tname
= trec
->data
.name
.string
;
3658 tlen
= trec
->data
.name
.size
;
3660 case FOREST_TRUST_TOP_LEVEL_NAME_EX
:
3662 tname
= trec
->data
.name
.string
;
3663 tlen
= trec
->data
.name
.size
;
3665 case FOREST_TRUST_DOMAIN_INFO
:
3667 tname
= trec
->data
.info
.dns_name
.string
;
3668 tlen
= trec
->data
.info
.dns_name
.size
;
3671 return NT_STATUS_INVALID_PARAMETER
;
3673 ret
= dns_cmp(dns_name
, dns_len
, tname
, tlen
);
3676 /* if it matches exclusion,
3677 * it doesn't conflict */
3683 case DNS_CMP_FIRST_IS_CHILD
:
3684 case DNS_CMP_SECOND_IS_CHILD
:
3685 tln_conflict
= true;
3691 /* explicit exclusion, no dns name conflict here */
3693 tln_conflict
= false;
3696 if (trec
->type
!= FOREST_TRUST_DOMAIN_INFO
) {
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
,
3713 nt_status
= add_collision(c_info
, new_fti_idx
,
3715 LSA_TLN_DISABLED_CONFLICT
,
3719 nt_status
= add_collision(c_info
, new_fti_idx
,
3721 LSA_SID_DISABLED_CONFLICT
,
3725 nt_status
= add_collision(c_info
, new_fti_idx
,
3727 LSA_NB_DISABLED_CONFLICT
,
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);
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
);
3752 return NT_STATUS_NO_MEMORY
;
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
,
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
;
3795 fti
->records
= talloc_array(fti
,
3796 struct ForestTrustInfoRecordArmor
, 2);
3797 if (!fti
->records
) {
3798 return NT_STATUS_NO_MEMORY
;
3802 rec
= &fti
->records
[0].record
;
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
);
3815 rec
= &fti
->records
[1].record
;
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
)
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
;
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
)) {
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) {
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
);
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
)) {
3911 c_info
= talloc_zero(r
->out
.collision_info
,
3912 struct lsa_ForestTrustCollisionInfo
);
3914 return NT_STATUS_NO_MEMORY
;
3917 /* first check own info, then other domains */
3918 fti
= talloc(p
->mem_ctx
, struct ForestTrustInfo
);
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
)) {
3930 status
= check_ft_info(c_info
, dom_info
->dns_domain
, fti
, nfti
, c_info
);
3931 if (!NT_STATUS_IS_OK(status
)) {
3935 for (j
= 0; j
< num_domains
; j
++) {
3936 fti
= talloc(p
->mem_ctx
, struct ForestTrustInfo
);
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
)) {
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
,
3956 if (!NT_STATUS_IS_OK(status
)) {
3961 *r
->out
.collision_info
= c_info
;
3963 if (r
->in
.check_only
!= 0) {
3964 return NT_STATUS_OK
;
3969 ndr_err
= ndr_push_struct_blob(&domains
[i
]->trust_forest_trust_info
,
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
)) {
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
;