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"
49 #include "../librpc/gen_ndr/ndr_wkssvc.h"
50 #include "../libcli/auth/libcli_auth.h"
51 #include "../libcli/lsarpc/util_lsarpc.h"
54 #define DBGC_CLASS DBGC_RPC_SRV
56 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
58 enum lsa_handle_type
{
59 LSA_HANDLE_POLICY_TYPE
= 1,
60 LSA_HANDLE_ACCOUNT_TYPE
= 2,
61 LSA_HANDLE_TRUST_TYPE
= 3,
62 LSA_HANDLE_SECRET_TYPE
= 4};
68 enum lsa_handle_type type
;
69 struct security_descriptor
*sd
;
72 const struct generic_mapping lsa_account_mapping
= {
76 LSA_ACCOUNT_ALL_ACCESS
79 const struct generic_mapping lsa_policy_mapping
= {
86 const struct generic_mapping lsa_secret_mapping
= {
93 const struct generic_mapping lsa_trusted_domain_mapping
= {
94 LSA_TRUSTED_DOMAIN_READ
,
95 LSA_TRUSTED_DOMAIN_WRITE
,
96 LSA_TRUSTED_DOMAIN_EXECUTE
,
97 LSA_TRUSTED_DOMAIN_ALL_ACCESS
100 /***************************************************************************
101 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
102 ***************************************************************************/
104 static int init_lsa_ref_domain_list(TALLOC_CTX
*mem_ctx
,
105 struct lsa_RefDomainList
*ref
,
106 const char *dom_name
,
107 struct dom_sid
*dom_sid
)
111 if (dom_name
!= NULL
) {
112 for (num
= 0; num
< ref
->count
; num
++) {
113 if (dom_sid_equal(dom_sid
, ref
->domains
[num
].sid
)) {
121 if (num
>= LSA_REF_DOMAIN_LIST_MULTIPLIER
) {
122 /* index not found, already at maximum domain limit */
126 ref
->count
= num
+ 1;
127 ref
->max_size
= LSA_REF_DOMAIN_LIST_MULTIPLIER
;
129 ref
->domains
= talloc_realloc(mem_ctx
, ref
->domains
,
130 struct lsa_DomainInfo
, ref
->count
);
135 ZERO_STRUCT(ref
->domains
[num
]);
137 init_lsa_StringLarge(&ref
->domains
[num
].name
, dom_name
);
138 ref
->domains
[num
].sid
= dom_sid_dup(mem_ctx
, dom_sid
);
139 if (!ref
->domains
[num
].sid
) {
147 /***************************************************************************
148 initialize a lsa_DomainInfo structure.
149 ***************************************************************************/
151 static void init_dom_query_3(struct lsa_DomainInfo
*r
,
155 init_lsa_StringLarge(&r
->name
, name
);
159 /***************************************************************************
160 initialize a lsa_DomainInfo structure.
161 ***************************************************************************/
163 static void init_dom_query_5(struct lsa_DomainInfo
*r
,
167 init_lsa_StringLarge(&r
->name
, name
);
171 /***************************************************************************
172 lookup_lsa_rids. Must be called as root for lookup_name to work.
173 ***************************************************************************/
175 static NTSTATUS
lookup_lsa_rids(TALLOC_CTX
*mem_ctx
,
176 struct lsa_RefDomainList
*ref
,
177 struct lsa_TranslatedSid
*prid
,
178 uint32_t num_entries
,
179 struct lsa_String
*name
,
181 uint32_t *pmapped_count
)
183 uint32 mapped_count
, i
;
185 SMB_ASSERT(num_entries
<= MAX_LOOKUP_SIDS
);
190 for (i
= 0; i
< num_entries
; i
++) {
194 const char *full_name
;
196 enum lsa_SidType type
;
198 /* Split name into domain and user component */
200 /* follow w2k8 behavior and return the builtin domain when no
201 * input has been passed in */
203 if (name
[i
].string
) {
204 full_name
= name
[i
].string
;
206 full_name
= "BUILTIN";
209 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name
));
211 if (!lookup_name(mem_ctx
, full_name
, flags
, &domain
, NULL
,
213 type
= SID_NAME_UNKNOWN
;
218 case SID_NAME_DOM_GRP
:
219 case SID_NAME_DOMAIN
:
221 case SID_NAME_WKN_GRP
:
222 DEBUG(5, ("init_lsa_rids: %s found\n", full_name
));
223 /* Leave these unchanged */
226 /* Don't hand out anything but the list above */
227 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name
));
228 type
= SID_NAME_UNKNOWN
;
235 if (type
!= SID_NAME_UNKNOWN
) {
236 if (type
== SID_NAME_DOMAIN
) {
239 sid_split_rid(&sid
, &rid
);
241 dom_idx
= init_lsa_ref_domain_list(mem_ctx
, ref
, domain
, &sid
);
245 prid
[i
].sid_type
= type
;
247 prid
[i
].sid_index
= dom_idx
;
250 *pmapped_count
= mapped_count
;
254 /***************************************************************************
255 lookup_lsa_sids. Must be called as root for lookup_name to work.
256 ***************************************************************************/
258 static NTSTATUS
lookup_lsa_sids(TALLOC_CTX
*mem_ctx
,
259 struct lsa_RefDomainList
*ref
,
260 struct lsa_TranslatedSid3
*trans_sids
,
261 uint32_t num_entries
,
262 struct lsa_String
*name
,
264 uint32
*pmapped_count
)
266 uint32 mapped_count
, i
;
268 SMB_ASSERT(num_entries
<= MAX_LOOKUP_SIDS
);
273 for (i
= 0; i
< num_entries
; i
++) {
277 const char *full_name
;
279 enum lsa_SidType type
;
283 /* Split name into domain and user component */
285 full_name
= name
[i
].string
;
286 if (full_name
== NULL
) {
287 return NT_STATUS_NO_MEMORY
;
290 DEBUG(5, ("lookup_lsa_sids: looking up name %s\n", full_name
));
292 if (!lookup_name(mem_ctx
, full_name
, flags
, &domain
, NULL
,
294 type
= SID_NAME_UNKNOWN
;
299 case SID_NAME_DOM_GRP
:
300 case SID_NAME_DOMAIN
:
302 case SID_NAME_WKN_GRP
:
303 DEBUG(5, ("lookup_lsa_sids: %s found\n", full_name
));
304 /* Leave these unchanged */
307 /* Don't hand out anything but the list above */
308 DEBUG(5, ("lookup_lsa_sids: %s not found\n", full_name
));
309 type
= SID_NAME_UNKNOWN
;
316 if (type
!= SID_NAME_UNKNOWN
) {
317 struct dom_sid domain_sid
;
318 sid_copy(&domain_sid
, &sid
);
319 sid_split_rid(&domain_sid
, &rid
);
320 dom_idx
= init_lsa_ref_domain_list(mem_ctx
, ref
, domain
, &domain_sid
);
324 /* Initialize the lsa_TranslatedSid3 return. */
325 trans_sids
[i
].sid_type
= type
;
326 trans_sids
[i
].sid
= dom_sid_dup(mem_ctx
, &sid
);
327 trans_sids
[i
].sid_index
= dom_idx
;
330 *pmapped_count
= mapped_count
;
334 static NTSTATUS
make_lsa_object_sd(TALLOC_CTX
*mem_ctx
, struct security_descriptor
**sd
, size_t *sd_size
,
335 const struct generic_mapping
*map
,
336 struct dom_sid
*sid
, uint32_t sid_access
)
338 struct dom_sid adm_sid
;
339 struct security_ace ace
[5];
342 struct security_acl
*psa
= NULL
;
344 /* READ|EXECUTE access for Everyone */
346 init_sec_ace(&ace
[i
++], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
347 map
->generic_execute
| map
->generic_read
, 0);
349 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
351 init_sec_ace(&ace
[i
++], &global_sid_Builtin_Administrators
,
352 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
353 init_sec_ace(&ace
[i
++], &global_sid_Builtin_Account_Operators
,
354 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
356 /* Add Full Access for Domain Admins */
357 sid_compose(&adm_sid
, get_global_sam_sid(), DOMAIN_RID_ADMINS
);
358 init_sec_ace(&ace
[i
++], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
359 map
->generic_all
, 0);
361 /* If we have a sid, give it some special access */
364 init_sec_ace(&ace
[i
++], sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
368 if((psa
= make_sec_acl(mem_ctx
, NT4_ACL_REVISION
, i
, ace
)) == NULL
)
369 return NT_STATUS_NO_MEMORY
;
371 if((*sd
= make_sec_desc(mem_ctx
, SECURITY_DESCRIPTOR_REVISION_1
,
372 SEC_DESC_SELF_RELATIVE
, &adm_sid
, NULL
, NULL
,
373 psa
, sd_size
)) == NULL
)
374 return NT_STATUS_NO_MEMORY
;
379 /***************************************************************************
380 ***************************************************************************/
382 static NTSTATUS
create_lsa_policy_handle(TALLOC_CTX
*mem_ctx
,
383 struct pipes_struct
*p
,
384 enum lsa_handle_type type
,
385 uint32_t acc_granted
,
388 const struct security_descriptor
*sd
,
389 struct policy_handle
*handle
)
391 struct lsa_info
*info
;
393 ZERO_STRUCTP(handle
);
395 info
= talloc_zero(mem_ctx
, struct lsa_info
);
397 return NT_STATUS_NO_MEMORY
;
401 info
->access
= acc_granted
;
404 sid_copy(&info
->sid
, sid
);
407 info
->name
= talloc_strdup(info
, name
);
410 info
->sd
= dup_sec_desc(info
, sd
);
413 return NT_STATUS_NO_MEMORY
;
417 if (!create_policy_hnd(p
, handle
, info
)) {
419 ZERO_STRUCTP(handle
);
420 return NT_STATUS_NO_MEMORY
;
426 /***************************************************************************
428 ***************************************************************************/
430 NTSTATUS
_lsa_OpenPolicy2(struct pipes_struct
*p
,
431 struct lsa_OpenPolicy2
*r
)
433 struct security_descriptor
*psd
= NULL
;
435 uint32 des_access
= r
->in
.access_mask
;
439 if (p
->transport
!= NCACN_NP
&& p
->transport
!= NCALRPC
) {
440 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
441 return NT_STATUS_ACCESS_DENIED
;
444 /* Work out max allowed. */
445 map_max_allowed_access(p
->session_info
->security_token
,
446 p
->session_info
->unix_token
,
449 /* map the generic bits to the lsa policy ones */
450 se_map_generic(&des_access
, &lsa_policy_mapping
);
452 /* get the generic lsa policy SD until we store it */
453 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &lsa_policy_mapping
,
455 if (!NT_STATUS_IS_OK(status
)) {
459 status
= access_check_object(psd
, p
->session_info
->security_token
,
460 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0, des_access
,
461 &acc_granted
, "_lsa_OpenPolicy2" );
462 if (!NT_STATUS_IS_OK(status
)) {
466 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
467 LSA_HANDLE_POLICY_TYPE
,
469 get_global_sam_sid(),
473 if (!NT_STATUS_IS_OK(status
)) {
474 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
480 /***************************************************************************
482 ***************************************************************************/
484 NTSTATUS
_lsa_OpenPolicy(struct pipes_struct
*p
,
485 struct lsa_OpenPolicy
*r
)
487 struct lsa_OpenPolicy2 o
;
489 /* _lsa_OpenPolicy2 will check if this is a NCACN_NP connection */
491 o
.in
.system_name
= NULL
; /* should be ignored */
492 o
.in
.attr
= r
->in
.attr
;
493 o
.in
.access_mask
= r
->in
.access_mask
;
495 o
.out
.handle
= r
->out
.handle
;
497 return _lsa_OpenPolicy2(p
, &o
);
500 /***************************************************************************
501 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
503 ***************************************************************************/
505 NTSTATUS
_lsa_EnumTrustDom(struct pipes_struct
*p
,
506 struct lsa_EnumTrustDom
*r
)
508 struct lsa_info
*info
;
510 struct trustdom_info
**domains
;
511 struct lsa_DomainInfo
*entries
;
515 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
516 return NT_STATUS_INVALID_HANDLE
;
518 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
519 return NT_STATUS_INVALID_HANDLE
;
522 /* check if the user has enough rights */
523 if (!(info
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
524 return NT_STATUS_ACCESS_DENIED
;
527 nt_status
= pdb_enum_trusteddoms(p
->mem_ctx
, &count
, &domains
);
530 if (!NT_STATUS_IS_OK(nt_status
)) {
534 entries
= talloc_zero_array(p
->mem_ctx
, struct lsa_DomainInfo
, count
);
536 return NT_STATUS_NO_MEMORY
;
539 for (i
=0; i
<count
; i
++) {
540 init_lsa_StringLarge(&entries
[i
].name
, domains
[i
]->name
);
541 entries
[i
].sid
= &domains
[i
]->sid
;
544 if (*r
->in
.resume_handle
>= count
) {
545 *r
->out
.resume_handle
= -1;
546 TALLOC_FREE(entries
);
547 return NT_STATUS_NO_MORE_ENTRIES
;
550 /* return the rest, limit by max_size. Note that we
551 use the w2k3 element size value of 60 */
552 r
->out
.domains
->count
= count
- *r
->in
.resume_handle
;
553 r
->out
.domains
->count
= MIN(r
->out
.domains
->count
,
554 1+(r
->in
.max_size
/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER
));
556 r
->out
.domains
->domains
= entries
+ *r
->in
.resume_handle
;
558 if (r
->out
.domains
->count
< count
- *r
->in
.resume_handle
) {
559 *r
->out
.resume_handle
= *r
->in
.resume_handle
+ r
->out
.domains
->count
;
560 return STATUS_MORE_ENTRIES
;
563 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
564 * always be larger than the previous input resume handle, in
565 * particular when hitting the last query it is vital to set the
566 * resume handle correctly to avoid infinite client loops, as
567 * seen e.g. with Windows XP SP3 when resume handle is 0 and
568 * status is NT_STATUS_OK - gd */
570 *r
->out
.resume_handle
= (uint32_t)-1;
575 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
576 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
577 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
579 /***************************************************************************
581 ***************************************************************************/
583 NTSTATUS
_lsa_QueryInfoPolicy(struct pipes_struct
*p
,
584 struct lsa_QueryInfoPolicy
*r
)
586 NTSTATUS status
= NT_STATUS_OK
;
587 struct lsa_info
*handle
;
588 struct dom_sid domain_sid
;
590 struct dom_sid
*sid
= NULL
;
591 union lsa_PolicyInformation
*info
= NULL
;
592 uint32_t acc_required
= 0;
594 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
595 return NT_STATUS_INVALID_HANDLE
;
597 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
598 return NT_STATUS_INVALID_HANDLE
;
601 switch (r
->in
.level
) {
602 case LSA_POLICY_INFO_AUDIT_LOG
:
603 case LSA_POLICY_INFO_AUDIT_EVENTS
:
604 acc_required
= LSA_POLICY_VIEW_AUDIT_INFORMATION
;
606 case LSA_POLICY_INFO_DOMAIN
:
607 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
609 case LSA_POLICY_INFO_PD
:
610 acc_required
= LSA_POLICY_GET_PRIVATE_INFORMATION
;
612 case LSA_POLICY_INFO_ACCOUNT_DOMAIN
:
613 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
615 case LSA_POLICY_INFO_ROLE
:
616 case LSA_POLICY_INFO_REPLICA
:
617 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
619 case LSA_POLICY_INFO_QUOTA
:
620 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
622 case LSA_POLICY_INFO_MOD
:
623 case LSA_POLICY_INFO_AUDIT_FULL_SET
:
624 /* according to MS-LSAD 3.1.4.4.3 */
625 return NT_STATUS_INVALID_PARAMETER
;
626 case LSA_POLICY_INFO_AUDIT_FULL_QUERY
:
627 acc_required
= LSA_POLICY_VIEW_AUDIT_INFORMATION
;
629 case LSA_POLICY_INFO_DNS
:
630 case LSA_POLICY_INFO_DNS_INT
:
631 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN
:
632 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
638 if (!(handle
->access
& acc_required
)) {
639 /* return NT_STATUS_ACCESS_DENIED; */
642 info
= talloc_zero(p
->mem_ctx
, union lsa_PolicyInformation
);
644 return NT_STATUS_NO_MEMORY
;
647 switch (r
->in
.level
) {
648 /* according to MS-LSAD 3.1.4.4.3 */
649 case LSA_POLICY_INFO_MOD
:
650 case LSA_POLICY_INFO_AUDIT_FULL_SET
:
651 case LSA_POLICY_INFO_AUDIT_FULL_QUERY
:
652 return NT_STATUS_INVALID_PARAMETER
;
653 case LSA_POLICY_INFO_AUDIT_LOG
:
654 info
->audit_log
.percent_full
= 0;
655 info
->audit_log
.maximum_log_size
= 0;
656 info
->audit_log
.retention_time
= 0;
657 info
->audit_log
.shutdown_in_progress
= 0;
658 info
->audit_log
.time_to_shutdown
= 0;
659 info
->audit_log
.next_audit_record
= 0;
660 status
= NT_STATUS_OK
;
662 case LSA_POLICY_INFO_PD
:
663 info
->pd
.name
.string
= NULL
;
664 status
= NT_STATUS_OK
;
666 case LSA_POLICY_INFO_REPLICA
:
667 info
->replica
.source
.string
= NULL
;
668 info
->replica
.account
.string
= NULL
;
669 status
= NT_STATUS_OK
;
671 case LSA_POLICY_INFO_QUOTA
:
672 info
->quota
.paged_pool
= 0;
673 info
->quota
.non_paged_pool
= 0;
674 info
->quota
.min_wss
= 0;
675 info
->quota
.max_wss
= 0;
676 info
->quota
.pagefile
= 0;
677 info
->quota
.unknown
= 0;
678 status
= NT_STATUS_OK
;
680 case LSA_POLICY_INFO_AUDIT_EVENTS
:
683 uint32 policy_def
= LSA_AUDIT_POLICY_ALL
;
685 /* check if the user has enough rights */
686 if (!(handle
->access
& LSA_POLICY_VIEW_AUDIT_INFORMATION
)) {
687 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
688 return NT_STATUS_ACCESS_DENIED
;
691 /* fake info: We audit everything. ;) */
693 info
->audit_events
.auditing_mode
= true;
694 info
->audit_events
.count
= LSA_AUDIT_NUM_CATEGORIES
;
695 info
->audit_events
.settings
= talloc_zero_array(p
->mem_ctx
,
696 enum lsa_PolicyAuditPolicy
,
697 info
->audit_events
.count
);
698 if (!info
->audit_events
.settings
) {
699 return NT_STATUS_NO_MEMORY
;
702 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT
] = policy_def
;
703 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS
] = policy_def
;
704 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_LOGON
] = policy_def
;
705 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING
] = policy_def
;
706 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES
] = policy_def
;
707 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_SYSTEM
] = policy_def
;
708 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS
] = policy_def
;
712 case LSA_POLICY_INFO_DOMAIN
:
713 /* check if the user has enough rights */
714 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
715 return NT_STATUS_ACCESS_DENIED
;
717 /* Request PolicyPrimaryDomainInformation. */
718 switch (lp_server_role()) {
719 case ROLE_DOMAIN_PDC
:
720 case ROLE_DOMAIN_BDC
:
721 name
= get_global_sam_name();
722 sid
= dom_sid_dup(p
->mem_ctx
, get_global_sam_sid());
724 return NT_STATUS_NO_MEMORY
;
727 case ROLE_DOMAIN_MEMBER
:
728 name
= lp_workgroup();
729 /* We need to return the Domain SID here. */
730 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid
)) {
731 sid
= dom_sid_dup(p
->mem_ctx
, &domain_sid
);
733 return NT_STATUS_NO_MEMORY
;
736 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
739 case ROLE_STANDALONE
:
740 name
= lp_workgroup();
744 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
746 init_dom_query_3(&info
->domain
, name
, sid
);
748 case LSA_POLICY_INFO_ACCOUNT_DOMAIN
:
749 /* check if the user has enough rights */
750 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
751 return NT_STATUS_ACCESS_DENIED
;
753 /* Request PolicyAccountDomainInformation. */
754 name
= get_global_sam_name();
755 sid
= get_global_sam_sid();
757 init_dom_query_5(&info
->account_domain
, name
, sid
);
759 case LSA_POLICY_INFO_ROLE
:
760 /* check if the user has enough rights */
761 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
762 return NT_STATUS_ACCESS_DENIED
;
764 switch (lp_server_role()) {
765 case ROLE_DOMAIN_BDC
:
767 * only a BDC is a backup controller
768 * of the domain, it controls.
770 info
->role
.role
= LSA_ROLE_BACKUP
;
774 * any other role is a primary
775 * of the domain, it controls.
777 info
->role
.role
= LSA_ROLE_PRIMARY
;
781 case LSA_POLICY_INFO_DNS
:
782 case LSA_POLICY_INFO_DNS_INT
: {
783 struct pdb_domain_info
*dominfo
;
785 if ((pdb_capabilities() & PDB_CAP_ADS
) == 0) {
786 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
787 "without ADS passdb backend\n"));
788 status
= NT_STATUS_INVALID_INFO_CLASS
;
792 dominfo
= pdb_get_domain_info(info
);
793 if (dominfo
== NULL
) {
794 status
= NT_STATUS_NO_MEMORY
;
798 init_lsa_StringLarge(&info
->dns
.name
,
800 init_lsa_StringLarge(&info
->dns
.dns_domain
,
801 dominfo
->dns_domain
);
802 init_lsa_StringLarge(&info
->dns
.dns_forest
,
803 dominfo
->dns_forest
);
804 info
->dns
.domain_guid
= dominfo
->guid
;
805 info
->dns
.sid
= &dominfo
->sid
;
809 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
811 status
= NT_STATUS_INVALID_INFO_CLASS
;
820 /***************************************************************************
821 _lsa_QueryInfoPolicy2
822 ***************************************************************************/
824 NTSTATUS
_lsa_QueryInfoPolicy2(struct pipes_struct
*p
,
825 struct lsa_QueryInfoPolicy2
*r2
)
827 struct lsa_QueryInfoPolicy r
;
829 if ((pdb_capabilities() & PDB_CAP_ADS
) == 0) {
830 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
831 return NT_STATUS_NOT_IMPLEMENTED
;
835 r
.in
.handle
= r2
->in
.handle
;
836 r
.in
.level
= r2
->in
.level
;
837 r
.out
.info
= r2
->out
.info
;
839 return _lsa_QueryInfoPolicy(p
, &r
);
842 /***************************************************************************
843 _lsa_lookup_sids_internal
844 ***************************************************************************/
846 static NTSTATUS
_lsa_lookup_sids_internal(struct pipes_struct
*p
,
848 uint16_t level
, /* input */
849 int num_sids
, /* input */
850 struct lsa_SidPtr
*sid
, /* input */
851 struct lsa_RefDomainList
**pp_ref
, /* input/output */
852 struct lsa_TranslatedName2
**pp_names
,/* input/output */
853 uint32_t *pp_mapped_count
) /* input/output */
857 const struct dom_sid
**sids
= NULL
;
858 struct lsa_RefDomainList
*ref
= NULL
;
859 uint32 mapped_count
= 0;
860 struct lsa_dom_info
*dom_infos
= NULL
;
861 struct lsa_name_info
*name_infos
= NULL
;
862 struct lsa_TranslatedName2
*names
= NULL
;
864 *pp_mapped_count
= 0;
872 sids
= talloc_array(p
->mem_ctx
, const struct dom_sid
*, num_sids
);
873 ref
= talloc_zero(p
->mem_ctx
, struct lsa_RefDomainList
);
875 if (sids
== NULL
|| ref
== NULL
) {
876 return NT_STATUS_NO_MEMORY
;
879 for (i
=0; i
<num_sids
; i
++) {
880 sids
[i
] = sid
[i
].sid
;
883 status
= lookup_sids(p
->mem_ctx
, num_sids
, sids
, level
,
884 &dom_infos
, &name_infos
);
886 if (!NT_STATUS_IS_OK(status
)) {
890 names
= talloc_array(p
->mem_ctx
, struct lsa_TranslatedName2
, num_sids
);
892 return NT_STATUS_NO_MEMORY
;
895 for (i
=0; i
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; i
++) {
897 if (!dom_infos
[i
].valid
) {
901 if (init_lsa_ref_domain_list(mem_ctx
, ref
,
903 &dom_infos
[i
].sid
) != i
) {
904 DEBUG(0, ("Domain %s mentioned twice??\n",
906 return NT_STATUS_INTERNAL_ERROR
;
910 for (i
=0; i
<num_sids
; i
++) {
911 struct lsa_name_info
*name
= &name_infos
[i
];
913 if (name
->type
== SID_NAME_UNKNOWN
) {
915 /* Unknown sids should return the string
916 * representation of the SID. Windows 2003 behaves
917 * rather erratic here, in many cases it returns the
918 * RID as 8 bytes hex, in others it returns the full
919 * SID. We (Jerry/VL) could not figure out which the
920 * hard cases are, so leave it with the SID. */
921 name
->name
= dom_sid_string(p
->mem_ctx
, sids
[i
]);
922 if (name
->name
== NULL
) {
923 return NT_STATUS_NO_MEMORY
;
929 names
[i
].sid_type
= name
->type
;
930 names
[i
].name
.string
= name
->name
;
931 names
[i
].sid_index
= name
->dom_idx
;
932 names
[i
].unknown
= 0;
935 status
= NT_STATUS_NONE_MAPPED
;
936 if (mapped_count
> 0) {
937 status
= (mapped_count
< num_sids
) ?
938 STATUS_SOME_UNMAPPED
: NT_STATUS_OK
;
941 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
942 num_sids
, mapped_count
, nt_errstr(status
)));
944 *pp_mapped_count
= mapped_count
;
951 /***************************************************************************
953 ***************************************************************************/
955 NTSTATUS
_lsa_LookupSids(struct pipes_struct
*p
,
956 struct lsa_LookupSids
*r
)
959 struct lsa_info
*handle
;
960 int num_sids
= r
->in
.sids
->num_sids
;
961 uint32 mapped_count
= 0;
962 struct lsa_RefDomainList
*domains
= NULL
;
963 struct lsa_TranslatedName
*names_out
= NULL
;
964 struct lsa_TranslatedName2
*names
= NULL
;
967 if (p
->transport
!= NCACN_NP
&& p
->transport
!= NCALRPC
) {
968 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
969 return NT_STATUS_ACCESS_DENIED
;
972 if ((r
->in
.level
< 1) || (r
->in
.level
> 6)) {
973 return NT_STATUS_INVALID_PARAMETER
;
976 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
977 return NT_STATUS_INVALID_HANDLE
;
980 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
981 return NT_STATUS_INVALID_HANDLE
;
984 /* check if the user has enough rights */
985 if (!(handle
->access
& LSA_POLICY_LOOKUP_NAMES
)) {
986 return NT_STATUS_ACCESS_DENIED
;
989 if (num_sids
> MAX_LOOKUP_SIDS
) {
990 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
991 MAX_LOOKUP_SIDS
, num_sids
));
992 return NT_STATUS_NONE_MAPPED
;
995 status
= _lsa_lookup_sids_internal(p
,
1004 /* Only return here when there is a real error.
1005 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
1006 the requested sids could be resolved. Older versions of XP (pre SP3)
1007 rely that we return with the string representations of those SIDs in
1008 that case. If we don't, XP crashes - Guenther
1011 if (NT_STATUS_IS_ERR(status
) &&
1012 !NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
1016 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
1017 names_out
= talloc_array(p
->mem_ctx
, struct lsa_TranslatedName
,
1020 return NT_STATUS_NO_MEMORY
;
1023 for (i
=0; i
<num_sids
; i
++) {
1024 names_out
[i
].sid_type
= names
[i
].sid_type
;
1025 names_out
[i
].name
= names
[i
].name
;
1026 names_out
[i
].sid_index
= names
[i
].sid_index
;
1029 *r
->out
.domains
= domains
;
1030 r
->out
.names
->count
= num_sids
;
1031 r
->out
.names
->names
= names_out
;
1032 *r
->out
.count
= mapped_count
;
1037 static NTSTATUS
_lsa_LookupSids_common(struct pipes_struct
*p
,
1038 struct lsa_LookupSids2
*r
)
1041 struct lsa_info
*handle
;
1042 int num_sids
= r
->in
.sids
->num_sids
;
1043 uint32 mapped_count
= 0;
1044 struct lsa_RefDomainList
*domains
= NULL
;
1045 struct lsa_TranslatedName2
*names
= NULL
;
1046 bool check_policy
= true;
1049 case NDR_LSA_LOOKUPSIDS3
:
1050 check_policy
= false;
1052 case NDR_LSA_LOOKUPSIDS2
:
1054 check_policy
= true;
1057 if ((r
->in
.level
< 1) || (r
->in
.level
> 6)) {
1058 return NT_STATUS_INVALID_PARAMETER
;
1062 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1063 return NT_STATUS_INVALID_HANDLE
;
1066 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1067 return NT_STATUS_INVALID_HANDLE
;
1070 /* check if the user has enough rights */
1071 if (!(handle
->access
& LSA_POLICY_LOOKUP_NAMES
)) {
1072 return NT_STATUS_ACCESS_DENIED
;
1076 if (num_sids
> MAX_LOOKUP_SIDS
) {
1077 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1078 MAX_LOOKUP_SIDS
, num_sids
));
1079 return NT_STATUS_NONE_MAPPED
;
1082 status
= _lsa_lookup_sids_internal(p
,
1091 *r
->out
.domains
= domains
;
1092 r
->out
.names
->count
= num_sids
;
1093 r
->out
.names
->names
= names
;
1094 *r
->out
.count
= mapped_count
;
1099 /***************************************************************************
1101 ***************************************************************************/
1103 NTSTATUS
_lsa_LookupSids2(struct pipes_struct
*p
,
1104 struct lsa_LookupSids2
*r
)
1106 if (p
->transport
!= NCACN_NP
&& p
->transport
!= NCALRPC
) {
1107 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
1108 return NT_STATUS_ACCESS_DENIED
;
1111 return _lsa_LookupSids_common(p
, r
);
1114 /***************************************************************************
1116 ***************************************************************************/
1118 NTSTATUS
_lsa_LookupSids3(struct pipes_struct
*p
,
1119 struct lsa_LookupSids3
*r
)
1121 struct lsa_LookupSids2 q
;
1123 if (p
->transport
!= NCACN_IP_TCP
) {
1124 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
1125 return NT_STATUS_ACCESS_DENIED
;
1128 /* No policy handle on this call. Restrict to crypto connections. */
1129 if (p
->auth
.auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
) {
1130 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1131 get_remote_machine_name() ));
1132 return NT_STATUS_INVALID_PARAMETER
;
1136 q
.in
.sids
= r
->in
.sids
;
1137 q
.in
.level
= r
->in
.level
;
1138 q
.in
.lookup_options
= r
->in
.lookup_options
;
1139 q
.in
.client_revision
= r
->in
.client_revision
;
1140 q
.in
.names
= r
->in
.names
;
1141 q
.in
.count
= r
->in
.count
;
1143 q
.out
.domains
= r
->out
.domains
;
1144 q
.out
.names
= r
->out
.names
;
1145 q
.out
.count
= r
->out
.count
;
1147 return _lsa_LookupSids_common(p
, &q
);
1150 /***************************************************************************
1151 ***************************************************************************/
1153 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level
)
1158 case LSA_LOOKUP_NAMES_ALL
: /* 1 */
1159 flags
= LOOKUP_NAME_ALL
;
1161 case LSA_LOOKUP_NAMES_DOMAINS_ONLY
: /* 2 */
1162 flags
= LOOKUP_NAME_DOMAIN
|LOOKUP_NAME_REMOTE
|LOOKUP_NAME_ISOLATED
;
1164 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY
: /* 3 */
1165 flags
= LOOKUP_NAME_DOMAIN
|LOOKUP_NAME_ISOLATED
;
1167 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY
: /* 4 */
1168 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY
: /* 5 */
1169 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2
: /* 6 */
1170 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC
: /* 7 */
1172 flags
= LOOKUP_NAME_NONE
;
1179 /***************************************************************************
1181 ***************************************************************************/
1183 NTSTATUS
_lsa_LookupNames(struct pipes_struct
*p
,
1184 struct lsa_LookupNames
*r
)
1186 NTSTATUS status
= NT_STATUS_NONE_MAPPED
;
1187 struct lsa_info
*handle
;
1188 struct lsa_String
*names
= r
->in
.names
;
1189 uint32 num_entries
= r
->in
.num_names
;
1190 struct lsa_RefDomainList
*domains
= NULL
;
1191 struct lsa_TranslatedSid
*rids
= NULL
;
1192 uint32 mapped_count
= 0;
1195 if (p
->transport
!= NCACN_NP
&& p
->transport
!= NCALRPC
) {
1196 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
1197 return NT_STATUS_ACCESS_DENIED
;
1200 if (num_entries
> MAX_LOOKUP_SIDS
) {
1201 num_entries
= MAX_LOOKUP_SIDS
;
1202 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1206 flags
= lsa_lookup_level_to_flags(r
->in
.level
);
1208 domains
= talloc_zero(p
->mem_ctx
, struct lsa_RefDomainList
);
1210 return NT_STATUS_NO_MEMORY
;
1214 rids
= talloc_zero_array(p
->mem_ctx
, struct lsa_TranslatedSid
,
1217 return NT_STATUS_NO_MEMORY
;
1223 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1224 status
= NT_STATUS_INVALID_HANDLE
;
1228 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1229 return NT_STATUS_INVALID_HANDLE
;
1232 /* check if the user has enough rights */
1233 if (!(handle
->access
& LSA_POLICY_LOOKUP_NAMES
)) {
1234 status
= NT_STATUS_ACCESS_DENIED
;
1238 /* set up the LSA Lookup RIDs response */
1239 become_root(); /* lookup_name can require root privs */
1240 status
= lookup_lsa_rids(p
->mem_ctx
, domains
, rids
, num_entries
,
1241 names
, flags
, &mapped_count
);
1246 if (NT_STATUS_IS_OK(status
) && (num_entries
!= 0) ) {
1247 if (mapped_count
== 0) {
1248 status
= NT_STATUS_NONE_MAPPED
;
1249 } else if (mapped_count
!= num_entries
) {
1250 status
= STATUS_SOME_UNMAPPED
;
1254 *r
->out
.count
= mapped_count
;
1255 *r
->out
.domains
= domains
;
1256 r
->out
.sids
->sids
= rids
;
1257 r
->out
.sids
->count
= num_entries
;
1262 /***************************************************************************
1264 ***************************************************************************/
1266 NTSTATUS
_lsa_LookupNames2(struct pipes_struct
*p
,
1267 struct lsa_LookupNames2
*r
)
1270 struct lsa_LookupNames q
;
1271 struct lsa_TransSidArray2
*sid_array2
= r
->in
.sids
;
1272 struct lsa_TransSidArray
*sid_array
= NULL
;
1275 if (p
->transport
!= NCACN_NP
&& p
->transport
!= NCALRPC
) {
1276 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
1277 return NT_STATUS_ACCESS_DENIED
;
1280 sid_array
= talloc_zero(p
->mem_ctx
, struct lsa_TransSidArray
);
1282 return NT_STATUS_NO_MEMORY
;
1285 q
.in
.handle
= r
->in
.handle
;
1286 q
.in
.num_names
= r
->in
.num_names
;
1287 q
.in
.names
= r
->in
.names
;
1288 q
.in
.level
= r
->in
.level
;
1289 q
.in
.sids
= sid_array
;
1290 q
.in
.count
= r
->in
.count
;
1291 /* we do not know what this is for */
1292 /* = r->in.unknown1; */
1293 /* = r->in.unknown2; */
1295 q
.out
.domains
= r
->out
.domains
;
1296 q
.out
.sids
= sid_array
;
1297 q
.out
.count
= r
->out
.count
;
1299 status
= _lsa_LookupNames(p
, &q
);
1301 sid_array2
->count
= sid_array
->count
;
1302 sid_array2
->sids
= talloc_array(p
->mem_ctx
, struct lsa_TranslatedSid2
, sid_array
->count
);
1303 if (!sid_array2
->sids
) {
1304 return NT_STATUS_NO_MEMORY
;
1307 for (i
=0; i
<sid_array
->count
; i
++) {
1308 sid_array2
->sids
[i
].sid_type
= sid_array
->sids
[i
].sid_type
;
1309 sid_array2
->sids
[i
].rid
= sid_array
->sids
[i
].rid
;
1310 sid_array2
->sids
[i
].sid_index
= sid_array
->sids
[i
].sid_index
;
1311 sid_array2
->sids
[i
].unknown
= 0;
1314 r
->out
.sids
= sid_array2
;
1319 /***************************************************************************
1321 ***************************************************************************/
1323 NTSTATUS
_lsa_LookupNames3(struct pipes_struct
*p
,
1324 struct lsa_LookupNames3
*r
)
1327 struct lsa_info
*handle
;
1328 struct lsa_String
*names
= r
->in
.names
;
1329 uint32 num_entries
= r
->in
.num_names
;
1330 struct lsa_RefDomainList
*domains
= NULL
;
1331 struct lsa_TranslatedSid3
*trans_sids
= NULL
;
1332 uint32 mapped_count
= 0;
1334 bool check_policy
= true;
1336 if (p
->transport
!= NCACN_NP
&& p
->transport
!= NCALRPC
) {
1337 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
1338 return NT_STATUS_ACCESS_DENIED
;
1342 case NDR_LSA_LOOKUPNAMES4
:
1343 check_policy
= false;
1345 case NDR_LSA_LOOKUPNAMES3
:
1347 check_policy
= true;
1350 if (num_entries
> MAX_LOOKUP_SIDS
) {
1351 num_entries
= MAX_LOOKUP_SIDS
;
1352 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries
));
1355 flags
= lsa_lookup_level_to_flags(r
->in
.level
);
1357 domains
= talloc_zero(p
->mem_ctx
, struct lsa_RefDomainList
);
1359 return NT_STATUS_NO_MEMORY
;
1363 trans_sids
= talloc_zero_array(p
->mem_ctx
, struct lsa_TranslatedSid3
,
1366 return NT_STATUS_NO_MEMORY
;
1374 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1375 status
= NT_STATUS_INVALID_HANDLE
;
1379 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1380 return NT_STATUS_INVALID_HANDLE
;
1383 /* check if the user has enough rights */
1384 if (!(handle
->access
& LSA_POLICY_LOOKUP_NAMES
)) {
1385 status
= NT_STATUS_ACCESS_DENIED
;
1390 /* set up the LSA Lookup SIDs response */
1391 become_root(); /* lookup_name can require root privs */
1392 status
= lookup_lsa_sids(p
->mem_ctx
, domains
, trans_sids
, num_entries
,
1393 names
, flags
, &mapped_count
);
1398 if (NT_STATUS_IS_OK(status
)) {
1399 if (mapped_count
== 0) {
1400 status
= NT_STATUS_NONE_MAPPED
;
1401 } else if (mapped_count
!= num_entries
) {
1402 status
= STATUS_SOME_UNMAPPED
;
1406 *r
->out
.count
= mapped_count
;
1407 *r
->out
.domains
= domains
;
1408 r
->out
.sids
->sids
= trans_sids
;
1409 r
->out
.sids
->count
= num_entries
;
1414 /***************************************************************************
1416 ***************************************************************************/
1418 NTSTATUS
_lsa_LookupNames4(struct pipes_struct
*p
,
1419 struct lsa_LookupNames4
*r
)
1421 struct lsa_LookupNames3 q
;
1423 /* No policy handle on this call. Restrict to crypto connections. */
1424 if (p
->auth
.auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
) {
1425 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1426 get_remote_machine_name() ));
1427 return NT_STATUS_INVALID_PARAMETER
;
1431 q
.in
.num_names
= r
->in
.num_names
;
1432 q
.in
.names
= r
->in
.names
;
1433 q
.in
.level
= r
->in
.level
;
1434 q
.in
.lookup_options
= r
->in
.lookup_options
;
1435 q
.in
.client_revision
= r
->in
.client_revision
;
1436 q
.in
.sids
= r
->in
.sids
;
1437 q
.in
.count
= r
->in
.count
;
1439 q
.out
.domains
= r
->out
.domains
;
1440 q
.out
.sids
= r
->out
.sids
;
1441 q
.out
.count
= r
->out
.count
;
1443 return _lsa_LookupNames3(p
, &q
);
1446 /***************************************************************************
1447 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1448 ***************************************************************************/
1450 NTSTATUS
_lsa_Close(struct pipes_struct
*p
, struct lsa_Close
*r
)
1452 if (p
->transport
!= NCACN_NP
&& p
->transport
!= NCALRPC
) {
1453 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
1454 return NT_STATUS_ACCESS_DENIED
;
1457 if (!find_policy_by_hnd(p
, r
->in
.handle
, NULL
)) {
1458 return NT_STATUS_INVALID_HANDLE
;
1461 close_policy_hnd(p
, r
->in
.handle
);
1462 ZERO_STRUCTP(r
->out
.handle
);
1463 return NT_STATUS_OK
;
1466 /***************************************************************************
1467 ***************************************************************************/
1469 static NTSTATUS
lsa_lookup_trusted_domain_by_sid(TALLOC_CTX
*mem_ctx
,
1470 const struct dom_sid
*sid
,
1471 struct trustdom_info
**info
)
1474 uint32_t num_domains
= 0;
1475 struct trustdom_info
**domains
= NULL
;
1478 status
= pdb_enum_trusteddoms(mem_ctx
, &num_domains
, &domains
);
1479 if (!NT_STATUS_IS_OK(status
)) {
1483 for (i
=0; i
< num_domains
; i
++) {
1484 if (dom_sid_equal(&domains
[i
]->sid
, sid
)) {
1489 if (i
== num_domains
) {
1490 return NT_STATUS_INVALID_PARAMETER
;
1495 return NT_STATUS_OK
;
1498 /***************************************************************************
1499 ***************************************************************************/
1501 static NTSTATUS
lsa_lookup_trusted_domain_by_name(TALLOC_CTX
*mem_ctx
,
1502 const char *netbios_domain_name
,
1503 struct trustdom_info
**info_p
)
1506 struct trustdom_info
*info
;
1507 struct pdb_trusted_domain
*td
;
1509 status
= pdb_get_trusted_domain(mem_ctx
, netbios_domain_name
, &td
);
1510 if (!NT_STATUS_IS_OK(status
)) {
1514 info
= talloc(mem_ctx
, struct trustdom_info
);
1516 return NT_STATUS_NO_MEMORY
;
1519 info
->name
= talloc_strdup(info
, netbios_domain_name
);
1520 NT_STATUS_HAVE_NO_MEMORY(info
->name
);
1522 sid_copy(&info
->sid
, &td
->security_identifier
);
1526 return NT_STATUS_OK
;
1529 /***************************************************************************
1531 ***************************************************************************/
1533 NTSTATUS
_lsa_OpenSecret(struct pipes_struct
*p
,
1534 struct lsa_OpenSecret
*r
)
1536 struct lsa_info
*handle
;
1537 struct security_descriptor
*psd
;
1539 uint32_t acc_granted
;
1541 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1542 return NT_STATUS_INVALID_HANDLE
;
1545 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1546 return NT_STATUS_INVALID_HANDLE
;
1549 if (!r
->in
.name
.string
) {
1550 return NT_STATUS_INVALID_PARAMETER
;
1553 /* Work out max allowed. */
1554 map_max_allowed_access(p
->session_info
->security_token
,
1555 p
->session_info
->unix_token
,
1556 &r
->in
.access_mask
);
1558 /* map the generic bits to the lsa policy ones */
1559 se_map_generic(&r
->in
.access_mask
, &lsa_secret_mapping
);
1561 status
= pdb_get_secret(p
->mem_ctx
, r
->in
.name
.string
,
1567 if (!NT_STATUS_IS_OK(status
)) {
1571 status
= access_check_object(psd
, p
->session_info
->security_token
,
1572 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
1574 &acc_granted
, "_lsa_OpenSecret");
1575 if (!NT_STATUS_IS_OK(status
)) {
1579 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
1580 LSA_HANDLE_SECRET_TYPE
,
1586 if (!NT_STATUS_IS_OK(status
)) {
1587 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1590 return NT_STATUS_OK
;
1593 /***************************************************************************
1594 _lsa_OpenTrustedDomain_base
1595 ***************************************************************************/
1597 static NTSTATUS
_lsa_OpenTrustedDomain_base(struct pipes_struct
*p
,
1598 uint32_t access_mask
,
1599 struct trustdom_info
*info
,
1600 struct policy_handle
*handle
)
1602 struct security_descriptor
*psd
= NULL
;
1604 uint32_t acc_granted
;
1607 /* des_access is for the account here, not the policy
1608 * handle - so don't check against policy handle. */
1610 /* Work out max allowed. */
1611 map_max_allowed_access(p
->session_info
->security_token
,
1612 p
->session_info
->unix_token
,
1615 /* map the generic bits to the lsa account ones */
1616 se_map_generic(&access_mask
, &lsa_trusted_domain_mapping
);
1618 /* get the generic lsa account SD until we store it */
1619 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
1620 &lsa_trusted_domain_mapping
,
1622 if (!NT_STATUS_IS_OK(status
)) {
1626 status
= access_check_object(psd
, p
->session_info
->security_token
,
1627 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
1628 access_mask
, &acc_granted
,
1629 "_lsa_OpenTrustedDomain");
1630 if (!NT_STATUS_IS_OK(status
)) {
1634 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
1635 LSA_HANDLE_TRUST_TYPE
,
1641 if (!NT_STATUS_IS_OK(status
)) {
1642 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1645 return NT_STATUS_OK
;
1648 /***************************************************************************
1649 _lsa_OpenTrustedDomain
1650 ***************************************************************************/
1652 NTSTATUS
_lsa_OpenTrustedDomain(struct pipes_struct
*p
,
1653 struct lsa_OpenTrustedDomain
*r
)
1655 struct lsa_info
*handle
= NULL
;
1656 struct trustdom_info
*info
= NULL
;
1659 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1660 return NT_STATUS_INVALID_HANDLE
;
1663 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1664 return NT_STATUS_INVALID_HANDLE
;
1667 status
= lsa_lookup_trusted_domain_by_sid(p
->mem_ctx
,
1670 if (!NT_STATUS_IS_OK(status
)) {
1674 return _lsa_OpenTrustedDomain_base(p
, r
->in
.access_mask
, info
,
1675 r
->out
.trustdom_handle
);
1678 /***************************************************************************
1679 _lsa_OpenTrustedDomainByName
1680 ***************************************************************************/
1682 NTSTATUS
_lsa_OpenTrustedDomainByName(struct pipes_struct
*p
,
1683 struct lsa_OpenTrustedDomainByName
*r
)
1685 struct lsa_info
*handle
= NULL
;
1686 struct trustdom_info
*info
= NULL
;
1689 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1690 return NT_STATUS_INVALID_HANDLE
;
1693 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1694 return NT_STATUS_INVALID_HANDLE
;
1697 status
= lsa_lookup_trusted_domain_by_name(p
->mem_ctx
,
1700 if (!NT_STATUS_IS_OK(status
)) {
1704 return _lsa_OpenTrustedDomain_base(p
, r
->in
.access_mask
, info
,
1705 r
->out
.trustdom_handle
);
1708 static NTSTATUS
get_trustdom_auth_blob(struct pipes_struct
*p
,
1709 TALLOC_CTX
*mem_ctx
, DATA_BLOB
*auth_blob
,
1710 struct trustDomainPasswords
*auth_struct
)
1712 enum ndr_err_code ndr_err
;
1713 DATA_BLOB lsession_key
;
1716 status
= session_extract_session_key(p
->session_info
, &lsession_key
, KEY_USE_16BYTES
);
1717 if (!NT_STATUS_IS_OK(status
)) {
1718 return NT_STATUS_INVALID_PARAMETER
;
1721 arcfour_crypt_blob(auth_blob
->data
, auth_blob
->length
, &lsession_key
);
1722 ndr_err
= ndr_pull_struct_blob(auth_blob
, mem_ctx
,
1724 (ndr_pull_flags_fn_t
)ndr_pull_trustDomainPasswords
);
1725 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1726 return NT_STATUS_INVALID_PARAMETER
;
1729 return NT_STATUS_OK
;
1732 static NTSTATUS
get_trustauth_inout_blob(TALLOC_CTX
*mem_ctx
,
1733 struct trustAuthInOutBlob
*iopw
,
1734 DATA_BLOB
*trustauth_blob
)
1736 enum ndr_err_code ndr_err
;
1738 ndr_err
= ndr_push_struct_blob(trustauth_blob
, mem_ctx
,
1740 (ndr_push_flags_fn_t
)ndr_push_trustAuthInOutBlob
);
1741 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1742 return NT_STATUS_INVALID_PARAMETER
;
1745 return NT_STATUS_OK
;
1748 /***************************************************************************
1749 _lsa_CreateTrustedDomainEx2
1750 ***************************************************************************/
1752 NTSTATUS
_lsa_CreateTrustedDomainEx2(struct pipes_struct
*p
,
1753 struct lsa_CreateTrustedDomainEx2
*r
)
1755 struct lsa_info
*policy
;
1757 uint32_t acc_granted
;
1758 struct security_descriptor
*psd
;
1760 struct pdb_trusted_domain td
;
1761 struct trustDomainPasswords auth_struct
;
1762 DATA_BLOB auth_blob
;
1765 return NT_STATUS_NOT_SUPPORTED
;
1768 if (!find_policy_by_hnd(p
, r
->in
.policy_handle
, (void **)(void *)&policy
)) {
1769 return NT_STATUS_INVALID_HANDLE
;
1772 if (!(policy
->access
& LSA_POLICY_TRUST_ADMIN
)) {
1773 return NT_STATUS_ACCESS_DENIED
;
1776 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() &&
1777 !nt_token_check_domain_rid(p
->session_info
->security_token
, DOMAIN_RID_ADMINS
)) {
1778 return NT_STATUS_ACCESS_DENIED
;
1781 /* Work out max allowed. */
1782 map_max_allowed_access(p
->session_info
->security_token
,
1783 p
->session_info
->unix_token
,
1784 &r
->in
.access_mask
);
1786 /* map the generic bits to the lsa policy ones */
1787 se_map_generic(&r
->in
.access_mask
, &lsa_account_mapping
);
1789 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
1790 &lsa_trusted_domain_mapping
,
1792 if (!NT_STATUS_IS_OK(status
)) {
1796 status
= access_check_object(psd
, p
->session_info
->security_token
,
1797 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
1798 r
->in
.access_mask
, &acc_granted
,
1799 "_lsa_CreateTrustedDomainEx2");
1800 if (!NT_STATUS_IS_OK(status
)) {
1806 td
.domain_name
= talloc_strdup(p
->mem_ctx
,
1807 r
->in
.info
->domain_name
.string
);
1808 if (td
.domain_name
== NULL
) {
1809 return NT_STATUS_NO_MEMORY
;
1811 td
.netbios_name
= talloc_strdup(p
->mem_ctx
,
1812 r
->in
.info
->netbios_name
.string
);
1813 if (td
.netbios_name
== NULL
) {
1814 return NT_STATUS_NO_MEMORY
;
1816 sid_copy(&td
.security_identifier
, r
->in
.info
->sid
);
1817 td
.trust_direction
= r
->in
.info
->trust_direction
;
1818 td
.trust_type
= r
->in
.info
->trust_type
;
1819 td
.trust_attributes
= r
->in
.info
->trust_attributes
;
1821 if (r
->in
.auth_info_internal
->auth_blob
.size
!= 0) {
1822 auth_blob
.length
= r
->in
.auth_info_internal
->auth_blob
.size
;
1823 auth_blob
.data
= r
->in
.auth_info_internal
->auth_blob
.data
;
1825 status
= get_trustdom_auth_blob(p
, p
->mem_ctx
, &auth_blob
, &auth_struct
);
1826 if (!NT_STATUS_IS_OK(status
)) {
1827 return NT_STATUS_UNSUCCESSFUL
;
1830 status
= get_trustauth_inout_blob(p
->mem_ctx
, &auth_struct
.incoming
, &td
.trust_auth_incoming
);
1831 if (!NT_STATUS_IS_OK(status
)) {
1832 return NT_STATUS_UNSUCCESSFUL
;
1835 status
= get_trustauth_inout_blob(p
->mem_ctx
, &auth_struct
.outgoing
, &td
.trust_auth_outgoing
);
1836 if (!NT_STATUS_IS_OK(status
)) {
1837 return NT_STATUS_UNSUCCESSFUL
;
1840 td
.trust_auth_incoming
.data
= NULL
;
1841 td
.trust_auth_incoming
.length
= 0;
1842 td
.trust_auth_outgoing
.data
= NULL
;
1843 td
.trust_auth_outgoing
.length
= 0;
1846 status
= pdb_set_trusted_domain(r
->in
.info
->domain_name
.string
, &td
);
1847 if (!NT_STATUS_IS_OK(status
)) {
1851 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
1852 LSA_HANDLE_TRUST_TYPE
,
1855 r
->in
.info
->netbios_name
.string
,
1857 r
->out
.trustdom_handle
);
1858 if (!NT_STATUS_IS_OK(status
)) {
1859 pdb_del_trusted_domain(r
->in
.info
->netbios_name
.string
);
1860 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1863 return NT_STATUS_OK
;
1866 /***************************************************************************
1867 _lsa_CreateTrustedDomainEx
1868 ***************************************************************************/
1870 NTSTATUS
_lsa_CreateTrustedDomainEx(struct pipes_struct
*p
,
1871 struct lsa_CreateTrustedDomainEx
*r
)
1873 struct lsa_CreateTrustedDomainEx2 q
;
1874 struct lsa_TrustDomainInfoAuthInfoInternal auth_info
;
1876 ZERO_STRUCT(auth_info
);
1878 q
.in
.policy_handle
= r
->in
.policy_handle
;
1879 q
.in
.info
= r
->in
.info
;
1880 q
.in
.auth_info_internal
= &auth_info
;
1881 q
.in
.access_mask
= r
->in
.access_mask
;
1882 q
.out
.trustdom_handle
= r
->out
.trustdom_handle
;
1884 return _lsa_CreateTrustedDomainEx2(p
, &q
);
1887 /***************************************************************************
1888 _lsa_CreateTrustedDomain
1889 ***************************************************************************/
1891 NTSTATUS
_lsa_CreateTrustedDomain(struct pipes_struct
*p
,
1892 struct lsa_CreateTrustedDomain
*r
)
1894 struct lsa_CreateTrustedDomainEx2 c
;
1895 struct lsa_TrustDomainInfoInfoEx info
;
1896 struct lsa_TrustDomainInfoAuthInfoInternal auth_info
;
1898 ZERO_STRUCT(auth_info
);
1900 info
.domain_name
= r
->in
.info
->name
;
1901 info
.netbios_name
= r
->in
.info
->name
;
1902 info
.sid
= r
->in
.info
->sid
;
1903 info
.trust_direction
= LSA_TRUST_DIRECTION_OUTBOUND
;
1904 info
.trust_type
= LSA_TRUST_TYPE_DOWNLEVEL
;
1905 info
.trust_attributes
= 0;
1907 c
.in
.policy_handle
= r
->in
.policy_handle
;
1909 c
.in
.auth_info_internal
= &auth_info
;
1910 c
.in
.access_mask
= r
->in
.access_mask
;
1911 c
.out
.trustdom_handle
= r
->out
.trustdom_handle
;
1913 return _lsa_CreateTrustedDomainEx2(p
, &c
);
1916 /***************************************************************************
1917 _lsa_DeleteTrustedDomain
1918 ***************************************************************************/
1920 NTSTATUS
_lsa_DeleteTrustedDomain(struct pipes_struct
*p
,
1921 struct lsa_DeleteTrustedDomain
*r
)
1924 struct lsa_info
*handle
;
1925 struct pdb_trusted_domain
*td
;
1927 /* find the connection policy handle. */
1928 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1929 return NT_STATUS_INVALID_HANDLE
;
1932 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1933 return NT_STATUS_INVALID_HANDLE
;
1936 if (!(handle
->access
& LSA_POLICY_TRUST_ADMIN
)) {
1937 return NT_STATUS_ACCESS_DENIED
;
1940 status
= pdb_get_trusted_domain_by_sid(p
->mem_ctx
, r
->in
.dom_sid
, &td
);
1941 if (!NT_STATUS_IS_OK(status
)) {
1945 if (td
->netbios_name
== NULL
|| *td
->netbios_name
== '\0') {
1946 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1947 sid_string_tos(r
->in
.dom_sid
)));
1948 return NT_STATUS_UNSUCCESSFUL
;
1951 status
= pdb_del_trusted_domain(td
->netbios_name
);
1952 if (!NT_STATUS_IS_OK(status
)) {
1956 return NT_STATUS_OK
;
1959 /***************************************************************************
1960 _lsa_CloseTrustedDomainEx
1961 ***************************************************************************/
1963 NTSTATUS
_lsa_CloseTrustedDomainEx(struct pipes_struct
*p
,
1964 struct lsa_CloseTrustedDomainEx
*r
)
1966 return NT_STATUS_NOT_IMPLEMENTED
;
1969 /***************************************************************************
1970 _lsa_QueryTrustedDomainInfo
1971 ***************************************************************************/
1973 static NTSTATUS
pdb_trusted_domain_2_info_ex(TALLOC_CTX
*mem_ctx
,
1974 struct pdb_trusted_domain
*td
,
1975 struct lsa_TrustDomainInfoInfoEx
*info_ex
)
1977 if (td
->domain_name
== NULL
||
1978 td
->netbios_name
== NULL
||
1979 is_null_sid(&td
->security_identifier
)) {
1980 return NT_STATUS_INVALID_PARAMETER
;
1983 info_ex
->domain_name
.string
= talloc_strdup(mem_ctx
, td
->domain_name
);
1984 info_ex
->netbios_name
.string
= talloc_strdup(mem_ctx
, td
->netbios_name
);
1985 info_ex
->sid
= dom_sid_dup(mem_ctx
, &td
->security_identifier
);
1986 if (info_ex
->domain_name
.string
== NULL
||
1987 info_ex
->netbios_name
.string
== NULL
||
1988 info_ex
->sid
== NULL
) {
1989 return NT_STATUS_NO_MEMORY
;
1992 info_ex
->trust_direction
= td
->trust_direction
;
1993 info_ex
->trust_type
= td
->trust_type
;
1994 info_ex
->trust_attributes
= td
->trust_attributes
;
1996 return NT_STATUS_OK
;
1999 NTSTATUS
_lsa_QueryTrustedDomainInfo(struct pipes_struct
*p
,
2000 struct lsa_QueryTrustedDomainInfo
*r
)
2003 struct lsa_info
*handle
;
2004 union lsa_TrustedDomainInfo
*info
;
2005 struct pdb_trusted_domain
*td
;
2006 uint32_t acc_required
;
2008 /* find the connection policy handle. */
2009 if (!find_policy_by_hnd(p
, r
->in
.trustdom_handle
, (void **)(void *)&handle
)) {
2010 return NT_STATUS_INVALID_HANDLE
;
2013 if (handle
->type
!= LSA_HANDLE_TRUST_TYPE
) {
2014 return NT_STATUS_INVALID_HANDLE
;
2017 switch (r
->in
.level
) {
2018 case LSA_TRUSTED_DOMAIN_INFO_NAME
:
2019 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
2021 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS
:
2022 acc_required
= LSA_TRUSTED_QUERY_CONTROLLERS
;
2024 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET
:
2025 acc_required
= LSA_TRUSTED_QUERY_POSIX
;
2027 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD
:
2028 acc_required
= LSA_TRUSTED_QUERY_AUTH
;
2030 case LSA_TRUSTED_DOMAIN_INFO_BASIC
:
2031 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
2033 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX
:
2034 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
2036 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO
:
2037 acc_required
= LSA_TRUSTED_QUERY_AUTH
;
2039 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
:
2040 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
|
2041 LSA_TRUSTED_QUERY_POSIX
|
2042 LSA_TRUSTED_QUERY_AUTH
;
2044 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL
:
2045 acc_required
= LSA_TRUSTED_QUERY_AUTH
;
2047 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL
:
2048 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
|
2049 LSA_TRUSTED_QUERY_POSIX
|
2050 LSA_TRUSTED_QUERY_AUTH
;
2052 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL
:
2053 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
2055 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL
:
2056 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
|
2057 LSA_TRUSTED_QUERY_POSIX
|
2058 LSA_TRUSTED_QUERY_AUTH
;
2060 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES
:
2061 acc_required
= LSA_TRUSTED_QUERY_POSIX
;
2064 return NT_STATUS_INVALID_PARAMETER
;
2067 if (!(handle
->access
& acc_required
)) {
2068 return NT_STATUS_ACCESS_DENIED
;
2071 status
= pdb_get_trusted_domain_by_sid(p
->mem_ctx
, &handle
->sid
, &td
);
2072 if (!NT_STATUS_IS_OK(status
)) {
2076 info
= talloc_zero(p
->mem_ctx
, union lsa_TrustedDomainInfo
);
2078 return NT_STATUS_NO_MEMORY
;
2081 switch (r
->in
.level
) {
2082 case LSA_TRUSTED_DOMAIN_INFO_NAME
:
2083 init_lsa_StringLarge(&info
->name
.netbios_name
, td
->netbios_name
);
2085 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS
:
2086 return NT_STATUS_INVALID_PARAMETER
;
2087 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET
:
2088 info
->posix_offset
.posix_offset
= *td
->trust_posix_offset
;
2090 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD
:
2091 return NT_STATUS_INVALID_INFO_CLASS
;
2092 case LSA_TRUSTED_DOMAIN_INFO_BASIC
:
2093 return NT_STATUS_INVALID_PARAMETER
;
2094 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX
:
2095 status
= pdb_trusted_domain_2_info_ex(info
, td
, &info
->info_ex
);
2096 if (!NT_STATUS_IS_OK(status
)) {
2100 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO
:
2101 return NT_STATUS_INVALID_INFO_CLASS
;
2102 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
:
2103 status
= pdb_trusted_domain_2_info_ex(info
, td
,
2104 &info
->full_info
.info_ex
);
2105 if (!NT_STATUS_IS_OK(status
)) {
2108 info
->full_info
.posix_offset
.posix_offset
= *td
->trust_posix_offset
;
2109 status
= auth_blob_2_auth_info(p
->mem_ctx
,
2110 td
->trust_auth_incoming
,
2111 td
->trust_auth_outgoing
,
2112 &info
->full_info
.auth_info
);
2113 if (!NT_STATUS_IS_OK(status
)) {
2117 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL
:
2118 return NT_STATUS_INVALID_INFO_CLASS
;
2119 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL
:
2120 return NT_STATUS_INVALID_INFO_CLASS
;
2121 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL
:
2122 return NT_STATUS_INVALID_PARAMETER
;
2123 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL
:
2124 info
->full_info2_internal
.posix_offset
.posix_offset
= *td
->trust_posix_offset
;
2125 status
= auth_blob_2_auth_info(p
->mem_ctx
,
2126 td
->trust_auth_incoming
,
2127 td
->trust_auth_outgoing
,
2128 &info
->full_info2_internal
.auth_info
);
2129 if (!NT_STATUS_IS_OK(status
)) {
2133 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES
:
2134 info
->enc_types
.enc_types
= *td
->supported_enc_type
;
2137 return NT_STATUS_INVALID_PARAMETER
;
2140 *r
->out
.info
= info
;
2142 return NT_STATUS_OK
;
2145 /***************************************************************************
2146 _lsa_QueryTrustedDomainInfoBySid
2147 ***************************************************************************/
2149 NTSTATUS
_lsa_QueryTrustedDomainInfoBySid(struct pipes_struct
*p
,
2150 struct lsa_QueryTrustedDomainInfoBySid
*r
)
2153 struct policy_handle trustdom_handle
;
2154 struct lsa_OpenTrustedDomain o
;
2155 struct lsa_QueryTrustedDomainInfo q
;
2158 o
.in
.handle
= r
->in
.handle
;
2159 o
.in
.sid
= r
->in
.dom_sid
;
2160 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2161 o
.out
.trustdom_handle
= &trustdom_handle
;
2163 status
= _lsa_OpenTrustedDomain(p
, &o
);
2164 if (!NT_STATUS_IS_OK(status
)) {
2168 q
.in
.trustdom_handle
= &trustdom_handle
;
2169 q
.in
.level
= r
->in
.level
;
2170 q
.out
.info
= r
->out
.info
;
2172 status
= _lsa_QueryTrustedDomainInfo(p
, &q
);
2173 if (!NT_STATUS_IS_OK(status
)) {
2177 c
.in
.handle
= &trustdom_handle
;
2178 c
.out
.handle
= &trustdom_handle
;
2180 return _lsa_Close(p
, &c
);
2183 /***************************************************************************
2184 _lsa_QueryTrustedDomainInfoByName
2185 ***************************************************************************/
2187 NTSTATUS
_lsa_QueryTrustedDomainInfoByName(struct pipes_struct
*p
,
2188 struct lsa_QueryTrustedDomainInfoByName
*r
)
2191 struct policy_handle trustdom_handle
;
2192 struct lsa_OpenTrustedDomainByName o
;
2193 struct lsa_QueryTrustedDomainInfo q
;
2196 o
.in
.handle
= r
->in
.handle
;
2197 o
.in
.name
.string
= r
->in
.trusted_domain
->string
;
2198 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2199 o
.out
.trustdom_handle
= &trustdom_handle
;
2201 status
= _lsa_OpenTrustedDomainByName(p
, &o
);
2202 if (!NT_STATUS_IS_OK(status
)) {
2203 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_DOMAIN
)) {
2204 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2209 q
.in
.trustdom_handle
= &trustdom_handle
;
2210 q
.in
.level
= r
->in
.level
;
2211 q
.out
.info
= r
->out
.info
;
2213 status
= _lsa_QueryTrustedDomainInfo(p
, &q
);
2214 if (!NT_STATUS_IS_OK(status
)) {
2218 c
.in
.handle
= &trustdom_handle
;
2219 c
.out
.handle
= &trustdom_handle
;
2221 return _lsa_Close(p
, &c
);
2224 /***************************************************************************
2226 ***************************************************************************/
2228 NTSTATUS
_lsa_CreateSecret(struct pipes_struct
*p
,
2229 struct lsa_CreateSecret
*r
)
2232 struct lsa_info
*handle
;
2233 uint32_t acc_granted
;
2234 struct security_descriptor
*psd
;
2237 /* find the connection policy handle. */
2238 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
2239 return NT_STATUS_INVALID_HANDLE
;
2242 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2243 return NT_STATUS_INVALID_HANDLE
;
2246 /* check if the user has enough rights */
2248 if (!(handle
->access
& LSA_POLICY_CREATE_SECRET
)) {
2249 return NT_STATUS_ACCESS_DENIED
;
2252 /* Work out max allowed. */
2253 map_max_allowed_access(p
->session_info
->security_token
,
2254 p
->session_info
->unix_token
,
2255 &r
->in
.access_mask
);
2257 /* map the generic bits to the lsa policy ones */
2258 se_map_generic(&r
->in
.access_mask
, &lsa_secret_mapping
);
2260 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
2261 &lsa_secret_mapping
,
2263 if (!NT_STATUS_IS_OK(status
)) {
2267 status
= access_check_object(psd
, p
->session_info
->security_token
,
2268 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
2270 &acc_granted
, "_lsa_CreateSecret");
2271 if (!NT_STATUS_IS_OK(status
)) {
2275 if (!r
->in
.name
.string
) {
2276 return NT_STATUS_INVALID_PARAMETER
;
2279 if (strlen(r
->in
.name
.string
) > 128) {
2280 return NT_STATUS_NAME_TOO_LONG
;
2283 status
= pdb_get_secret(p
->mem_ctx
, r
->in
.name
.string
,
2284 NULL
, NULL
, NULL
, NULL
, NULL
);
2285 if (NT_STATUS_IS_OK(status
)) {
2286 return NT_STATUS_OBJECT_NAME_COLLISION
;
2289 status
= pdb_set_secret(r
->in
.name
.string
, NULL
, NULL
, psd
);
2290 if (!NT_STATUS_IS_OK(status
)) {
2294 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
2295 LSA_HANDLE_SECRET_TYPE
,
2301 if (!NT_STATUS_IS_OK(status
)) {
2302 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2305 return NT_STATUS_OK
;
2308 /***************************************************************************
2310 ***************************************************************************/
2312 NTSTATUS
_lsa_SetSecret(struct pipes_struct
*p
,
2313 struct lsa_SetSecret
*r
)
2316 struct lsa_info
*info
= NULL
;
2317 DATA_BLOB blob_new
, blob_old
;
2318 DATA_BLOB cleartext_blob_new
= data_blob_null
;
2319 DATA_BLOB cleartext_blob_old
= data_blob_null
;
2320 DATA_BLOB
*cleartext_blob_new_p
= NULL
;
2321 DATA_BLOB
*cleartext_blob_old_p
= NULL
;
2322 DATA_BLOB session_key
;
2324 if (!find_policy_by_hnd(p
, r
->in
.sec_handle
, (void **)(void *)&info
)) {
2325 return NT_STATUS_INVALID_HANDLE
;
2328 if (info
->type
!= LSA_HANDLE_SECRET_TYPE
) {
2329 return NT_STATUS_INVALID_HANDLE
;
2332 if (!(info
->access
& LSA_SECRET_SET_VALUE
)) {
2333 return NT_STATUS_ACCESS_DENIED
;
2336 status
= session_extract_session_key(p
->session_info
, &session_key
, KEY_USE_16BYTES
);
2337 if(!NT_STATUS_IS_OK(status
)) {
2341 if (r
->in
.new_val
) {
2342 blob_new
= data_blob_const(r
->in
.new_val
->data
,
2343 r
->in
.new_val
->length
);
2345 status
= sess_decrypt_blob(p
->mem_ctx
, &blob_new
,
2347 &cleartext_blob_new
);
2348 if (!NT_STATUS_IS_OK(status
)) {
2352 cleartext_blob_new_p
= &cleartext_blob_new
;
2355 if (r
->in
.old_val
) {
2356 blob_old
= data_blob_const(r
->in
.old_val
->data
,
2357 r
->in
.old_val
->length
);
2359 status
= sess_decrypt_blob(p
->mem_ctx
, &blob_old
,
2361 &cleartext_blob_old
);
2362 if (!NT_STATUS_IS_OK(status
)) {
2366 cleartext_blob_old_p
= &cleartext_blob_old
;
2369 status
= pdb_set_secret(info
->name
, cleartext_blob_new_p
, cleartext_blob_old_p
, NULL
);
2370 if (!NT_STATUS_IS_OK(status
)) {
2374 #ifdef DEBUG_PASSWORD
2375 DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
2376 dump_data(10, cleartext_blob_new
.data
, cleartext_blob_new
.length
);
2377 DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
2378 dump_data(10, cleartext_blob_old
.data
, cleartext_blob_old
.length
);
2381 return NT_STATUS_OK
;
2384 /***************************************************************************
2386 ***************************************************************************/
2388 NTSTATUS
_lsa_QuerySecret(struct pipes_struct
*p
,
2389 struct lsa_QuerySecret
*r
)
2391 struct lsa_info
*info
= NULL
;
2392 DATA_BLOB blob_new
, blob_old
;
2393 DATA_BLOB blob_new_crypt
, blob_old_crypt
;
2394 DATA_BLOB session_key
;
2395 NTTIME nttime_new
, nttime_old
;
2398 if (!find_policy_by_hnd(p
, r
->in
.sec_handle
, (void **)(void *)&info
)) {
2399 return NT_STATUS_INVALID_HANDLE
;
2402 if (info
->type
!= LSA_HANDLE_SECRET_TYPE
) {
2403 return NT_STATUS_INVALID_HANDLE
;
2406 if (!(info
->access
& LSA_SECRET_QUERY_VALUE
)) {
2407 return NT_STATUS_ACCESS_DENIED
;
2410 status
= pdb_get_secret(p
->mem_ctx
, info
->name
,
2411 &blob_new
, &nttime_new
,
2412 &blob_old
, &nttime_old
,
2414 if (!NT_STATUS_IS_OK(status
)) {
2418 status
= session_extract_session_key(p
->session_info
, &session_key
, KEY_USE_16BYTES
);
2419 if(!NT_STATUS_IS_OK(status
)) {
2423 if (r
->in
.new_val
) {
2424 if (blob_new
.length
) {
2425 if (!r
->out
.new_val
->buf
) {
2426 r
->out
.new_val
->buf
= talloc_zero(p
->mem_ctx
, struct lsa_DATA_BUF
);
2428 if (!r
->out
.new_val
->buf
) {
2429 return NT_STATUS_NO_MEMORY
;
2432 blob_new_crypt
= sess_encrypt_blob(p
->mem_ctx
, &blob_new
,
2434 if (!blob_new_crypt
.length
) {
2435 return NT_STATUS_NO_MEMORY
;
2438 r
->out
.new_val
->buf
->data
= blob_new_crypt
.data
;
2439 r
->out
.new_val
->buf
->length
= blob_new_crypt
.length
;
2440 r
->out
.new_val
->buf
->size
= blob_new_crypt
.length
;
2444 if (r
->in
.old_val
) {
2445 if (blob_old
.length
) {
2446 if (!r
->out
.old_val
->buf
) {
2447 r
->out
.old_val
->buf
= talloc_zero(p
->mem_ctx
, struct lsa_DATA_BUF
);
2449 if (!r
->out
.old_val
->buf
) {
2450 return NT_STATUS_NO_MEMORY
;
2453 blob_old_crypt
= sess_encrypt_blob(p
->mem_ctx
, &blob_old
,
2455 if (!blob_old_crypt
.length
) {
2456 return NT_STATUS_NO_MEMORY
;
2459 r
->out
.old_val
->buf
->data
= blob_old_crypt
.data
;
2460 r
->out
.old_val
->buf
->length
= blob_old_crypt
.length
;
2461 r
->out
.old_val
->buf
->size
= blob_old_crypt
.length
;
2465 if (r
->out
.new_mtime
) {
2466 *r
->out
.new_mtime
= nttime_new
;
2469 if (r
->out
.old_mtime
) {
2470 *r
->out
.old_mtime
= nttime_old
;
2473 return NT_STATUS_OK
;
2476 /***************************************************************************
2478 ***************************************************************************/
2480 NTSTATUS
_lsa_DeleteObject(struct pipes_struct
*p
,
2481 struct lsa_DeleteObject
*r
)
2484 struct lsa_info
*info
= NULL
;
2486 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
)) {
2487 return NT_STATUS_INVALID_HANDLE
;
2490 if (!(info
->access
& SEC_STD_DELETE
)) {
2491 return NT_STATUS_ACCESS_DENIED
;
2494 switch (info
->type
) {
2495 case LSA_HANDLE_ACCOUNT_TYPE
:
2496 status
= privilege_delete_account(&info
->sid
);
2497 if (!NT_STATUS_IS_OK(status
)) {
2498 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2499 nt_errstr(status
)));
2503 case LSA_HANDLE_TRUST_TYPE
:
2504 if (!pdb_del_trusteddom_pw(info
->name
)) {
2505 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2507 status
= NT_STATUS_OK
;
2509 case LSA_HANDLE_SECRET_TYPE
:
2510 status
= pdb_delete_secret(info
->name
);
2511 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
2512 return NT_STATUS_INVALID_HANDLE
;
2516 return NT_STATUS_INVALID_HANDLE
;
2519 close_policy_hnd(p
, r
->in
.handle
);
2520 ZERO_STRUCTP(r
->out
.handle
);
2525 /***************************************************************************
2527 ***************************************************************************/
2529 NTSTATUS
_lsa_EnumPrivs(struct pipes_struct
*p
,
2530 struct lsa_EnumPrivs
*r
)
2532 struct lsa_info
*handle
;
2534 uint32 enum_context
= *r
->in
.resume_handle
;
2535 int num_privs
= num_privileges_in_short_list();
2536 struct lsa_PrivEntry
*entries
= NULL
;
2538 /* remember that the enum_context starts at 0 and not 1 */
2540 if ( enum_context
>= num_privs
)
2541 return NT_STATUS_NO_MORE_ENTRIES
;
2543 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2544 enum_context
, num_privs
));
2546 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2547 return NT_STATUS_INVALID_HANDLE
;
2549 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2550 return NT_STATUS_INVALID_HANDLE
;
2553 /* check if the user has enough rights
2554 I don't know if it's the right one. not documented. */
2556 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
2557 return NT_STATUS_ACCESS_DENIED
;
2560 entries
= talloc_zero_array(p
->mem_ctx
, struct lsa_PrivEntry
, num_privs
);
2562 return NT_STATUS_NO_MEMORY
;
2568 for (i
= 0; i
< num_privs
; i
++) {
2569 if( i
< enum_context
) {
2571 init_lsa_StringLarge(&entries
[i
].name
, NULL
);
2573 entries
[i
].luid
.low
= 0;
2574 entries
[i
].luid
.high
= 0;
2577 init_lsa_StringLarge(&entries
[i
].name
, sec_privilege_name_from_index(i
));
2579 entries
[i
].luid
.low
= sec_privilege_from_index(i
);
2580 entries
[i
].luid
.high
= 0;
2584 enum_context
= num_privs
;
2586 *r
->out
.resume_handle
= enum_context
;
2587 r
->out
.privs
->count
= num_privs
;
2588 r
->out
.privs
->privs
= entries
;
2590 return NT_STATUS_OK
;
2593 /***************************************************************************
2594 _lsa_LookupPrivDisplayName
2595 ***************************************************************************/
2597 NTSTATUS
_lsa_LookupPrivDisplayName(struct pipes_struct
*p
,
2598 struct lsa_LookupPrivDisplayName
*r
)
2600 struct lsa_info
*handle
;
2601 const char *description
;
2602 struct lsa_StringLarge
*lsa_name
;
2604 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2605 return NT_STATUS_INVALID_HANDLE
;
2607 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2608 return NT_STATUS_INVALID_HANDLE
;
2611 /* check if the user has enough rights */
2614 * I don't know if it's the right one. not documented.
2616 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
2617 return NT_STATUS_ACCESS_DENIED
;
2619 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r
->in
.name
->string
));
2621 description
= get_privilege_dispname(r
->in
.name
->string
);
2623 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2624 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2627 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description
));
2629 lsa_name
= talloc_zero(p
->mem_ctx
, struct lsa_StringLarge
);
2631 return NT_STATUS_NO_MEMORY
;
2634 init_lsa_StringLarge(lsa_name
, description
);
2636 *r
->out
.returned_language_id
= r
->in
.language_id
;
2637 *r
->out
.disp_name
= lsa_name
;
2639 return NT_STATUS_OK
;
2642 /***************************************************************************
2644 ***************************************************************************/
2646 NTSTATUS
_lsa_EnumAccounts(struct pipes_struct
*p
,
2647 struct lsa_EnumAccounts
*r
)
2649 struct lsa_info
*handle
;
2650 struct dom_sid
*sid_list
;
2651 int i
, j
, num_entries
;
2653 struct lsa_SidPtr
*sids
= NULL
;
2655 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2656 return NT_STATUS_INVALID_HANDLE
;
2658 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2659 return NT_STATUS_INVALID_HANDLE
;
2662 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
2663 return NT_STATUS_ACCESS_DENIED
;
2668 /* The only way we can currently find out all the SIDs that have been
2669 privileged is to scan all privileges */
2671 status
= privilege_enumerate_accounts(&sid_list
, &num_entries
);
2672 if (!NT_STATUS_IS_OK(status
)) {
2676 if (*r
->in
.resume_handle
>= num_entries
) {
2677 return NT_STATUS_NO_MORE_ENTRIES
;
2680 if (num_entries
- *r
->in
.resume_handle
) {
2681 sids
= talloc_zero_array(p
->mem_ctx
, struct lsa_SidPtr
,
2682 num_entries
- *r
->in
.resume_handle
);
2684 talloc_free(sid_list
);
2685 return NT_STATUS_NO_MEMORY
;
2688 for (i
= *r
->in
.resume_handle
, j
= 0; i
< num_entries
; i
++, j
++) {
2689 sids
[j
].sid
= dom_sid_dup(p
->mem_ctx
, &sid_list
[i
]);
2691 talloc_free(sid_list
);
2692 return NT_STATUS_NO_MEMORY
;
2697 talloc_free(sid_list
);
2699 *r
->out
.resume_handle
= num_entries
;
2700 r
->out
.sids
->num_sids
= num_entries
;
2701 r
->out
.sids
->sids
= sids
;
2703 return NT_STATUS_OK
;
2706 /***************************************************************************
2708 ***************************************************************************/
2710 NTSTATUS
_lsa_GetUserName(struct pipes_struct
*p
,
2711 struct lsa_GetUserName
*r
)
2713 const char *username
, *domname
;
2714 struct lsa_String
*account_name
= NULL
;
2715 struct lsa_String
*authority_name
= NULL
;
2717 if (p
->transport
!= NCACN_NP
&& p
->transport
!= NCALRPC
) {
2718 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
2719 return NT_STATUS_ACCESS_DENIED
;
2722 if (r
->in
.account_name
&&
2723 *r
->in
.account_name
) {
2724 return NT_STATUS_INVALID_PARAMETER
;
2727 if (r
->in
.authority_name
&&
2728 *r
->in
.authority_name
) {
2729 return NT_STATUS_INVALID_PARAMETER
;
2732 if (security_session_user_level(p
->session_info
, NULL
) < SECURITY_USER
) {
2734 * I'm 99% sure this is not the right place to do this,
2735 * global_sid_Anonymous should probably be put into the token
2736 * instead of the guest id -- vl
2738 if (!lookup_sid(p
->mem_ctx
, &global_sid_Anonymous
,
2739 &domname
, &username
, NULL
)) {
2740 return NT_STATUS_NO_MEMORY
;
2743 username
= p
->session_info
->unix_info
->sanitized_username
;
2744 domname
= p
->session_info
->info
->domain_name
;
2747 account_name
= talloc(p
->mem_ctx
, struct lsa_String
);
2748 if (!account_name
) {
2749 return NT_STATUS_NO_MEMORY
;
2751 init_lsa_String(account_name
, username
);
2753 if (r
->out
.authority_name
) {
2754 authority_name
= talloc(p
->mem_ctx
, struct lsa_String
);
2755 if (!authority_name
) {
2756 return NT_STATUS_NO_MEMORY
;
2758 init_lsa_String(authority_name
, domname
);
2761 *r
->out
.account_name
= account_name
;
2762 if (r
->out
.authority_name
) {
2763 *r
->out
.authority_name
= authority_name
;
2766 return NT_STATUS_OK
;
2769 /***************************************************************************
2771 ***************************************************************************/
2773 NTSTATUS
_lsa_CreateAccount(struct pipes_struct
*p
,
2774 struct lsa_CreateAccount
*r
)
2777 struct lsa_info
*handle
;
2778 uint32_t acc_granted
;
2779 struct security_descriptor
*psd
;
2781 uint32_t owner_access
= (LSA_ACCOUNT_ALL_ACCESS
&
2782 ~(LSA_ACCOUNT_ADJUST_PRIVILEGES
|
2783 LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS
|
2786 /* find the connection policy handle. */
2787 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2788 return NT_STATUS_INVALID_HANDLE
;
2790 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2791 return NT_STATUS_INVALID_HANDLE
;
2794 /* check if the user has enough rights */
2796 if (!(handle
->access
& LSA_POLICY_CREATE_ACCOUNT
)) {
2797 return NT_STATUS_ACCESS_DENIED
;
2800 /* Work out max allowed. */
2801 map_max_allowed_access(p
->session_info
->security_token
,
2802 p
->session_info
->unix_token
,
2803 &r
->in
.access_mask
);
2805 /* map the generic bits to the lsa policy ones */
2806 se_map_generic(&r
->in
.access_mask
, &lsa_account_mapping
);
2808 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
2809 &lsa_account_mapping
,
2810 r
->in
.sid
, owner_access
);
2811 if (!NT_STATUS_IS_OK(status
)) {
2815 status
= access_check_object(psd
, p
->session_info
->security_token
,
2816 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0, r
->in
.access_mask
,
2817 &acc_granted
, "_lsa_CreateAccount");
2818 if (!NT_STATUS_IS_OK(status
)) {
2822 if ( is_privileged_sid( r
->in
.sid
) )
2823 return NT_STATUS_OBJECT_NAME_COLLISION
;
2825 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
2826 LSA_HANDLE_ACCOUNT_TYPE
,
2831 r
->out
.acct_handle
);
2832 if (!NT_STATUS_IS_OK(status
)) {
2833 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2836 return privilege_create_account(r
->in
.sid
);
2839 /***************************************************************************
2841 ***************************************************************************/
2843 NTSTATUS
_lsa_OpenAccount(struct pipes_struct
*p
,
2844 struct lsa_OpenAccount
*r
)
2846 struct lsa_info
*handle
;
2847 struct security_descriptor
*psd
= NULL
;
2849 uint32_t des_access
= r
->in
.access_mask
;
2850 uint32_t acc_granted
;
2851 uint32_t owner_access
= (LSA_ACCOUNT_ALL_ACCESS
&
2852 ~(LSA_ACCOUNT_ADJUST_PRIVILEGES
|
2853 LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS
|
2857 /* find the connection policy handle. */
2858 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2859 return NT_STATUS_INVALID_HANDLE
;
2861 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2862 return NT_STATUS_INVALID_HANDLE
;
2865 /* des_access is for the account here, not the policy
2866 * handle - so don't check against policy handle. */
2868 /* Work out max allowed. */
2869 map_max_allowed_access(p
->session_info
->security_token
,
2870 p
->session_info
->unix_token
,
2873 /* map the generic bits to the lsa account ones */
2874 se_map_generic(&des_access
, &lsa_account_mapping
);
2876 /* get the generic lsa account SD until we store it */
2877 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
2878 &lsa_account_mapping
,
2879 r
->in
.sid
, owner_access
);
2880 if (!NT_STATUS_IS_OK(status
)) {
2884 status
= access_check_object(psd
, p
->session_info
->security_token
,
2885 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0, des_access
,
2886 &acc_granted
, "_lsa_OpenAccount" );
2887 if (!NT_STATUS_IS_OK(status
)) {
2891 /* TODO: Fis the parsing routine before reenabling this check! */
2893 if (!lookup_sid(&handle
->sid
, dom_name
, name
, &type
))
2894 return NT_STATUS_ACCESS_DENIED
;
2897 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
2898 LSA_HANDLE_ACCOUNT_TYPE
,
2903 r
->out
.acct_handle
);
2904 if (!NT_STATUS_IS_OK(status
)) {
2905 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2908 return NT_STATUS_OK
;
2911 /***************************************************************************
2912 _lsa_EnumPrivsAccount
2913 For a given SID, enumerate all the privilege this account has.
2914 ***************************************************************************/
2916 NTSTATUS
_lsa_EnumPrivsAccount(struct pipes_struct
*p
,
2917 struct lsa_EnumPrivsAccount
*r
)
2919 NTSTATUS status
= NT_STATUS_OK
;
2920 struct lsa_info
*info
=NULL
;
2921 PRIVILEGE_SET
*privileges
;
2922 struct lsa_PrivilegeSet
*priv_set
= NULL
;
2924 /* find the connection policy handle. */
2925 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
2926 return NT_STATUS_INVALID_HANDLE
;
2928 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
2929 return NT_STATUS_INVALID_HANDLE
;
2932 if (!(info
->access
& LSA_ACCOUNT_VIEW
))
2933 return NT_STATUS_ACCESS_DENIED
;
2935 status
= get_privileges_for_sid_as_set(p
->mem_ctx
, &privileges
, &info
->sid
);
2936 if (!NT_STATUS_IS_OK(status
)) {
2940 *r
->out
.privs
= priv_set
= talloc_zero(p
->mem_ctx
, struct lsa_PrivilegeSet
);
2942 return NT_STATUS_NO_MEMORY
;
2945 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2946 sid_string_dbg(&info
->sid
),
2947 privileges
->count
));
2949 priv_set
->count
= privileges
->count
;
2950 priv_set
->unknown
= 0;
2951 priv_set
->set
= talloc_move(priv_set
, &privileges
->set
);
2956 /***************************************************************************
2957 _lsa_GetSystemAccessAccount
2958 ***************************************************************************/
2960 NTSTATUS
_lsa_GetSystemAccessAccount(struct pipes_struct
*p
,
2961 struct lsa_GetSystemAccessAccount
*r
)
2964 struct lsa_info
*info
= NULL
;
2965 struct lsa_EnumPrivsAccount e
;
2966 struct lsa_PrivilegeSet
*privset
;
2968 /* find the connection policy handle. */
2970 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
2971 return NT_STATUS_INVALID_HANDLE
;
2973 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
2974 return NT_STATUS_INVALID_HANDLE
;
2977 if (!(info
->access
& LSA_ACCOUNT_VIEW
))
2978 return NT_STATUS_ACCESS_DENIED
;
2980 privset
= talloc_zero(p
->mem_ctx
, struct lsa_PrivilegeSet
);
2982 return NT_STATUS_NO_MEMORY
;
2985 e
.in
.handle
= r
->in
.handle
;
2986 e
.out
.privs
= &privset
;
2988 status
= _lsa_EnumPrivsAccount(p
, &e
);
2989 if (!NT_STATUS_IS_OK(status
)) {
2990 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2991 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2992 nt_errstr(status
)));
2996 /* Samba4 would iterate over the privset to merge the policy mode bits,
2997 * not sure samba3 can do the same here, so just return what we did in
3001 0x01 -> Log on locally
3002 0x02 -> Access this computer from network
3003 0x04 -> Log on as a batch job
3004 0x10 -> Log on as a service
3006 they can be ORed together
3009 *r
->out
.access_mask
= LSA_POLICY_MODE_INTERACTIVE
|
3010 LSA_POLICY_MODE_NETWORK
;
3012 return NT_STATUS_OK
;
3015 /***************************************************************************
3016 update the systemaccount information
3017 ***************************************************************************/
3019 NTSTATUS
_lsa_SetSystemAccessAccount(struct pipes_struct
*p
,
3020 struct lsa_SetSystemAccessAccount
*r
)
3022 struct lsa_info
*info
=NULL
;
3026 /* find the connection policy handle. */
3027 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3028 return NT_STATUS_INVALID_HANDLE
;
3030 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
3031 return NT_STATUS_INVALID_HANDLE
;
3034 if (!(info
->access
& LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS
)) {
3035 return NT_STATUS_ACCESS_DENIED
;
3038 map
= talloc_zero(p
->mem_ctx
, GROUP_MAP
);
3040 return NT_STATUS_NO_MEMORY
;
3043 if (!pdb_getgrsid(map
, info
->sid
)) {
3045 return NT_STATUS_NO_SUCH_GROUP
;
3048 status
= pdb_update_group_mapping_entry(map
);
3053 /***************************************************************************
3054 _lsa_AddPrivilegesToAccount
3055 For a given SID, add some privileges.
3056 ***************************************************************************/
3058 NTSTATUS
_lsa_AddPrivilegesToAccount(struct pipes_struct
*p
,
3059 struct lsa_AddPrivilegesToAccount
*r
)
3061 struct lsa_info
*info
= NULL
;
3062 struct lsa_PrivilegeSet
*set
= NULL
;
3064 /* find the connection policy handle. */
3065 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3066 return NT_STATUS_INVALID_HANDLE
;
3068 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
3069 return NT_STATUS_INVALID_HANDLE
;
3072 if (!(info
->access
& LSA_ACCOUNT_ADJUST_PRIVILEGES
)) {
3073 return NT_STATUS_ACCESS_DENIED
;
3078 if ( !grant_privilege_set( &info
->sid
, set
) ) {
3079 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
3080 sid_string_dbg(&info
->sid
) ));
3081 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3084 return NT_STATUS_OK
;
3087 /***************************************************************************
3088 _lsa_RemovePrivilegesFromAccount
3089 For a given SID, remove some privileges.
3090 ***************************************************************************/
3092 NTSTATUS
_lsa_RemovePrivilegesFromAccount(struct pipes_struct
*p
,
3093 struct lsa_RemovePrivilegesFromAccount
*r
)
3095 struct lsa_info
*info
= NULL
;
3096 struct lsa_PrivilegeSet
*set
= NULL
;
3098 /* find the connection policy handle. */
3099 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3100 return NT_STATUS_INVALID_HANDLE
;
3102 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
3103 return NT_STATUS_INVALID_HANDLE
;
3106 if (!(info
->access
& LSA_ACCOUNT_ADJUST_PRIVILEGES
)) {
3107 return NT_STATUS_ACCESS_DENIED
;
3112 if ( !revoke_privilege_set( &info
->sid
, set
) ) {
3113 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
3114 sid_string_dbg(&info
->sid
) ));
3115 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3118 return NT_STATUS_OK
;
3121 /***************************************************************************
3123 ***************************************************************************/
3125 NTSTATUS
_lsa_LookupPrivName(struct pipes_struct
*p
,
3126 struct lsa_LookupPrivName
*r
)
3128 struct lsa_info
*info
= NULL
;
3130 struct lsa_StringLarge
*lsa_name
;
3132 /* find the connection policy handle. */
3133 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
)) {
3134 return NT_STATUS_INVALID_HANDLE
;
3137 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3138 return NT_STATUS_INVALID_HANDLE
;
3141 if (!(info
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
)) {
3142 return NT_STATUS_ACCESS_DENIED
;
3145 if (r
->in
.luid
->high
!= 0) {
3146 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3149 name
= sec_privilege_name(r
->in
.luid
->low
);
3151 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3154 lsa_name
= talloc_zero(p
->mem_ctx
, struct lsa_StringLarge
);
3156 return NT_STATUS_NO_MEMORY
;
3159 lsa_name
->string
= talloc_strdup(lsa_name
, name
);
3160 if (!lsa_name
->string
) {
3161 TALLOC_FREE(lsa_name
);
3162 return NT_STATUS_NO_MEMORY
;
3165 *r
->out
.name
= lsa_name
;
3167 return NT_STATUS_OK
;
3170 /***************************************************************************
3172 ***************************************************************************/
3174 NTSTATUS
_lsa_QuerySecurity(struct pipes_struct
*p
,
3175 struct lsa_QuerySecurity
*r
)
3177 struct lsa_info
*handle
=NULL
;
3178 struct security_descriptor
*psd
= NULL
;
3182 /* find the connection policy handle. */
3183 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
3184 return NT_STATUS_INVALID_HANDLE
;
3186 switch (handle
->type
) {
3187 case LSA_HANDLE_POLICY_TYPE
:
3188 case LSA_HANDLE_ACCOUNT_TYPE
:
3189 case LSA_HANDLE_TRUST_TYPE
:
3190 case LSA_HANDLE_SECRET_TYPE
:
3192 sd_size
= ndr_size_security_descriptor(psd
, 0);
3193 status
= NT_STATUS_OK
;
3196 status
= NT_STATUS_INVALID_HANDLE
;
3200 if (!NT_STATUS_IS_OK(status
)) {
3204 *r
->out
.sdbuf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
);
3205 if (!*r
->out
.sdbuf
) {
3206 return NT_STATUS_NO_MEMORY
;
3212 /***************************************************************************
3213 _lsa_AddAccountRights
3214 ***************************************************************************/
3216 NTSTATUS
_lsa_AddAccountRights(struct pipes_struct
*p
,
3217 struct lsa_AddAccountRights
*r
)
3219 struct lsa_info
*info
= NULL
;
3221 uint32_t acc_granted
= 0;
3222 struct security_descriptor
*psd
= NULL
;
3227 /* find the connection policy handle. */
3228 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3229 return NT_STATUS_INVALID_HANDLE
;
3231 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3232 return NT_STATUS_INVALID_HANDLE
;
3235 /* get the generic lsa account SD for this SID until we store it */
3236 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
3237 &lsa_account_mapping
,
3239 if (!NT_STATUS_IS_OK(status
)) {
3244 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3245 * on the policy handle. If it does, ask for
3246 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3247 * on the account sid. We don't check here so just use the latter. JRA.
3250 status
= access_check_object(psd
, p
->session_info
->security_token
,
3251 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
3252 LSA_ACCOUNT_ADJUST_PRIVILEGES
|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS
|LSA_ACCOUNT_VIEW
,
3253 &acc_granted
, "_lsa_AddAccountRights" );
3254 if (!NT_STATUS_IS_OK(status
)) {
3258 /* according to an NT4 PDC, you can add privileges to SIDs even without
3259 call_lsa_create_account() first. And you can use any arbitrary SID. */
3261 sid_copy( &sid
, r
->in
.sid
);
3263 for ( i
=0; i
< r
->in
.rights
->count
; i
++ ) {
3265 const char *privname
= r
->in
.rights
->names
[i
].string
;
3267 /* only try to add non-null strings */
3272 if ( !grant_privilege_by_name( &sid
, privname
) ) {
3273 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3275 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3279 return NT_STATUS_OK
;
3282 /***************************************************************************
3283 _lsa_RemoveAccountRights
3284 ***************************************************************************/
3286 NTSTATUS
_lsa_RemoveAccountRights(struct pipes_struct
*p
,
3287 struct lsa_RemoveAccountRights
*r
)
3289 struct lsa_info
*info
= NULL
;
3291 struct security_descriptor
*psd
= NULL
;
3294 const char *privname
= NULL
;
3295 uint32_t acc_granted
= 0;
3298 /* find the connection policy handle. */
3299 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3300 return NT_STATUS_INVALID_HANDLE
;
3302 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3303 return NT_STATUS_INVALID_HANDLE
;
3306 /* get the generic lsa account SD for this SID until we store it */
3307 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
3308 &lsa_account_mapping
,
3310 if (!NT_STATUS_IS_OK(status
)) {
3315 * From the MS DOCs. We need
3316 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3317 * and DELETE on the account sid.
3320 status
= access_check_object(psd
, p
->session_info
->security_token
,
3321 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
3322 LSA_ACCOUNT_ADJUST_PRIVILEGES
|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS
|
3323 LSA_ACCOUNT_VIEW
|SEC_STD_DELETE
,
3324 &acc_granted
, "_lsa_RemoveAccountRights");
3325 if (!NT_STATUS_IS_OK(status
)) {
3329 sid_copy( &sid
, r
->in
.sid
);
3331 if ( r
->in
.remove_all
) {
3332 if ( !revoke_all_privileges( &sid
) )
3333 return NT_STATUS_ACCESS_DENIED
;
3335 return NT_STATUS_OK
;
3338 for ( i
=0; i
< r
->in
.rights
->count
; i
++ ) {
3340 privname
= r
->in
.rights
->names
[i
].string
;
3342 /* only try to add non-null strings */
3347 if ( !revoke_privilege_by_name( &sid
, privname
) ) {
3348 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3350 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3354 return NT_STATUS_OK
;
3357 /*******************************************************************
3358 ********************************************************************/
3360 static NTSTATUS
init_lsa_right_set(TALLOC_CTX
*mem_ctx
,
3361 struct lsa_RightSet
*r
,
3362 PRIVILEGE_SET
*privileges
)
3365 const char *privname
;
3366 const char **privname_array
= NULL
;
3369 for (i
=0; i
<privileges
->count
; i
++) {
3370 if (privileges
->set
[i
].luid
.high
) {
3373 privname
= sec_privilege_name(privileges
->set
[i
].luid
.low
);
3375 if (!add_string_to_array(mem_ctx
, privname
,
3376 &privname_array
, &num_priv
)) {
3377 return NT_STATUS_NO_MEMORY
;
3384 r
->names
= talloc_zero_array(mem_ctx
, struct lsa_StringLarge
,
3387 return NT_STATUS_NO_MEMORY
;
3390 for (i
=0; i
<num_priv
; i
++) {
3391 init_lsa_StringLarge(&r
->names
[i
], privname_array
[i
]);
3394 r
->count
= num_priv
;
3397 return NT_STATUS_OK
;
3400 /***************************************************************************
3401 _lsa_EnumAccountRights
3402 ***************************************************************************/
3404 NTSTATUS
_lsa_EnumAccountRights(struct pipes_struct
*p
,
3405 struct lsa_EnumAccountRights
*r
)
3408 struct lsa_info
*info
= NULL
;
3409 PRIVILEGE_SET
*privileges
;
3411 /* find the connection policy handle. */
3413 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3414 return NT_STATUS_INVALID_HANDLE
;
3416 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3417 return NT_STATUS_INVALID_HANDLE
;
3420 if (!(info
->access
& LSA_ACCOUNT_VIEW
)) {
3421 return NT_STATUS_ACCESS_DENIED
;
3424 /* according to an NT4 PDC, you can add privileges to SIDs even without
3425 call_lsa_create_account() first. And you can use any arbitrary SID. */
3427 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3428 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3429 * the lsa database */
3431 status
= get_privileges_for_sid_as_set(p
->mem_ctx
, &privileges
, r
->in
.sid
);
3432 if (!NT_STATUS_IS_OK(status
)) {
3436 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3437 sid_string_dbg(r
->in
.sid
), privileges
->count
));
3439 status
= init_lsa_right_set(p
->mem_ctx
, r
->out
.rights
, privileges
);
3444 /***************************************************************************
3445 _lsa_LookupPrivValue
3446 ***************************************************************************/
3448 NTSTATUS
_lsa_LookupPrivValue(struct pipes_struct
*p
,
3449 struct lsa_LookupPrivValue
*r
)
3451 struct lsa_info
*info
= NULL
;
3452 const char *name
= NULL
;
3454 /* find the connection policy handle. */
3456 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3457 return NT_STATUS_INVALID_HANDLE
;
3459 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3460 return NT_STATUS_INVALID_HANDLE
;
3463 if (!(info
->access
& LSA_POLICY_LOOKUP_NAMES
))
3464 return NT_STATUS_ACCESS_DENIED
;
3466 name
= r
->in
.name
->string
;
3468 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name
));
3470 r
->out
.luid
->low
= sec_privilege_id(name
);
3471 r
->out
.luid
->high
= 0;
3472 if (r
->out
.luid
->low
== SEC_PRIV_INVALID
) {
3473 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3475 return NT_STATUS_OK
;
3478 /***************************************************************************
3479 _lsa_EnumAccountsWithUserRight
3480 ***************************************************************************/
3482 NTSTATUS
_lsa_EnumAccountsWithUserRight(struct pipes_struct
*p
,
3483 struct lsa_EnumAccountsWithUserRight
*r
)
3486 struct lsa_info
*info
= NULL
;
3487 struct dom_sid
*sids
= NULL
;
3490 enum sec_privilege privilege
;
3492 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
)) {
3493 return NT_STATUS_INVALID_HANDLE
;
3496 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3497 return NT_STATUS_INVALID_HANDLE
;
3500 if (!(info
->access
& LSA_POLICY_LOOKUP_NAMES
)) {
3501 return NT_STATUS_ACCESS_DENIED
;
3504 if (!r
->in
.name
|| !r
->in
.name
->string
) {
3505 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3508 privilege
= sec_privilege_id(r
->in
.name
->string
);
3509 if (privilege
== SEC_PRIV_INVALID
) {
3510 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3513 status
= privilege_enum_sids(privilege
, p
->mem_ctx
,
3515 if (!NT_STATUS_IS_OK(status
)) {
3519 r
->out
.sids
->num_sids
= num_sids
;
3520 r
->out
.sids
->sids
= talloc_array(p
->mem_ctx
, struct lsa_SidPtr
,
3521 r
->out
.sids
->num_sids
);
3523 for (i
=0; i
< r
->out
.sids
->num_sids
; i
++) {
3524 r
->out
.sids
->sids
[i
].sid
= dom_sid_dup(r
->out
.sids
->sids
,
3526 if (!r
->out
.sids
->sids
[i
].sid
) {
3527 TALLOC_FREE(r
->out
.sids
->sids
);
3528 r
->out
.sids
->num_sids
= 0;
3529 return NT_STATUS_NO_MEMORY
;
3533 return NT_STATUS_OK
;
3536 /***************************************************************************
3538 ***************************************************************************/
3540 NTSTATUS
_lsa_Delete(struct pipes_struct
*p
,
3541 struct lsa_Delete
*r
)
3543 return NT_STATUS_NOT_SUPPORTED
;
3546 static NTSTATUS
info_ex_2_pdb_trusted_domain(
3547 struct lsa_TrustDomainInfoInfoEx
*info_ex
,
3548 struct pdb_trusted_domain
*td
)
3550 if (info_ex
->domain_name
.string
== NULL
||
3551 info_ex
->netbios_name
.string
== NULL
||
3552 info_ex
->sid
== NULL
) {
3553 return NT_STATUS_INVALID_PARAMETER
;
3556 td
->domain_name
= talloc_strdup(td
, info_ex
->domain_name
.string
);
3557 td
->netbios_name
= talloc_strdup(td
, info_ex
->netbios_name
.string
);
3558 sid_copy(&td
->security_identifier
, info_ex
->sid
);
3559 if (td
->domain_name
== NULL
||
3560 td
->netbios_name
== NULL
||
3561 is_null_sid(&td
->security_identifier
)) {
3562 return NT_STATUS_NO_MEMORY
;
3564 td
->trust_direction
= info_ex
->trust_direction
;
3565 td
->trust_type
= info_ex
->trust_type
;
3566 td
->trust_attributes
= info_ex
->trust_attributes
;
3568 return NT_STATUS_OK
;
3571 static NTSTATUS
setInfoTrustedDomain_base(struct pipes_struct
*p
,
3572 TALLOC_CTX
*mem_ctx
,
3573 struct lsa_info
*policy
,
3574 enum lsa_TrustDomInfoEnum level
,
3575 union lsa_TrustedDomainInfo
*info
)
3577 struct lsa_TrustDomainInfoAuthInfoInternal
*auth_info_int
= NULL
;
3578 DATA_BLOB auth_blob
;
3579 struct trustDomainPasswords auth_struct
;
3582 struct pdb_trusted_domain
*td
;
3583 struct pdb_trusted_domain
*orig_td
;
3585 td
= talloc_zero(mem_ctx
, struct pdb_trusted_domain
);
3587 return NT_STATUS_NO_MEMORY
;
3591 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET
:
3592 if (!(policy
->access
& LSA_TRUSTED_SET_POSIX
)) {
3593 return NT_STATUS_ACCESS_DENIED
;
3595 td
->trust_posix_offset
= &info
->posix_offset
.posix_offset
;
3597 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX
:
3598 if (!(policy
->access
& LSA_TRUSTED_SET_POSIX
)) {
3599 return NT_STATUS_ACCESS_DENIED
;
3601 nt_status
= info_ex_2_pdb_trusted_domain(&info
->info_ex
, td
);
3602 if (!NT_STATUS_IS_OK(nt_status
)) {
3606 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO
:
3607 if (!(policy
->access
& LSA_TRUSTED_SET_AUTH
)) {
3608 return NT_STATUS_ACCESS_DENIED
;
3610 nt_status
= auth_info_2_auth_blob(td
, &info
->auth_info
,
3611 &td
->trust_auth_incoming
,
3612 &td
->trust_auth_outgoing
);
3613 if (!NT_STATUS_IS_OK(nt_status
)) {
3617 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
:
3618 if (!(policy
->access
& (LSA_TRUSTED_SET_AUTH
| LSA_TRUSTED_SET_POSIX
))) {
3619 return NT_STATUS_ACCESS_DENIED
;
3621 td
->trust_posix_offset
= &info
->full_info
.posix_offset
.posix_offset
;
3622 nt_status
= info_ex_2_pdb_trusted_domain(&info
->full_info
.info_ex
,
3624 if (!NT_STATUS_IS_OK(nt_status
)) {
3627 nt_status
= auth_info_2_auth_blob(td
,
3628 &info
->full_info
.auth_info
,
3629 &td
->trust_auth_incoming
,
3630 &td
->trust_auth_outgoing
);
3631 if (!NT_STATUS_IS_OK(nt_status
)) {
3635 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL
:
3636 if (!(policy
->access
& LSA_TRUSTED_SET_AUTH
)) {
3637 return NT_STATUS_ACCESS_DENIED
;
3639 auth_info_int
= &info
->auth_info_internal
;
3641 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL
:
3642 if (!(policy
->access
& (LSA_TRUSTED_SET_AUTH
| LSA_TRUSTED_SET_POSIX
))) {
3643 return NT_STATUS_ACCESS_DENIED
;
3645 td
->trust_posix_offset
= &info
->full_info_internal
.posix_offset
.posix_offset
;
3646 nt_status
= info_ex_2_pdb_trusted_domain(&info
->full_info_internal
.info_ex
,
3648 if (!NT_STATUS_IS_OK(nt_status
)) {
3651 auth_info_int
= &info
->full_info_internal
.auth_info
;
3653 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES
:
3654 if (!(policy
->access
& LSA_TRUSTED_SET_POSIX
)) {
3655 return NT_STATUS_ACCESS_DENIED
;
3657 td
->supported_enc_type
= &info
->enc_types
.enc_types
;
3660 return NT_STATUS_INVALID_PARAMETER
;
3663 /* decode auth_info_int if set */
3664 if (auth_info_int
) {
3666 /* now decrypt blob */
3667 auth_blob
= data_blob_const(auth_info_int
->auth_blob
.data
,
3668 auth_info_int
->auth_blob
.size
);
3670 nt_status
= get_trustdom_auth_blob(p
, mem_ctx
,
3671 &auth_blob
, &auth_struct
);
3672 if (!NT_STATUS_IS_OK(nt_status
)) {
3676 memset(&auth_struct
, 0, sizeof(auth_struct
));
3679 /* TODO: verify only one object matches the dns/netbios/sid triplet and that
3680 * this is the one we already have */
3682 /* TODO: check if the trust direction is changed and we need to add or remove
3685 /* TODO: check if trust type shall be changed and return an error in this case
3687 nt_status
= pdb_get_trusted_domain_by_sid(p
->mem_ctx
, &policy
->sid
,
3689 if (!NT_STATUS_IS_OK(nt_status
)) {
3694 /* TODO: should we fetch previous values from the existing entry
3695 * and append them ? */
3696 if (auth_struct
.incoming
.count
) {
3697 nt_status
= get_trustauth_inout_blob(mem_ctx
,
3698 &auth_struct
.incoming
,
3699 &td
->trust_auth_incoming
);
3700 if (!NT_STATUS_IS_OK(nt_status
)) {
3704 ZERO_STRUCT(td
->trust_auth_incoming
);
3707 if (auth_struct
.outgoing
.count
) {
3708 nt_status
= get_trustauth_inout_blob(mem_ctx
,
3709 &auth_struct
.outgoing
,
3710 &td
->trust_auth_outgoing
);
3711 if (!NT_STATUS_IS_OK(nt_status
)) {
3715 ZERO_STRUCT(td
->trust_auth_outgoing
);
3718 nt_status
= pdb_set_trusted_domain(orig_td
->domain_name
, td
);
3719 if (!NT_STATUS_IS_OK(nt_status
)) {
3723 return NT_STATUS_OK
;
3726 NTSTATUS
_lsa_SetTrustedDomainInfo(struct pipes_struct
*p
,
3727 struct lsa_SetTrustedDomainInfo
*r
)
3730 struct policy_handle trustdom_handle
;
3731 struct lsa_OpenTrustedDomain o
;
3732 struct lsa_SetInformationTrustedDomain s
;
3735 o
.in
.handle
= r
->in
.handle
;
3736 o
.in
.sid
= r
->in
.dom_sid
;
3737 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3738 o
.out
.trustdom_handle
= &trustdom_handle
;
3740 status
= _lsa_OpenTrustedDomain(p
, &o
);
3741 if (!NT_STATUS_IS_OK(status
)) {
3745 s
.in
.trustdom_handle
= &trustdom_handle
;
3746 s
.in
.level
= r
->in
.level
;
3747 s
.in
.info
= r
->in
.info
;
3749 status
= _lsa_SetInformationTrustedDomain(p
, &s
);
3750 if (!NT_STATUS_IS_OK(status
)) {
3754 c
.in
.handle
= &trustdom_handle
;
3755 c
.out
.handle
= &trustdom_handle
;
3757 return _lsa_Close(p
, &c
);
3760 NTSTATUS
_lsa_SetTrustedDomainInfoByName(struct pipes_struct
*p
,
3761 struct lsa_SetTrustedDomainInfoByName
*r
)
3764 struct policy_handle trustdom_handle
;
3765 struct lsa_OpenTrustedDomainByName o
;
3766 struct lsa_SetInformationTrustedDomain s
;
3769 o
.in
.handle
= r
->in
.handle
;
3770 o
.in
.name
.string
= r
->in
.trusted_domain
->string
;
3771 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3772 o
.out
.trustdom_handle
= &trustdom_handle
;
3774 status
= _lsa_OpenTrustedDomainByName(p
, &o
);
3775 if (!NT_STATUS_IS_OK(status
)) {
3776 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_DOMAIN
)) {
3777 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3782 s
.in
.trustdom_handle
= &trustdom_handle
;
3783 s
.in
.level
= r
->in
.level
;
3784 s
.in
.info
= r
->in
.info
;
3786 status
= _lsa_SetInformationTrustedDomain(p
, &s
);
3787 if (!NT_STATUS_IS_OK(status
)) {
3791 c
.in
.handle
= &trustdom_handle
;
3792 c
.out
.handle
= &trustdom_handle
;
3794 return _lsa_Close(p
, &c
);
3797 NTSTATUS
_lsa_SetInformationTrustedDomain(struct pipes_struct
*p
,
3798 struct lsa_SetInformationTrustedDomain
*r
)
3800 struct lsa_info
*policy
;
3802 if (!find_policy_by_hnd(p
, r
->in
.trustdom_handle
, (void **)(void *)&policy
)) {
3803 return NT_STATUS_INVALID_HANDLE
;
3806 if (policy
->type
!= LSA_HANDLE_TRUST_TYPE
) {
3807 return NT_STATUS_INVALID_HANDLE
;
3810 return setInfoTrustedDomain_base(p
, p
->mem_ctx
, policy
,
3811 r
->in
.level
, r
->in
.info
);
3816 * From here on the server routines are just dummy ones to make smbd link with
3817 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3818 * pulling the server stubs across one by one.
3821 NTSTATUS
_lsa_SetSecObj(struct pipes_struct
*p
, struct lsa_SetSecObj
*r
)
3823 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3824 return NT_STATUS_NOT_IMPLEMENTED
;
3827 NTSTATUS
_lsa_ChangePassword(struct pipes_struct
*p
,
3828 struct lsa_ChangePassword
*r
)
3830 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3831 return NT_STATUS_NOT_IMPLEMENTED
;
3834 NTSTATUS
_lsa_SetInfoPolicy(struct pipes_struct
*p
, struct lsa_SetInfoPolicy
*r
)
3836 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3837 return NT_STATUS_NOT_IMPLEMENTED
;
3840 NTSTATUS
_lsa_ClearAuditLog(struct pipes_struct
*p
, struct lsa_ClearAuditLog
*r
)
3842 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3843 return NT_STATUS_NOT_IMPLEMENTED
;
3846 NTSTATUS
_lsa_GetQuotasForAccount(struct pipes_struct
*p
,
3847 struct lsa_GetQuotasForAccount
*r
)
3849 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3850 return NT_STATUS_NOT_IMPLEMENTED
;
3853 NTSTATUS
_lsa_SetQuotasForAccount(struct pipes_struct
*p
,
3854 struct lsa_SetQuotasForAccount
*r
)
3856 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3857 return NT_STATUS_NOT_IMPLEMENTED
;
3860 NTSTATUS
_lsa_StorePrivateData(struct pipes_struct
*p
,
3861 struct lsa_StorePrivateData
*r
)
3863 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3864 return NT_STATUS_NOT_IMPLEMENTED
;
3867 NTSTATUS
_lsa_RetrievePrivateData(struct pipes_struct
*p
,
3868 struct lsa_RetrievePrivateData
*r
)
3870 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3871 return NT_STATUS_NOT_IMPLEMENTED
;
3874 NTSTATUS
_lsa_SetInfoPolicy2(struct pipes_struct
*p
,
3875 struct lsa_SetInfoPolicy2
*r
)
3877 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3878 return NT_STATUS_NOT_IMPLEMENTED
;
3881 NTSTATUS
_lsa_EnumTrustedDomainsEx(struct pipes_struct
*p
,
3882 struct lsa_EnumTrustedDomainsEx
*r
)
3884 struct lsa_info
*info
;
3886 struct pdb_trusted_domain
**domains
;
3887 struct lsa_TrustDomainInfoInfoEx
*entries
;
3891 /* bail out early if pdb backend is not capable of ex trusted domains,
3892 * if we dont do that, the client might not call
3893 * _lsa_EnumTrustedDomains() afterwards - gd */
3895 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX
)) {
3896 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3897 return NT_STATUS_NOT_IMPLEMENTED
;
3900 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3901 return NT_STATUS_INVALID_HANDLE
;
3903 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3904 return NT_STATUS_INVALID_HANDLE
;
3907 /* check if the user has enough rights */
3908 if (!(info
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
3909 return NT_STATUS_ACCESS_DENIED
;
3912 nt_status
= pdb_enum_trusted_domains(p
->mem_ctx
, &count
, &domains
);
3915 if (!NT_STATUS_IS_OK(nt_status
)) {
3919 entries
= talloc_zero_array(p
->mem_ctx
, struct lsa_TrustDomainInfoInfoEx
,
3922 return NT_STATUS_NO_MEMORY
;
3925 for (i
=0; i
<count
; i
++) {
3926 init_lsa_StringLarge(&entries
[i
].netbios_name
,
3927 domains
[i
]->netbios_name
);
3928 entries
[i
].sid
= &domains
[i
]->security_identifier
;
3931 if (*r
->in
.resume_handle
>= count
) {
3932 *r
->out
.resume_handle
= -1;
3933 TALLOC_FREE(entries
);
3934 return NT_STATUS_NO_MORE_ENTRIES
;
3937 /* return the rest, limit by max_size. Note that we
3938 use the w2k3 element size value of 60 */
3939 r
->out
.domains
->count
= count
- *r
->in
.resume_handle
;
3940 r
->out
.domains
->count
= MIN(r
->out
.domains
->count
,
3941 (r
->in
.max_size
/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER
));
3943 r
->out
.domains
->domains
= entries
+ *r
->in
.resume_handle
;
3945 if (r
->out
.domains
->count
< count
- *r
->in
.resume_handle
) {
3946 *r
->out
.resume_handle
= *r
->in
.resume_handle
+ r
->out
.domains
->count
;
3947 return STATUS_MORE_ENTRIES
;
3950 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3951 * always be larger than the previous input resume handle, in
3952 * particular when hitting the last query it is vital to set the
3953 * resume handle correctly to avoid infinite client loops, as
3954 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3955 * status is NT_STATUS_OK - gd */
3957 *r
->out
.resume_handle
= (uint32_t)-1;
3959 return NT_STATUS_OK
;
3962 NTSTATUS
_lsa_QueryDomainInformationPolicy(struct pipes_struct
*p
,
3963 struct lsa_QueryDomainInformationPolicy
*r
)
3965 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3966 return NT_STATUS_NOT_IMPLEMENTED
;
3969 NTSTATUS
_lsa_SetDomainInformationPolicy(struct pipes_struct
*p
,
3970 struct lsa_SetDomainInformationPolicy
*r
)
3972 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3973 return NT_STATUS_NOT_IMPLEMENTED
;
3976 NTSTATUS
_lsa_TestCall(struct pipes_struct
*p
, struct lsa_TestCall
*r
)
3978 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3979 return NT_STATUS_NOT_IMPLEMENTED
;
3982 NTSTATUS
_lsa_CREDRWRITE(struct pipes_struct
*p
, struct lsa_CREDRWRITE
*r
)
3984 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3985 return NT_STATUS_NOT_IMPLEMENTED
;
3988 NTSTATUS
_lsa_CREDRREAD(struct pipes_struct
*p
, struct lsa_CREDRREAD
*r
)
3990 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3991 return NT_STATUS_NOT_IMPLEMENTED
;
3994 NTSTATUS
_lsa_CREDRENUMERATE(struct pipes_struct
*p
, struct lsa_CREDRENUMERATE
*r
)
3996 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3997 return NT_STATUS_NOT_IMPLEMENTED
;
4000 NTSTATUS
_lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct
*p
,
4001 struct lsa_CREDRWRITEDOMAINCREDENTIALS
*r
)
4003 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4004 return NT_STATUS_NOT_IMPLEMENTED
;
4007 NTSTATUS
_lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct
*p
,
4008 struct lsa_CREDRREADDOMAINCREDENTIALS
*r
)
4010 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4011 return NT_STATUS_NOT_IMPLEMENTED
;
4014 NTSTATUS
_lsa_CREDRDELETE(struct pipes_struct
*p
, struct lsa_CREDRDELETE
*r
)
4016 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4017 return NT_STATUS_NOT_IMPLEMENTED
;
4020 NTSTATUS
_lsa_CREDRGETTARGETINFO(struct pipes_struct
*p
,
4021 struct lsa_CREDRGETTARGETINFO
*r
)
4023 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4024 return NT_STATUS_NOT_IMPLEMENTED
;
4027 NTSTATUS
_lsa_CREDRPROFILELOADED(struct pipes_struct
*p
,
4028 struct lsa_CREDRPROFILELOADED
*r
)
4030 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4031 return NT_STATUS_NOT_IMPLEMENTED
;
4034 NTSTATUS
_lsa_CREDRGETSESSIONTYPES(struct pipes_struct
*p
,
4035 struct lsa_CREDRGETSESSIONTYPES
*r
)
4037 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4038 return NT_STATUS_NOT_IMPLEMENTED
;
4041 NTSTATUS
_lsa_LSARREGISTERAUDITEVENT(struct pipes_struct
*p
,
4042 struct lsa_LSARREGISTERAUDITEVENT
*r
)
4044 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4045 return NT_STATUS_NOT_IMPLEMENTED
;
4048 NTSTATUS
_lsa_LSARGENAUDITEVENT(struct pipes_struct
*p
,
4049 struct lsa_LSARGENAUDITEVENT
*r
)
4051 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4052 return NT_STATUS_NOT_IMPLEMENTED
;
4055 NTSTATUS
_lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct
*p
,
4056 struct lsa_LSARUNREGISTERAUDITEVENT
*r
)
4058 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4059 return NT_STATUS_NOT_IMPLEMENTED
;
4062 NTSTATUS
_lsa_lsaRQueryForestTrustInformation(struct pipes_struct
*p
,
4063 struct lsa_lsaRQueryForestTrustInformation
*r
)
4065 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4066 return NT_STATUS_NOT_IMPLEMENTED
;
4069 #define DNS_CMP_MATCH 0
4070 #define DNS_CMP_FIRST_IS_CHILD 1
4071 #define DNS_CMP_SECOND_IS_CHILD 2
4072 #define DNS_CMP_NO_MATCH 3
4074 /* this function assumes names are well formed DNS names.
4075 * it doesn't validate them */
4076 static int dns_cmp(const char *s1
, size_t l1
,
4077 const char *s2
, size_t l2
)
4079 const char *p1
, *p2
;
4084 if (strcasecmp_m(s1
, s2
) == 0) {
4085 return DNS_CMP_MATCH
;
4087 return DNS_CMP_NO_MATCH
;
4095 cret
= DNS_CMP_FIRST_IS_CHILD
;
4101 cret
= DNS_CMP_SECOND_IS_CHILD
;
4104 if (p1
[t1
- t2
- 1] != '.') {
4105 return DNS_CMP_NO_MATCH
;
4108 if (strcasecmp_m(&p1
[t1
- t2
], p2
) == 0) {
4112 return DNS_CMP_NO_MATCH
;
4115 static NTSTATUS
make_ft_info(TALLOC_CTX
*mem_ctx
,
4116 struct lsa_ForestTrustInformation
*lfti
,
4117 struct ForestTrustInfo
*fti
)
4119 struct lsa_ForestTrustRecord
*lrec
;
4120 struct ForestTrustInfoRecord
*rec
;
4121 struct lsa_StringLarge
*tln
;
4122 struct lsa_ForestTrustDomainInfo
*info
;
4126 fti
->count
= lfti
->count
;
4127 fti
->records
= talloc_array(mem_ctx
,
4128 struct ForestTrustInfoRecordArmor
,
4130 if (!fti
->records
) {
4131 return NT_STATUS_NO_MEMORY
;
4133 for (i
= 0; i
< fti
->count
; i
++) {
4134 lrec
= lfti
->entries
[i
];
4135 rec
= &fti
->records
[i
].record
;
4137 rec
->flags
= lrec
->flags
;
4138 rec
->timestamp
= lrec
->time
;
4139 rec
->type
= lrec
->type
;
4141 switch (lrec
->type
) {
4142 case LSA_FOREST_TRUST_TOP_LEVEL_NAME
:
4143 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX
:
4144 tln
= &lrec
->forest_trust_data
.top_level_name
;
4145 rec
->data
.name
.string
=
4146 talloc_strdup(mem_ctx
, tln
->string
);
4147 if (!rec
->data
.name
.string
) {
4148 return NT_STATUS_NO_MEMORY
;
4150 rec
->data
.name
.size
= strlen(rec
->data
.name
.string
);
4152 case LSA_FOREST_TRUST_DOMAIN_INFO
:
4153 info
= &lrec
->forest_trust_data
.domain_info
;
4154 rec
->data
.info
.sid
= *info
->domain_sid
;
4155 rec
->data
.info
.dns_name
.string
=
4156 talloc_strdup(mem_ctx
,
4157 info
->dns_domain_name
.string
);
4158 if (!rec
->data
.info
.dns_name
.string
) {
4159 return NT_STATUS_NO_MEMORY
;
4161 rec
->data
.info
.dns_name
.size
=
4162 strlen(rec
->data
.info
.dns_name
.string
);
4163 rec
->data
.info
.netbios_name
.string
=
4164 talloc_strdup(mem_ctx
,
4165 info
->netbios_domain_name
.string
);
4166 if (!rec
->data
.info
.netbios_name
.string
) {
4167 return NT_STATUS_NO_MEMORY
;
4169 rec
->data
.info
.netbios_name
.size
=
4170 strlen(rec
->data
.info
.netbios_name
.string
);
4173 return NT_STATUS_INVALID_DOMAIN_STATE
;
4177 return NT_STATUS_OK
;
4180 static NTSTATUS
add_collision(struct lsa_ForestTrustCollisionInfo
*c_info
,
4181 uint32_t index
, uint32_t collision_type
,
4182 uint32_t conflict_type
, const char *tdo_name
);
4184 static NTSTATUS
check_ft_info(TALLOC_CTX
*mem_ctx
,
4185 const char *tdo_name
,
4186 struct ForestTrustInfo
*tdo_fti
,
4187 struct ForestTrustInfo
*new_fti
,
4188 struct lsa_ForestTrustCollisionInfo
*c_info
)
4190 struct ForestTrustInfoRecord
*nrec
;
4191 struct ForestTrustInfoRecord
*trec
;
4192 const char *dns_name
;
4193 const char *nb_name
= NULL
;
4194 struct dom_sid
*sid
= NULL
;
4195 const char *tname
= NULL
;
4198 uint32_t new_fti_idx
;
4200 /* use always TDO type, until we understand when Xref can be used */
4201 uint32_t collision_type
= LSA_FOREST_TRUST_COLLISION_TDO
;
4206 bool ex_rule
= false;
4209 for (new_fti_idx
= 0; new_fti_idx
< new_fti
->count
; new_fti_idx
++) {
4211 nrec
= &new_fti
->records
[new_fti_idx
].record
;
4213 tln_conflict
= false;
4214 sid_conflict
= false;
4215 nb_conflict
= false;
4218 switch (nrec
->type
) {
4219 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX
:
4220 /* exclusions do not conflict by definition */
4223 case FOREST_TRUST_TOP_LEVEL_NAME
:
4224 dns_name
= nrec
->data
.name
.string
;
4225 dns_len
= nrec
->data
.name
.size
;
4228 case LSA_FOREST_TRUST_DOMAIN_INFO
:
4229 dns_name
= nrec
->data
.info
.dns_name
.string
;
4230 dns_len
= nrec
->data
.info
.dns_name
.size
;
4231 nb_name
= nrec
->data
.info
.netbios_name
.string
;
4232 sid
= &nrec
->data
.info
.sid
;
4236 if (!dns_name
) continue;
4238 /* check if this is already taken and not excluded */
4239 for (i
= 0; i
< tdo_fti
->count
; i
++) {
4240 trec
= &tdo_fti
->records
[i
].record
;
4242 switch (trec
->type
) {
4243 case FOREST_TRUST_TOP_LEVEL_NAME
:
4245 tname
= trec
->data
.name
.string
;
4246 tlen
= trec
->data
.name
.size
;
4248 case FOREST_TRUST_TOP_LEVEL_NAME_EX
:
4250 tname
= trec
->data
.name
.string
;
4251 tlen
= trec
->data
.name
.size
;
4253 case FOREST_TRUST_DOMAIN_INFO
:
4255 tname
= trec
->data
.info
.dns_name
.string
;
4256 tlen
= trec
->data
.info
.dns_name
.size
;
4259 return NT_STATUS_INVALID_PARAMETER
;
4261 ret
= dns_cmp(dns_name
, dns_len
, tname
, tlen
);
4264 /* if it matches exclusion,
4265 * it doesn't conflict */
4271 case DNS_CMP_FIRST_IS_CHILD
:
4272 case DNS_CMP_SECOND_IS_CHILD
:
4273 tln_conflict
= true;
4279 /* explicit exclusion, no dns name conflict here */
4281 tln_conflict
= false;
4284 if (trec
->type
!= FOREST_TRUST_DOMAIN_INFO
) {
4288 /* also test for domain info */
4289 if (!(trec
->flags
& LSA_SID_DISABLED_ADMIN
) &&
4290 dom_sid_compare(&trec
->data
.info
.sid
, sid
) == 0) {
4291 sid_conflict
= true;
4293 if (!(trec
->flags
& LSA_NB_DISABLED_ADMIN
) &&
4294 strcasecmp_m(trec
->data
.info
.netbios_name
.string
,
4301 (void)add_collision(c_info
, new_fti_idx
,
4303 LSA_TLN_DISABLED_CONFLICT
,
4307 (void)add_collision(c_info
, new_fti_idx
,
4309 LSA_SID_DISABLED_CONFLICT
,
4313 (void)add_collision(c_info
, new_fti_idx
,
4315 LSA_NB_DISABLED_CONFLICT
,
4320 return NT_STATUS_OK
;
4323 static NTSTATUS
add_collision(struct lsa_ForestTrustCollisionInfo
*c_info
,
4324 uint32_t idx
, uint32_t collision_type
,
4325 uint32_t conflict_type
, const char *tdo_name
)
4327 struct lsa_ForestTrustCollisionRecord
**es
;
4328 uint32_t i
= c_info
->count
;
4330 es
= talloc_realloc(c_info
, c_info
->entries
,
4331 struct lsa_ForestTrustCollisionRecord
*, i
+ 1);
4333 return NT_STATUS_NO_MEMORY
;
4335 c_info
->entries
= es
;
4336 c_info
->count
= i
+ 1;
4338 es
[i
] = talloc(es
, struct lsa_ForestTrustCollisionRecord
);
4340 return NT_STATUS_NO_MEMORY
;
4344 es
[i
]->type
= collision_type
;
4345 es
[i
]->flags
.flags
= conflict_type
;
4346 es
[i
]->name
.string
= talloc_strdup(es
[i
], tdo_name
);
4347 if (!es
[i
]->name
.string
) {
4348 return NT_STATUS_NO_MEMORY
;
4350 es
[i
]->name
.size
= strlen(es
[i
]->name
.string
);
4352 return NT_STATUS_OK
;
4355 static NTSTATUS
get_ft_info(TALLOC_CTX
*mem_ctx
,
4356 struct pdb_trusted_domain
*td
,
4357 struct ForestTrustInfo
*info
)
4359 enum ndr_err_code ndr_err
;
4361 if (td
->trust_forest_trust_info
.length
== 0 ||
4362 td
->trust_forest_trust_info
.data
== NULL
) {
4363 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4365 ndr_err
= ndr_pull_struct_blob_all(&td
->trust_forest_trust_info
, mem_ctx
,
4367 (ndr_pull_flags_fn_t
)ndr_pull_ForestTrustInfo
);
4368 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
4369 return NT_STATUS_INVALID_DOMAIN_STATE
;
4372 return NT_STATUS_OK
;
4375 static NTSTATUS
own_ft_info(struct pdb_domain_info
*dom_info
,
4376 struct ForestTrustInfo
*fti
)
4378 struct ForestTrustDataDomainInfo
*info
;
4379 struct ForestTrustInfoRecord
*rec
;
4383 fti
->records
= talloc_array(fti
,
4384 struct ForestTrustInfoRecordArmor
, 2);
4385 if (!fti
->records
) {
4386 return NT_STATUS_NO_MEMORY
;
4390 rec
= &fti
->records
[0].record
;
4394 rec
->type
= LSA_FOREST_TRUST_TOP_LEVEL_NAME
;
4396 rec
->data
.name
.string
= talloc_strdup(fti
, dom_info
->dns_forest
);
4397 if (!rec
->data
.name
.string
) {
4398 return NT_STATUS_NO_MEMORY
;
4400 rec
->data
.name
.size
= strlen(rec
->data
.name
.string
);
4403 rec
= &fti
->records
[1].record
;
4407 rec
->type
= LSA_FOREST_TRUST_DOMAIN_INFO
;
4409 info
= &rec
->data
.info
;
4411 info
->sid
= dom_info
->sid
;
4412 info
->dns_name
.string
= talloc_strdup(fti
, dom_info
->dns_domain
);
4413 if (!info
->dns_name
.string
) {
4414 return NT_STATUS_NO_MEMORY
;
4416 info
->dns_name
.size
= strlen(info
->dns_name
.string
);
4417 info
->netbios_name
.string
= talloc_strdup(fti
, dom_info
->name
);
4418 if (!info
->netbios_name
.string
) {
4419 return NT_STATUS_NO_MEMORY
;
4421 info
->netbios_name
.size
= strlen(info
->netbios_name
.string
);
4423 return NT_STATUS_OK
;
4426 NTSTATUS
_lsa_lsaRSetForestTrustInformation(struct pipes_struct
*p
,
4427 struct lsa_lsaRSetForestTrustInformation
*r
)
4432 struct lsa_info
*handle
;
4433 uint32_t num_domains
;
4434 struct pdb_trusted_domain
**domains
;
4435 struct ForestTrustInfo
*nfti
;
4436 struct ForestTrustInfo
*fti
;
4437 struct lsa_ForestTrustCollisionInfo
*c_info
;
4438 struct pdb_domain_info
*dom_info
;
4439 enum ndr_err_code ndr_err
;
4442 return NT_STATUS_NOT_SUPPORTED
;
4445 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
4446 return NT_STATUS_INVALID_HANDLE
;
4449 if (handle
->type
!= LSA_HANDLE_TRUST_TYPE
) {
4450 return NT_STATUS_INVALID_HANDLE
;
4453 if (!(handle
->access
& LSA_TRUSTED_SET_AUTH
)) {
4454 return NT_STATUS_ACCESS_DENIED
;
4457 status
= pdb_enum_trusted_domains(p
->mem_ctx
, &num_domains
, &domains
);
4458 if (!NT_STATUS_IS_OK(status
)) {
4461 if (num_domains
== 0) {
4462 return NT_STATUS_NO_SUCH_DOMAIN
;
4465 for (i
= 0; i
< num_domains
; i
++) {
4466 if (domains
[i
]->domain_name
== NULL
) {
4467 return NT_STATUS_INVALID_DOMAIN_STATE
;
4469 if (strcasecmp_m(domains
[i
]->domain_name
,
4470 r
->in
.trusted_domain_name
->string
) == 0) {
4474 if (i
>= num_domains
) {
4475 return NT_STATUS_NO_SUCH_DOMAIN
;
4478 if (!(domains
[i
]->trust_attributes
&
4479 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE
)) {
4480 return NT_STATUS_INVALID_PARAMETER
;
4483 if (r
->in
.highest_record_type
>= LSA_FOREST_TRUST_RECORD_TYPE_LAST
) {
4484 return NT_STATUS_INVALID_PARAMETER
;
4487 /* The following section until COPY_END is a copy from
4488 * source4/rpmc_server/lsa/scesrc_lsa.c */
4489 nfti
= talloc(p
->mem_ctx
, struct ForestTrustInfo
);
4491 return NT_STATUS_NO_MEMORY
;
4494 status
= make_ft_info(nfti
, r
->in
.forest_trust_info
, nfti
);
4495 if (!NT_STATUS_IS_OK(status
)) {
4499 c_info
= talloc_zero(r
->out
.collision_info
,
4500 struct lsa_ForestTrustCollisionInfo
);
4502 return NT_STATUS_NO_MEMORY
;
4505 /* first check own info, then other domains */
4506 fti
= talloc(p
->mem_ctx
, struct ForestTrustInfo
);
4508 return NT_STATUS_NO_MEMORY
;
4511 dom_info
= pdb_get_domain_info(p
->mem_ctx
);
4513 status
= own_ft_info(dom_info
, fti
);
4514 if (!NT_STATUS_IS_OK(status
)) {
4518 status
= check_ft_info(c_info
, dom_info
->dns_domain
, fti
, nfti
, c_info
);
4519 if (!NT_STATUS_IS_OK(status
)) {
4523 for (j
= 0; j
< num_domains
; j
++) {
4524 fti
= talloc(p
->mem_ctx
, struct ForestTrustInfo
);
4526 return NT_STATUS_NO_MEMORY
;
4529 status
= get_ft_info(p
->mem_ctx
, domains
[j
], fti
);
4530 if (!NT_STATUS_IS_OK(status
)) {
4531 if (NT_STATUS_EQUAL(status
,
4532 NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4538 if (domains
[j
]->domain_name
== NULL
) {
4539 return NT_STATUS_INVALID_DOMAIN_STATE
;
4542 status
= check_ft_info(c_info
, domains
[j
]->domain_name
,
4544 if (!NT_STATUS_IS_OK(status
)) {
4549 *r
->out
.collision_info
= c_info
;
4551 if (r
->in
.check_only
!= 0) {
4552 return NT_STATUS_OK
;
4557 ndr_err
= ndr_push_struct_blob(&domains
[i
]->trust_forest_trust_info
,
4559 (ndr_push_flags_fn_t
)ndr_push_ForestTrustInfo
);
4560 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
4561 return NT_STATUS_INVALID_PARAMETER
;
4564 status
= pdb_set_trusted_domain(domains
[i
]->domain_name
, domains
[i
]);
4565 if (!NT_STATUS_IS_OK(status
)) {
4569 return NT_STATUS_OK
;
4572 NTSTATUS
_lsa_CREDRRENAME(struct pipes_struct
*p
,
4573 struct lsa_CREDRRENAME
*r
)
4575 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4576 return NT_STATUS_NOT_IMPLEMENTED
;
4579 NTSTATUS
_lsa_LSAROPENPOLICYSCE(struct pipes_struct
*p
,
4580 struct lsa_LSAROPENPOLICYSCE
*r
)
4582 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4583 return NT_STATUS_NOT_IMPLEMENTED
;
4586 NTSTATUS
_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct
*p
,
4587 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE
*r
)
4589 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4590 return NT_STATUS_NOT_IMPLEMENTED
;
4593 NTSTATUS
_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct
*p
,
4594 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
*r
)
4596 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4597 return NT_STATUS_NOT_IMPLEMENTED
;
4600 NTSTATUS
_lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct
*p
,
4601 struct lsa_LSARADTREPORTSECURITYEVENT
*r
)
4603 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4604 return NT_STATUS_NOT_IMPLEMENTED
;