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"
55 #define DBGC_CLASS DBGC_RPC_SRV
57 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
59 enum lsa_handle_type
{
60 LSA_HANDLE_POLICY_TYPE
= 1,
61 LSA_HANDLE_ACCOUNT_TYPE
= 2,
62 LSA_HANDLE_TRUST_TYPE
= 3,
63 LSA_HANDLE_SECRET_TYPE
= 4};
69 enum lsa_handle_type type
;
70 struct security_descriptor
*sd
;
73 const struct generic_mapping lsa_account_mapping
= {
77 LSA_ACCOUNT_ALL_ACCESS
80 const struct generic_mapping lsa_policy_mapping
= {
87 const struct generic_mapping lsa_secret_mapping
= {
94 const struct generic_mapping lsa_trusted_domain_mapping
= {
95 LSA_TRUSTED_DOMAIN_READ
,
96 LSA_TRUSTED_DOMAIN_WRITE
,
97 LSA_TRUSTED_DOMAIN_EXECUTE
,
98 LSA_TRUSTED_DOMAIN_ALL_ACCESS
101 /***************************************************************************
102 initialize a lsa_DomainInfo structure.
103 ***************************************************************************/
105 static void init_dom_query_3(struct lsa_DomainInfo
*r
,
109 init_lsa_StringLarge(&r
->name
, name
);
113 /***************************************************************************
114 initialize a lsa_DomainInfo structure.
115 ***************************************************************************/
117 static void init_dom_query_5(struct lsa_DomainInfo
*r
,
121 init_lsa_StringLarge(&r
->name
, name
);
125 /***************************************************************************
126 lookup_lsa_rids. Must be called as root for lookup_name to work.
127 ***************************************************************************/
129 static NTSTATUS
lookup_lsa_rids(TALLOC_CTX
*mem_ctx
,
130 struct lsa_RefDomainList
*ref
,
131 struct lsa_TranslatedSid
*prid
,
132 uint32_t num_entries
,
133 struct lsa_String
*name
,
135 uint32_t *pmapped_count
)
137 uint32 mapped_count
, i
;
139 SMB_ASSERT(num_entries
<= MAX_LOOKUP_SIDS
);
144 for (i
= 0; i
< num_entries
; i
++) {
148 const char *full_name
;
150 enum lsa_SidType type
;
152 /* Split name into domain and user component */
154 /* follow w2k8 behavior and return the builtin domain when no
155 * input has been passed in */
157 if (name
[i
].string
) {
158 full_name
= name
[i
].string
;
160 full_name
= "BUILTIN";
163 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name
));
165 if (!lookup_name(mem_ctx
, full_name
, flags
, &domain
, NULL
,
167 type
= SID_NAME_UNKNOWN
;
172 case SID_NAME_DOM_GRP
:
173 case SID_NAME_DOMAIN
:
175 case SID_NAME_WKN_GRP
:
176 DEBUG(5, ("init_lsa_rids: %s found\n", full_name
));
177 /* Leave these unchanged */
180 /* Don't hand out anything but the list above */
181 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name
));
182 type
= SID_NAME_UNKNOWN
;
189 if (type
!= SID_NAME_UNKNOWN
) {
190 if (type
== SID_NAME_DOMAIN
) {
193 sid_split_rid(&sid
, &rid
);
195 dom_idx
= init_lsa_ref_domain_list(mem_ctx
, ref
, domain
, &sid
);
199 prid
[i
].sid_type
= type
;
201 prid
[i
].sid_index
= dom_idx
;
204 *pmapped_count
= mapped_count
;
208 /***************************************************************************
209 lookup_lsa_sids. Must be called as root for lookup_name to work.
210 ***************************************************************************/
212 static NTSTATUS
lookup_lsa_sids(TALLOC_CTX
*mem_ctx
,
213 struct lsa_RefDomainList
*ref
,
214 struct lsa_TranslatedSid3
*trans_sids
,
215 uint32_t num_entries
,
216 struct lsa_String
*name
,
218 uint32
*pmapped_count
)
220 uint32 mapped_count
, i
;
222 SMB_ASSERT(num_entries
<= MAX_LOOKUP_SIDS
);
227 for (i
= 0; i
< num_entries
; i
++) {
231 const char *full_name
;
233 enum lsa_SidType type
;
237 /* Split name into domain and user component */
239 full_name
= name
[i
].string
;
240 if (full_name
== NULL
) {
241 return NT_STATUS_NO_MEMORY
;
244 DEBUG(5, ("lookup_lsa_sids: looking up name %s\n", full_name
));
246 if (!lookup_name(mem_ctx
, full_name
, flags
, &domain
, NULL
,
248 type
= SID_NAME_UNKNOWN
;
253 case SID_NAME_DOM_GRP
:
254 case SID_NAME_DOMAIN
:
256 case SID_NAME_WKN_GRP
:
257 DEBUG(5, ("lookup_lsa_sids: %s found\n", full_name
));
258 /* Leave these unchanged */
261 /* Don't hand out anything but the list above */
262 DEBUG(5, ("lookup_lsa_sids: %s not found\n", full_name
));
263 type
= SID_NAME_UNKNOWN
;
270 if (type
!= SID_NAME_UNKNOWN
) {
271 struct dom_sid domain_sid
;
272 sid_copy(&domain_sid
, &sid
);
273 sid_split_rid(&domain_sid
, &rid
);
274 dom_idx
= init_lsa_ref_domain_list(mem_ctx
, ref
, domain
, &domain_sid
);
278 /* Initialize the lsa_TranslatedSid3 return. */
279 trans_sids
[i
].sid_type
= type
;
280 trans_sids
[i
].sid
= dom_sid_dup(mem_ctx
, &sid
);
281 trans_sids
[i
].sid_index
= dom_idx
;
284 *pmapped_count
= mapped_count
;
288 static NTSTATUS
make_lsa_object_sd(TALLOC_CTX
*mem_ctx
, struct security_descriptor
**sd
, size_t *sd_size
,
289 const struct generic_mapping
*map
,
290 struct dom_sid
*sid
, uint32_t sid_access
)
292 struct dom_sid adm_sid
;
293 struct security_ace ace
[5];
296 struct security_acl
*psa
= NULL
;
298 /* READ|EXECUTE access for Everyone */
300 init_sec_ace(&ace
[i
++], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
301 map
->generic_execute
| map
->generic_read
, 0);
303 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
305 init_sec_ace(&ace
[i
++], &global_sid_Builtin_Administrators
,
306 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
307 init_sec_ace(&ace
[i
++], &global_sid_Builtin_Account_Operators
,
308 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
310 /* Add Full Access for Domain Admins */
311 sid_compose(&adm_sid
, get_global_sam_sid(), DOMAIN_RID_ADMINS
);
312 init_sec_ace(&ace
[i
++], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
313 map
->generic_all
, 0);
315 /* If we have a sid, give it some special access */
318 init_sec_ace(&ace
[i
++], sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
322 if((psa
= make_sec_acl(mem_ctx
, NT4_ACL_REVISION
, i
, ace
)) == NULL
)
323 return NT_STATUS_NO_MEMORY
;
325 if((*sd
= make_sec_desc(mem_ctx
, SECURITY_DESCRIPTOR_REVISION_1
,
326 SEC_DESC_SELF_RELATIVE
, &adm_sid
, NULL
, NULL
,
327 psa
, sd_size
)) == NULL
)
328 return NT_STATUS_NO_MEMORY
;
333 /***************************************************************************
334 ***************************************************************************/
336 static NTSTATUS
create_lsa_policy_handle(TALLOC_CTX
*mem_ctx
,
337 struct pipes_struct
*p
,
338 enum lsa_handle_type type
,
339 uint32_t acc_granted
,
342 const struct security_descriptor
*sd
,
343 struct policy_handle
*handle
)
345 struct lsa_info
*info
;
347 ZERO_STRUCTP(handle
);
349 info
= talloc_zero(mem_ctx
, struct lsa_info
);
351 return NT_STATUS_NO_MEMORY
;
355 info
->access
= acc_granted
;
358 sid_copy(&info
->sid
, sid
);
361 info
->name
= talloc_strdup(info
, name
);
364 info
->sd
= dup_sec_desc(info
, sd
);
367 return NT_STATUS_NO_MEMORY
;
371 if (!create_policy_hnd(p
, handle
, info
)) {
373 ZERO_STRUCTP(handle
);
374 return NT_STATUS_NO_MEMORY
;
380 /***************************************************************************
382 ***************************************************************************/
384 NTSTATUS
_lsa_OpenPolicy2(struct pipes_struct
*p
,
385 struct lsa_OpenPolicy2
*r
)
387 struct security_descriptor
*psd
= NULL
;
389 uint32 des_access
= r
->in
.access_mask
;
393 if (p
->transport
!= NCACN_NP
&& p
->transport
!= NCALRPC
) {
394 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
395 return NT_STATUS_ACCESS_DENIED
;
398 /* Work out max allowed. */
399 map_max_allowed_access(p
->session_info
->security_token
,
400 p
->session_info
->unix_token
,
403 /* map the generic bits to the lsa policy ones */
404 se_map_generic(&des_access
, &lsa_policy_mapping
);
406 /* get the generic lsa policy SD until we store it */
407 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &lsa_policy_mapping
,
409 if (!NT_STATUS_IS_OK(status
)) {
413 status
= access_check_object(psd
, p
->session_info
->security_token
,
414 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0, des_access
,
415 &acc_granted
, "_lsa_OpenPolicy2" );
416 if (!NT_STATUS_IS_OK(status
)) {
420 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
421 LSA_HANDLE_POLICY_TYPE
,
423 get_global_sam_sid(),
427 if (!NT_STATUS_IS_OK(status
)) {
428 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
434 /***************************************************************************
436 ***************************************************************************/
438 NTSTATUS
_lsa_OpenPolicy(struct pipes_struct
*p
,
439 struct lsa_OpenPolicy
*r
)
441 struct lsa_OpenPolicy2 o
;
443 /* _lsa_OpenPolicy2 will check if this is a NCACN_NP connection */
445 o
.in
.system_name
= NULL
; /* should be ignored */
446 o
.in
.attr
= r
->in
.attr
;
447 o
.in
.access_mask
= r
->in
.access_mask
;
449 o
.out
.handle
= r
->out
.handle
;
451 return _lsa_OpenPolicy2(p
, &o
);
454 /***************************************************************************
455 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
457 ***************************************************************************/
459 NTSTATUS
_lsa_EnumTrustDom(struct pipes_struct
*p
,
460 struct lsa_EnumTrustDom
*r
)
462 struct lsa_info
*info
;
464 struct trustdom_info
**domains
;
465 struct lsa_DomainInfo
*entries
;
469 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
470 return NT_STATUS_INVALID_HANDLE
;
472 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
473 return NT_STATUS_INVALID_HANDLE
;
476 /* check if the user has enough rights */
477 if (!(info
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
478 return NT_STATUS_ACCESS_DENIED
;
481 nt_status
= pdb_enum_trusteddoms(p
->mem_ctx
, &count
, &domains
);
484 if (!NT_STATUS_IS_OK(nt_status
)) {
488 entries
= talloc_zero_array(p
->mem_ctx
, struct lsa_DomainInfo
, count
);
490 return NT_STATUS_NO_MEMORY
;
493 for (i
=0; i
<count
; i
++) {
494 init_lsa_StringLarge(&entries
[i
].name
, domains
[i
]->name
);
495 entries
[i
].sid
= &domains
[i
]->sid
;
498 if (*r
->in
.resume_handle
>= count
) {
499 *r
->out
.resume_handle
= -1;
500 TALLOC_FREE(entries
);
501 return NT_STATUS_NO_MORE_ENTRIES
;
504 /* return the rest, limit by max_size. Note that we
505 use the w2k3 element size value of 60 */
506 r
->out
.domains
->count
= count
- *r
->in
.resume_handle
;
507 r
->out
.domains
->count
= MIN(r
->out
.domains
->count
,
508 1+(r
->in
.max_size
/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER
));
510 r
->out
.domains
->domains
= entries
+ *r
->in
.resume_handle
;
512 if (r
->out
.domains
->count
< count
- *r
->in
.resume_handle
) {
513 *r
->out
.resume_handle
= *r
->in
.resume_handle
+ r
->out
.domains
->count
;
514 return STATUS_MORE_ENTRIES
;
517 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
518 * always be larger than the previous input resume handle, in
519 * particular when hitting the last query it is vital to set the
520 * resume handle correctly to avoid infinite client loops, as
521 * seen e.g. with Windows XP SP3 when resume handle is 0 and
522 * status is NT_STATUS_OK - gd */
524 *r
->out
.resume_handle
= (uint32_t)-1;
529 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
530 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
531 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
533 /***************************************************************************
535 ***************************************************************************/
537 NTSTATUS
_lsa_QueryInfoPolicy(struct pipes_struct
*p
,
538 struct lsa_QueryInfoPolicy
*r
)
540 NTSTATUS status
= NT_STATUS_OK
;
541 struct lsa_info
*handle
;
542 struct dom_sid domain_sid
;
544 struct dom_sid
*sid
= NULL
;
545 union lsa_PolicyInformation
*info
= NULL
;
546 uint32_t acc_required
= 0;
548 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
549 return NT_STATUS_INVALID_HANDLE
;
551 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
552 return NT_STATUS_INVALID_HANDLE
;
555 switch (r
->in
.level
) {
556 case LSA_POLICY_INFO_AUDIT_LOG
:
557 case LSA_POLICY_INFO_AUDIT_EVENTS
:
558 acc_required
= LSA_POLICY_VIEW_AUDIT_INFORMATION
;
560 case LSA_POLICY_INFO_DOMAIN
:
561 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
563 case LSA_POLICY_INFO_PD
:
564 acc_required
= LSA_POLICY_GET_PRIVATE_INFORMATION
;
566 case LSA_POLICY_INFO_ACCOUNT_DOMAIN
:
567 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
569 case LSA_POLICY_INFO_ROLE
:
570 case LSA_POLICY_INFO_REPLICA
:
571 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
573 case LSA_POLICY_INFO_QUOTA
:
574 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
576 case LSA_POLICY_INFO_MOD
:
577 case LSA_POLICY_INFO_AUDIT_FULL_SET
:
578 /* according to MS-LSAD 3.1.4.4.3 */
579 return NT_STATUS_INVALID_PARAMETER
;
580 case LSA_POLICY_INFO_AUDIT_FULL_QUERY
:
581 acc_required
= LSA_POLICY_VIEW_AUDIT_INFORMATION
;
583 case LSA_POLICY_INFO_DNS
:
584 case LSA_POLICY_INFO_DNS_INT
:
585 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN
:
586 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
592 if (!(handle
->access
& acc_required
)) {
593 /* return NT_STATUS_ACCESS_DENIED; */
596 info
= talloc_zero(p
->mem_ctx
, union lsa_PolicyInformation
);
598 return NT_STATUS_NO_MEMORY
;
601 switch (r
->in
.level
) {
602 /* according to MS-LSAD 3.1.4.4.3 */
603 case LSA_POLICY_INFO_MOD
:
604 case LSA_POLICY_INFO_AUDIT_FULL_SET
:
605 case LSA_POLICY_INFO_AUDIT_FULL_QUERY
:
606 return NT_STATUS_INVALID_PARAMETER
;
607 case LSA_POLICY_INFO_AUDIT_LOG
:
608 info
->audit_log
.percent_full
= 0;
609 info
->audit_log
.maximum_log_size
= 0;
610 info
->audit_log
.retention_time
= 0;
611 info
->audit_log
.shutdown_in_progress
= 0;
612 info
->audit_log
.time_to_shutdown
= 0;
613 info
->audit_log
.next_audit_record
= 0;
614 status
= NT_STATUS_OK
;
616 case LSA_POLICY_INFO_PD
:
617 info
->pd
.name
.string
= NULL
;
618 status
= NT_STATUS_OK
;
620 case LSA_POLICY_INFO_REPLICA
:
621 info
->replica
.source
.string
= NULL
;
622 info
->replica
.account
.string
= NULL
;
623 status
= NT_STATUS_OK
;
625 case LSA_POLICY_INFO_QUOTA
:
626 info
->quota
.paged_pool
= 0;
627 info
->quota
.non_paged_pool
= 0;
628 info
->quota
.min_wss
= 0;
629 info
->quota
.max_wss
= 0;
630 info
->quota
.pagefile
= 0;
631 info
->quota
.unknown
= 0;
632 status
= NT_STATUS_OK
;
634 case LSA_POLICY_INFO_AUDIT_EVENTS
:
637 uint32 policy_def
= LSA_AUDIT_POLICY_ALL
;
639 /* check if the user has enough rights */
640 if (!(handle
->access
& LSA_POLICY_VIEW_AUDIT_INFORMATION
)) {
641 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
642 return NT_STATUS_ACCESS_DENIED
;
645 /* fake info: We audit everything. ;) */
647 info
->audit_events
.auditing_mode
= true;
648 info
->audit_events
.count
= LSA_AUDIT_NUM_CATEGORIES
;
649 info
->audit_events
.settings
= talloc_zero_array(p
->mem_ctx
,
650 enum lsa_PolicyAuditPolicy
,
651 info
->audit_events
.count
);
652 if (!info
->audit_events
.settings
) {
653 return NT_STATUS_NO_MEMORY
;
656 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT
] = policy_def
;
657 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS
] = policy_def
;
658 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_LOGON
] = policy_def
;
659 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING
] = policy_def
;
660 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES
] = policy_def
;
661 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_SYSTEM
] = policy_def
;
662 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS
] = policy_def
;
666 case LSA_POLICY_INFO_DOMAIN
:
667 /* check if the user has enough rights */
668 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
669 return NT_STATUS_ACCESS_DENIED
;
671 /* Request PolicyPrimaryDomainInformation. */
672 switch (lp_server_role()) {
673 case ROLE_DOMAIN_PDC
:
674 case ROLE_DOMAIN_BDC
:
675 name
= get_global_sam_name();
676 sid
= dom_sid_dup(p
->mem_ctx
, get_global_sam_sid());
678 return NT_STATUS_NO_MEMORY
;
681 case ROLE_DOMAIN_MEMBER
:
682 name
= lp_workgroup();
683 /* We need to return the Domain SID here. */
684 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid
)) {
685 sid
= dom_sid_dup(p
->mem_ctx
, &domain_sid
);
687 return NT_STATUS_NO_MEMORY
;
690 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
693 case ROLE_STANDALONE
:
694 name
= lp_workgroup();
698 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
700 init_dom_query_3(&info
->domain
, name
, sid
);
702 case LSA_POLICY_INFO_ACCOUNT_DOMAIN
:
703 /* check if the user has enough rights */
704 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
705 return NT_STATUS_ACCESS_DENIED
;
707 /* Request PolicyAccountDomainInformation. */
708 name
= get_global_sam_name();
709 sid
= get_global_sam_sid();
711 init_dom_query_5(&info
->account_domain
, name
, sid
);
713 case LSA_POLICY_INFO_ROLE
:
714 /* check if the user has enough rights */
715 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
716 return NT_STATUS_ACCESS_DENIED
;
718 switch (lp_server_role()) {
719 case ROLE_DOMAIN_BDC
:
721 * only a BDC is a backup controller
722 * of the domain, it controls.
724 info
->role
.role
= LSA_ROLE_BACKUP
;
728 * any other role is a primary
729 * of the domain, it controls.
731 info
->role
.role
= LSA_ROLE_PRIMARY
;
735 case LSA_POLICY_INFO_DNS
:
736 case LSA_POLICY_INFO_DNS_INT
: {
737 struct pdb_domain_info
*dominfo
;
739 if ((pdb_capabilities() & PDB_CAP_ADS
) == 0) {
740 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
741 "without ADS passdb backend\n"));
742 status
= NT_STATUS_INVALID_INFO_CLASS
;
746 dominfo
= pdb_get_domain_info(info
);
747 if (dominfo
== NULL
) {
748 status
= NT_STATUS_NO_MEMORY
;
752 init_lsa_StringLarge(&info
->dns
.name
,
754 init_lsa_StringLarge(&info
->dns
.dns_domain
,
755 dominfo
->dns_domain
);
756 init_lsa_StringLarge(&info
->dns
.dns_forest
,
757 dominfo
->dns_forest
);
758 info
->dns
.domain_guid
= dominfo
->guid
;
759 info
->dns
.sid
= &dominfo
->sid
;
763 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
765 status
= NT_STATUS_INVALID_INFO_CLASS
;
774 /***************************************************************************
775 _lsa_QueryInfoPolicy2
776 ***************************************************************************/
778 NTSTATUS
_lsa_QueryInfoPolicy2(struct pipes_struct
*p
,
779 struct lsa_QueryInfoPolicy2
*r2
)
781 struct lsa_QueryInfoPolicy r
;
783 if ((pdb_capabilities() & PDB_CAP_ADS
) == 0) {
784 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
785 return NT_STATUS_NOT_IMPLEMENTED
;
789 r
.in
.handle
= r2
->in
.handle
;
790 r
.in
.level
= r2
->in
.level
;
791 r
.out
.info
= r2
->out
.info
;
793 return _lsa_QueryInfoPolicy(p
, &r
);
796 /***************************************************************************
797 _lsa_lookup_sids_internal
798 ***************************************************************************/
800 static NTSTATUS
_lsa_lookup_sids_internal(struct pipes_struct
*p
,
802 uint16_t level
, /* input */
803 int num_sids
, /* input */
804 struct lsa_SidPtr
*sid
, /* input */
805 struct lsa_RefDomainList
**pp_ref
, /* input/output */
806 struct lsa_TranslatedName2
**pp_names
,/* input/output */
807 uint32_t *pp_mapped_count
) /* input/output */
811 const struct dom_sid
**sids
= NULL
;
812 struct lsa_RefDomainList
*ref
= NULL
;
813 uint32 mapped_count
= 0;
814 struct lsa_dom_info
*dom_infos
= NULL
;
815 struct lsa_name_info
*name_infos
= NULL
;
816 struct lsa_TranslatedName2
*names
= NULL
;
818 *pp_mapped_count
= 0;
826 sids
= talloc_array(p
->mem_ctx
, const struct dom_sid
*, num_sids
);
827 ref
= talloc_zero(p
->mem_ctx
, struct lsa_RefDomainList
);
829 if (sids
== NULL
|| ref
== NULL
) {
830 return NT_STATUS_NO_MEMORY
;
833 for (i
=0; i
<num_sids
; i
++) {
834 sids
[i
] = sid
[i
].sid
;
837 status
= lookup_sids(p
->mem_ctx
, num_sids
, sids
, level
,
838 &dom_infos
, &name_infos
);
840 if (!NT_STATUS_IS_OK(status
)) {
844 names
= talloc_array(p
->mem_ctx
, struct lsa_TranslatedName2
, num_sids
);
846 return NT_STATUS_NO_MEMORY
;
849 for (i
=0; i
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; i
++) {
851 if (!dom_infos
[i
].valid
) {
855 if (init_lsa_ref_domain_list(mem_ctx
, ref
,
857 &dom_infos
[i
].sid
) != i
) {
858 DEBUG(0, ("Domain %s mentioned twice??\n",
860 return NT_STATUS_INTERNAL_ERROR
;
864 for (i
=0; i
<num_sids
; i
++) {
865 struct lsa_name_info
*name
= &name_infos
[i
];
867 if (name
->type
== SID_NAME_UNKNOWN
) {
869 /* Unknown sids should return the string
870 * representation of the SID. Windows 2003 behaves
871 * rather erratic here, in many cases it returns the
872 * RID as 8 bytes hex, in others it returns the full
873 * SID. We (Jerry/VL) could not figure out which the
874 * hard cases are, so leave it with the SID. */
875 name
->name
= dom_sid_string(p
->mem_ctx
, sids
[i
]);
876 if (name
->name
== NULL
) {
877 return NT_STATUS_NO_MEMORY
;
883 names
[i
].sid_type
= name
->type
;
884 names
[i
].name
.string
= name
->name
;
885 names
[i
].sid_index
= name
->dom_idx
;
886 names
[i
].unknown
= 0;
889 status
= NT_STATUS_NONE_MAPPED
;
890 if (mapped_count
> 0) {
891 status
= (mapped_count
< num_sids
) ?
892 STATUS_SOME_UNMAPPED
: NT_STATUS_OK
;
895 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
896 num_sids
, mapped_count
, nt_errstr(status
)));
898 *pp_mapped_count
= mapped_count
;
905 /***************************************************************************
907 ***************************************************************************/
909 NTSTATUS
_lsa_LookupSids(struct pipes_struct
*p
,
910 struct lsa_LookupSids
*r
)
913 struct lsa_info
*handle
;
914 int num_sids
= r
->in
.sids
->num_sids
;
915 uint32 mapped_count
= 0;
916 struct lsa_RefDomainList
*domains
= NULL
;
917 struct lsa_TranslatedName
*names_out
= NULL
;
918 struct lsa_TranslatedName2
*names
= NULL
;
921 if (p
->transport
!= NCACN_NP
&& p
->transport
!= NCALRPC
) {
922 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
923 return NT_STATUS_ACCESS_DENIED
;
926 if ((r
->in
.level
< 1) || (r
->in
.level
> 6)) {
927 return NT_STATUS_INVALID_PARAMETER
;
930 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
931 return NT_STATUS_INVALID_HANDLE
;
934 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
935 return NT_STATUS_INVALID_HANDLE
;
938 /* check if the user has enough rights */
939 if (!(handle
->access
& LSA_POLICY_LOOKUP_NAMES
)) {
940 return NT_STATUS_ACCESS_DENIED
;
943 if (num_sids
> MAX_LOOKUP_SIDS
) {
944 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
945 MAX_LOOKUP_SIDS
, num_sids
));
946 return NT_STATUS_NONE_MAPPED
;
949 status
= _lsa_lookup_sids_internal(p
,
958 /* Only return here when there is a real error.
959 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
960 the requested sids could be resolved. Older versions of XP (pre SP3)
961 rely that we return with the string representations of those SIDs in
962 that case. If we don't, XP crashes - Guenther
965 if (NT_STATUS_IS_ERR(status
) &&
966 !NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
970 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
971 names_out
= talloc_array(p
->mem_ctx
, struct lsa_TranslatedName
,
974 return NT_STATUS_NO_MEMORY
;
977 for (i
=0; i
<num_sids
; i
++) {
978 names_out
[i
].sid_type
= names
[i
].sid_type
;
979 names_out
[i
].name
= names
[i
].name
;
980 names_out
[i
].sid_index
= names
[i
].sid_index
;
983 *r
->out
.domains
= domains
;
984 r
->out
.names
->count
= num_sids
;
985 r
->out
.names
->names
= names_out
;
986 *r
->out
.count
= mapped_count
;
991 static NTSTATUS
_lsa_LookupSids_common(struct pipes_struct
*p
,
992 struct lsa_LookupSids2
*r
)
995 struct lsa_info
*handle
;
996 int num_sids
= r
->in
.sids
->num_sids
;
997 uint32 mapped_count
= 0;
998 struct lsa_RefDomainList
*domains
= NULL
;
999 struct lsa_TranslatedName2
*names
= NULL
;
1000 bool check_policy
= true;
1003 case NDR_LSA_LOOKUPSIDS3
:
1004 check_policy
= false;
1006 case NDR_LSA_LOOKUPSIDS2
:
1008 check_policy
= true;
1011 if ((r
->in
.level
< 1) || (r
->in
.level
> 6)) {
1012 return NT_STATUS_INVALID_PARAMETER
;
1016 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1017 return NT_STATUS_INVALID_HANDLE
;
1020 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1021 return NT_STATUS_INVALID_HANDLE
;
1024 /* check if the user has enough rights */
1025 if (!(handle
->access
& LSA_POLICY_LOOKUP_NAMES
)) {
1026 return NT_STATUS_ACCESS_DENIED
;
1030 if (num_sids
> MAX_LOOKUP_SIDS
) {
1031 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1032 MAX_LOOKUP_SIDS
, num_sids
));
1033 return NT_STATUS_NONE_MAPPED
;
1036 status
= _lsa_lookup_sids_internal(p
,
1045 *r
->out
.domains
= domains
;
1046 r
->out
.names
->count
= num_sids
;
1047 r
->out
.names
->names
= names
;
1048 *r
->out
.count
= mapped_count
;
1053 /***************************************************************************
1055 ***************************************************************************/
1057 NTSTATUS
_lsa_LookupSids2(struct pipes_struct
*p
,
1058 struct lsa_LookupSids2
*r
)
1060 if (p
->transport
!= NCACN_NP
&& p
->transport
!= NCALRPC
) {
1061 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
1062 return NT_STATUS_ACCESS_DENIED
;
1065 return _lsa_LookupSids_common(p
, r
);
1068 /***************************************************************************
1070 ***************************************************************************/
1072 NTSTATUS
_lsa_LookupSids3(struct pipes_struct
*p
,
1073 struct lsa_LookupSids3
*r
)
1075 struct lsa_LookupSids2 q
;
1077 if (p
->transport
!= NCACN_IP_TCP
) {
1078 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
1079 return NT_STATUS_ACCESS_DENIED
;
1082 /* No policy handle on this call. Restrict to crypto connections. */
1083 if (p
->auth
.auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
||
1084 p
->auth
.auth_level
< DCERPC_AUTH_LEVEL_INTEGRITY
) {
1085 DEBUG(1, ("_lsa_LookupSids3: The client %s is not using "
1086 "a secure connection over netlogon\n",
1087 get_remote_machine_name() ));
1088 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
1089 return NT_STATUS_ACCESS_DENIED
;
1093 q
.in
.sids
= r
->in
.sids
;
1094 q
.in
.level
= r
->in
.level
;
1095 q
.in
.lookup_options
= r
->in
.lookup_options
;
1096 q
.in
.client_revision
= r
->in
.client_revision
;
1097 q
.in
.names
= r
->in
.names
;
1098 q
.in
.count
= r
->in
.count
;
1100 q
.out
.domains
= r
->out
.domains
;
1101 q
.out
.names
= r
->out
.names
;
1102 q
.out
.count
= r
->out
.count
;
1104 return _lsa_LookupSids_common(p
, &q
);
1107 /***************************************************************************
1108 ***************************************************************************/
1110 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level
)
1115 case LSA_LOOKUP_NAMES_ALL
: /* 1 */
1116 flags
= LOOKUP_NAME_ALL
;
1118 case LSA_LOOKUP_NAMES_DOMAINS_ONLY
: /* 2 */
1119 flags
= LOOKUP_NAME_DOMAIN
|LOOKUP_NAME_REMOTE
|LOOKUP_NAME_ISOLATED
;
1121 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY
: /* 3 */
1122 flags
= LOOKUP_NAME_DOMAIN
|LOOKUP_NAME_ISOLATED
;
1124 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY
: /* 4 */
1125 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY
: /* 5 */
1126 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2
: /* 6 */
1127 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC
: /* 7 */
1129 flags
= LOOKUP_NAME_NONE
;
1136 /***************************************************************************
1138 ***************************************************************************/
1140 NTSTATUS
_lsa_LookupNames(struct pipes_struct
*p
,
1141 struct lsa_LookupNames
*r
)
1143 NTSTATUS status
= NT_STATUS_NONE_MAPPED
;
1144 struct lsa_info
*handle
;
1145 struct lsa_String
*names
= r
->in
.names
;
1146 uint32 num_entries
= r
->in
.num_names
;
1147 struct lsa_RefDomainList
*domains
= NULL
;
1148 struct lsa_TranslatedSid
*rids
= NULL
;
1149 uint32 mapped_count
= 0;
1152 if (p
->transport
!= NCACN_NP
&& p
->transport
!= NCALRPC
) {
1153 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
1154 return NT_STATUS_ACCESS_DENIED
;
1157 if (num_entries
> MAX_LOOKUP_SIDS
) {
1158 num_entries
= MAX_LOOKUP_SIDS
;
1159 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1163 flags
= lsa_lookup_level_to_flags(r
->in
.level
);
1165 domains
= talloc_zero(p
->mem_ctx
, struct lsa_RefDomainList
);
1167 return NT_STATUS_NO_MEMORY
;
1171 rids
= talloc_zero_array(p
->mem_ctx
, struct lsa_TranslatedSid
,
1174 return NT_STATUS_NO_MEMORY
;
1180 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1181 status
= NT_STATUS_INVALID_HANDLE
;
1185 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1186 return NT_STATUS_INVALID_HANDLE
;
1189 /* check if the user has enough rights */
1190 if (!(handle
->access
& LSA_POLICY_LOOKUP_NAMES
)) {
1191 status
= NT_STATUS_ACCESS_DENIED
;
1195 /* set up the LSA Lookup RIDs response */
1196 become_root(); /* lookup_name can require root privs */
1197 status
= lookup_lsa_rids(p
->mem_ctx
, domains
, rids
, num_entries
,
1198 names
, flags
, &mapped_count
);
1203 if (NT_STATUS_IS_OK(status
) && (num_entries
!= 0) ) {
1204 if (mapped_count
== 0) {
1205 status
= NT_STATUS_NONE_MAPPED
;
1206 } else if (mapped_count
!= num_entries
) {
1207 status
= STATUS_SOME_UNMAPPED
;
1211 *r
->out
.count
= mapped_count
;
1212 *r
->out
.domains
= domains
;
1213 r
->out
.sids
->sids
= rids
;
1214 r
->out
.sids
->count
= num_entries
;
1219 /***************************************************************************
1221 ***************************************************************************/
1223 NTSTATUS
_lsa_LookupNames2(struct pipes_struct
*p
,
1224 struct lsa_LookupNames2
*r
)
1227 struct lsa_LookupNames q
;
1228 struct lsa_TransSidArray2
*sid_array2
= r
->in
.sids
;
1229 struct lsa_TransSidArray
*sid_array
= NULL
;
1232 if (p
->transport
!= NCACN_NP
&& p
->transport
!= NCALRPC
) {
1233 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
1234 return NT_STATUS_ACCESS_DENIED
;
1237 sid_array
= talloc_zero(p
->mem_ctx
, struct lsa_TransSidArray
);
1239 return NT_STATUS_NO_MEMORY
;
1242 q
.in
.handle
= r
->in
.handle
;
1243 q
.in
.num_names
= r
->in
.num_names
;
1244 q
.in
.names
= r
->in
.names
;
1245 q
.in
.level
= r
->in
.level
;
1246 q
.in
.sids
= sid_array
;
1247 q
.in
.count
= r
->in
.count
;
1248 /* we do not know what this is for */
1249 /* = r->in.unknown1; */
1250 /* = r->in.unknown2; */
1252 q
.out
.domains
= r
->out
.domains
;
1253 q
.out
.sids
= sid_array
;
1254 q
.out
.count
= r
->out
.count
;
1256 status
= _lsa_LookupNames(p
, &q
);
1258 sid_array2
->count
= sid_array
->count
;
1259 sid_array2
->sids
= talloc_array(p
->mem_ctx
, struct lsa_TranslatedSid2
, sid_array
->count
);
1260 if (!sid_array2
->sids
) {
1261 return NT_STATUS_NO_MEMORY
;
1264 for (i
=0; i
<sid_array
->count
; i
++) {
1265 sid_array2
->sids
[i
].sid_type
= sid_array
->sids
[i
].sid_type
;
1266 sid_array2
->sids
[i
].rid
= sid_array
->sids
[i
].rid
;
1267 sid_array2
->sids
[i
].sid_index
= sid_array
->sids
[i
].sid_index
;
1268 sid_array2
->sids
[i
].unknown
= 0;
1271 r
->out
.sids
= sid_array2
;
1276 static NTSTATUS
_lsa_LookupNames_common(struct pipes_struct
*p
,
1277 struct lsa_LookupNames3
*r
)
1280 struct lsa_info
*handle
;
1281 struct lsa_String
*names
= r
->in
.names
;
1282 uint32 num_entries
= r
->in
.num_names
;
1283 struct lsa_RefDomainList
*domains
= NULL
;
1284 struct lsa_TranslatedSid3
*trans_sids
= NULL
;
1285 uint32 mapped_count
= 0;
1287 bool check_policy
= true;
1290 case NDR_LSA_LOOKUPNAMES4
:
1291 check_policy
= false;
1293 case NDR_LSA_LOOKUPNAMES3
:
1295 check_policy
= true;
1298 if (num_entries
> MAX_LOOKUP_SIDS
) {
1299 num_entries
= MAX_LOOKUP_SIDS
;
1300 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries
));
1303 flags
= lsa_lookup_level_to_flags(r
->in
.level
);
1305 domains
= talloc_zero(p
->mem_ctx
, struct lsa_RefDomainList
);
1307 return NT_STATUS_NO_MEMORY
;
1311 trans_sids
= talloc_zero_array(p
->mem_ctx
, struct lsa_TranslatedSid3
,
1314 return NT_STATUS_NO_MEMORY
;
1322 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1323 status
= NT_STATUS_INVALID_HANDLE
;
1327 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1328 return NT_STATUS_INVALID_HANDLE
;
1331 /* check if the user has enough rights */
1332 if (!(handle
->access
& LSA_POLICY_LOOKUP_NAMES
)) {
1333 status
= NT_STATUS_ACCESS_DENIED
;
1338 /* set up the LSA Lookup SIDs response */
1339 become_root(); /* lookup_name can require root privs */
1340 status
= lookup_lsa_sids(p
->mem_ctx
, domains
, trans_sids
, num_entries
,
1341 names
, flags
, &mapped_count
);
1346 if (NT_STATUS_IS_OK(status
)) {
1347 if (mapped_count
== 0) {
1348 status
= NT_STATUS_NONE_MAPPED
;
1349 } else if (mapped_count
!= num_entries
) {
1350 status
= STATUS_SOME_UNMAPPED
;
1354 *r
->out
.count
= mapped_count
;
1355 *r
->out
.domains
= domains
;
1356 r
->out
.sids
->sids
= trans_sids
;
1357 r
->out
.sids
->count
= num_entries
;
1362 /***************************************************************************
1364 ***************************************************************************/
1366 NTSTATUS
_lsa_LookupNames3(struct pipes_struct
*p
,
1367 struct lsa_LookupNames3
*r
)
1369 if (p
->transport
!= NCACN_NP
&& p
->transport
!= NCALRPC
) {
1370 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
1371 return NT_STATUS_ACCESS_DENIED
;
1374 return _lsa_LookupNames_common(p
, r
);
1377 /***************************************************************************
1379 ***************************************************************************/
1381 NTSTATUS
_lsa_LookupNames4(struct pipes_struct
*p
,
1382 struct lsa_LookupNames4
*r
)
1384 struct lsa_LookupNames3 q
;
1386 if (p
->transport
!= NCACN_IP_TCP
) {
1387 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
1388 return NT_STATUS_ACCESS_DENIED
;
1391 /* No policy handle on this call. Restrict to crypto connections. */
1392 if (p
->auth
.auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
||
1393 p
->auth
.auth_level
< DCERPC_AUTH_LEVEL_INTEGRITY
) {
1394 DEBUG(1, ("_lsa_LookupNames4: The client %s is not using "
1395 "a secure connection over netlogon\n",
1396 get_remote_machine_name()));
1397 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
1398 return NT_STATUS_ACCESS_DENIED
;
1402 q
.in
.num_names
= r
->in
.num_names
;
1403 q
.in
.names
= r
->in
.names
;
1404 q
.in
.level
= r
->in
.level
;
1405 q
.in
.lookup_options
= r
->in
.lookup_options
;
1406 q
.in
.client_revision
= r
->in
.client_revision
;
1407 q
.in
.sids
= r
->in
.sids
;
1408 q
.in
.count
= r
->in
.count
;
1410 q
.out
.domains
= r
->out
.domains
;
1411 q
.out
.sids
= r
->out
.sids
;
1412 q
.out
.count
= r
->out
.count
;
1414 return _lsa_LookupNames_common(p
, &q
);
1417 /***************************************************************************
1418 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1419 ***************************************************************************/
1421 NTSTATUS
_lsa_Close(struct pipes_struct
*p
, struct lsa_Close
*r
)
1423 if (p
->transport
!= NCACN_NP
&& p
->transport
!= NCALRPC
) {
1424 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
1425 return NT_STATUS_ACCESS_DENIED
;
1428 if (!find_policy_by_hnd(p
, r
->in
.handle
, NULL
)) {
1429 return NT_STATUS_INVALID_HANDLE
;
1432 close_policy_hnd(p
, r
->in
.handle
);
1433 ZERO_STRUCTP(r
->out
.handle
);
1434 return NT_STATUS_OK
;
1437 /***************************************************************************
1438 ***************************************************************************/
1440 static NTSTATUS
lsa_lookup_trusted_domain_by_sid(TALLOC_CTX
*mem_ctx
,
1441 const struct dom_sid
*sid
,
1442 struct trustdom_info
**info
)
1445 uint32_t num_domains
= 0;
1446 struct trustdom_info
**domains
= NULL
;
1449 status
= pdb_enum_trusteddoms(mem_ctx
, &num_domains
, &domains
);
1450 if (!NT_STATUS_IS_OK(status
)) {
1454 for (i
=0; i
< num_domains
; i
++) {
1455 if (dom_sid_equal(&domains
[i
]->sid
, sid
)) {
1460 if (i
== num_domains
) {
1461 return NT_STATUS_INVALID_PARAMETER
;
1466 return NT_STATUS_OK
;
1469 /***************************************************************************
1470 ***************************************************************************/
1472 static NTSTATUS
lsa_lookup_trusted_domain_by_name(TALLOC_CTX
*mem_ctx
,
1473 const char *netbios_domain_name
,
1474 struct trustdom_info
**info_p
)
1477 struct trustdom_info
*info
;
1478 struct pdb_trusted_domain
*td
;
1480 status
= pdb_get_trusted_domain(mem_ctx
, netbios_domain_name
, &td
);
1481 if (!NT_STATUS_IS_OK(status
)) {
1485 info
= talloc(mem_ctx
, struct trustdom_info
);
1487 return NT_STATUS_NO_MEMORY
;
1490 info
->name
= talloc_strdup(info
, netbios_domain_name
);
1491 NT_STATUS_HAVE_NO_MEMORY(info
->name
);
1493 sid_copy(&info
->sid
, &td
->security_identifier
);
1497 return NT_STATUS_OK
;
1500 /***************************************************************************
1502 ***************************************************************************/
1504 NTSTATUS
_lsa_OpenSecret(struct pipes_struct
*p
,
1505 struct lsa_OpenSecret
*r
)
1507 struct lsa_info
*handle
;
1508 struct security_descriptor
*psd
;
1510 uint32_t acc_granted
;
1512 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1513 return NT_STATUS_INVALID_HANDLE
;
1516 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1517 return NT_STATUS_INVALID_HANDLE
;
1520 if (!r
->in
.name
.string
) {
1521 return NT_STATUS_INVALID_PARAMETER
;
1524 /* Work out max allowed. */
1525 map_max_allowed_access(p
->session_info
->security_token
,
1526 p
->session_info
->unix_token
,
1527 &r
->in
.access_mask
);
1529 /* map the generic bits to the lsa policy ones */
1530 se_map_generic(&r
->in
.access_mask
, &lsa_secret_mapping
);
1532 status
= pdb_get_secret(p
->mem_ctx
, r
->in
.name
.string
,
1538 if (!NT_STATUS_IS_OK(status
)) {
1542 status
= access_check_object(psd
, p
->session_info
->security_token
,
1543 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
1545 &acc_granted
, "_lsa_OpenSecret");
1546 if (!NT_STATUS_IS_OK(status
)) {
1550 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
1551 LSA_HANDLE_SECRET_TYPE
,
1557 if (!NT_STATUS_IS_OK(status
)) {
1558 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1561 return NT_STATUS_OK
;
1564 /***************************************************************************
1565 _lsa_OpenTrustedDomain_base
1566 ***************************************************************************/
1568 static NTSTATUS
_lsa_OpenTrustedDomain_base(struct pipes_struct
*p
,
1569 uint32_t access_mask
,
1570 struct trustdom_info
*info
,
1571 struct policy_handle
*handle
)
1573 struct security_descriptor
*psd
= NULL
;
1575 uint32_t acc_granted
;
1578 /* des_access is for the account here, not the policy
1579 * handle - so don't check against policy handle. */
1581 /* Work out max allowed. */
1582 map_max_allowed_access(p
->session_info
->security_token
,
1583 p
->session_info
->unix_token
,
1586 /* map the generic bits to the lsa account ones */
1587 se_map_generic(&access_mask
, &lsa_trusted_domain_mapping
);
1589 /* get the generic lsa account SD until we store it */
1590 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
1591 &lsa_trusted_domain_mapping
,
1593 if (!NT_STATUS_IS_OK(status
)) {
1597 status
= access_check_object(psd
, p
->session_info
->security_token
,
1598 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
1599 access_mask
, &acc_granted
,
1600 "_lsa_OpenTrustedDomain");
1601 if (!NT_STATUS_IS_OK(status
)) {
1605 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
1606 LSA_HANDLE_TRUST_TYPE
,
1612 if (!NT_STATUS_IS_OK(status
)) {
1613 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1616 return NT_STATUS_OK
;
1619 /***************************************************************************
1620 _lsa_OpenTrustedDomain
1621 ***************************************************************************/
1623 NTSTATUS
_lsa_OpenTrustedDomain(struct pipes_struct
*p
,
1624 struct lsa_OpenTrustedDomain
*r
)
1626 struct lsa_info
*handle
= NULL
;
1627 struct trustdom_info
*info
= NULL
;
1630 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1631 return NT_STATUS_INVALID_HANDLE
;
1634 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1635 return NT_STATUS_INVALID_HANDLE
;
1638 status
= lsa_lookup_trusted_domain_by_sid(p
->mem_ctx
,
1641 if (!NT_STATUS_IS_OK(status
)) {
1645 return _lsa_OpenTrustedDomain_base(p
, r
->in
.access_mask
, info
,
1646 r
->out
.trustdom_handle
);
1649 /***************************************************************************
1650 _lsa_OpenTrustedDomainByName
1651 ***************************************************************************/
1653 NTSTATUS
_lsa_OpenTrustedDomainByName(struct pipes_struct
*p
,
1654 struct lsa_OpenTrustedDomainByName
*r
)
1656 struct lsa_info
*handle
= NULL
;
1657 struct trustdom_info
*info
= NULL
;
1660 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1661 return NT_STATUS_INVALID_HANDLE
;
1664 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1665 return NT_STATUS_INVALID_HANDLE
;
1668 status
= lsa_lookup_trusted_domain_by_name(p
->mem_ctx
,
1671 if (!NT_STATUS_IS_OK(status
)) {
1675 return _lsa_OpenTrustedDomain_base(p
, r
->in
.access_mask
, info
,
1676 r
->out
.trustdom_handle
);
1679 static NTSTATUS
get_trustdom_auth_blob(struct pipes_struct
*p
,
1680 TALLOC_CTX
*mem_ctx
, DATA_BLOB
*auth_blob
,
1681 struct trustDomainPasswords
*auth_struct
)
1683 enum ndr_err_code ndr_err
;
1684 DATA_BLOB lsession_key
;
1687 status
= session_extract_session_key(p
->session_info
, &lsession_key
, KEY_USE_16BYTES
);
1688 if (!NT_STATUS_IS_OK(status
)) {
1689 return NT_STATUS_INVALID_PARAMETER
;
1692 arcfour_crypt_blob(auth_blob
->data
, auth_blob
->length
, &lsession_key
);
1693 ndr_err
= ndr_pull_struct_blob(auth_blob
, mem_ctx
,
1695 (ndr_pull_flags_fn_t
)ndr_pull_trustDomainPasswords
);
1696 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1697 return NT_STATUS_INVALID_PARAMETER
;
1700 return NT_STATUS_OK
;
1703 static NTSTATUS
get_trustauth_inout_blob(TALLOC_CTX
*mem_ctx
,
1704 struct trustAuthInOutBlob
*iopw
,
1705 DATA_BLOB
*trustauth_blob
)
1707 enum ndr_err_code ndr_err
;
1709 ndr_err
= ndr_push_struct_blob(trustauth_blob
, mem_ctx
,
1711 (ndr_push_flags_fn_t
)ndr_push_trustAuthInOutBlob
);
1712 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1713 return NT_STATUS_INVALID_PARAMETER
;
1716 return NT_STATUS_OK
;
1719 /***************************************************************************
1720 _lsa_CreateTrustedDomainEx2
1721 ***************************************************************************/
1723 NTSTATUS
_lsa_CreateTrustedDomainEx2(struct pipes_struct
*p
,
1724 struct lsa_CreateTrustedDomainEx2
*r
)
1726 struct lsa_info
*policy
;
1728 uint32_t acc_granted
;
1729 struct security_descriptor
*psd
;
1731 struct pdb_trusted_domain td
;
1732 struct trustDomainPasswords auth_struct
;
1733 DATA_BLOB auth_blob
;
1736 return NT_STATUS_NOT_SUPPORTED
;
1739 if (!find_policy_by_hnd(p
, r
->in
.policy_handle
, (void **)(void *)&policy
)) {
1740 return NT_STATUS_INVALID_HANDLE
;
1743 if (!(policy
->access
& LSA_POLICY_TRUST_ADMIN
)) {
1744 return NT_STATUS_ACCESS_DENIED
;
1747 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() &&
1748 !nt_token_check_domain_rid(p
->session_info
->security_token
, DOMAIN_RID_ADMINS
)) {
1749 return NT_STATUS_ACCESS_DENIED
;
1752 /* Work out max allowed. */
1753 map_max_allowed_access(p
->session_info
->security_token
,
1754 p
->session_info
->unix_token
,
1755 &r
->in
.access_mask
);
1757 /* map the generic bits to the lsa policy ones */
1758 se_map_generic(&r
->in
.access_mask
, &lsa_account_mapping
);
1760 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
1761 &lsa_trusted_domain_mapping
,
1763 if (!NT_STATUS_IS_OK(status
)) {
1767 status
= access_check_object(psd
, p
->session_info
->security_token
,
1768 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
1769 r
->in
.access_mask
, &acc_granted
,
1770 "_lsa_CreateTrustedDomainEx2");
1771 if (!NT_STATUS_IS_OK(status
)) {
1777 td
.domain_name
= talloc_strdup(p
->mem_ctx
,
1778 r
->in
.info
->domain_name
.string
);
1779 if (td
.domain_name
== NULL
) {
1780 return NT_STATUS_NO_MEMORY
;
1782 td
.netbios_name
= talloc_strdup(p
->mem_ctx
,
1783 r
->in
.info
->netbios_name
.string
);
1784 if (td
.netbios_name
== NULL
) {
1785 return NT_STATUS_NO_MEMORY
;
1787 sid_copy(&td
.security_identifier
, r
->in
.info
->sid
);
1788 td
.trust_direction
= r
->in
.info
->trust_direction
;
1789 td
.trust_type
= r
->in
.info
->trust_type
;
1790 td
.trust_attributes
= r
->in
.info
->trust_attributes
;
1792 if (r
->in
.auth_info_internal
->auth_blob
.size
!= 0) {
1793 auth_blob
.length
= r
->in
.auth_info_internal
->auth_blob
.size
;
1794 auth_blob
.data
= r
->in
.auth_info_internal
->auth_blob
.data
;
1796 status
= get_trustdom_auth_blob(p
, p
->mem_ctx
, &auth_blob
, &auth_struct
);
1797 if (!NT_STATUS_IS_OK(status
)) {
1798 return NT_STATUS_UNSUCCESSFUL
;
1801 status
= get_trustauth_inout_blob(p
->mem_ctx
, &auth_struct
.incoming
, &td
.trust_auth_incoming
);
1802 if (!NT_STATUS_IS_OK(status
)) {
1803 return NT_STATUS_UNSUCCESSFUL
;
1806 status
= get_trustauth_inout_blob(p
->mem_ctx
, &auth_struct
.outgoing
, &td
.trust_auth_outgoing
);
1807 if (!NT_STATUS_IS_OK(status
)) {
1808 return NT_STATUS_UNSUCCESSFUL
;
1811 td
.trust_auth_incoming
.data
= NULL
;
1812 td
.trust_auth_incoming
.length
= 0;
1813 td
.trust_auth_outgoing
.data
= NULL
;
1814 td
.trust_auth_outgoing
.length
= 0;
1817 status
= pdb_set_trusted_domain(r
->in
.info
->domain_name
.string
, &td
);
1818 if (!NT_STATUS_IS_OK(status
)) {
1822 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
1823 LSA_HANDLE_TRUST_TYPE
,
1826 r
->in
.info
->netbios_name
.string
,
1828 r
->out
.trustdom_handle
);
1829 if (!NT_STATUS_IS_OK(status
)) {
1830 pdb_del_trusted_domain(r
->in
.info
->netbios_name
.string
);
1831 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1834 return NT_STATUS_OK
;
1837 /***************************************************************************
1838 _lsa_CreateTrustedDomainEx
1839 ***************************************************************************/
1841 NTSTATUS
_lsa_CreateTrustedDomainEx(struct pipes_struct
*p
,
1842 struct lsa_CreateTrustedDomainEx
*r
)
1844 struct lsa_CreateTrustedDomainEx2 q
;
1845 struct lsa_TrustDomainInfoAuthInfoInternal auth_info
;
1847 ZERO_STRUCT(auth_info
);
1849 q
.in
.policy_handle
= r
->in
.policy_handle
;
1850 q
.in
.info
= r
->in
.info
;
1851 q
.in
.auth_info_internal
= &auth_info
;
1852 q
.in
.access_mask
= r
->in
.access_mask
;
1853 q
.out
.trustdom_handle
= r
->out
.trustdom_handle
;
1855 return _lsa_CreateTrustedDomainEx2(p
, &q
);
1858 /***************************************************************************
1859 _lsa_CreateTrustedDomain
1860 ***************************************************************************/
1862 NTSTATUS
_lsa_CreateTrustedDomain(struct pipes_struct
*p
,
1863 struct lsa_CreateTrustedDomain
*r
)
1865 struct lsa_CreateTrustedDomainEx2 c
;
1866 struct lsa_TrustDomainInfoInfoEx info
;
1867 struct lsa_TrustDomainInfoAuthInfoInternal auth_info
;
1869 ZERO_STRUCT(auth_info
);
1871 info
.domain_name
= r
->in
.info
->name
;
1872 info
.netbios_name
= r
->in
.info
->name
;
1873 info
.sid
= r
->in
.info
->sid
;
1874 info
.trust_direction
= LSA_TRUST_DIRECTION_OUTBOUND
;
1875 info
.trust_type
= LSA_TRUST_TYPE_DOWNLEVEL
;
1876 info
.trust_attributes
= 0;
1878 c
.in
.policy_handle
= r
->in
.policy_handle
;
1880 c
.in
.auth_info_internal
= &auth_info
;
1881 c
.in
.access_mask
= r
->in
.access_mask
;
1882 c
.out
.trustdom_handle
= r
->out
.trustdom_handle
;
1884 return _lsa_CreateTrustedDomainEx2(p
, &c
);
1887 /***************************************************************************
1888 _lsa_DeleteTrustedDomain
1889 ***************************************************************************/
1891 NTSTATUS
_lsa_DeleteTrustedDomain(struct pipes_struct
*p
,
1892 struct lsa_DeleteTrustedDomain
*r
)
1895 struct lsa_info
*handle
;
1896 struct pdb_trusted_domain
*td
;
1898 /* find the connection policy handle. */
1899 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1900 return NT_STATUS_INVALID_HANDLE
;
1903 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1904 return NT_STATUS_INVALID_HANDLE
;
1907 if (!(handle
->access
& LSA_POLICY_TRUST_ADMIN
)) {
1908 return NT_STATUS_ACCESS_DENIED
;
1911 status
= pdb_get_trusted_domain_by_sid(p
->mem_ctx
, r
->in
.dom_sid
, &td
);
1912 if (!NT_STATUS_IS_OK(status
)) {
1916 if (td
->netbios_name
== NULL
|| *td
->netbios_name
== '\0') {
1917 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1918 sid_string_tos(r
->in
.dom_sid
)));
1919 return NT_STATUS_UNSUCCESSFUL
;
1922 status
= pdb_del_trusted_domain(td
->netbios_name
);
1923 if (!NT_STATUS_IS_OK(status
)) {
1927 return NT_STATUS_OK
;
1930 /***************************************************************************
1931 _lsa_CloseTrustedDomainEx
1932 ***************************************************************************/
1934 NTSTATUS
_lsa_CloseTrustedDomainEx(struct pipes_struct
*p
,
1935 struct lsa_CloseTrustedDomainEx
*r
)
1937 return NT_STATUS_NOT_IMPLEMENTED
;
1940 /***************************************************************************
1941 _lsa_QueryTrustedDomainInfo
1942 ***************************************************************************/
1944 static NTSTATUS
pdb_trusted_domain_2_info_ex(TALLOC_CTX
*mem_ctx
,
1945 struct pdb_trusted_domain
*td
,
1946 struct lsa_TrustDomainInfoInfoEx
*info_ex
)
1948 if (td
->domain_name
== NULL
||
1949 td
->netbios_name
== NULL
||
1950 is_null_sid(&td
->security_identifier
)) {
1951 return NT_STATUS_INVALID_PARAMETER
;
1954 info_ex
->domain_name
.string
= talloc_strdup(mem_ctx
, td
->domain_name
);
1955 info_ex
->netbios_name
.string
= talloc_strdup(mem_ctx
, td
->netbios_name
);
1956 info_ex
->sid
= dom_sid_dup(mem_ctx
, &td
->security_identifier
);
1957 if (info_ex
->domain_name
.string
== NULL
||
1958 info_ex
->netbios_name
.string
== NULL
||
1959 info_ex
->sid
== NULL
) {
1960 return NT_STATUS_NO_MEMORY
;
1963 info_ex
->trust_direction
= td
->trust_direction
;
1964 info_ex
->trust_type
= td
->trust_type
;
1965 info_ex
->trust_attributes
= td
->trust_attributes
;
1967 return NT_STATUS_OK
;
1970 NTSTATUS
_lsa_QueryTrustedDomainInfo(struct pipes_struct
*p
,
1971 struct lsa_QueryTrustedDomainInfo
*r
)
1974 struct lsa_info
*handle
;
1975 union lsa_TrustedDomainInfo
*info
;
1976 struct pdb_trusted_domain
*td
;
1977 uint32_t acc_required
;
1979 /* find the connection policy handle. */
1980 if (!find_policy_by_hnd(p
, r
->in
.trustdom_handle
, (void **)(void *)&handle
)) {
1981 return NT_STATUS_INVALID_HANDLE
;
1984 if (handle
->type
!= LSA_HANDLE_TRUST_TYPE
) {
1985 return NT_STATUS_INVALID_HANDLE
;
1988 switch (r
->in
.level
) {
1989 case LSA_TRUSTED_DOMAIN_INFO_NAME
:
1990 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
1992 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS
:
1993 acc_required
= LSA_TRUSTED_QUERY_CONTROLLERS
;
1995 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET
:
1996 acc_required
= LSA_TRUSTED_QUERY_POSIX
;
1998 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD
:
1999 acc_required
= LSA_TRUSTED_QUERY_AUTH
;
2001 case LSA_TRUSTED_DOMAIN_INFO_BASIC
:
2002 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
2004 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX
:
2005 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
2007 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO
:
2008 acc_required
= LSA_TRUSTED_QUERY_AUTH
;
2010 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
:
2011 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
|
2012 LSA_TRUSTED_QUERY_POSIX
|
2013 LSA_TRUSTED_QUERY_AUTH
;
2015 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL
:
2016 acc_required
= LSA_TRUSTED_QUERY_AUTH
;
2018 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL
:
2019 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
|
2020 LSA_TRUSTED_QUERY_POSIX
|
2021 LSA_TRUSTED_QUERY_AUTH
;
2023 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL
:
2024 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
2026 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL
:
2027 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
|
2028 LSA_TRUSTED_QUERY_POSIX
|
2029 LSA_TRUSTED_QUERY_AUTH
;
2031 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES
:
2032 acc_required
= LSA_TRUSTED_QUERY_POSIX
;
2035 return NT_STATUS_INVALID_PARAMETER
;
2038 if (!(handle
->access
& acc_required
)) {
2039 return NT_STATUS_ACCESS_DENIED
;
2042 status
= pdb_get_trusted_domain_by_sid(p
->mem_ctx
, &handle
->sid
, &td
);
2043 if (!NT_STATUS_IS_OK(status
)) {
2047 info
= talloc_zero(p
->mem_ctx
, union lsa_TrustedDomainInfo
);
2049 return NT_STATUS_NO_MEMORY
;
2052 switch (r
->in
.level
) {
2053 case LSA_TRUSTED_DOMAIN_INFO_NAME
:
2054 init_lsa_StringLarge(&info
->name
.netbios_name
, td
->netbios_name
);
2056 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS
:
2057 return NT_STATUS_INVALID_PARAMETER
;
2058 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET
:
2059 info
->posix_offset
.posix_offset
= *td
->trust_posix_offset
;
2061 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD
:
2062 return NT_STATUS_INVALID_INFO_CLASS
;
2063 case LSA_TRUSTED_DOMAIN_INFO_BASIC
:
2064 return NT_STATUS_INVALID_PARAMETER
;
2065 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX
:
2066 status
= pdb_trusted_domain_2_info_ex(info
, td
, &info
->info_ex
);
2067 if (!NT_STATUS_IS_OK(status
)) {
2071 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO
:
2072 return NT_STATUS_INVALID_INFO_CLASS
;
2073 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
:
2074 status
= pdb_trusted_domain_2_info_ex(info
, td
,
2075 &info
->full_info
.info_ex
);
2076 if (!NT_STATUS_IS_OK(status
)) {
2079 info
->full_info
.posix_offset
.posix_offset
= *td
->trust_posix_offset
;
2080 status
= auth_blob_2_auth_info(p
->mem_ctx
,
2081 td
->trust_auth_incoming
,
2082 td
->trust_auth_outgoing
,
2083 &info
->full_info
.auth_info
);
2084 if (!NT_STATUS_IS_OK(status
)) {
2088 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL
:
2089 return NT_STATUS_INVALID_INFO_CLASS
;
2090 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL
:
2091 return NT_STATUS_INVALID_INFO_CLASS
;
2092 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL
:
2093 return NT_STATUS_INVALID_PARAMETER
;
2094 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL
:
2095 info
->full_info2_internal
.posix_offset
.posix_offset
= *td
->trust_posix_offset
;
2096 status
= auth_blob_2_auth_info(p
->mem_ctx
,
2097 td
->trust_auth_incoming
,
2098 td
->trust_auth_outgoing
,
2099 &info
->full_info2_internal
.auth_info
);
2100 if (!NT_STATUS_IS_OK(status
)) {
2104 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES
:
2105 info
->enc_types
.enc_types
= *td
->supported_enc_type
;
2108 return NT_STATUS_INVALID_PARAMETER
;
2111 *r
->out
.info
= info
;
2113 return NT_STATUS_OK
;
2116 /***************************************************************************
2117 _lsa_QueryTrustedDomainInfoBySid
2118 ***************************************************************************/
2120 NTSTATUS
_lsa_QueryTrustedDomainInfoBySid(struct pipes_struct
*p
,
2121 struct lsa_QueryTrustedDomainInfoBySid
*r
)
2124 struct policy_handle trustdom_handle
;
2125 struct lsa_OpenTrustedDomain o
;
2126 struct lsa_QueryTrustedDomainInfo q
;
2129 o
.in
.handle
= r
->in
.handle
;
2130 o
.in
.sid
= r
->in
.dom_sid
;
2131 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2132 o
.out
.trustdom_handle
= &trustdom_handle
;
2134 status
= _lsa_OpenTrustedDomain(p
, &o
);
2135 if (!NT_STATUS_IS_OK(status
)) {
2139 q
.in
.trustdom_handle
= &trustdom_handle
;
2140 q
.in
.level
= r
->in
.level
;
2141 q
.out
.info
= r
->out
.info
;
2143 status
= _lsa_QueryTrustedDomainInfo(p
, &q
);
2144 if (!NT_STATUS_IS_OK(status
)) {
2148 c
.in
.handle
= &trustdom_handle
;
2149 c
.out
.handle
= &trustdom_handle
;
2151 return _lsa_Close(p
, &c
);
2154 /***************************************************************************
2155 _lsa_QueryTrustedDomainInfoByName
2156 ***************************************************************************/
2158 NTSTATUS
_lsa_QueryTrustedDomainInfoByName(struct pipes_struct
*p
,
2159 struct lsa_QueryTrustedDomainInfoByName
*r
)
2162 struct policy_handle trustdom_handle
;
2163 struct lsa_OpenTrustedDomainByName o
;
2164 struct lsa_QueryTrustedDomainInfo q
;
2167 o
.in
.handle
= r
->in
.handle
;
2168 o
.in
.name
.string
= r
->in
.trusted_domain
->string
;
2169 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2170 o
.out
.trustdom_handle
= &trustdom_handle
;
2172 status
= _lsa_OpenTrustedDomainByName(p
, &o
);
2173 if (!NT_STATUS_IS_OK(status
)) {
2174 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_DOMAIN
)) {
2175 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2180 q
.in
.trustdom_handle
= &trustdom_handle
;
2181 q
.in
.level
= r
->in
.level
;
2182 q
.out
.info
= r
->out
.info
;
2184 status
= _lsa_QueryTrustedDomainInfo(p
, &q
);
2185 if (!NT_STATUS_IS_OK(status
)) {
2189 c
.in
.handle
= &trustdom_handle
;
2190 c
.out
.handle
= &trustdom_handle
;
2192 return _lsa_Close(p
, &c
);
2195 /***************************************************************************
2197 ***************************************************************************/
2199 NTSTATUS
_lsa_CreateSecret(struct pipes_struct
*p
,
2200 struct lsa_CreateSecret
*r
)
2203 struct lsa_info
*handle
;
2204 uint32_t acc_granted
;
2205 struct security_descriptor
*psd
;
2208 /* find the connection policy handle. */
2209 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
2210 return NT_STATUS_INVALID_HANDLE
;
2213 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2214 return NT_STATUS_INVALID_HANDLE
;
2217 /* check if the user has enough rights */
2219 if (!(handle
->access
& LSA_POLICY_CREATE_SECRET
)) {
2220 return NT_STATUS_ACCESS_DENIED
;
2223 /* Work out max allowed. */
2224 map_max_allowed_access(p
->session_info
->security_token
,
2225 p
->session_info
->unix_token
,
2226 &r
->in
.access_mask
);
2228 /* map the generic bits to the lsa policy ones */
2229 se_map_generic(&r
->in
.access_mask
, &lsa_secret_mapping
);
2231 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
2232 &lsa_secret_mapping
,
2234 if (!NT_STATUS_IS_OK(status
)) {
2238 status
= access_check_object(psd
, p
->session_info
->security_token
,
2239 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
2241 &acc_granted
, "_lsa_CreateSecret");
2242 if (!NT_STATUS_IS_OK(status
)) {
2246 if (!r
->in
.name
.string
) {
2247 return NT_STATUS_INVALID_PARAMETER
;
2250 if (strlen(r
->in
.name
.string
) > 128) {
2251 return NT_STATUS_NAME_TOO_LONG
;
2254 status
= pdb_get_secret(p
->mem_ctx
, r
->in
.name
.string
,
2255 NULL
, NULL
, NULL
, NULL
, NULL
);
2256 if (NT_STATUS_IS_OK(status
)) {
2257 return NT_STATUS_OBJECT_NAME_COLLISION
;
2260 status
= pdb_set_secret(r
->in
.name
.string
, NULL
, NULL
, psd
);
2261 if (!NT_STATUS_IS_OK(status
)) {
2265 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
2266 LSA_HANDLE_SECRET_TYPE
,
2272 if (!NT_STATUS_IS_OK(status
)) {
2273 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2276 return NT_STATUS_OK
;
2279 /***************************************************************************
2281 ***************************************************************************/
2283 NTSTATUS
_lsa_SetSecret(struct pipes_struct
*p
,
2284 struct lsa_SetSecret
*r
)
2287 struct lsa_info
*info
= NULL
;
2288 DATA_BLOB blob_new
, blob_old
;
2289 DATA_BLOB cleartext_blob_new
= data_blob_null
;
2290 DATA_BLOB cleartext_blob_old
= data_blob_null
;
2291 DATA_BLOB
*cleartext_blob_new_p
= NULL
;
2292 DATA_BLOB
*cleartext_blob_old_p
= NULL
;
2293 DATA_BLOB session_key
;
2295 if (!find_policy_by_hnd(p
, r
->in
.sec_handle
, (void **)(void *)&info
)) {
2296 return NT_STATUS_INVALID_HANDLE
;
2299 if (info
->type
!= LSA_HANDLE_SECRET_TYPE
) {
2300 return NT_STATUS_INVALID_HANDLE
;
2303 if (!(info
->access
& LSA_SECRET_SET_VALUE
)) {
2304 return NT_STATUS_ACCESS_DENIED
;
2307 status
= session_extract_session_key(p
->session_info
, &session_key
, KEY_USE_16BYTES
);
2308 if(!NT_STATUS_IS_OK(status
)) {
2312 if (r
->in
.new_val
) {
2313 blob_new
= data_blob_const(r
->in
.new_val
->data
,
2314 r
->in
.new_val
->length
);
2316 status
= sess_decrypt_blob(p
->mem_ctx
, &blob_new
,
2318 &cleartext_blob_new
);
2319 if (!NT_STATUS_IS_OK(status
)) {
2323 cleartext_blob_new_p
= &cleartext_blob_new
;
2326 if (r
->in
.old_val
) {
2327 blob_old
= data_blob_const(r
->in
.old_val
->data
,
2328 r
->in
.old_val
->length
);
2330 status
= sess_decrypt_blob(p
->mem_ctx
, &blob_old
,
2332 &cleartext_blob_old
);
2333 if (!NT_STATUS_IS_OK(status
)) {
2337 cleartext_blob_old_p
= &cleartext_blob_old
;
2340 status
= pdb_set_secret(info
->name
, cleartext_blob_new_p
, cleartext_blob_old_p
, NULL
);
2341 if (!NT_STATUS_IS_OK(status
)) {
2345 #ifdef DEBUG_PASSWORD
2346 DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
2347 dump_data(10, cleartext_blob_new
.data
, cleartext_blob_new
.length
);
2348 DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
2349 dump_data(10, cleartext_blob_old
.data
, cleartext_blob_old
.length
);
2352 return NT_STATUS_OK
;
2355 /***************************************************************************
2357 ***************************************************************************/
2359 NTSTATUS
_lsa_QuerySecret(struct pipes_struct
*p
,
2360 struct lsa_QuerySecret
*r
)
2362 struct lsa_info
*info
= NULL
;
2363 DATA_BLOB blob_new
, blob_old
;
2364 DATA_BLOB blob_new_crypt
, blob_old_crypt
;
2365 DATA_BLOB session_key
;
2366 NTTIME nttime_new
, nttime_old
;
2369 if (!find_policy_by_hnd(p
, r
->in
.sec_handle
, (void **)(void *)&info
)) {
2370 return NT_STATUS_INVALID_HANDLE
;
2373 if (info
->type
!= LSA_HANDLE_SECRET_TYPE
) {
2374 return NT_STATUS_INVALID_HANDLE
;
2377 if (!(info
->access
& LSA_SECRET_QUERY_VALUE
)) {
2378 return NT_STATUS_ACCESS_DENIED
;
2381 status
= pdb_get_secret(p
->mem_ctx
, info
->name
,
2382 &blob_new
, &nttime_new
,
2383 &blob_old
, &nttime_old
,
2385 if (!NT_STATUS_IS_OK(status
)) {
2389 status
= session_extract_session_key(p
->session_info
, &session_key
, KEY_USE_16BYTES
);
2390 if(!NT_STATUS_IS_OK(status
)) {
2394 if (r
->in
.new_val
) {
2395 if (blob_new
.length
) {
2396 if (!r
->out
.new_val
->buf
) {
2397 r
->out
.new_val
->buf
= talloc_zero(p
->mem_ctx
, struct lsa_DATA_BUF
);
2399 if (!r
->out
.new_val
->buf
) {
2400 return NT_STATUS_NO_MEMORY
;
2403 blob_new_crypt
= sess_encrypt_blob(p
->mem_ctx
, &blob_new
,
2405 if (!blob_new_crypt
.length
) {
2406 return NT_STATUS_NO_MEMORY
;
2409 r
->out
.new_val
->buf
->data
= blob_new_crypt
.data
;
2410 r
->out
.new_val
->buf
->length
= blob_new_crypt
.length
;
2411 r
->out
.new_val
->buf
->size
= blob_new_crypt
.length
;
2415 if (r
->in
.old_val
) {
2416 if (blob_old
.length
) {
2417 if (!r
->out
.old_val
->buf
) {
2418 r
->out
.old_val
->buf
= talloc_zero(p
->mem_ctx
, struct lsa_DATA_BUF
);
2420 if (!r
->out
.old_val
->buf
) {
2421 return NT_STATUS_NO_MEMORY
;
2424 blob_old_crypt
= sess_encrypt_blob(p
->mem_ctx
, &blob_old
,
2426 if (!blob_old_crypt
.length
) {
2427 return NT_STATUS_NO_MEMORY
;
2430 r
->out
.old_val
->buf
->data
= blob_old_crypt
.data
;
2431 r
->out
.old_val
->buf
->length
= blob_old_crypt
.length
;
2432 r
->out
.old_val
->buf
->size
= blob_old_crypt
.length
;
2436 if (r
->out
.new_mtime
) {
2437 *r
->out
.new_mtime
= nttime_new
;
2440 if (r
->out
.old_mtime
) {
2441 *r
->out
.old_mtime
= nttime_old
;
2444 return NT_STATUS_OK
;
2447 /***************************************************************************
2449 ***************************************************************************/
2451 NTSTATUS
_lsa_DeleteObject(struct pipes_struct
*p
,
2452 struct lsa_DeleteObject
*r
)
2455 struct lsa_info
*info
= NULL
;
2457 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
)) {
2458 return NT_STATUS_INVALID_HANDLE
;
2461 if (!(info
->access
& SEC_STD_DELETE
)) {
2462 return NT_STATUS_ACCESS_DENIED
;
2465 switch (info
->type
) {
2466 case LSA_HANDLE_ACCOUNT_TYPE
:
2467 status
= privilege_delete_account(&info
->sid
);
2468 if (!NT_STATUS_IS_OK(status
)) {
2469 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2470 nt_errstr(status
)));
2474 case LSA_HANDLE_TRUST_TYPE
:
2475 if (!pdb_del_trusteddom_pw(info
->name
)) {
2476 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2478 status
= NT_STATUS_OK
;
2480 case LSA_HANDLE_SECRET_TYPE
:
2481 status
= pdb_delete_secret(info
->name
);
2482 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
2483 return NT_STATUS_INVALID_HANDLE
;
2487 return NT_STATUS_INVALID_HANDLE
;
2490 close_policy_hnd(p
, r
->in
.handle
);
2491 ZERO_STRUCTP(r
->out
.handle
);
2496 /***************************************************************************
2498 ***************************************************************************/
2500 NTSTATUS
_lsa_EnumPrivs(struct pipes_struct
*p
,
2501 struct lsa_EnumPrivs
*r
)
2503 struct lsa_info
*handle
;
2505 uint32 enum_context
= *r
->in
.resume_handle
;
2506 int num_privs
= num_privileges_in_short_list();
2507 struct lsa_PrivEntry
*entries
= NULL
;
2509 /* remember that the enum_context starts at 0 and not 1 */
2511 if ( enum_context
>= num_privs
)
2512 return NT_STATUS_NO_MORE_ENTRIES
;
2514 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2515 enum_context
, num_privs
));
2517 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2518 return NT_STATUS_INVALID_HANDLE
;
2520 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2521 return NT_STATUS_INVALID_HANDLE
;
2524 /* check if the user has enough rights
2525 I don't know if it's the right one. not documented. */
2527 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
2528 return NT_STATUS_ACCESS_DENIED
;
2531 entries
= talloc_zero_array(p
->mem_ctx
, struct lsa_PrivEntry
, num_privs
);
2533 return NT_STATUS_NO_MEMORY
;
2539 for (i
= 0; i
< num_privs
; i
++) {
2540 if( i
< enum_context
) {
2542 init_lsa_StringLarge(&entries
[i
].name
, NULL
);
2544 entries
[i
].luid
.low
= 0;
2545 entries
[i
].luid
.high
= 0;
2548 init_lsa_StringLarge(&entries
[i
].name
, sec_privilege_name_from_index(i
));
2550 entries
[i
].luid
.low
= sec_privilege_from_index(i
);
2551 entries
[i
].luid
.high
= 0;
2555 enum_context
= num_privs
;
2557 *r
->out
.resume_handle
= enum_context
;
2558 r
->out
.privs
->count
= num_privs
;
2559 r
->out
.privs
->privs
= entries
;
2561 return NT_STATUS_OK
;
2564 /***************************************************************************
2565 _lsa_LookupPrivDisplayName
2566 ***************************************************************************/
2568 NTSTATUS
_lsa_LookupPrivDisplayName(struct pipes_struct
*p
,
2569 struct lsa_LookupPrivDisplayName
*r
)
2571 struct lsa_info
*handle
;
2572 const char *description
;
2573 struct lsa_StringLarge
*lsa_name
;
2575 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2576 return NT_STATUS_INVALID_HANDLE
;
2578 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2579 return NT_STATUS_INVALID_HANDLE
;
2582 /* check if the user has enough rights */
2585 * I don't know if it's the right one. not documented.
2587 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
2588 return NT_STATUS_ACCESS_DENIED
;
2590 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r
->in
.name
->string
));
2592 description
= get_privilege_dispname(r
->in
.name
->string
);
2594 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2595 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2598 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description
));
2600 lsa_name
= talloc_zero(p
->mem_ctx
, struct lsa_StringLarge
);
2602 return NT_STATUS_NO_MEMORY
;
2605 init_lsa_StringLarge(lsa_name
, description
);
2607 *r
->out
.returned_language_id
= r
->in
.language_id
;
2608 *r
->out
.disp_name
= lsa_name
;
2610 return NT_STATUS_OK
;
2613 /***************************************************************************
2615 ***************************************************************************/
2617 NTSTATUS
_lsa_EnumAccounts(struct pipes_struct
*p
,
2618 struct lsa_EnumAccounts
*r
)
2620 struct lsa_info
*handle
;
2621 struct dom_sid
*sid_list
;
2622 int i
, j
, num_entries
;
2624 struct lsa_SidPtr
*sids
= NULL
;
2626 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2627 return NT_STATUS_INVALID_HANDLE
;
2629 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2630 return NT_STATUS_INVALID_HANDLE
;
2633 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
2634 return NT_STATUS_ACCESS_DENIED
;
2639 /* The only way we can currently find out all the SIDs that have been
2640 privileged is to scan all privileges */
2642 status
= privilege_enumerate_accounts(&sid_list
, &num_entries
);
2643 if (!NT_STATUS_IS_OK(status
)) {
2647 if (*r
->in
.resume_handle
>= num_entries
) {
2648 return NT_STATUS_NO_MORE_ENTRIES
;
2651 if (num_entries
- *r
->in
.resume_handle
) {
2652 sids
= talloc_zero_array(p
->mem_ctx
, struct lsa_SidPtr
,
2653 num_entries
- *r
->in
.resume_handle
);
2655 talloc_free(sid_list
);
2656 return NT_STATUS_NO_MEMORY
;
2659 for (i
= *r
->in
.resume_handle
, j
= 0; i
< num_entries
; i
++, j
++) {
2660 sids
[j
].sid
= dom_sid_dup(p
->mem_ctx
, &sid_list
[i
]);
2662 talloc_free(sid_list
);
2663 return NT_STATUS_NO_MEMORY
;
2668 talloc_free(sid_list
);
2670 *r
->out
.resume_handle
= num_entries
;
2671 r
->out
.sids
->num_sids
= num_entries
;
2672 r
->out
.sids
->sids
= sids
;
2674 return NT_STATUS_OK
;
2677 /***************************************************************************
2679 ***************************************************************************/
2681 NTSTATUS
_lsa_GetUserName(struct pipes_struct
*p
,
2682 struct lsa_GetUserName
*r
)
2684 const char *username
, *domname
;
2685 struct lsa_String
*account_name
= NULL
;
2686 struct lsa_String
*authority_name
= NULL
;
2688 if (p
->transport
!= NCACN_NP
&& p
->transport
!= NCALRPC
) {
2689 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
2690 return NT_STATUS_ACCESS_DENIED
;
2693 if (r
->in
.account_name
&&
2694 *r
->in
.account_name
) {
2695 return NT_STATUS_INVALID_PARAMETER
;
2698 if (r
->in
.authority_name
&&
2699 *r
->in
.authority_name
) {
2700 return NT_STATUS_INVALID_PARAMETER
;
2703 if (security_session_user_level(p
->session_info
, NULL
) < SECURITY_USER
) {
2705 * I'm 99% sure this is not the right place to do this,
2706 * global_sid_Anonymous should probably be put into the token
2707 * instead of the guest id -- vl
2709 if (!lookup_sid(p
->mem_ctx
, &global_sid_Anonymous
,
2710 &domname
, &username
, NULL
)) {
2711 return NT_STATUS_NO_MEMORY
;
2714 username
= p
->session_info
->unix_info
->sanitized_username
;
2715 domname
= p
->session_info
->info
->domain_name
;
2718 account_name
= talloc(p
->mem_ctx
, struct lsa_String
);
2719 if (!account_name
) {
2720 return NT_STATUS_NO_MEMORY
;
2722 init_lsa_String(account_name
, username
);
2724 if (r
->out
.authority_name
) {
2725 authority_name
= talloc(p
->mem_ctx
, struct lsa_String
);
2726 if (!authority_name
) {
2727 return NT_STATUS_NO_MEMORY
;
2729 init_lsa_String(authority_name
, domname
);
2732 *r
->out
.account_name
= account_name
;
2733 if (r
->out
.authority_name
) {
2734 *r
->out
.authority_name
= authority_name
;
2737 return NT_STATUS_OK
;
2740 /***************************************************************************
2742 ***************************************************************************/
2744 NTSTATUS
_lsa_CreateAccount(struct pipes_struct
*p
,
2745 struct lsa_CreateAccount
*r
)
2748 struct lsa_info
*handle
;
2749 uint32_t acc_granted
;
2750 struct security_descriptor
*psd
;
2752 uint32_t owner_access
= (LSA_ACCOUNT_ALL_ACCESS
&
2753 ~(LSA_ACCOUNT_ADJUST_PRIVILEGES
|
2754 LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS
|
2757 /* find the connection policy handle. */
2758 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2759 return NT_STATUS_INVALID_HANDLE
;
2761 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2762 return NT_STATUS_INVALID_HANDLE
;
2765 /* check if the user has enough rights */
2767 if (!(handle
->access
& LSA_POLICY_CREATE_ACCOUNT
)) {
2768 return NT_STATUS_ACCESS_DENIED
;
2771 /* Work out max allowed. */
2772 map_max_allowed_access(p
->session_info
->security_token
,
2773 p
->session_info
->unix_token
,
2774 &r
->in
.access_mask
);
2776 /* map the generic bits to the lsa policy ones */
2777 se_map_generic(&r
->in
.access_mask
, &lsa_account_mapping
);
2779 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
2780 &lsa_account_mapping
,
2781 r
->in
.sid
, owner_access
);
2782 if (!NT_STATUS_IS_OK(status
)) {
2786 status
= access_check_object(psd
, p
->session_info
->security_token
,
2787 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0, r
->in
.access_mask
,
2788 &acc_granted
, "_lsa_CreateAccount");
2789 if (!NT_STATUS_IS_OK(status
)) {
2793 if ( is_privileged_sid( r
->in
.sid
) )
2794 return NT_STATUS_OBJECT_NAME_COLLISION
;
2796 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
2797 LSA_HANDLE_ACCOUNT_TYPE
,
2802 r
->out
.acct_handle
);
2803 if (!NT_STATUS_IS_OK(status
)) {
2804 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2807 return privilege_create_account(r
->in
.sid
);
2810 /***************************************************************************
2812 ***************************************************************************/
2814 NTSTATUS
_lsa_OpenAccount(struct pipes_struct
*p
,
2815 struct lsa_OpenAccount
*r
)
2817 struct lsa_info
*handle
;
2818 struct security_descriptor
*psd
= NULL
;
2820 uint32_t des_access
= r
->in
.access_mask
;
2821 uint32_t acc_granted
;
2822 uint32_t owner_access
= (LSA_ACCOUNT_ALL_ACCESS
&
2823 ~(LSA_ACCOUNT_ADJUST_PRIVILEGES
|
2824 LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS
|
2828 /* find the connection policy handle. */
2829 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2830 return NT_STATUS_INVALID_HANDLE
;
2832 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2833 return NT_STATUS_INVALID_HANDLE
;
2836 /* des_access is for the account here, not the policy
2837 * handle - so don't check against policy handle. */
2839 /* Work out max allowed. */
2840 map_max_allowed_access(p
->session_info
->security_token
,
2841 p
->session_info
->unix_token
,
2844 /* map the generic bits to the lsa account ones */
2845 se_map_generic(&des_access
, &lsa_account_mapping
);
2847 /* get the generic lsa account SD until we store it */
2848 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
2849 &lsa_account_mapping
,
2850 r
->in
.sid
, owner_access
);
2851 if (!NT_STATUS_IS_OK(status
)) {
2855 status
= access_check_object(psd
, p
->session_info
->security_token
,
2856 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0, des_access
,
2857 &acc_granted
, "_lsa_OpenAccount" );
2858 if (!NT_STATUS_IS_OK(status
)) {
2862 /* TODO: Fis the parsing routine before reenabling this check! */
2864 if (!lookup_sid(&handle
->sid
, dom_name
, name
, &type
))
2865 return NT_STATUS_ACCESS_DENIED
;
2868 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
2869 LSA_HANDLE_ACCOUNT_TYPE
,
2874 r
->out
.acct_handle
);
2875 if (!NT_STATUS_IS_OK(status
)) {
2876 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2879 return NT_STATUS_OK
;
2882 /***************************************************************************
2883 _lsa_EnumPrivsAccount
2884 For a given SID, enumerate all the privilege this account has.
2885 ***************************************************************************/
2887 NTSTATUS
_lsa_EnumPrivsAccount(struct pipes_struct
*p
,
2888 struct lsa_EnumPrivsAccount
*r
)
2890 NTSTATUS status
= NT_STATUS_OK
;
2891 struct lsa_info
*info
=NULL
;
2892 PRIVILEGE_SET
*privileges
;
2893 struct lsa_PrivilegeSet
*priv_set
= NULL
;
2895 /* find the connection policy handle. */
2896 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
2897 return NT_STATUS_INVALID_HANDLE
;
2899 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
2900 return NT_STATUS_INVALID_HANDLE
;
2903 if (!(info
->access
& LSA_ACCOUNT_VIEW
))
2904 return NT_STATUS_ACCESS_DENIED
;
2906 status
= get_privileges_for_sid_as_set(p
->mem_ctx
, &privileges
, &info
->sid
);
2907 if (!NT_STATUS_IS_OK(status
)) {
2911 *r
->out
.privs
= priv_set
= talloc_zero(p
->mem_ctx
, struct lsa_PrivilegeSet
);
2913 return NT_STATUS_NO_MEMORY
;
2916 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2917 sid_string_dbg(&info
->sid
),
2918 privileges
->count
));
2920 priv_set
->count
= privileges
->count
;
2921 priv_set
->unknown
= 0;
2922 priv_set
->set
= talloc_move(priv_set
, &privileges
->set
);
2927 /***************************************************************************
2928 _lsa_GetSystemAccessAccount
2929 ***************************************************************************/
2931 NTSTATUS
_lsa_GetSystemAccessAccount(struct pipes_struct
*p
,
2932 struct lsa_GetSystemAccessAccount
*r
)
2935 struct lsa_info
*info
= NULL
;
2936 struct lsa_EnumPrivsAccount e
;
2937 struct lsa_PrivilegeSet
*privset
;
2939 /* find the connection policy handle. */
2941 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
2942 return NT_STATUS_INVALID_HANDLE
;
2944 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
2945 return NT_STATUS_INVALID_HANDLE
;
2948 if (!(info
->access
& LSA_ACCOUNT_VIEW
))
2949 return NT_STATUS_ACCESS_DENIED
;
2951 privset
= talloc_zero(p
->mem_ctx
, struct lsa_PrivilegeSet
);
2953 return NT_STATUS_NO_MEMORY
;
2956 e
.in
.handle
= r
->in
.handle
;
2957 e
.out
.privs
= &privset
;
2959 status
= _lsa_EnumPrivsAccount(p
, &e
);
2960 if (!NT_STATUS_IS_OK(status
)) {
2961 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2962 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2963 nt_errstr(status
)));
2967 /* Samba4 would iterate over the privset to merge the policy mode bits,
2968 * not sure samba3 can do the same here, so just return what we did in
2972 0x01 -> Log on locally
2973 0x02 -> Access this computer from network
2974 0x04 -> Log on as a batch job
2975 0x10 -> Log on as a service
2977 they can be ORed together
2980 *r
->out
.access_mask
= LSA_POLICY_MODE_INTERACTIVE
|
2981 LSA_POLICY_MODE_NETWORK
;
2983 return NT_STATUS_OK
;
2986 /***************************************************************************
2987 update the systemaccount information
2988 ***************************************************************************/
2990 NTSTATUS
_lsa_SetSystemAccessAccount(struct pipes_struct
*p
,
2991 struct lsa_SetSystemAccessAccount
*r
)
2993 struct lsa_info
*info
=NULL
;
2997 /* find the connection policy handle. */
2998 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
2999 return NT_STATUS_INVALID_HANDLE
;
3001 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
3002 return NT_STATUS_INVALID_HANDLE
;
3005 if (!(info
->access
& LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS
)) {
3006 return NT_STATUS_ACCESS_DENIED
;
3009 map
= talloc_zero(p
->mem_ctx
, GROUP_MAP
);
3011 return NT_STATUS_NO_MEMORY
;
3014 if (!pdb_getgrsid(map
, info
->sid
)) {
3016 return NT_STATUS_NO_SUCH_GROUP
;
3019 status
= pdb_update_group_mapping_entry(map
);
3024 /***************************************************************************
3025 _lsa_AddPrivilegesToAccount
3026 For a given SID, add some privileges.
3027 ***************************************************************************/
3029 NTSTATUS
_lsa_AddPrivilegesToAccount(struct pipes_struct
*p
,
3030 struct lsa_AddPrivilegesToAccount
*r
)
3032 struct lsa_info
*info
= NULL
;
3033 struct lsa_PrivilegeSet
*set
= NULL
;
3035 /* find the connection policy handle. */
3036 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3037 return NT_STATUS_INVALID_HANDLE
;
3039 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
3040 return NT_STATUS_INVALID_HANDLE
;
3043 if (!(info
->access
& LSA_ACCOUNT_ADJUST_PRIVILEGES
)) {
3044 return NT_STATUS_ACCESS_DENIED
;
3049 if ( !grant_privilege_set( &info
->sid
, set
) ) {
3050 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
3051 sid_string_dbg(&info
->sid
) ));
3052 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3055 return NT_STATUS_OK
;
3058 /***************************************************************************
3059 _lsa_RemovePrivilegesFromAccount
3060 For a given SID, remove some privileges.
3061 ***************************************************************************/
3063 NTSTATUS
_lsa_RemovePrivilegesFromAccount(struct pipes_struct
*p
,
3064 struct lsa_RemovePrivilegesFromAccount
*r
)
3066 struct lsa_info
*info
= NULL
;
3067 struct lsa_PrivilegeSet
*set
= NULL
;
3069 /* find the connection policy handle. */
3070 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3071 return NT_STATUS_INVALID_HANDLE
;
3073 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
3074 return NT_STATUS_INVALID_HANDLE
;
3077 if (!(info
->access
& LSA_ACCOUNT_ADJUST_PRIVILEGES
)) {
3078 return NT_STATUS_ACCESS_DENIED
;
3083 if ( !revoke_privilege_set( &info
->sid
, set
) ) {
3084 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
3085 sid_string_dbg(&info
->sid
) ));
3086 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3089 return NT_STATUS_OK
;
3092 /***************************************************************************
3094 ***************************************************************************/
3096 NTSTATUS
_lsa_LookupPrivName(struct pipes_struct
*p
,
3097 struct lsa_LookupPrivName
*r
)
3099 struct lsa_info
*info
= NULL
;
3101 struct lsa_StringLarge
*lsa_name
;
3103 /* find the connection policy handle. */
3104 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
)) {
3105 return NT_STATUS_INVALID_HANDLE
;
3108 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3109 return NT_STATUS_INVALID_HANDLE
;
3112 if (!(info
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
)) {
3113 return NT_STATUS_ACCESS_DENIED
;
3116 if (r
->in
.luid
->high
!= 0) {
3117 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3120 name
= sec_privilege_name(r
->in
.luid
->low
);
3122 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3125 lsa_name
= talloc_zero(p
->mem_ctx
, struct lsa_StringLarge
);
3127 return NT_STATUS_NO_MEMORY
;
3130 lsa_name
->string
= talloc_strdup(lsa_name
, name
);
3131 if (!lsa_name
->string
) {
3132 TALLOC_FREE(lsa_name
);
3133 return NT_STATUS_NO_MEMORY
;
3136 *r
->out
.name
= lsa_name
;
3138 return NT_STATUS_OK
;
3141 /***************************************************************************
3143 ***************************************************************************/
3145 NTSTATUS
_lsa_QuerySecurity(struct pipes_struct
*p
,
3146 struct lsa_QuerySecurity
*r
)
3148 struct lsa_info
*handle
=NULL
;
3149 struct security_descriptor
*psd
= NULL
;
3153 /* find the connection policy handle. */
3154 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
3155 return NT_STATUS_INVALID_HANDLE
;
3157 switch (handle
->type
) {
3158 case LSA_HANDLE_POLICY_TYPE
:
3159 case LSA_HANDLE_ACCOUNT_TYPE
:
3160 case LSA_HANDLE_TRUST_TYPE
:
3161 case LSA_HANDLE_SECRET_TYPE
:
3163 sd_size
= ndr_size_security_descriptor(psd
, 0);
3164 status
= NT_STATUS_OK
;
3167 status
= NT_STATUS_INVALID_HANDLE
;
3171 if (!NT_STATUS_IS_OK(status
)) {
3175 *r
->out
.sdbuf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
);
3176 if (!*r
->out
.sdbuf
) {
3177 return NT_STATUS_NO_MEMORY
;
3183 /***************************************************************************
3184 _lsa_AddAccountRights
3185 ***************************************************************************/
3187 NTSTATUS
_lsa_AddAccountRights(struct pipes_struct
*p
,
3188 struct lsa_AddAccountRights
*r
)
3190 struct lsa_info
*info
= NULL
;
3192 uint32_t acc_granted
= 0;
3193 struct security_descriptor
*psd
= NULL
;
3198 /* find the connection policy handle. */
3199 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3200 return NT_STATUS_INVALID_HANDLE
;
3202 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3203 return NT_STATUS_INVALID_HANDLE
;
3206 /* get the generic lsa account SD for this SID until we store it */
3207 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
3208 &lsa_account_mapping
,
3210 if (!NT_STATUS_IS_OK(status
)) {
3215 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3216 * on the policy handle. If it does, ask for
3217 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3218 * on the account sid. We don't check here so just use the latter. JRA.
3221 status
= access_check_object(psd
, p
->session_info
->security_token
,
3222 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
3223 LSA_ACCOUNT_ADJUST_PRIVILEGES
|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS
|LSA_ACCOUNT_VIEW
,
3224 &acc_granted
, "_lsa_AddAccountRights" );
3225 if (!NT_STATUS_IS_OK(status
)) {
3229 /* according to an NT4 PDC, you can add privileges to SIDs even without
3230 call_lsa_create_account() first. And you can use any arbitrary SID. */
3232 sid_copy( &sid
, r
->in
.sid
);
3234 for ( i
=0; i
< r
->in
.rights
->count
; i
++ ) {
3236 const char *privname
= r
->in
.rights
->names
[i
].string
;
3238 /* only try to add non-null strings */
3243 if ( !grant_privilege_by_name( &sid
, privname
) ) {
3244 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3246 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3250 return NT_STATUS_OK
;
3253 /***************************************************************************
3254 _lsa_RemoveAccountRights
3255 ***************************************************************************/
3257 NTSTATUS
_lsa_RemoveAccountRights(struct pipes_struct
*p
,
3258 struct lsa_RemoveAccountRights
*r
)
3260 struct lsa_info
*info
= NULL
;
3262 struct security_descriptor
*psd
= NULL
;
3265 const char *privname
= NULL
;
3266 uint32_t acc_granted
= 0;
3269 /* find the connection policy handle. */
3270 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3271 return NT_STATUS_INVALID_HANDLE
;
3273 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3274 return NT_STATUS_INVALID_HANDLE
;
3277 /* get the generic lsa account SD for this SID until we store it */
3278 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
3279 &lsa_account_mapping
,
3281 if (!NT_STATUS_IS_OK(status
)) {
3286 * From the MS DOCs. We need
3287 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3288 * and DELETE on the account sid.
3291 status
= access_check_object(psd
, p
->session_info
->security_token
,
3292 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
3293 LSA_ACCOUNT_ADJUST_PRIVILEGES
|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS
|
3294 LSA_ACCOUNT_VIEW
|SEC_STD_DELETE
,
3295 &acc_granted
, "_lsa_RemoveAccountRights");
3296 if (!NT_STATUS_IS_OK(status
)) {
3300 sid_copy( &sid
, r
->in
.sid
);
3302 if ( r
->in
.remove_all
) {
3303 if ( !revoke_all_privileges( &sid
) )
3304 return NT_STATUS_ACCESS_DENIED
;
3306 return NT_STATUS_OK
;
3309 for ( i
=0; i
< r
->in
.rights
->count
; i
++ ) {
3311 privname
= r
->in
.rights
->names
[i
].string
;
3313 /* only try to add non-null strings */
3318 if ( !revoke_privilege_by_name( &sid
, privname
) ) {
3319 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3321 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3325 return NT_STATUS_OK
;
3328 /*******************************************************************
3329 ********************************************************************/
3331 static NTSTATUS
init_lsa_right_set(TALLOC_CTX
*mem_ctx
,
3332 struct lsa_RightSet
*r
,
3333 PRIVILEGE_SET
*privileges
)
3336 const char *privname
;
3337 const char **privname_array
= NULL
;
3340 for (i
=0; i
<privileges
->count
; i
++) {
3341 if (privileges
->set
[i
].luid
.high
) {
3344 privname
= sec_privilege_name(privileges
->set
[i
].luid
.low
);
3346 if (!add_string_to_array(mem_ctx
, privname
,
3347 &privname_array
, &num_priv
)) {
3348 return NT_STATUS_NO_MEMORY
;
3355 r
->names
= talloc_zero_array(mem_ctx
, struct lsa_StringLarge
,
3358 return NT_STATUS_NO_MEMORY
;
3361 for (i
=0; i
<num_priv
; i
++) {
3362 init_lsa_StringLarge(&r
->names
[i
], privname_array
[i
]);
3365 r
->count
= num_priv
;
3368 return NT_STATUS_OK
;
3371 /***************************************************************************
3372 _lsa_EnumAccountRights
3373 ***************************************************************************/
3375 NTSTATUS
_lsa_EnumAccountRights(struct pipes_struct
*p
,
3376 struct lsa_EnumAccountRights
*r
)
3379 struct lsa_info
*info
= NULL
;
3380 PRIVILEGE_SET
*privileges
;
3382 /* find the connection policy handle. */
3384 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3385 return NT_STATUS_INVALID_HANDLE
;
3387 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3388 return NT_STATUS_INVALID_HANDLE
;
3391 if (!(info
->access
& LSA_ACCOUNT_VIEW
)) {
3392 return NT_STATUS_ACCESS_DENIED
;
3395 /* according to an NT4 PDC, you can add privileges to SIDs even without
3396 call_lsa_create_account() first. And you can use any arbitrary SID. */
3398 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3399 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3400 * the lsa database */
3402 status
= get_privileges_for_sid_as_set(p
->mem_ctx
, &privileges
, r
->in
.sid
);
3403 if (!NT_STATUS_IS_OK(status
)) {
3407 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3408 sid_string_dbg(r
->in
.sid
), privileges
->count
));
3410 status
= init_lsa_right_set(p
->mem_ctx
, r
->out
.rights
, privileges
);
3415 /***************************************************************************
3416 _lsa_LookupPrivValue
3417 ***************************************************************************/
3419 NTSTATUS
_lsa_LookupPrivValue(struct pipes_struct
*p
,
3420 struct lsa_LookupPrivValue
*r
)
3422 struct lsa_info
*info
= NULL
;
3423 const char *name
= NULL
;
3425 /* find the connection policy handle. */
3427 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3428 return NT_STATUS_INVALID_HANDLE
;
3430 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3431 return NT_STATUS_INVALID_HANDLE
;
3434 if (!(info
->access
& LSA_POLICY_LOOKUP_NAMES
))
3435 return NT_STATUS_ACCESS_DENIED
;
3437 name
= r
->in
.name
->string
;
3439 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name
));
3441 r
->out
.luid
->low
= sec_privilege_id(name
);
3442 r
->out
.luid
->high
= 0;
3443 if (r
->out
.luid
->low
== SEC_PRIV_INVALID
) {
3444 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3446 return NT_STATUS_OK
;
3449 /***************************************************************************
3450 _lsa_EnumAccountsWithUserRight
3451 ***************************************************************************/
3453 NTSTATUS
_lsa_EnumAccountsWithUserRight(struct pipes_struct
*p
,
3454 struct lsa_EnumAccountsWithUserRight
*r
)
3457 struct lsa_info
*info
= NULL
;
3458 struct dom_sid
*sids
= NULL
;
3461 enum sec_privilege privilege
;
3463 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
)) {
3464 return NT_STATUS_INVALID_HANDLE
;
3467 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3468 return NT_STATUS_INVALID_HANDLE
;
3471 if (!(info
->access
& LSA_POLICY_LOOKUP_NAMES
)) {
3472 return NT_STATUS_ACCESS_DENIED
;
3475 if (!r
->in
.name
|| !r
->in
.name
->string
) {
3476 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3479 privilege
= sec_privilege_id(r
->in
.name
->string
);
3480 if (privilege
== SEC_PRIV_INVALID
) {
3481 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3484 status
= privilege_enum_sids(privilege
, p
->mem_ctx
,
3486 if (!NT_STATUS_IS_OK(status
)) {
3490 r
->out
.sids
->num_sids
= num_sids
;
3491 r
->out
.sids
->sids
= talloc_array(p
->mem_ctx
, struct lsa_SidPtr
,
3492 r
->out
.sids
->num_sids
);
3494 for (i
=0; i
< r
->out
.sids
->num_sids
; i
++) {
3495 r
->out
.sids
->sids
[i
].sid
= dom_sid_dup(r
->out
.sids
->sids
,
3497 if (!r
->out
.sids
->sids
[i
].sid
) {
3498 TALLOC_FREE(r
->out
.sids
->sids
);
3499 r
->out
.sids
->num_sids
= 0;
3500 return NT_STATUS_NO_MEMORY
;
3504 return NT_STATUS_OK
;
3507 /***************************************************************************
3509 ***************************************************************************/
3511 NTSTATUS
_lsa_Delete(struct pipes_struct
*p
,
3512 struct lsa_Delete
*r
)
3514 return NT_STATUS_NOT_SUPPORTED
;
3517 static NTSTATUS
info_ex_2_pdb_trusted_domain(
3518 struct lsa_TrustDomainInfoInfoEx
*info_ex
,
3519 struct pdb_trusted_domain
*td
)
3521 if (info_ex
->domain_name
.string
== NULL
||
3522 info_ex
->netbios_name
.string
== NULL
||
3523 info_ex
->sid
== NULL
) {
3524 return NT_STATUS_INVALID_PARAMETER
;
3527 td
->domain_name
= talloc_strdup(td
, info_ex
->domain_name
.string
);
3528 td
->netbios_name
= talloc_strdup(td
, info_ex
->netbios_name
.string
);
3529 sid_copy(&td
->security_identifier
, info_ex
->sid
);
3530 if (td
->domain_name
== NULL
||
3531 td
->netbios_name
== NULL
||
3532 is_null_sid(&td
->security_identifier
)) {
3533 return NT_STATUS_NO_MEMORY
;
3535 td
->trust_direction
= info_ex
->trust_direction
;
3536 td
->trust_type
= info_ex
->trust_type
;
3537 td
->trust_attributes
= info_ex
->trust_attributes
;
3539 return NT_STATUS_OK
;
3542 static NTSTATUS
setInfoTrustedDomain_base(struct pipes_struct
*p
,
3543 TALLOC_CTX
*mem_ctx
,
3544 struct lsa_info
*policy
,
3545 enum lsa_TrustDomInfoEnum level
,
3546 union lsa_TrustedDomainInfo
*info
)
3548 struct lsa_TrustDomainInfoAuthInfoInternal
*auth_info_int
= NULL
;
3549 DATA_BLOB auth_blob
;
3550 struct trustDomainPasswords auth_struct
;
3553 struct pdb_trusted_domain
*td
;
3554 struct pdb_trusted_domain
*orig_td
;
3556 td
= talloc_zero(mem_ctx
, struct pdb_trusted_domain
);
3558 return NT_STATUS_NO_MEMORY
;
3562 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET
:
3563 if (!(policy
->access
& LSA_TRUSTED_SET_POSIX
)) {
3564 return NT_STATUS_ACCESS_DENIED
;
3566 td
->trust_posix_offset
= &info
->posix_offset
.posix_offset
;
3568 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX
:
3569 if (!(policy
->access
& LSA_TRUSTED_SET_POSIX
)) {
3570 return NT_STATUS_ACCESS_DENIED
;
3572 nt_status
= info_ex_2_pdb_trusted_domain(&info
->info_ex
, td
);
3573 if (!NT_STATUS_IS_OK(nt_status
)) {
3577 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO
:
3578 if (!(policy
->access
& LSA_TRUSTED_SET_AUTH
)) {
3579 return NT_STATUS_ACCESS_DENIED
;
3581 nt_status
= auth_info_2_auth_blob(td
, &info
->auth_info
,
3582 &td
->trust_auth_incoming
,
3583 &td
->trust_auth_outgoing
);
3584 if (!NT_STATUS_IS_OK(nt_status
)) {
3588 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
:
3589 if (!(policy
->access
& (LSA_TRUSTED_SET_AUTH
| LSA_TRUSTED_SET_POSIX
))) {
3590 return NT_STATUS_ACCESS_DENIED
;
3592 td
->trust_posix_offset
= &info
->full_info
.posix_offset
.posix_offset
;
3593 nt_status
= info_ex_2_pdb_trusted_domain(&info
->full_info
.info_ex
,
3595 if (!NT_STATUS_IS_OK(nt_status
)) {
3598 nt_status
= auth_info_2_auth_blob(td
,
3599 &info
->full_info
.auth_info
,
3600 &td
->trust_auth_incoming
,
3601 &td
->trust_auth_outgoing
);
3602 if (!NT_STATUS_IS_OK(nt_status
)) {
3606 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL
:
3607 if (!(policy
->access
& LSA_TRUSTED_SET_AUTH
)) {
3608 return NT_STATUS_ACCESS_DENIED
;
3610 auth_info_int
= &info
->auth_info_internal
;
3612 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL
:
3613 if (!(policy
->access
& (LSA_TRUSTED_SET_AUTH
| LSA_TRUSTED_SET_POSIX
))) {
3614 return NT_STATUS_ACCESS_DENIED
;
3616 td
->trust_posix_offset
= &info
->full_info_internal
.posix_offset
.posix_offset
;
3617 nt_status
= info_ex_2_pdb_trusted_domain(&info
->full_info_internal
.info_ex
,
3619 if (!NT_STATUS_IS_OK(nt_status
)) {
3622 auth_info_int
= &info
->full_info_internal
.auth_info
;
3624 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES
:
3625 if (!(policy
->access
& LSA_TRUSTED_SET_POSIX
)) {
3626 return NT_STATUS_ACCESS_DENIED
;
3628 td
->supported_enc_type
= &info
->enc_types
.enc_types
;
3631 return NT_STATUS_INVALID_PARAMETER
;
3634 /* decode auth_info_int if set */
3635 if (auth_info_int
) {
3637 /* now decrypt blob */
3638 auth_blob
= data_blob_const(auth_info_int
->auth_blob
.data
,
3639 auth_info_int
->auth_blob
.size
);
3641 nt_status
= get_trustdom_auth_blob(p
, mem_ctx
,
3642 &auth_blob
, &auth_struct
);
3643 if (!NT_STATUS_IS_OK(nt_status
)) {
3647 memset(&auth_struct
, 0, sizeof(auth_struct
));
3650 /* TODO: verify only one object matches the dns/netbios/sid triplet and that
3651 * this is the one we already have */
3653 /* TODO: check if the trust direction is changed and we need to add or remove
3656 /* TODO: check if trust type shall be changed and return an error in this case
3658 nt_status
= pdb_get_trusted_domain_by_sid(p
->mem_ctx
, &policy
->sid
,
3660 if (!NT_STATUS_IS_OK(nt_status
)) {
3665 /* TODO: should we fetch previous values from the existing entry
3666 * and append them ? */
3667 if (auth_struct
.incoming
.count
) {
3668 nt_status
= get_trustauth_inout_blob(mem_ctx
,
3669 &auth_struct
.incoming
,
3670 &td
->trust_auth_incoming
);
3671 if (!NT_STATUS_IS_OK(nt_status
)) {
3675 ZERO_STRUCT(td
->trust_auth_incoming
);
3678 if (auth_struct
.outgoing
.count
) {
3679 nt_status
= get_trustauth_inout_blob(mem_ctx
,
3680 &auth_struct
.outgoing
,
3681 &td
->trust_auth_outgoing
);
3682 if (!NT_STATUS_IS_OK(nt_status
)) {
3686 ZERO_STRUCT(td
->trust_auth_outgoing
);
3689 nt_status
= pdb_set_trusted_domain(orig_td
->domain_name
, td
);
3690 if (!NT_STATUS_IS_OK(nt_status
)) {
3694 return NT_STATUS_OK
;
3697 NTSTATUS
_lsa_SetTrustedDomainInfo(struct pipes_struct
*p
,
3698 struct lsa_SetTrustedDomainInfo
*r
)
3701 struct policy_handle trustdom_handle
;
3702 struct lsa_OpenTrustedDomain o
;
3703 struct lsa_SetInformationTrustedDomain s
;
3706 o
.in
.handle
= r
->in
.handle
;
3707 o
.in
.sid
= r
->in
.dom_sid
;
3708 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3709 o
.out
.trustdom_handle
= &trustdom_handle
;
3711 status
= _lsa_OpenTrustedDomain(p
, &o
);
3712 if (!NT_STATUS_IS_OK(status
)) {
3716 s
.in
.trustdom_handle
= &trustdom_handle
;
3717 s
.in
.level
= r
->in
.level
;
3718 s
.in
.info
= r
->in
.info
;
3720 status
= _lsa_SetInformationTrustedDomain(p
, &s
);
3721 if (!NT_STATUS_IS_OK(status
)) {
3725 c
.in
.handle
= &trustdom_handle
;
3726 c
.out
.handle
= &trustdom_handle
;
3728 return _lsa_Close(p
, &c
);
3731 NTSTATUS
_lsa_SetTrustedDomainInfoByName(struct pipes_struct
*p
,
3732 struct lsa_SetTrustedDomainInfoByName
*r
)
3735 struct policy_handle trustdom_handle
;
3736 struct lsa_OpenTrustedDomainByName o
;
3737 struct lsa_SetInformationTrustedDomain s
;
3740 o
.in
.handle
= r
->in
.handle
;
3741 o
.in
.name
.string
= r
->in
.trusted_domain
->string
;
3742 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3743 o
.out
.trustdom_handle
= &trustdom_handle
;
3745 status
= _lsa_OpenTrustedDomainByName(p
, &o
);
3746 if (!NT_STATUS_IS_OK(status
)) {
3747 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_DOMAIN
)) {
3748 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3753 s
.in
.trustdom_handle
= &trustdom_handle
;
3754 s
.in
.level
= r
->in
.level
;
3755 s
.in
.info
= r
->in
.info
;
3757 status
= _lsa_SetInformationTrustedDomain(p
, &s
);
3758 if (!NT_STATUS_IS_OK(status
)) {
3762 c
.in
.handle
= &trustdom_handle
;
3763 c
.out
.handle
= &trustdom_handle
;
3765 return _lsa_Close(p
, &c
);
3768 NTSTATUS
_lsa_SetInformationTrustedDomain(struct pipes_struct
*p
,
3769 struct lsa_SetInformationTrustedDomain
*r
)
3771 struct lsa_info
*policy
;
3773 if (!find_policy_by_hnd(p
, r
->in
.trustdom_handle
, (void **)(void *)&policy
)) {
3774 return NT_STATUS_INVALID_HANDLE
;
3777 if (policy
->type
!= LSA_HANDLE_TRUST_TYPE
) {
3778 return NT_STATUS_INVALID_HANDLE
;
3781 return setInfoTrustedDomain_base(p
, p
->mem_ctx
, policy
,
3782 r
->in
.level
, r
->in
.info
);
3787 * From here on the server routines are just dummy ones to make smbd link with
3788 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3789 * pulling the server stubs across one by one.
3792 NTSTATUS
_lsa_SetSecObj(struct pipes_struct
*p
, struct lsa_SetSecObj
*r
)
3794 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3795 return NT_STATUS_NOT_IMPLEMENTED
;
3798 NTSTATUS
_lsa_ChangePassword(struct pipes_struct
*p
,
3799 struct lsa_ChangePassword
*r
)
3801 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3802 return NT_STATUS_NOT_IMPLEMENTED
;
3805 NTSTATUS
_lsa_SetInfoPolicy(struct pipes_struct
*p
, struct lsa_SetInfoPolicy
*r
)
3807 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3808 return NT_STATUS_NOT_IMPLEMENTED
;
3811 NTSTATUS
_lsa_ClearAuditLog(struct pipes_struct
*p
, struct lsa_ClearAuditLog
*r
)
3813 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3814 return NT_STATUS_NOT_IMPLEMENTED
;
3817 NTSTATUS
_lsa_GetQuotasForAccount(struct pipes_struct
*p
,
3818 struct lsa_GetQuotasForAccount
*r
)
3820 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3821 return NT_STATUS_NOT_IMPLEMENTED
;
3824 NTSTATUS
_lsa_SetQuotasForAccount(struct pipes_struct
*p
,
3825 struct lsa_SetQuotasForAccount
*r
)
3827 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3828 return NT_STATUS_NOT_IMPLEMENTED
;
3831 NTSTATUS
_lsa_StorePrivateData(struct pipes_struct
*p
,
3832 struct lsa_StorePrivateData
*r
)
3834 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3835 return NT_STATUS_NOT_IMPLEMENTED
;
3838 NTSTATUS
_lsa_RetrievePrivateData(struct pipes_struct
*p
,
3839 struct lsa_RetrievePrivateData
*r
)
3841 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3842 return NT_STATUS_NOT_IMPLEMENTED
;
3845 NTSTATUS
_lsa_SetInfoPolicy2(struct pipes_struct
*p
,
3846 struct lsa_SetInfoPolicy2
*r
)
3848 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3849 return NT_STATUS_NOT_IMPLEMENTED
;
3852 NTSTATUS
_lsa_EnumTrustedDomainsEx(struct pipes_struct
*p
,
3853 struct lsa_EnumTrustedDomainsEx
*r
)
3855 struct lsa_info
*info
;
3857 struct pdb_trusted_domain
**domains
;
3858 struct lsa_TrustDomainInfoInfoEx
*entries
;
3862 /* bail out early if pdb backend is not capable of ex trusted domains,
3863 * if we dont do that, the client might not call
3864 * _lsa_EnumTrustedDomains() afterwards - gd */
3866 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX
)) {
3867 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3868 return NT_STATUS_NOT_IMPLEMENTED
;
3871 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3872 return NT_STATUS_INVALID_HANDLE
;
3874 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3875 return NT_STATUS_INVALID_HANDLE
;
3878 /* check if the user has enough rights */
3879 if (!(info
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
3880 return NT_STATUS_ACCESS_DENIED
;
3883 nt_status
= pdb_enum_trusted_domains(p
->mem_ctx
, &count
, &domains
);
3886 if (!NT_STATUS_IS_OK(nt_status
)) {
3890 entries
= talloc_zero_array(p
->mem_ctx
, struct lsa_TrustDomainInfoInfoEx
,
3893 return NT_STATUS_NO_MEMORY
;
3896 for (i
=0; i
<count
; i
++) {
3897 init_lsa_StringLarge(&entries
[i
].domain_name
,
3898 domains
[i
]->domain_name
);
3899 init_lsa_StringLarge(&entries
[i
].netbios_name
,
3900 domains
[i
]->netbios_name
);
3901 entries
[i
].sid
= &domains
[i
]->security_identifier
;
3902 entries
[i
].trust_direction
= domains
[i
]->trust_direction
;
3903 entries
[i
].trust_type
= domains
[i
]->trust_type
;
3904 entries
[i
].trust_attributes
= domains
[i
]->trust_attributes
;
3907 if (*r
->in
.resume_handle
>= count
) {
3908 *r
->out
.resume_handle
= -1;
3909 TALLOC_FREE(entries
);
3910 return NT_STATUS_NO_MORE_ENTRIES
;
3913 /* return the rest, limit by max_size. Note that we
3914 use the w2k3 element size value of 60 */
3915 r
->out
.domains
->count
= count
- *r
->in
.resume_handle
;
3916 r
->out
.domains
->count
= MIN(r
->out
.domains
->count
,
3917 (r
->in
.max_size
/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER
));
3919 r
->out
.domains
->domains
= entries
+ *r
->in
.resume_handle
;
3921 if (r
->out
.domains
->count
< count
- *r
->in
.resume_handle
) {
3922 *r
->out
.resume_handle
= *r
->in
.resume_handle
+ r
->out
.domains
->count
;
3923 return STATUS_MORE_ENTRIES
;
3926 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3927 * always be larger than the previous input resume handle, in
3928 * particular when hitting the last query it is vital to set the
3929 * resume handle correctly to avoid infinite client loops, as
3930 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3931 * status is NT_STATUS_OK - gd */
3933 *r
->out
.resume_handle
= (uint32_t)-1;
3935 return NT_STATUS_OK
;
3938 NTSTATUS
_lsa_QueryDomainInformationPolicy(struct pipes_struct
*p
,
3939 struct lsa_QueryDomainInformationPolicy
*r
)
3941 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3942 return NT_STATUS_NOT_IMPLEMENTED
;
3945 NTSTATUS
_lsa_SetDomainInformationPolicy(struct pipes_struct
*p
,
3946 struct lsa_SetDomainInformationPolicy
*r
)
3948 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3949 return NT_STATUS_NOT_IMPLEMENTED
;
3952 NTSTATUS
_lsa_TestCall(struct pipes_struct
*p
, struct lsa_TestCall
*r
)
3954 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3955 return NT_STATUS_NOT_IMPLEMENTED
;
3958 NTSTATUS
_lsa_CREDRWRITE(struct pipes_struct
*p
, struct lsa_CREDRWRITE
*r
)
3960 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3961 return NT_STATUS_NOT_IMPLEMENTED
;
3964 NTSTATUS
_lsa_CREDRREAD(struct pipes_struct
*p
, struct lsa_CREDRREAD
*r
)
3966 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3967 return NT_STATUS_NOT_IMPLEMENTED
;
3970 NTSTATUS
_lsa_CREDRENUMERATE(struct pipes_struct
*p
, struct lsa_CREDRENUMERATE
*r
)
3972 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3973 return NT_STATUS_NOT_IMPLEMENTED
;
3976 NTSTATUS
_lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct
*p
,
3977 struct lsa_CREDRWRITEDOMAINCREDENTIALS
*r
)
3979 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3980 return NT_STATUS_NOT_IMPLEMENTED
;
3983 NTSTATUS
_lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct
*p
,
3984 struct lsa_CREDRREADDOMAINCREDENTIALS
*r
)
3986 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3987 return NT_STATUS_NOT_IMPLEMENTED
;
3990 NTSTATUS
_lsa_CREDRDELETE(struct pipes_struct
*p
, struct lsa_CREDRDELETE
*r
)
3992 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3993 return NT_STATUS_NOT_IMPLEMENTED
;
3996 NTSTATUS
_lsa_CREDRGETTARGETINFO(struct pipes_struct
*p
,
3997 struct lsa_CREDRGETTARGETINFO
*r
)
3999 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4000 return NT_STATUS_NOT_IMPLEMENTED
;
4003 NTSTATUS
_lsa_CREDRPROFILELOADED(struct pipes_struct
*p
,
4004 struct lsa_CREDRPROFILELOADED
*r
)
4006 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4007 return NT_STATUS_NOT_IMPLEMENTED
;
4010 NTSTATUS
_lsa_CREDRGETSESSIONTYPES(struct pipes_struct
*p
,
4011 struct lsa_CREDRGETSESSIONTYPES
*r
)
4013 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4014 return NT_STATUS_NOT_IMPLEMENTED
;
4017 NTSTATUS
_lsa_LSARREGISTERAUDITEVENT(struct pipes_struct
*p
,
4018 struct lsa_LSARREGISTERAUDITEVENT
*r
)
4020 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4021 return NT_STATUS_NOT_IMPLEMENTED
;
4024 NTSTATUS
_lsa_LSARGENAUDITEVENT(struct pipes_struct
*p
,
4025 struct lsa_LSARGENAUDITEVENT
*r
)
4027 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4028 return NT_STATUS_NOT_IMPLEMENTED
;
4031 NTSTATUS
_lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct
*p
,
4032 struct lsa_LSARUNREGISTERAUDITEVENT
*r
)
4034 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4035 return NT_STATUS_NOT_IMPLEMENTED
;
4038 NTSTATUS
_lsa_lsaRQueryForestTrustInformation(struct pipes_struct
*p
,
4039 struct lsa_lsaRQueryForestTrustInformation
*r
)
4041 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4042 return NT_STATUS_NOT_IMPLEMENTED
;
4045 #define DNS_CMP_MATCH 0
4046 #define DNS_CMP_FIRST_IS_CHILD 1
4047 #define DNS_CMP_SECOND_IS_CHILD 2
4048 #define DNS_CMP_NO_MATCH 3
4050 /* this function assumes names are well formed DNS names.
4051 * it doesn't validate them */
4052 static int dns_cmp(const char *s1
, size_t l1
,
4053 const char *s2
, size_t l2
)
4055 const char *p1
, *p2
;
4060 if (strcasecmp_m(s1
, s2
) == 0) {
4061 return DNS_CMP_MATCH
;
4063 return DNS_CMP_NO_MATCH
;
4071 cret
= DNS_CMP_FIRST_IS_CHILD
;
4077 cret
= DNS_CMP_SECOND_IS_CHILD
;
4080 if (p1
[t1
- t2
- 1] != '.') {
4081 return DNS_CMP_NO_MATCH
;
4084 if (strcasecmp_m(&p1
[t1
- t2
], p2
) == 0) {
4088 return DNS_CMP_NO_MATCH
;
4091 static NTSTATUS
make_ft_info(TALLOC_CTX
*mem_ctx
,
4092 struct lsa_ForestTrustInformation
*lfti
,
4093 struct ForestTrustInfo
*fti
)
4095 struct lsa_ForestTrustRecord
*lrec
;
4096 struct ForestTrustInfoRecord
*rec
;
4097 struct lsa_StringLarge
*tln
;
4098 struct lsa_ForestTrustDomainInfo
*info
;
4102 fti
->count
= lfti
->count
;
4103 fti
->records
= talloc_array(mem_ctx
,
4104 struct ForestTrustInfoRecordArmor
,
4106 if (!fti
->records
) {
4107 return NT_STATUS_NO_MEMORY
;
4109 for (i
= 0; i
< fti
->count
; i
++) {
4110 lrec
= lfti
->entries
[i
];
4111 rec
= &fti
->records
[i
].record
;
4113 rec
->flags
= lrec
->flags
;
4114 rec
->timestamp
= lrec
->time
;
4115 rec
->type
= lrec
->type
;
4117 switch (lrec
->type
) {
4118 case LSA_FOREST_TRUST_TOP_LEVEL_NAME
:
4119 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX
:
4120 tln
= &lrec
->forest_trust_data
.top_level_name
;
4121 rec
->data
.name
.string
=
4122 talloc_strdup(mem_ctx
, tln
->string
);
4123 if (!rec
->data
.name
.string
) {
4124 return NT_STATUS_NO_MEMORY
;
4126 rec
->data
.name
.size
= strlen(rec
->data
.name
.string
);
4128 case LSA_FOREST_TRUST_DOMAIN_INFO
:
4129 info
= &lrec
->forest_trust_data
.domain_info
;
4130 rec
->data
.info
.sid
= *info
->domain_sid
;
4131 rec
->data
.info
.dns_name
.string
=
4132 talloc_strdup(mem_ctx
,
4133 info
->dns_domain_name
.string
);
4134 if (!rec
->data
.info
.dns_name
.string
) {
4135 return NT_STATUS_NO_MEMORY
;
4137 rec
->data
.info
.dns_name
.size
=
4138 strlen(rec
->data
.info
.dns_name
.string
);
4139 rec
->data
.info
.netbios_name
.string
=
4140 talloc_strdup(mem_ctx
,
4141 info
->netbios_domain_name
.string
);
4142 if (!rec
->data
.info
.netbios_name
.string
) {
4143 return NT_STATUS_NO_MEMORY
;
4145 rec
->data
.info
.netbios_name
.size
=
4146 strlen(rec
->data
.info
.netbios_name
.string
);
4149 return NT_STATUS_INVALID_DOMAIN_STATE
;
4153 return NT_STATUS_OK
;
4156 static NTSTATUS
add_collision(struct lsa_ForestTrustCollisionInfo
*c_info
,
4157 uint32_t index
, uint32_t collision_type
,
4158 uint32_t conflict_type
, const char *tdo_name
);
4160 static NTSTATUS
check_ft_info(TALLOC_CTX
*mem_ctx
,
4161 const char *tdo_name
,
4162 struct ForestTrustInfo
*tdo_fti
,
4163 struct ForestTrustInfo
*new_fti
,
4164 struct lsa_ForestTrustCollisionInfo
*c_info
)
4166 struct ForestTrustInfoRecord
*nrec
;
4167 struct ForestTrustInfoRecord
*trec
;
4168 const char *dns_name
;
4169 const char *nb_name
= NULL
;
4170 struct dom_sid
*sid
= NULL
;
4171 const char *tname
= NULL
;
4174 uint32_t new_fti_idx
;
4176 /* use always TDO type, until we understand when Xref can be used */
4177 uint32_t collision_type
= LSA_FOREST_TRUST_COLLISION_TDO
;
4182 bool ex_rule
= false;
4185 for (new_fti_idx
= 0; new_fti_idx
< new_fti
->count
; new_fti_idx
++) {
4187 nrec
= &new_fti
->records
[new_fti_idx
].record
;
4189 tln_conflict
= false;
4190 sid_conflict
= false;
4191 nb_conflict
= false;
4194 switch (nrec
->type
) {
4195 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX
:
4196 /* exclusions do not conflict by definition */
4199 case FOREST_TRUST_TOP_LEVEL_NAME
:
4200 dns_name
= nrec
->data
.name
.string
;
4201 dns_len
= nrec
->data
.name
.size
;
4204 case LSA_FOREST_TRUST_DOMAIN_INFO
:
4205 dns_name
= nrec
->data
.info
.dns_name
.string
;
4206 dns_len
= nrec
->data
.info
.dns_name
.size
;
4207 nb_name
= nrec
->data
.info
.netbios_name
.string
;
4208 sid
= &nrec
->data
.info
.sid
;
4212 if (!dns_name
) continue;
4214 /* check if this is already taken and not excluded */
4215 for (i
= 0; i
< tdo_fti
->count
; i
++) {
4216 trec
= &tdo_fti
->records
[i
].record
;
4218 switch (trec
->type
) {
4219 case FOREST_TRUST_TOP_LEVEL_NAME
:
4221 tname
= trec
->data
.name
.string
;
4222 tlen
= trec
->data
.name
.size
;
4224 case FOREST_TRUST_TOP_LEVEL_NAME_EX
:
4226 tname
= trec
->data
.name
.string
;
4227 tlen
= trec
->data
.name
.size
;
4229 case FOREST_TRUST_DOMAIN_INFO
:
4231 tname
= trec
->data
.info
.dns_name
.string
;
4232 tlen
= trec
->data
.info
.dns_name
.size
;
4235 return NT_STATUS_INVALID_PARAMETER
;
4237 ret
= dns_cmp(dns_name
, dns_len
, tname
, tlen
);
4240 /* if it matches exclusion,
4241 * it doesn't conflict */
4247 case DNS_CMP_FIRST_IS_CHILD
:
4248 case DNS_CMP_SECOND_IS_CHILD
:
4249 tln_conflict
= true;
4255 /* explicit exclusion, no dns name conflict here */
4257 tln_conflict
= false;
4260 if (trec
->type
!= FOREST_TRUST_DOMAIN_INFO
) {
4264 /* also test for domain info */
4265 if (!(trec
->flags
& LSA_SID_DISABLED_ADMIN
) &&
4266 dom_sid_compare(&trec
->data
.info
.sid
, sid
) == 0) {
4267 sid_conflict
= true;
4269 if (!(trec
->flags
& LSA_NB_DISABLED_ADMIN
) &&
4270 strcasecmp_m(trec
->data
.info
.netbios_name
.string
,
4277 (void)add_collision(c_info
, new_fti_idx
,
4279 LSA_TLN_DISABLED_CONFLICT
,
4283 (void)add_collision(c_info
, new_fti_idx
,
4285 LSA_SID_DISABLED_CONFLICT
,
4289 (void)add_collision(c_info
, new_fti_idx
,
4291 LSA_NB_DISABLED_CONFLICT
,
4296 return NT_STATUS_OK
;
4299 static NTSTATUS
add_collision(struct lsa_ForestTrustCollisionInfo
*c_info
,
4300 uint32_t idx
, uint32_t collision_type
,
4301 uint32_t conflict_type
, const char *tdo_name
)
4303 struct lsa_ForestTrustCollisionRecord
**es
;
4304 uint32_t i
= c_info
->count
;
4306 es
= talloc_realloc(c_info
, c_info
->entries
,
4307 struct lsa_ForestTrustCollisionRecord
*, i
+ 1);
4309 return NT_STATUS_NO_MEMORY
;
4311 c_info
->entries
= es
;
4312 c_info
->count
= i
+ 1;
4314 es
[i
] = talloc(es
, struct lsa_ForestTrustCollisionRecord
);
4316 return NT_STATUS_NO_MEMORY
;
4320 es
[i
]->type
= collision_type
;
4321 es
[i
]->flags
.flags
= conflict_type
;
4322 es
[i
]->name
.string
= talloc_strdup(es
[i
], tdo_name
);
4323 if (!es
[i
]->name
.string
) {
4324 return NT_STATUS_NO_MEMORY
;
4326 es
[i
]->name
.size
= strlen(es
[i
]->name
.string
);
4328 return NT_STATUS_OK
;
4331 static NTSTATUS
get_ft_info(TALLOC_CTX
*mem_ctx
,
4332 struct pdb_trusted_domain
*td
,
4333 struct ForestTrustInfo
*info
)
4335 enum ndr_err_code ndr_err
;
4337 if (td
->trust_forest_trust_info
.length
== 0 ||
4338 td
->trust_forest_trust_info
.data
== NULL
) {
4339 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4341 ndr_err
= ndr_pull_struct_blob_all(&td
->trust_forest_trust_info
, mem_ctx
,
4343 (ndr_pull_flags_fn_t
)ndr_pull_ForestTrustInfo
);
4344 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
4345 return NT_STATUS_INVALID_DOMAIN_STATE
;
4348 return NT_STATUS_OK
;
4351 static NTSTATUS
own_ft_info(struct pdb_domain_info
*dom_info
,
4352 struct ForestTrustInfo
*fti
)
4354 struct ForestTrustDataDomainInfo
*info
;
4355 struct ForestTrustInfoRecord
*rec
;
4359 fti
->records
= talloc_array(fti
,
4360 struct ForestTrustInfoRecordArmor
, 2);
4361 if (!fti
->records
) {
4362 return NT_STATUS_NO_MEMORY
;
4366 rec
= &fti
->records
[0].record
;
4370 rec
->type
= LSA_FOREST_TRUST_TOP_LEVEL_NAME
;
4372 rec
->data
.name
.string
= talloc_strdup(fti
, dom_info
->dns_forest
);
4373 if (!rec
->data
.name
.string
) {
4374 return NT_STATUS_NO_MEMORY
;
4376 rec
->data
.name
.size
= strlen(rec
->data
.name
.string
);
4379 rec
= &fti
->records
[1].record
;
4383 rec
->type
= LSA_FOREST_TRUST_DOMAIN_INFO
;
4385 info
= &rec
->data
.info
;
4387 info
->sid
= dom_info
->sid
;
4388 info
->dns_name
.string
= talloc_strdup(fti
, dom_info
->dns_domain
);
4389 if (!info
->dns_name
.string
) {
4390 return NT_STATUS_NO_MEMORY
;
4392 info
->dns_name
.size
= strlen(info
->dns_name
.string
);
4393 info
->netbios_name
.string
= talloc_strdup(fti
, dom_info
->name
);
4394 if (!info
->netbios_name
.string
) {
4395 return NT_STATUS_NO_MEMORY
;
4397 info
->netbios_name
.size
= strlen(info
->netbios_name
.string
);
4399 return NT_STATUS_OK
;
4402 NTSTATUS
_lsa_lsaRSetForestTrustInformation(struct pipes_struct
*p
,
4403 struct lsa_lsaRSetForestTrustInformation
*r
)
4408 struct lsa_info
*handle
;
4409 uint32_t num_domains
;
4410 struct pdb_trusted_domain
**domains
;
4411 struct ForestTrustInfo
*nfti
;
4412 struct ForestTrustInfo
*fti
;
4413 struct lsa_ForestTrustCollisionInfo
*c_info
;
4414 struct pdb_domain_info
*dom_info
;
4415 enum ndr_err_code ndr_err
;
4418 return NT_STATUS_NOT_SUPPORTED
;
4421 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
4422 return NT_STATUS_INVALID_HANDLE
;
4425 if (handle
->type
!= LSA_HANDLE_TRUST_TYPE
) {
4426 return NT_STATUS_INVALID_HANDLE
;
4429 if (!(handle
->access
& LSA_TRUSTED_SET_AUTH
)) {
4430 return NT_STATUS_ACCESS_DENIED
;
4433 status
= pdb_enum_trusted_domains(p
->mem_ctx
, &num_domains
, &domains
);
4434 if (!NT_STATUS_IS_OK(status
)) {
4437 if (num_domains
== 0) {
4438 return NT_STATUS_NO_SUCH_DOMAIN
;
4441 for (i
= 0; i
< num_domains
; i
++) {
4442 if (domains
[i
]->domain_name
== NULL
) {
4443 return NT_STATUS_INVALID_DOMAIN_STATE
;
4445 if (strcasecmp_m(domains
[i
]->domain_name
,
4446 r
->in
.trusted_domain_name
->string
) == 0) {
4450 if (i
>= num_domains
) {
4451 return NT_STATUS_NO_SUCH_DOMAIN
;
4454 if (!(domains
[i
]->trust_attributes
&
4455 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE
)) {
4456 return NT_STATUS_INVALID_PARAMETER
;
4459 if (r
->in
.highest_record_type
>= LSA_FOREST_TRUST_RECORD_TYPE_LAST
) {
4460 return NT_STATUS_INVALID_PARAMETER
;
4463 /* The following section until COPY_END is a copy from
4464 * source4/rpmc_server/lsa/scesrc_lsa.c */
4465 nfti
= talloc(p
->mem_ctx
, struct ForestTrustInfo
);
4467 return NT_STATUS_NO_MEMORY
;
4470 status
= make_ft_info(nfti
, r
->in
.forest_trust_info
, nfti
);
4471 if (!NT_STATUS_IS_OK(status
)) {
4475 c_info
= talloc_zero(r
->out
.collision_info
,
4476 struct lsa_ForestTrustCollisionInfo
);
4478 return NT_STATUS_NO_MEMORY
;
4481 /* first check own info, then other domains */
4482 fti
= talloc(p
->mem_ctx
, struct ForestTrustInfo
);
4484 return NT_STATUS_NO_MEMORY
;
4487 dom_info
= pdb_get_domain_info(p
->mem_ctx
);
4489 status
= own_ft_info(dom_info
, fti
);
4490 if (!NT_STATUS_IS_OK(status
)) {
4494 status
= check_ft_info(c_info
, dom_info
->dns_domain
, fti
, nfti
, c_info
);
4495 if (!NT_STATUS_IS_OK(status
)) {
4499 for (j
= 0; j
< num_domains
; j
++) {
4500 fti
= talloc(p
->mem_ctx
, struct ForestTrustInfo
);
4502 return NT_STATUS_NO_MEMORY
;
4505 status
= get_ft_info(p
->mem_ctx
, domains
[j
], fti
);
4506 if (!NT_STATUS_IS_OK(status
)) {
4507 if (NT_STATUS_EQUAL(status
,
4508 NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4514 if (domains
[j
]->domain_name
== NULL
) {
4515 return NT_STATUS_INVALID_DOMAIN_STATE
;
4518 status
= check_ft_info(c_info
, domains
[j
]->domain_name
,
4520 if (!NT_STATUS_IS_OK(status
)) {
4525 *r
->out
.collision_info
= c_info
;
4527 if (r
->in
.check_only
!= 0) {
4528 return NT_STATUS_OK
;
4533 ndr_err
= ndr_push_struct_blob(&domains
[i
]->trust_forest_trust_info
,
4535 (ndr_push_flags_fn_t
)ndr_push_ForestTrustInfo
);
4536 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
4537 return NT_STATUS_INVALID_PARAMETER
;
4540 status
= pdb_set_trusted_domain(domains
[i
]->domain_name
, domains
[i
]);
4541 if (!NT_STATUS_IS_OK(status
)) {
4545 return NT_STATUS_OK
;
4548 NTSTATUS
_lsa_CREDRRENAME(struct pipes_struct
*p
,
4549 struct lsa_CREDRRENAME
*r
)
4551 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4552 return NT_STATUS_NOT_IMPLEMENTED
;
4555 NTSTATUS
_lsa_LSAROPENPOLICYSCE(struct pipes_struct
*p
,
4556 struct lsa_LSAROPENPOLICYSCE
*r
)
4558 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4559 return NT_STATUS_NOT_IMPLEMENTED
;
4562 NTSTATUS
_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct
*p
,
4563 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE
*r
)
4565 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4566 return NT_STATUS_NOT_IMPLEMENTED
;
4569 NTSTATUS
_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct
*p
,
4570 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
*r
)
4572 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4573 return NT_STATUS_NOT_IMPLEMENTED
;
4576 NTSTATUS
_lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct
*p
,
4577 struct lsa_LSARADTREPORTSECURITYEVENT
*r
)
4579 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4580 return NT_STATUS_NOT_IMPLEMENTED
;