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_t 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_t *pmapped_count
)
220 uint32_t 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
= security_descriptor_copy(info
, sd
);
365 if (info
->sd
== NULL
) {
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_t des_access
= r
->in
.access_mask
;
390 uint32_t acc_granted
;
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_t 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_t 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_t 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_t 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_t num_entries
= r
->in
.num_names
;
1147 struct lsa_RefDomainList
*domains
= NULL
;
1148 struct lsa_TranslatedSid
*rids
= NULL
;
1149 uint32_t 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_t num_entries
= r
->in
.num_names
;
1283 struct lsa_RefDomainList
*domains
= NULL
;
1284 struct lsa_TranslatedSid3
*trans_sids
= NULL
;
1285 uint32_t 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 if (iopw
->current
.count
!= iopw
->count
) {
1710 return NT_STATUS_INVALID_PARAMETER
;
1713 if (iopw
->previous
.count
> iopw
->current
.count
) {
1714 return NT_STATUS_INVALID_PARAMETER
;
1717 if (iopw
->previous
.count
== 0) {
1719 * If the previous credentials are not present
1720 * we need to make a copy.
1722 iopw
->previous
= iopw
->current
;
1725 if (iopw
->previous
.count
< iopw
->current
.count
) {
1726 struct AuthenticationInformationArray
*c
= &iopw
->current
;
1727 struct AuthenticationInformationArray
*p
= &iopw
->previous
;
1730 * The previous array needs to have the same size
1731 * as the current one.
1733 * We may have to fill with TRUST_AUTH_TYPE_NONE
1736 p
->array
= talloc_realloc(mem_ctx
, p
->array
,
1737 struct AuthenticationInformation
,
1739 if (p
->array
== NULL
) {
1740 return NT_STATUS_NO_MEMORY
;
1743 while (p
->count
< c
->count
) {
1744 struct AuthenticationInformation
*a
=
1745 &p
->array
[p
->count
++];
1747 *a
= (struct AuthenticationInformation
) {
1748 .LastUpdateTime
= p
->array
[0].LastUpdateTime
,
1749 .AuthType
= TRUST_AUTH_TYPE_NONE
,
1754 ndr_err
= ndr_push_struct_blob(trustauth_blob
, mem_ctx
,
1756 (ndr_push_flags_fn_t
)ndr_push_trustAuthInOutBlob
);
1757 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1758 return NT_STATUS_INVALID_PARAMETER
;
1761 return NT_STATUS_OK
;
1764 /***************************************************************************
1765 _lsa_CreateTrustedDomainEx2
1766 ***************************************************************************/
1768 NTSTATUS
_lsa_CreateTrustedDomainEx2(struct pipes_struct
*p
,
1769 struct lsa_CreateTrustedDomainEx2
*r
)
1771 struct lsa_info
*policy
;
1773 uint32_t acc_granted
;
1774 struct security_descriptor
*psd
;
1776 struct pdb_trusted_domain td
;
1777 struct trustDomainPasswords auth_struct
;
1778 DATA_BLOB auth_blob
;
1781 return NT_STATUS_NOT_SUPPORTED
;
1784 if (!find_policy_by_hnd(p
, r
->in
.policy_handle
, (void **)(void *)&policy
)) {
1785 return NT_STATUS_INVALID_HANDLE
;
1788 if (!(policy
->access
& LSA_POLICY_TRUST_ADMIN
)) {
1789 return NT_STATUS_ACCESS_DENIED
;
1792 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() &&
1793 !nt_token_check_domain_rid(p
->session_info
->security_token
, DOMAIN_RID_ADMINS
)) {
1794 return NT_STATUS_ACCESS_DENIED
;
1797 /* Work out max allowed. */
1798 map_max_allowed_access(p
->session_info
->security_token
,
1799 p
->session_info
->unix_token
,
1800 &r
->in
.access_mask
);
1802 /* map the generic bits to the lsa policy ones */
1803 se_map_generic(&r
->in
.access_mask
, &lsa_account_mapping
);
1805 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
1806 &lsa_trusted_domain_mapping
,
1808 if (!NT_STATUS_IS_OK(status
)) {
1812 status
= access_check_object(psd
, p
->session_info
->security_token
,
1813 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
1814 r
->in
.access_mask
, &acc_granted
,
1815 "_lsa_CreateTrustedDomainEx2");
1816 if (!NT_STATUS_IS_OK(status
)) {
1822 td
.domain_name
= talloc_strdup(p
->mem_ctx
,
1823 r
->in
.info
->domain_name
.string
);
1824 if (td
.domain_name
== NULL
) {
1825 return NT_STATUS_NO_MEMORY
;
1827 td
.netbios_name
= talloc_strdup(p
->mem_ctx
,
1828 r
->in
.info
->netbios_name
.string
);
1829 if (td
.netbios_name
== NULL
) {
1830 return NT_STATUS_NO_MEMORY
;
1832 sid_copy(&td
.security_identifier
, r
->in
.info
->sid
);
1833 td
.trust_direction
= r
->in
.info
->trust_direction
;
1834 td
.trust_type
= r
->in
.info
->trust_type
;
1835 td
.trust_attributes
= r
->in
.info
->trust_attributes
;
1837 if (r
->in
.auth_info_internal
->auth_blob
.size
!= 0) {
1838 auth_blob
.length
= r
->in
.auth_info_internal
->auth_blob
.size
;
1839 auth_blob
.data
= r
->in
.auth_info_internal
->auth_blob
.data
;
1841 status
= get_trustdom_auth_blob(p
, p
->mem_ctx
, &auth_blob
, &auth_struct
);
1842 if (!NT_STATUS_IS_OK(status
)) {
1843 return NT_STATUS_UNSUCCESSFUL
;
1846 status
= get_trustauth_inout_blob(p
->mem_ctx
, &auth_struct
.incoming
, &td
.trust_auth_incoming
);
1847 if (!NT_STATUS_IS_OK(status
)) {
1848 return NT_STATUS_UNSUCCESSFUL
;
1851 status
= get_trustauth_inout_blob(p
->mem_ctx
, &auth_struct
.outgoing
, &td
.trust_auth_outgoing
);
1852 if (!NT_STATUS_IS_OK(status
)) {
1853 return NT_STATUS_UNSUCCESSFUL
;
1856 td
.trust_auth_incoming
.data
= NULL
;
1857 td
.trust_auth_incoming
.length
= 0;
1858 td
.trust_auth_outgoing
.data
= NULL
;
1859 td
.trust_auth_outgoing
.length
= 0;
1862 status
= pdb_set_trusted_domain(r
->in
.info
->domain_name
.string
, &td
);
1863 if (!NT_STATUS_IS_OK(status
)) {
1867 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
1868 LSA_HANDLE_TRUST_TYPE
,
1871 r
->in
.info
->netbios_name
.string
,
1873 r
->out
.trustdom_handle
);
1874 if (!NT_STATUS_IS_OK(status
)) {
1875 pdb_del_trusted_domain(r
->in
.info
->netbios_name
.string
);
1876 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1879 return NT_STATUS_OK
;
1882 /***************************************************************************
1883 _lsa_CreateTrustedDomainEx
1884 ***************************************************************************/
1886 NTSTATUS
_lsa_CreateTrustedDomainEx(struct pipes_struct
*p
,
1887 struct lsa_CreateTrustedDomainEx
*r
)
1889 struct lsa_CreateTrustedDomainEx2 q
;
1890 struct lsa_TrustDomainInfoAuthInfoInternal auth_info
;
1892 ZERO_STRUCT(auth_info
);
1894 q
.in
.policy_handle
= r
->in
.policy_handle
;
1895 q
.in
.info
= r
->in
.info
;
1896 q
.in
.auth_info_internal
= &auth_info
;
1897 q
.in
.access_mask
= r
->in
.access_mask
;
1898 q
.out
.trustdom_handle
= r
->out
.trustdom_handle
;
1900 return _lsa_CreateTrustedDomainEx2(p
, &q
);
1903 /***************************************************************************
1904 _lsa_CreateTrustedDomain
1905 ***************************************************************************/
1907 NTSTATUS
_lsa_CreateTrustedDomain(struct pipes_struct
*p
,
1908 struct lsa_CreateTrustedDomain
*r
)
1910 struct lsa_CreateTrustedDomainEx2 c
;
1911 struct lsa_TrustDomainInfoInfoEx info
;
1912 struct lsa_TrustDomainInfoAuthInfoInternal auth_info
;
1914 ZERO_STRUCT(auth_info
);
1916 info
.domain_name
= r
->in
.info
->name
;
1917 info
.netbios_name
= r
->in
.info
->name
;
1918 info
.sid
= r
->in
.info
->sid
;
1919 info
.trust_direction
= LSA_TRUST_DIRECTION_OUTBOUND
;
1920 info
.trust_type
= LSA_TRUST_TYPE_DOWNLEVEL
;
1921 info
.trust_attributes
= 0;
1923 c
.in
.policy_handle
= r
->in
.policy_handle
;
1925 c
.in
.auth_info_internal
= &auth_info
;
1926 c
.in
.access_mask
= r
->in
.access_mask
;
1927 c
.out
.trustdom_handle
= r
->out
.trustdom_handle
;
1929 return _lsa_CreateTrustedDomainEx2(p
, &c
);
1932 /***************************************************************************
1933 _lsa_DeleteTrustedDomain
1934 ***************************************************************************/
1936 NTSTATUS
_lsa_DeleteTrustedDomain(struct pipes_struct
*p
,
1937 struct lsa_DeleteTrustedDomain
*r
)
1940 struct lsa_info
*handle
;
1941 struct pdb_trusted_domain
*td
;
1943 /* find the connection policy handle. */
1944 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1945 return NT_STATUS_INVALID_HANDLE
;
1948 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1949 return NT_STATUS_INVALID_HANDLE
;
1952 if (!(handle
->access
& LSA_POLICY_TRUST_ADMIN
)) {
1953 return NT_STATUS_ACCESS_DENIED
;
1956 status
= pdb_get_trusted_domain_by_sid(p
->mem_ctx
, r
->in
.dom_sid
, &td
);
1957 if (!NT_STATUS_IS_OK(status
)) {
1961 if (td
->netbios_name
== NULL
|| *td
->netbios_name
== '\0') {
1962 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1963 sid_string_tos(r
->in
.dom_sid
)));
1964 return NT_STATUS_UNSUCCESSFUL
;
1967 status
= pdb_del_trusted_domain(td
->netbios_name
);
1968 if (!NT_STATUS_IS_OK(status
)) {
1972 return NT_STATUS_OK
;
1975 /***************************************************************************
1976 _lsa_CloseTrustedDomainEx
1977 ***************************************************************************/
1979 NTSTATUS
_lsa_CloseTrustedDomainEx(struct pipes_struct
*p
,
1980 struct lsa_CloseTrustedDomainEx
*r
)
1982 return NT_STATUS_NOT_IMPLEMENTED
;
1985 /***************************************************************************
1986 _lsa_QueryTrustedDomainInfo
1987 ***************************************************************************/
1989 static NTSTATUS
pdb_trusted_domain_2_info_ex(TALLOC_CTX
*mem_ctx
,
1990 struct pdb_trusted_domain
*td
,
1991 struct lsa_TrustDomainInfoInfoEx
*info_ex
)
1993 if (td
->domain_name
== NULL
||
1994 td
->netbios_name
== NULL
||
1995 is_null_sid(&td
->security_identifier
)) {
1996 return NT_STATUS_INVALID_PARAMETER
;
1999 info_ex
->domain_name
.string
= talloc_strdup(mem_ctx
, td
->domain_name
);
2000 info_ex
->netbios_name
.string
= talloc_strdup(mem_ctx
, td
->netbios_name
);
2001 info_ex
->sid
= dom_sid_dup(mem_ctx
, &td
->security_identifier
);
2002 if (info_ex
->domain_name
.string
== NULL
||
2003 info_ex
->netbios_name
.string
== NULL
||
2004 info_ex
->sid
== NULL
) {
2005 return NT_STATUS_NO_MEMORY
;
2008 info_ex
->trust_direction
= td
->trust_direction
;
2009 info_ex
->trust_type
= td
->trust_type
;
2010 info_ex
->trust_attributes
= td
->trust_attributes
;
2012 return NT_STATUS_OK
;
2015 NTSTATUS
_lsa_QueryTrustedDomainInfo(struct pipes_struct
*p
,
2016 struct lsa_QueryTrustedDomainInfo
*r
)
2019 struct lsa_info
*handle
;
2020 union lsa_TrustedDomainInfo
*info
;
2021 struct pdb_trusted_domain
*td
;
2022 uint32_t acc_required
;
2024 /* find the connection policy handle. */
2025 if (!find_policy_by_hnd(p
, r
->in
.trustdom_handle
, (void **)(void *)&handle
)) {
2026 return NT_STATUS_INVALID_HANDLE
;
2029 if (handle
->type
!= LSA_HANDLE_TRUST_TYPE
) {
2030 return NT_STATUS_INVALID_HANDLE
;
2033 switch (r
->in
.level
) {
2034 case LSA_TRUSTED_DOMAIN_INFO_NAME
:
2035 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
2037 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS
:
2038 acc_required
= LSA_TRUSTED_QUERY_CONTROLLERS
;
2040 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET
:
2041 acc_required
= LSA_TRUSTED_QUERY_POSIX
;
2043 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD
:
2044 acc_required
= LSA_TRUSTED_QUERY_AUTH
;
2046 case LSA_TRUSTED_DOMAIN_INFO_BASIC
:
2047 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
2049 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX
:
2050 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
2052 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO
:
2053 acc_required
= LSA_TRUSTED_QUERY_AUTH
;
2055 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
:
2056 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
|
2057 LSA_TRUSTED_QUERY_POSIX
|
2058 LSA_TRUSTED_QUERY_AUTH
;
2060 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL
:
2061 acc_required
= LSA_TRUSTED_QUERY_AUTH
;
2063 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL
:
2064 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
|
2065 LSA_TRUSTED_QUERY_POSIX
|
2066 LSA_TRUSTED_QUERY_AUTH
;
2068 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL
:
2069 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
2071 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL
:
2072 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
|
2073 LSA_TRUSTED_QUERY_POSIX
|
2074 LSA_TRUSTED_QUERY_AUTH
;
2076 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES
:
2077 acc_required
= LSA_TRUSTED_QUERY_POSIX
;
2080 return NT_STATUS_INVALID_PARAMETER
;
2083 if (!(handle
->access
& acc_required
)) {
2084 return NT_STATUS_ACCESS_DENIED
;
2087 status
= pdb_get_trusted_domain_by_sid(p
->mem_ctx
, &handle
->sid
, &td
);
2088 if (!NT_STATUS_IS_OK(status
)) {
2092 info
= talloc_zero(p
->mem_ctx
, union lsa_TrustedDomainInfo
);
2094 return NT_STATUS_NO_MEMORY
;
2097 switch (r
->in
.level
) {
2098 case LSA_TRUSTED_DOMAIN_INFO_NAME
:
2099 init_lsa_StringLarge(&info
->name
.netbios_name
, td
->netbios_name
);
2101 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS
:
2102 return NT_STATUS_INVALID_PARAMETER
;
2103 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET
:
2104 info
->posix_offset
.posix_offset
= *td
->trust_posix_offset
;
2106 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD
:
2107 return NT_STATUS_INVALID_INFO_CLASS
;
2108 case LSA_TRUSTED_DOMAIN_INFO_BASIC
:
2109 return NT_STATUS_INVALID_PARAMETER
;
2110 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX
:
2111 status
= pdb_trusted_domain_2_info_ex(info
, td
, &info
->info_ex
);
2112 if (!NT_STATUS_IS_OK(status
)) {
2116 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO
:
2117 return NT_STATUS_INVALID_INFO_CLASS
;
2118 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
:
2119 status
= pdb_trusted_domain_2_info_ex(info
, td
,
2120 &info
->full_info
.info_ex
);
2121 if (!NT_STATUS_IS_OK(status
)) {
2124 info
->full_info
.posix_offset
.posix_offset
= *td
->trust_posix_offset
;
2125 status
= auth_blob_2_auth_info(p
->mem_ctx
,
2126 td
->trust_auth_incoming
,
2127 td
->trust_auth_outgoing
,
2128 &info
->full_info
.auth_info
);
2129 if (!NT_STATUS_IS_OK(status
)) {
2133 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL
:
2134 return NT_STATUS_INVALID_INFO_CLASS
;
2135 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL
:
2136 return NT_STATUS_INVALID_INFO_CLASS
;
2137 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL
:
2138 return NT_STATUS_INVALID_PARAMETER
;
2139 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL
:
2140 info
->full_info2_internal
.posix_offset
.posix_offset
= *td
->trust_posix_offset
;
2141 status
= auth_blob_2_auth_info(p
->mem_ctx
,
2142 td
->trust_auth_incoming
,
2143 td
->trust_auth_outgoing
,
2144 &info
->full_info2_internal
.auth_info
);
2145 if (!NT_STATUS_IS_OK(status
)) {
2149 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES
:
2150 info
->enc_types
.enc_types
= *td
->supported_enc_type
;
2153 return NT_STATUS_INVALID_PARAMETER
;
2156 *r
->out
.info
= info
;
2158 return NT_STATUS_OK
;
2161 /***************************************************************************
2162 _lsa_QueryTrustedDomainInfoBySid
2163 ***************************************************************************/
2165 NTSTATUS
_lsa_QueryTrustedDomainInfoBySid(struct pipes_struct
*p
,
2166 struct lsa_QueryTrustedDomainInfoBySid
*r
)
2169 struct policy_handle trustdom_handle
;
2170 struct lsa_OpenTrustedDomain o
;
2171 struct lsa_QueryTrustedDomainInfo q
;
2174 o
.in
.handle
= r
->in
.handle
;
2175 o
.in
.sid
= r
->in
.dom_sid
;
2176 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2177 o
.out
.trustdom_handle
= &trustdom_handle
;
2179 status
= _lsa_OpenTrustedDomain(p
, &o
);
2180 if (!NT_STATUS_IS_OK(status
)) {
2184 q
.in
.trustdom_handle
= &trustdom_handle
;
2185 q
.in
.level
= r
->in
.level
;
2186 q
.out
.info
= r
->out
.info
;
2188 status
= _lsa_QueryTrustedDomainInfo(p
, &q
);
2189 if (!NT_STATUS_IS_OK(status
)) {
2193 c
.in
.handle
= &trustdom_handle
;
2194 c
.out
.handle
= &trustdom_handle
;
2196 return _lsa_Close(p
, &c
);
2199 /***************************************************************************
2200 _lsa_QueryTrustedDomainInfoByName
2201 ***************************************************************************/
2203 NTSTATUS
_lsa_QueryTrustedDomainInfoByName(struct pipes_struct
*p
,
2204 struct lsa_QueryTrustedDomainInfoByName
*r
)
2207 struct policy_handle trustdom_handle
;
2208 struct lsa_OpenTrustedDomainByName o
;
2209 struct lsa_QueryTrustedDomainInfo q
;
2212 o
.in
.handle
= r
->in
.handle
;
2213 o
.in
.name
.string
= r
->in
.trusted_domain
->string
;
2214 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2215 o
.out
.trustdom_handle
= &trustdom_handle
;
2217 status
= _lsa_OpenTrustedDomainByName(p
, &o
);
2218 if (!NT_STATUS_IS_OK(status
)) {
2219 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_DOMAIN
)) {
2220 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2225 q
.in
.trustdom_handle
= &trustdom_handle
;
2226 q
.in
.level
= r
->in
.level
;
2227 q
.out
.info
= r
->out
.info
;
2229 status
= _lsa_QueryTrustedDomainInfo(p
, &q
);
2230 if (!NT_STATUS_IS_OK(status
)) {
2234 c
.in
.handle
= &trustdom_handle
;
2235 c
.out
.handle
= &trustdom_handle
;
2237 return _lsa_Close(p
, &c
);
2240 /***************************************************************************
2242 ***************************************************************************/
2244 NTSTATUS
_lsa_CreateSecret(struct pipes_struct
*p
,
2245 struct lsa_CreateSecret
*r
)
2248 struct lsa_info
*handle
;
2249 uint32_t acc_granted
;
2250 struct security_descriptor
*psd
;
2253 /* find the connection policy handle. */
2254 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
2255 return NT_STATUS_INVALID_HANDLE
;
2258 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2259 return NT_STATUS_INVALID_HANDLE
;
2262 /* check if the user has enough rights */
2264 if (!(handle
->access
& LSA_POLICY_CREATE_SECRET
)) {
2265 return NT_STATUS_ACCESS_DENIED
;
2268 /* Work out max allowed. */
2269 map_max_allowed_access(p
->session_info
->security_token
,
2270 p
->session_info
->unix_token
,
2271 &r
->in
.access_mask
);
2273 /* map the generic bits to the lsa policy ones */
2274 se_map_generic(&r
->in
.access_mask
, &lsa_secret_mapping
);
2276 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
2277 &lsa_secret_mapping
,
2279 if (!NT_STATUS_IS_OK(status
)) {
2283 status
= access_check_object(psd
, p
->session_info
->security_token
,
2284 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
2286 &acc_granted
, "_lsa_CreateSecret");
2287 if (!NT_STATUS_IS_OK(status
)) {
2291 if (!r
->in
.name
.string
) {
2292 return NT_STATUS_INVALID_PARAMETER
;
2295 if (strlen(r
->in
.name
.string
) > 128) {
2296 return NT_STATUS_NAME_TOO_LONG
;
2299 status
= pdb_get_secret(p
->mem_ctx
, r
->in
.name
.string
,
2300 NULL
, NULL
, NULL
, NULL
, NULL
);
2301 if (NT_STATUS_IS_OK(status
)) {
2302 return NT_STATUS_OBJECT_NAME_COLLISION
;
2305 status
= pdb_set_secret(r
->in
.name
.string
, NULL
, NULL
, psd
);
2306 if (!NT_STATUS_IS_OK(status
)) {
2310 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
2311 LSA_HANDLE_SECRET_TYPE
,
2317 if (!NT_STATUS_IS_OK(status
)) {
2318 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2321 return NT_STATUS_OK
;
2324 /***************************************************************************
2326 ***************************************************************************/
2328 NTSTATUS
_lsa_SetSecret(struct pipes_struct
*p
,
2329 struct lsa_SetSecret
*r
)
2332 struct lsa_info
*info
= NULL
;
2333 DATA_BLOB blob_new
, blob_old
;
2334 DATA_BLOB cleartext_blob_new
= data_blob_null
;
2335 DATA_BLOB cleartext_blob_old
= data_blob_null
;
2336 DATA_BLOB
*cleartext_blob_new_p
= NULL
;
2337 DATA_BLOB
*cleartext_blob_old_p
= NULL
;
2338 DATA_BLOB session_key
;
2340 if (!find_policy_by_hnd(p
, r
->in
.sec_handle
, (void **)(void *)&info
)) {
2341 return NT_STATUS_INVALID_HANDLE
;
2344 if (info
->type
!= LSA_HANDLE_SECRET_TYPE
) {
2345 return NT_STATUS_INVALID_HANDLE
;
2348 if (!(info
->access
& LSA_SECRET_SET_VALUE
)) {
2349 return NT_STATUS_ACCESS_DENIED
;
2352 status
= session_extract_session_key(p
->session_info
, &session_key
, KEY_USE_16BYTES
);
2353 if(!NT_STATUS_IS_OK(status
)) {
2357 if (r
->in
.new_val
) {
2358 blob_new
= data_blob_const(r
->in
.new_val
->data
,
2359 r
->in
.new_val
->length
);
2361 status
= sess_decrypt_blob(p
->mem_ctx
, &blob_new
,
2363 &cleartext_blob_new
);
2364 if (!NT_STATUS_IS_OK(status
)) {
2368 cleartext_blob_new_p
= &cleartext_blob_new
;
2371 if (r
->in
.old_val
) {
2372 blob_old
= data_blob_const(r
->in
.old_val
->data
,
2373 r
->in
.old_val
->length
);
2375 status
= sess_decrypt_blob(p
->mem_ctx
, &blob_old
,
2377 &cleartext_blob_old
);
2378 if (!NT_STATUS_IS_OK(status
)) {
2382 cleartext_blob_old_p
= &cleartext_blob_old
;
2385 status
= pdb_set_secret(info
->name
, cleartext_blob_new_p
, cleartext_blob_old_p
, NULL
);
2386 if (!NT_STATUS_IS_OK(status
)) {
2390 #ifdef DEBUG_PASSWORD
2391 DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
2392 dump_data(10, cleartext_blob_new
.data
, cleartext_blob_new
.length
);
2393 DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
2394 dump_data(10, cleartext_blob_old
.data
, cleartext_blob_old
.length
);
2397 return NT_STATUS_OK
;
2400 /***************************************************************************
2402 ***************************************************************************/
2404 NTSTATUS
_lsa_QuerySecret(struct pipes_struct
*p
,
2405 struct lsa_QuerySecret
*r
)
2407 struct lsa_info
*info
= NULL
;
2408 DATA_BLOB blob_new
, blob_old
;
2409 DATA_BLOB blob_new_crypt
, blob_old_crypt
;
2410 DATA_BLOB session_key
;
2411 NTTIME nttime_new
, nttime_old
;
2414 if (!find_policy_by_hnd(p
, r
->in
.sec_handle
, (void **)(void *)&info
)) {
2415 return NT_STATUS_INVALID_HANDLE
;
2418 if (info
->type
!= LSA_HANDLE_SECRET_TYPE
) {
2419 return NT_STATUS_INVALID_HANDLE
;
2422 if (!(info
->access
& LSA_SECRET_QUERY_VALUE
)) {
2423 return NT_STATUS_ACCESS_DENIED
;
2426 status
= pdb_get_secret(p
->mem_ctx
, info
->name
,
2427 &blob_new
, &nttime_new
,
2428 &blob_old
, &nttime_old
,
2430 if (!NT_STATUS_IS_OK(status
)) {
2434 status
= session_extract_session_key(p
->session_info
, &session_key
, KEY_USE_16BYTES
);
2435 if(!NT_STATUS_IS_OK(status
)) {
2439 if (r
->in
.new_val
) {
2440 if (blob_new
.length
) {
2441 if (!r
->out
.new_val
->buf
) {
2442 r
->out
.new_val
->buf
= talloc_zero(p
->mem_ctx
, struct lsa_DATA_BUF
);
2444 if (!r
->out
.new_val
->buf
) {
2445 return NT_STATUS_NO_MEMORY
;
2448 blob_new_crypt
= sess_encrypt_blob(p
->mem_ctx
, &blob_new
,
2450 if (!blob_new_crypt
.length
) {
2451 return NT_STATUS_NO_MEMORY
;
2454 r
->out
.new_val
->buf
->data
= blob_new_crypt
.data
;
2455 r
->out
.new_val
->buf
->length
= blob_new_crypt
.length
;
2456 r
->out
.new_val
->buf
->size
= blob_new_crypt
.length
;
2460 if (r
->in
.old_val
) {
2461 if (blob_old
.length
) {
2462 if (!r
->out
.old_val
->buf
) {
2463 r
->out
.old_val
->buf
= talloc_zero(p
->mem_ctx
, struct lsa_DATA_BUF
);
2465 if (!r
->out
.old_val
->buf
) {
2466 return NT_STATUS_NO_MEMORY
;
2469 blob_old_crypt
= sess_encrypt_blob(p
->mem_ctx
, &blob_old
,
2471 if (!blob_old_crypt
.length
) {
2472 return NT_STATUS_NO_MEMORY
;
2475 r
->out
.old_val
->buf
->data
= blob_old_crypt
.data
;
2476 r
->out
.old_val
->buf
->length
= blob_old_crypt
.length
;
2477 r
->out
.old_val
->buf
->size
= blob_old_crypt
.length
;
2481 if (r
->out
.new_mtime
) {
2482 *r
->out
.new_mtime
= nttime_new
;
2485 if (r
->out
.old_mtime
) {
2486 *r
->out
.old_mtime
= nttime_old
;
2489 return NT_STATUS_OK
;
2492 /***************************************************************************
2494 ***************************************************************************/
2496 NTSTATUS
_lsa_DeleteObject(struct pipes_struct
*p
,
2497 struct lsa_DeleteObject
*r
)
2500 struct lsa_info
*info
= NULL
;
2502 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
)) {
2503 return NT_STATUS_INVALID_HANDLE
;
2506 if (!(info
->access
& SEC_STD_DELETE
)) {
2507 return NT_STATUS_ACCESS_DENIED
;
2510 switch (info
->type
) {
2511 case LSA_HANDLE_ACCOUNT_TYPE
:
2512 status
= privilege_delete_account(&info
->sid
);
2513 if (!NT_STATUS_IS_OK(status
)) {
2514 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2515 nt_errstr(status
)));
2519 case LSA_HANDLE_TRUST_TYPE
:
2520 if (!pdb_del_trusteddom_pw(info
->name
)) {
2521 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2523 status
= NT_STATUS_OK
;
2525 case LSA_HANDLE_SECRET_TYPE
:
2526 status
= pdb_delete_secret(info
->name
);
2527 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
2528 return NT_STATUS_INVALID_HANDLE
;
2532 return NT_STATUS_INVALID_HANDLE
;
2535 close_policy_hnd(p
, r
->in
.handle
);
2536 ZERO_STRUCTP(r
->out
.handle
);
2541 /***************************************************************************
2543 ***************************************************************************/
2545 NTSTATUS
_lsa_EnumPrivs(struct pipes_struct
*p
,
2546 struct lsa_EnumPrivs
*r
)
2548 struct lsa_info
*handle
;
2550 uint32_t enum_context
= *r
->in
.resume_handle
;
2551 int num_privs
= num_privileges_in_short_list();
2552 struct lsa_PrivEntry
*entries
= NULL
;
2554 /* remember that the enum_context starts at 0 and not 1 */
2556 if ( enum_context
>= num_privs
)
2557 return NT_STATUS_NO_MORE_ENTRIES
;
2559 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2560 enum_context
, num_privs
));
2562 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2563 return NT_STATUS_INVALID_HANDLE
;
2565 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2566 return NT_STATUS_INVALID_HANDLE
;
2569 /* check if the user has enough rights
2570 I don't know if it's the right one. not documented. */
2572 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
2573 return NT_STATUS_ACCESS_DENIED
;
2576 entries
= talloc_zero_array(p
->mem_ctx
, struct lsa_PrivEntry
, num_privs
);
2578 return NT_STATUS_NO_MEMORY
;
2584 for (i
= 0; i
< num_privs
; i
++) {
2585 if( i
< enum_context
) {
2587 init_lsa_StringLarge(&entries
[i
].name
, NULL
);
2589 entries
[i
].luid
.low
= 0;
2590 entries
[i
].luid
.high
= 0;
2593 init_lsa_StringLarge(&entries
[i
].name
, sec_privilege_name_from_index(i
));
2595 entries
[i
].luid
.low
= sec_privilege_from_index(i
);
2596 entries
[i
].luid
.high
= 0;
2600 enum_context
= num_privs
;
2602 *r
->out
.resume_handle
= enum_context
;
2603 r
->out
.privs
->count
= num_privs
;
2604 r
->out
.privs
->privs
= entries
;
2606 return NT_STATUS_OK
;
2609 /***************************************************************************
2610 _lsa_LookupPrivDisplayName
2611 ***************************************************************************/
2613 NTSTATUS
_lsa_LookupPrivDisplayName(struct pipes_struct
*p
,
2614 struct lsa_LookupPrivDisplayName
*r
)
2616 struct lsa_info
*handle
;
2617 const char *description
;
2618 struct lsa_StringLarge
*lsa_name
;
2620 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2621 return NT_STATUS_INVALID_HANDLE
;
2623 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2624 return NT_STATUS_INVALID_HANDLE
;
2627 /* check if the user has enough rights */
2630 * I don't know if it's the right one. not documented.
2632 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
2633 return NT_STATUS_ACCESS_DENIED
;
2635 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r
->in
.name
->string
));
2637 description
= get_privilege_dispname(r
->in
.name
->string
);
2639 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2640 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2643 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description
));
2645 lsa_name
= talloc_zero(p
->mem_ctx
, struct lsa_StringLarge
);
2647 return NT_STATUS_NO_MEMORY
;
2650 init_lsa_StringLarge(lsa_name
, description
);
2652 *r
->out
.returned_language_id
= r
->in
.language_id
;
2653 *r
->out
.disp_name
= lsa_name
;
2655 return NT_STATUS_OK
;
2658 /***************************************************************************
2660 ***************************************************************************/
2662 NTSTATUS
_lsa_EnumAccounts(struct pipes_struct
*p
,
2663 struct lsa_EnumAccounts
*r
)
2665 struct lsa_info
*handle
;
2666 struct dom_sid
*sid_list
;
2667 int i
, j
, num_entries
;
2669 struct lsa_SidPtr
*sids
= NULL
;
2671 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2672 return NT_STATUS_INVALID_HANDLE
;
2674 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2675 return NT_STATUS_INVALID_HANDLE
;
2678 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
2679 return NT_STATUS_ACCESS_DENIED
;
2684 /* The only way we can currently find out all the SIDs that have been
2685 privileged is to scan all privileges */
2687 status
= privilege_enumerate_accounts(&sid_list
, &num_entries
);
2688 if (!NT_STATUS_IS_OK(status
)) {
2692 if (*r
->in
.resume_handle
>= num_entries
) {
2693 return NT_STATUS_NO_MORE_ENTRIES
;
2696 if (num_entries
- *r
->in
.resume_handle
) {
2697 sids
= talloc_zero_array(p
->mem_ctx
, struct lsa_SidPtr
,
2698 num_entries
- *r
->in
.resume_handle
);
2700 talloc_free(sid_list
);
2701 return NT_STATUS_NO_MEMORY
;
2704 for (i
= *r
->in
.resume_handle
, j
= 0; i
< num_entries
; i
++, j
++) {
2705 sids
[j
].sid
= dom_sid_dup(p
->mem_ctx
, &sid_list
[i
]);
2707 talloc_free(sid_list
);
2708 return NT_STATUS_NO_MEMORY
;
2713 talloc_free(sid_list
);
2715 *r
->out
.resume_handle
= num_entries
;
2716 r
->out
.sids
->num_sids
= num_entries
;
2717 r
->out
.sids
->sids
= sids
;
2719 return NT_STATUS_OK
;
2722 /***************************************************************************
2724 ***************************************************************************/
2726 NTSTATUS
_lsa_GetUserName(struct pipes_struct
*p
,
2727 struct lsa_GetUserName
*r
)
2729 const char *username
, *domname
;
2730 struct lsa_String
*account_name
= NULL
;
2731 struct lsa_String
*authority_name
= NULL
;
2733 if (p
->transport
!= NCACN_NP
&& p
->transport
!= NCALRPC
) {
2734 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
2735 return NT_STATUS_ACCESS_DENIED
;
2738 if (r
->in
.account_name
&&
2739 *r
->in
.account_name
) {
2740 return NT_STATUS_INVALID_PARAMETER
;
2743 if (r
->in
.authority_name
&&
2744 *r
->in
.authority_name
) {
2745 return NT_STATUS_INVALID_PARAMETER
;
2748 if (security_session_user_level(p
->session_info
, NULL
) < SECURITY_USER
) {
2750 * I'm 99% sure this is not the right place to do this,
2751 * global_sid_Anonymous should probably be put into the token
2752 * instead of the guest id -- vl
2754 if (!lookup_sid(p
->mem_ctx
, &global_sid_Anonymous
,
2755 &domname
, &username
, NULL
)) {
2756 return NT_STATUS_NO_MEMORY
;
2759 username
= p
->session_info
->unix_info
->sanitized_username
;
2760 domname
= p
->session_info
->info
->domain_name
;
2763 account_name
= talloc(p
->mem_ctx
, struct lsa_String
);
2764 if (!account_name
) {
2765 return NT_STATUS_NO_MEMORY
;
2767 init_lsa_String(account_name
, username
);
2769 if (r
->out
.authority_name
) {
2770 authority_name
= talloc(p
->mem_ctx
, struct lsa_String
);
2771 if (!authority_name
) {
2772 return NT_STATUS_NO_MEMORY
;
2774 init_lsa_String(authority_name
, domname
);
2777 *r
->out
.account_name
= account_name
;
2778 if (r
->out
.authority_name
) {
2779 *r
->out
.authority_name
= authority_name
;
2782 return NT_STATUS_OK
;
2785 /***************************************************************************
2787 ***************************************************************************/
2789 NTSTATUS
_lsa_CreateAccount(struct pipes_struct
*p
,
2790 struct lsa_CreateAccount
*r
)
2793 struct lsa_info
*handle
;
2794 uint32_t acc_granted
;
2795 struct security_descriptor
*psd
;
2797 uint32_t owner_access
= (LSA_ACCOUNT_ALL_ACCESS
&
2798 ~(LSA_ACCOUNT_ADJUST_PRIVILEGES
|
2799 LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS
|
2802 /* find the connection policy handle. */
2803 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2804 return NT_STATUS_INVALID_HANDLE
;
2806 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2807 return NT_STATUS_INVALID_HANDLE
;
2810 /* check if the user has enough rights */
2812 if (!(handle
->access
& LSA_POLICY_CREATE_ACCOUNT
)) {
2813 return NT_STATUS_ACCESS_DENIED
;
2816 /* Work out max allowed. */
2817 map_max_allowed_access(p
->session_info
->security_token
,
2818 p
->session_info
->unix_token
,
2819 &r
->in
.access_mask
);
2821 /* map the generic bits to the lsa policy ones */
2822 se_map_generic(&r
->in
.access_mask
, &lsa_account_mapping
);
2824 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
2825 &lsa_account_mapping
,
2826 r
->in
.sid
, owner_access
);
2827 if (!NT_STATUS_IS_OK(status
)) {
2831 status
= access_check_object(psd
, p
->session_info
->security_token
,
2832 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0, r
->in
.access_mask
,
2833 &acc_granted
, "_lsa_CreateAccount");
2834 if (!NT_STATUS_IS_OK(status
)) {
2838 if ( is_privileged_sid( r
->in
.sid
) )
2839 return NT_STATUS_OBJECT_NAME_COLLISION
;
2841 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
2842 LSA_HANDLE_ACCOUNT_TYPE
,
2847 r
->out
.acct_handle
);
2848 if (!NT_STATUS_IS_OK(status
)) {
2849 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2852 return privilege_create_account(r
->in
.sid
);
2855 /***************************************************************************
2857 ***************************************************************************/
2859 NTSTATUS
_lsa_OpenAccount(struct pipes_struct
*p
,
2860 struct lsa_OpenAccount
*r
)
2862 struct lsa_info
*handle
;
2863 struct security_descriptor
*psd
= NULL
;
2865 uint32_t des_access
= r
->in
.access_mask
;
2866 uint32_t acc_granted
;
2867 uint32_t owner_access
= (LSA_ACCOUNT_ALL_ACCESS
&
2868 ~(LSA_ACCOUNT_ADJUST_PRIVILEGES
|
2869 LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS
|
2873 /* find the connection policy handle. */
2874 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2875 return NT_STATUS_INVALID_HANDLE
;
2877 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2878 return NT_STATUS_INVALID_HANDLE
;
2881 /* des_access is for the account here, not the policy
2882 * handle - so don't check against policy handle. */
2884 /* Work out max allowed. */
2885 map_max_allowed_access(p
->session_info
->security_token
,
2886 p
->session_info
->unix_token
,
2889 /* map the generic bits to the lsa account ones */
2890 se_map_generic(&des_access
, &lsa_account_mapping
);
2892 /* get the generic lsa account SD until we store it */
2893 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
2894 &lsa_account_mapping
,
2895 r
->in
.sid
, owner_access
);
2896 if (!NT_STATUS_IS_OK(status
)) {
2900 status
= access_check_object(psd
, p
->session_info
->security_token
,
2901 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0, des_access
,
2902 &acc_granted
, "_lsa_OpenAccount" );
2903 if (!NT_STATUS_IS_OK(status
)) {
2907 /* TODO: Fis the parsing routine before reenabling this check! */
2909 if (!lookup_sid(&handle
->sid
, dom_name
, name
, &type
))
2910 return NT_STATUS_ACCESS_DENIED
;
2913 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
2914 LSA_HANDLE_ACCOUNT_TYPE
,
2919 r
->out
.acct_handle
);
2920 if (!NT_STATUS_IS_OK(status
)) {
2921 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2924 return NT_STATUS_OK
;
2927 /***************************************************************************
2928 _lsa_EnumPrivsAccount
2929 For a given SID, enumerate all the privilege this account has.
2930 ***************************************************************************/
2932 NTSTATUS
_lsa_EnumPrivsAccount(struct pipes_struct
*p
,
2933 struct lsa_EnumPrivsAccount
*r
)
2935 NTSTATUS status
= NT_STATUS_OK
;
2936 struct lsa_info
*info
=NULL
;
2937 PRIVILEGE_SET
*privileges
;
2938 struct lsa_PrivilegeSet
*priv_set
= NULL
;
2940 /* 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 status
= get_privileges_for_sid_as_set(p
->mem_ctx
, &privileges
, &info
->sid
);
2952 if (!NT_STATUS_IS_OK(status
)) {
2956 *r
->out
.privs
= priv_set
= talloc_zero(p
->mem_ctx
, struct lsa_PrivilegeSet
);
2958 return NT_STATUS_NO_MEMORY
;
2961 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2962 sid_string_dbg(&info
->sid
),
2963 privileges
->count
));
2965 priv_set
->count
= privileges
->count
;
2966 priv_set
->unknown
= 0;
2967 priv_set
->set
= talloc_move(priv_set
, &privileges
->set
);
2972 /***************************************************************************
2973 _lsa_GetSystemAccessAccount
2974 ***************************************************************************/
2976 NTSTATUS
_lsa_GetSystemAccessAccount(struct pipes_struct
*p
,
2977 struct lsa_GetSystemAccessAccount
*r
)
2980 struct lsa_info
*info
= NULL
;
2981 struct lsa_EnumPrivsAccount e
;
2982 struct lsa_PrivilegeSet
*privset
;
2984 /* find the connection policy handle. */
2986 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
2987 return NT_STATUS_INVALID_HANDLE
;
2989 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
2990 return NT_STATUS_INVALID_HANDLE
;
2993 if (!(info
->access
& LSA_ACCOUNT_VIEW
))
2994 return NT_STATUS_ACCESS_DENIED
;
2996 privset
= talloc_zero(p
->mem_ctx
, struct lsa_PrivilegeSet
);
2998 return NT_STATUS_NO_MEMORY
;
3001 e
.in
.handle
= r
->in
.handle
;
3002 e
.out
.privs
= &privset
;
3004 status
= _lsa_EnumPrivsAccount(p
, &e
);
3005 if (!NT_STATUS_IS_OK(status
)) {
3006 DEBUG(10,("_lsa_GetSystemAccessAccount: "
3007 "failed to call _lsa_EnumPrivsAccount(): %s\n",
3008 nt_errstr(status
)));
3012 /* Samba4 would iterate over the privset to merge the policy mode bits,
3013 * not sure samba3 can do the same here, so just return what we did in
3017 0x01 -> Log on locally
3018 0x02 -> Access this computer from network
3019 0x04 -> Log on as a batch job
3020 0x10 -> Log on as a service
3022 they can be ORed together
3025 *r
->out
.access_mask
= LSA_POLICY_MODE_INTERACTIVE
|
3026 LSA_POLICY_MODE_NETWORK
;
3028 return NT_STATUS_OK
;
3031 /***************************************************************************
3032 update the systemaccount information
3033 ***************************************************************************/
3035 NTSTATUS
_lsa_SetSystemAccessAccount(struct pipes_struct
*p
,
3036 struct lsa_SetSystemAccessAccount
*r
)
3038 struct lsa_info
*info
=NULL
;
3042 /* find the connection policy handle. */
3043 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3044 return NT_STATUS_INVALID_HANDLE
;
3046 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
3047 return NT_STATUS_INVALID_HANDLE
;
3050 if (!(info
->access
& LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS
)) {
3051 return NT_STATUS_ACCESS_DENIED
;
3054 map
= talloc_zero(p
->mem_ctx
, GROUP_MAP
);
3056 return NT_STATUS_NO_MEMORY
;
3059 if (!pdb_getgrsid(map
, info
->sid
)) {
3061 return NT_STATUS_NO_SUCH_GROUP
;
3064 status
= pdb_update_group_mapping_entry(map
);
3069 /***************************************************************************
3070 _lsa_AddPrivilegesToAccount
3071 For a given SID, add some privileges.
3072 ***************************************************************************/
3074 NTSTATUS
_lsa_AddPrivilegesToAccount(struct pipes_struct
*p
,
3075 struct lsa_AddPrivilegesToAccount
*r
)
3077 struct lsa_info
*info
= NULL
;
3078 struct lsa_PrivilegeSet
*set
= NULL
;
3080 /* find the connection policy handle. */
3081 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3082 return NT_STATUS_INVALID_HANDLE
;
3084 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
3085 return NT_STATUS_INVALID_HANDLE
;
3088 if (!(info
->access
& LSA_ACCOUNT_ADJUST_PRIVILEGES
)) {
3089 return NT_STATUS_ACCESS_DENIED
;
3094 if ( !grant_privilege_set( &info
->sid
, set
) ) {
3095 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
3096 sid_string_dbg(&info
->sid
) ));
3097 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3100 return NT_STATUS_OK
;
3103 /***************************************************************************
3104 _lsa_RemovePrivilegesFromAccount
3105 For a given SID, remove some privileges.
3106 ***************************************************************************/
3108 NTSTATUS
_lsa_RemovePrivilegesFromAccount(struct pipes_struct
*p
,
3109 struct lsa_RemovePrivilegesFromAccount
*r
)
3111 struct lsa_info
*info
= NULL
;
3112 struct lsa_PrivilegeSet
*set
= NULL
;
3114 /* find the connection policy handle. */
3115 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3116 return NT_STATUS_INVALID_HANDLE
;
3118 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
3119 return NT_STATUS_INVALID_HANDLE
;
3122 if (!(info
->access
& LSA_ACCOUNT_ADJUST_PRIVILEGES
)) {
3123 return NT_STATUS_ACCESS_DENIED
;
3128 if ( !revoke_privilege_set( &info
->sid
, set
) ) {
3129 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
3130 sid_string_dbg(&info
->sid
) ));
3131 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3134 return NT_STATUS_OK
;
3137 /***************************************************************************
3139 ***************************************************************************/
3141 NTSTATUS
_lsa_LookupPrivName(struct pipes_struct
*p
,
3142 struct lsa_LookupPrivName
*r
)
3144 struct lsa_info
*info
= NULL
;
3146 struct lsa_StringLarge
*lsa_name
;
3148 /* find the connection policy handle. */
3149 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
)) {
3150 return NT_STATUS_INVALID_HANDLE
;
3153 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3154 return NT_STATUS_INVALID_HANDLE
;
3157 if (!(info
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
)) {
3158 return NT_STATUS_ACCESS_DENIED
;
3161 if (r
->in
.luid
->high
!= 0) {
3162 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3165 name
= sec_privilege_name(r
->in
.luid
->low
);
3167 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3170 lsa_name
= talloc_zero(p
->mem_ctx
, struct lsa_StringLarge
);
3172 return NT_STATUS_NO_MEMORY
;
3175 lsa_name
->string
= talloc_strdup(lsa_name
, name
);
3176 if (!lsa_name
->string
) {
3177 TALLOC_FREE(lsa_name
);
3178 return NT_STATUS_NO_MEMORY
;
3181 *r
->out
.name
= lsa_name
;
3183 return NT_STATUS_OK
;
3186 /***************************************************************************
3188 ***************************************************************************/
3190 NTSTATUS
_lsa_QuerySecurity(struct pipes_struct
*p
,
3191 struct lsa_QuerySecurity
*r
)
3193 struct lsa_info
*handle
=NULL
;
3194 struct security_descriptor
*psd
= NULL
;
3198 /* find the connection policy handle. */
3199 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
3200 return NT_STATUS_INVALID_HANDLE
;
3202 switch (handle
->type
) {
3203 case LSA_HANDLE_POLICY_TYPE
:
3204 case LSA_HANDLE_ACCOUNT_TYPE
:
3205 case LSA_HANDLE_TRUST_TYPE
:
3206 case LSA_HANDLE_SECRET_TYPE
:
3208 sd_size
= ndr_size_security_descriptor(psd
, 0);
3209 status
= NT_STATUS_OK
;
3212 status
= NT_STATUS_INVALID_HANDLE
;
3216 if (!NT_STATUS_IS_OK(status
)) {
3220 *r
->out
.sdbuf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
);
3221 if (!*r
->out
.sdbuf
) {
3222 return NT_STATUS_NO_MEMORY
;
3228 /***************************************************************************
3229 _lsa_AddAccountRights
3230 ***************************************************************************/
3232 NTSTATUS
_lsa_AddAccountRights(struct pipes_struct
*p
,
3233 struct lsa_AddAccountRights
*r
)
3235 struct lsa_info
*info
= NULL
;
3237 uint32_t acc_granted
= 0;
3238 struct security_descriptor
*psd
= NULL
;
3243 /* find the connection policy handle. */
3244 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3245 return NT_STATUS_INVALID_HANDLE
;
3247 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3248 return NT_STATUS_INVALID_HANDLE
;
3251 /* get the generic lsa account SD for this SID until we store it */
3252 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
3253 &lsa_account_mapping
,
3255 if (!NT_STATUS_IS_OK(status
)) {
3260 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3261 * on the policy handle. If it does, ask for
3262 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3263 * on the account sid. We don't check here so just use the latter. JRA.
3266 status
= access_check_object(psd
, p
->session_info
->security_token
,
3267 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
3268 LSA_ACCOUNT_ADJUST_PRIVILEGES
|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS
|LSA_ACCOUNT_VIEW
,
3269 &acc_granted
, "_lsa_AddAccountRights" );
3270 if (!NT_STATUS_IS_OK(status
)) {
3274 /* according to an NT4 PDC, you can add privileges to SIDs even without
3275 call_lsa_create_account() first. And you can use any arbitrary SID. */
3277 sid_copy( &sid
, r
->in
.sid
);
3279 for ( i
=0; i
< r
->in
.rights
->count
; i
++ ) {
3281 const char *privname
= r
->in
.rights
->names
[i
].string
;
3283 /* only try to add non-null strings */
3288 if ( !grant_privilege_by_name( &sid
, privname
) ) {
3289 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3291 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3295 return NT_STATUS_OK
;
3298 /***************************************************************************
3299 _lsa_RemoveAccountRights
3300 ***************************************************************************/
3302 NTSTATUS
_lsa_RemoveAccountRights(struct pipes_struct
*p
,
3303 struct lsa_RemoveAccountRights
*r
)
3305 struct lsa_info
*info
= NULL
;
3307 struct security_descriptor
*psd
= NULL
;
3310 const char *privname
= NULL
;
3311 uint32_t acc_granted
= 0;
3314 /* find the connection policy handle. */
3315 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3316 return NT_STATUS_INVALID_HANDLE
;
3318 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3319 return NT_STATUS_INVALID_HANDLE
;
3322 /* get the generic lsa account SD for this SID until we store it */
3323 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
3324 &lsa_account_mapping
,
3326 if (!NT_STATUS_IS_OK(status
)) {
3331 * From the MS DOCs. We need
3332 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3333 * and DELETE on the account sid.
3336 status
= access_check_object(psd
, p
->session_info
->security_token
,
3337 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
3338 LSA_ACCOUNT_ADJUST_PRIVILEGES
|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS
|
3339 LSA_ACCOUNT_VIEW
|SEC_STD_DELETE
,
3340 &acc_granted
, "_lsa_RemoveAccountRights");
3341 if (!NT_STATUS_IS_OK(status
)) {
3345 sid_copy( &sid
, r
->in
.sid
);
3347 if ( r
->in
.remove_all
) {
3348 if ( !revoke_all_privileges( &sid
) )
3349 return NT_STATUS_ACCESS_DENIED
;
3351 return NT_STATUS_OK
;
3354 for ( i
=0; i
< r
->in
.rights
->count
; i
++ ) {
3356 privname
= r
->in
.rights
->names
[i
].string
;
3358 /* only try to add non-null strings */
3363 if ( !revoke_privilege_by_name( &sid
, privname
) ) {
3364 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3366 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3370 return NT_STATUS_OK
;
3373 /*******************************************************************
3374 ********************************************************************/
3376 static NTSTATUS
init_lsa_right_set(TALLOC_CTX
*mem_ctx
,
3377 struct lsa_RightSet
*r
,
3378 PRIVILEGE_SET
*privileges
)
3381 const char *privname
;
3382 const char **privname_array
= NULL
;
3383 size_t num_priv
= 0;
3385 for (i
=0; i
<privileges
->count
; i
++) {
3386 if (privileges
->set
[i
].luid
.high
) {
3389 privname
= sec_privilege_name(privileges
->set
[i
].luid
.low
);
3391 if (!add_string_to_array(mem_ctx
, privname
,
3392 &privname_array
, &num_priv
)) {
3393 return NT_STATUS_NO_MEMORY
;
3400 r
->names
= talloc_zero_array(mem_ctx
, struct lsa_StringLarge
,
3403 return NT_STATUS_NO_MEMORY
;
3406 for (i
=0; i
<num_priv
; i
++) {
3407 init_lsa_StringLarge(&r
->names
[i
], privname_array
[i
]);
3410 r
->count
= num_priv
;
3413 return NT_STATUS_OK
;
3416 /***************************************************************************
3417 _lsa_EnumAccountRights
3418 ***************************************************************************/
3420 NTSTATUS
_lsa_EnumAccountRights(struct pipes_struct
*p
,
3421 struct lsa_EnumAccountRights
*r
)
3424 struct lsa_info
*info
= NULL
;
3425 PRIVILEGE_SET
*privileges
;
3427 /* find the connection policy handle. */
3429 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3430 return NT_STATUS_INVALID_HANDLE
;
3432 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3433 return NT_STATUS_INVALID_HANDLE
;
3436 if (!(info
->access
& LSA_ACCOUNT_VIEW
)) {
3437 return NT_STATUS_ACCESS_DENIED
;
3440 /* according to an NT4 PDC, you can add privileges to SIDs even without
3441 call_lsa_create_account() first. And you can use any arbitrary SID. */
3443 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3444 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3445 * the lsa database */
3447 status
= get_privileges_for_sid_as_set(p
->mem_ctx
, &privileges
, r
->in
.sid
);
3448 if (!NT_STATUS_IS_OK(status
)) {
3452 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3453 sid_string_dbg(r
->in
.sid
), privileges
->count
));
3455 status
= init_lsa_right_set(p
->mem_ctx
, r
->out
.rights
, privileges
);
3460 /***************************************************************************
3461 _lsa_LookupPrivValue
3462 ***************************************************************************/
3464 NTSTATUS
_lsa_LookupPrivValue(struct pipes_struct
*p
,
3465 struct lsa_LookupPrivValue
*r
)
3467 struct lsa_info
*info
= NULL
;
3468 const char *name
= NULL
;
3470 /* find the connection policy handle. */
3472 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3473 return NT_STATUS_INVALID_HANDLE
;
3475 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3476 return NT_STATUS_INVALID_HANDLE
;
3479 if (!(info
->access
& LSA_POLICY_LOOKUP_NAMES
))
3480 return NT_STATUS_ACCESS_DENIED
;
3482 name
= r
->in
.name
->string
;
3484 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name
));
3486 r
->out
.luid
->low
= sec_privilege_id(name
);
3487 r
->out
.luid
->high
= 0;
3488 if (r
->out
.luid
->low
== SEC_PRIV_INVALID
) {
3489 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3491 return NT_STATUS_OK
;
3494 /***************************************************************************
3495 _lsa_EnumAccountsWithUserRight
3496 ***************************************************************************/
3498 NTSTATUS
_lsa_EnumAccountsWithUserRight(struct pipes_struct
*p
,
3499 struct lsa_EnumAccountsWithUserRight
*r
)
3502 struct lsa_info
*info
= NULL
;
3503 struct dom_sid
*sids
= NULL
;
3506 enum sec_privilege privilege
;
3508 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
)) {
3509 return NT_STATUS_INVALID_HANDLE
;
3512 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3513 return NT_STATUS_INVALID_HANDLE
;
3516 if (!(info
->access
& LSA_POLICY_LOOKUP_NAMES
)) {
3517 return NT_STATUS_ACCESS_DENIED
;
3520 if (!r
->in
.name
|| !r
->in
.name
->string
) {
3521 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3524 privilege
= sec_privilege_id(r
->in
.name
->string
);
3525 if (privilege
== SEC_PRIV_INVALID
) {
3526 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3529 status
= privilege_enum_sids(privilege
, p
->mem_ctx
,
3531 if (!NT_STATUS_IS_OK(status
)) {
3535 r
->out
.sids
->num_sids
= num_sids
;
3536 r
->out
.sids
->sids
= talloc_array(p
->mem_ctx
, struct lsa_SidPtr
,
3537 r
->out
.sids
->num_sids
);
3539 for (i
=0; i
< r
->out
.sids
->num_sids
; i
++) {
3540 r
->out
.sids
->sids
[i
].sid
= dom_sid_dup(r
->out
.sids
->sids
,
3542 if (!r
->out
.sids
->sids
[i
].sid
) {
3543 TALLOC_FREE(r
->out
.sids
->sids
);
3544 r
->out
.sids
->num_sids
= 0;
3545 return NT_STATUS_NO_MEMORY
;
3549 return NT_STATUS_OK
;
3552 /***************************************************************************
3554 ***************************************************************************/
3556 NTSTATUS
_lsa_Delete(struct pipes_struct
*p
,
3557 struct lsa_Delete
*r
)
3559 return NT_STATUS_NOT_SUPPORTED
;
3562 static NTSTATUS
info_ex_2_pdb_trusted_domain(
3563 struct lsa_TrustDomainInfoInfoEx
*info_ex
,
3564 struct pdb_trusted_domain
*td
)
3566 if (info_ex
->domain_name
.string
== NULL
||
3567 info_ex
->netbios_name
.string
== NULL
||
3568 info_ex
->sid
== NULL
) {
3569 return NT_STATUS_INVALID_PARAMETER
;
3572 td
->domain_name
= talloc_strdup(td
, info_ex
->domain_name
.string
);
3573 td
->netbios_name
= talloc_strdup(td
, info_ex
->netbios_name
.string
);
3574 sid_copy(&td
->security_identifier
, info_ex
->sid
);
3575 if (td
->domain_name
== NULL
||
3576 td
->netbios_name
== NULL
||
3577 is_null_sid(&td
->security_identifier
)) {
3578 return NT_STATUS_NO_MEMORY
;
3580 td
->trust_direction
= info_ex
->trust_direction
;
3581 td
->trust_type
= info_ex
->trust_type
;
3582 td
->trust_attributes
= info_ex
->trust_attributes
;
3584 return NT_STATUS_OK
;
3587 static NTSTATUS
setInfoTrustedDomain_base(struct pipes_struct
*p
,
3588 TALLOC_CTX
*mem_ctx
,
3589 struct lsa_info
*policy
,
3590 enum lsa_TrustDomInfoEnum level
,
3591 union lsa_TrustedDomainInfo
*info
)
3593 struct lsa_TrustDomainInfoAuthInfoInternal
*auth_info_int
= NULL
;
3594 DATA_BLOB auth_blob
;
3595 struct trustDomainPasswords auth_struct
;
3598 struct pdb_trusted_domain
*td
;
3599 struct pdb_trusted_domain
*orig_td
;
3601 td
= talloc_zero(mem_ctx
, struct pdb_trusted_domain
);
3603 return NT_STATUS_NO_MEMORY
;
3607 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET
:
3608 if (!(policy
->access
& LSA_TRUSTED_SET_POSIX
)) {
3609 return NT_STATUS_ACCESS_DENIED
;
3611 td
->trust_posix_offset
= &info
->posix_offset
.posix_offset
;
3613 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX
:
3614 if (!(policy
->access
& LSA_TRUSTED_SET_POSIX
)) {
3615 return NT_STATUS_ACCESS_DENIED
;
3617 nt_status
= info_ex_2_pdb_trusted_domain(&info
->info_ex
, td
);
3618 if (!NT_STATUS_IS_OK(nt_status
)) {
3622 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO
:
3623 if (!(policy
->access
& LSA_TRUSTED_SET_AUTH
)) {
3624 return NT_STATUS_ACCESS_DENIED
;
3626 nt_status
= auth_info_2_auth_blob(td
, &info
->auth_info
,
3627 &td
->trust_auth_incoming
,
3628 &td
->trust_auth_outgoing
);
3629 if (!NT_STATUS_IS_OK(nt_status
)) {
3633 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
:
3634 if (!(policy
->access
& (LSA_TRUSTED_SET_AUTH
| LSA_TRUSTED_SET_POSIX
))) {
3635 return NT_STATUS_ACCESS_DENIED
;
3637 td
->trust_posix_offset
= &info
->full_info
.posix_offset
.posix_offset
;
3638 nt_status
= info_ex_2_pdb_trusted_domain(&info
->full_info
.info_ex
,
3640 if (!NT_STATUS_IS_OK(nt_status
)) {
3643 nt_status
= auth_info_2_auth_blob(td
,
3644 &info
->full_info
.auth_info
,
3645 &td
->trust_auth_incoming
,
3646 &td
->trust_auth_outgoing
);
3647 if (!NT_STATUS_IS_OK(nt_status
)) {
3651 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL
:
3652 if (!(policy
->access
& LSA_TRUSTED_SET_AUTH
)) {
3653 return NT_STATUS_ACCESS_DENIED
;
3655 auth_info_int
= &info
->auth_info_internal
;
3657 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL
:
3658 if (!(policy
->access
& (LSA_TRUSTED_SET_AUTH
| LSA_TRUSTED_SET_POSIX
))) {
3659 return NT_STATUS_ACCESS_DENIED
;
3661 td
->trust_posix_offset
= &info
->full_info_internal
.posix_offset
.posix_offset
;
3662 nt_status
= info_ex_2_pdb_trusted_domain(&info
->full_info_internal
.info_ex
,
3664 if (!NT_STATUS_IS_OK(nt_status
)) {
3667 auth_info_int
= &info
->full_info_internal
.auth_info
;
3669 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES
:
3670 if (!(policy
->access
& LSA_TRUSTED_SET_POSIX
)) {
3671 return NT_STATUS_ACCESS_DENIED
;
3673 td
->supported_enc_type
= &info
->enc_types
.enc_types
;
3676 return NT_STATUS_INVALID_PARAMETER
;
3679 /* decode auth_info_int if set */
3680 if (auth_info_int
) {
3682 /* now decrypt blob */
3683 auth_blob
= data_blob_const(auth_info_int
->auth_blob
.data
,
3684 auth_info_int
->auth_blob
.size
);
3686 nt_status
= get_trustdom_auth_blob(p
, mem_ctx
,
3687 &auth_blob
, &auth_struct
);
3688 if (!NT_STATUS_IS_OK(nt_status
)) {
3692 memset(&auth_struct
, 0, sizeof(auth_struct
));
3695 /* TODO: verify only one object matches the dns/netbios/sid triplet and that
3696 * this is the one we already have */
3698 /* TODO: check if the trust direction is changed and we need to add or remove
3701 /* TODO: check if trust type shall be changed and return an error in this case
3703 nt_status
= pdb_get_trusted_domain_by_sid(p
->mem_ctx
, &policy
->sid
,
3705 if (!NT_STATUS_IS_OK(nt_status
)) {
3710 /* TODO: should we fetch previous values from the existing entry
3711 * and append them ? */
3712 if (auth_struct
.incoming
.count
) {
3713 nt_status
= get_trustauth_inout_blob(mem_ctx
,
3714 &auth_struct
.incoming
,
3715 &td
->trust_auth_incoming
);
3716 if (!NT_STATUS_IS_OK(nt_status
)) {
3720 ZERO_STRUCT(td
->trust_auth_incoming
);
3723 if (auth_struct
.outgoing
.count
) {
3724 nt_status
= get_trustauth_inout_blob(mem_ctx
,
3725 &auth_struct
.outgoing
,
3726 &td
->trust_auth_outgoing
);
3727 if (!NT_STATUS_IS_OK(nt_status
)) {
3731 ZERO_STRUCT(td
->trust_auth_outgoing
);
3734 nt_status
= pdb_set_trusted_domain(orig_td
->domain_name
, td
);
3735 if (!NT_STATUS_IS_OK(nt_status
)) {
3739 return NT_STATUS_OK
;
3742 NTSTATUS
_lsa_SetTrustedDomainInfo(struct pipes_struct
*p
,
3743 struct lsa_SetTrustedDomainInfo
*r
)
3746 struct policy_handle trustdom_handle
;
3747 struct lsa_OpenTrustedDomain o
;
3748 struct lsa_SetInformationTrustedDomain s
;
3751 o
.in
.handle
= r
->in
.handle
;
3752 o
.in
.sid
= r
->in
.dom_sid
;
3753 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3754 o
.out
.trustdom_handle
= &trustdom_handle
;
3756 status
= _lsa_OpenTrustedDomain(p
, &o
);
3757 if (!NT_STATUS_IS_OK(status
)) {
3761 s
.in
.trustdom_handle
= &trustdom_handle
;
3762 s
.in
.level
= r
->in
.level
;
3763 s
.in
.info
= r
->in
.info
;
3765 status
= _lsa_SetInformationTrustedDomain(p
, &s
);
3766 if (!NT_STATUS_IS_OK(status
)) {
3770 c
.in
.handle
= &trustdom_handle
;
3771 c
.out
.handle
= &trustdom_handle
;
3773 return _lsa_Close(p
, &c
);
3776 NTSTATUS
_lsa_SetTrustedDomainInfoByName(struct pipes_struct
*p
,
3777 struct lsa_SetTrustedDomainInfoByName
*r
)
3780 struct policy_handle trustdom_handle
;
3781 struct lsa_OpenTrustedDomainByName o
;
3782 struct lsa_SetInformationTrustedDomain s
;
3785 o
.in
.handle
= r
->in
.handle
;
3786 o
.in
.name
.string
= r
->in
.trusted_domain
->string
;
3787 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3788 o
.out
.trustdom_handle
= &trustdom_handle
;
3790 status
= _lsa_OpenTrustedDomainByName(p
, &o
);
3791 if (!NT_STATUS_IS_OK(status
)) {
3792 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_DOMAIN
)) {
3793 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3798 s
.in
.trustdom_handle
= &trustdom_handle
;
3799 s
.in
.level
= r
->in
.level
;
3800 s
.in
.info
= r
->in
.info
;
3802 status
= _lsa_SetInformationTrustedDomain(p
, &s
);
3803 if (!NT_STATUS_IS_OK(status
)) {
3807 c
.in
.handle
= &trustdom_handle
;
3808 c
.out
.handle
= &trustdom_handle
;
3810 return _lsa_Close(p
, &c
);
3813 NTSTATUS
_lsa_SetInformationTrustedDomain(struct pipes_struct
*p
,
3814 struct lsa_SetInformationTrustedDomain
*r
)
3816 struct lsa_info
*policy
;
3818 if (!find_policy_by_hnd(p
, r
->in
.trustdom_handle
, (void **)(void *)&policy
)) {
3819 return NT_STATUS_INVALID_HANDLE
;
3822 if (policy
->type
!= LSA_HANDLE_TRUST_TYPE
) {
3823 return NT_STATUS_INVALID_HANDLE
;
3826 return setInfoTrustedDomain_base(p
, p
->mem_ctx
, policy
,
3827 r
->in
.level
, r
->in
.info
);
3832 * From here on the server routines are just dummy ones to make smbd link with
3833 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3834 * pulling the server stubs across one by one.
3837 NTSTATUS
_lsa_SetSecObj(struct pipes_struct
*p
, struct lsa_SetSecObj
*r
)
3839 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3840 return NT_STATUS_NOT_IMPLEMENTED
;
3843 NTSTATUS
_lsa_ChangePassword(struct pipes_struct
*p
,
3844 struct lsa_ChangePassword
*r
)
3846 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3847 return NT_STATUS_NOT_IMPLEMENTED
;
3850 NTSTATUS
_lsa_SetInfoPolicy(struct pipes_struct
*p
, struct lsa_SetInfoPolicy
*r
)
3852 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3853 return NT_STATUS_NOT_IMPLEMENTED
;
3856 NTSTATUS
_lsa_ClearAuditLog(struct pipes_struct
*p
, struct lsa_ClearAuditLog
*r
)
3858 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3859 return NT_STATUS_NOT_IMPLEMENTED
;
3862 NTSTATUS
_lsa_GetQuotasForAccount(struct pipes_struct
*p
,
3863 struct lsa_GetQuotasForAccount
*r
)
3865 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3866 return NT_STATUS_NOT_IMPLEMENTED
;
3869 NTSTATUS
_lsa_SetQuotasForAccount(struct pipes_struct
*p
,
3870 struct lsa_SetQuotasForAccount
*r
)
3872 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3873 return NT_STATUS_NOT_IMPLEMENTED
;
3876 NTSTATUS
_lsa_StorePrivateData(struct pipes_struct
*p
,
3877 struct lsa_StorePrivateData
*r
)
3879 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3880 return NT_STATUS_NOT_IMPLEMENTED
;
3883 NTSTATUS
_lsa_RetrievePrivateData(struct pipes_struct
*p
,
3884 struct lsa_RetrievePrivateData
*r
)
3886 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3887 return NT_STATUS_NOT_IMPLEMENTED
;
3890 NTSTATUS
_lsa_SetInfoPolicy2(struct pipes_struct
*p
,
3891 struct lsa_SetInfoPolicy2
*r
)
3893 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3894 return NT_STATUS_NOT_IMPLEMENTED
;
3897 NTSTATUS
_lsa_EnumTrustedDomainsEx(struct pipes_struct
*p
,
3898 struct lsa_EnumTrustedDomainsEx
*r
)
3900 struct lsa_info
*info
;
3902 struct pdb_trusted_domain
**domains
;
3903 struct lsa_TrustDomainInfoInfoEx
*entries
;
3907 /* bail out early if pdb backend is not capable of ex trusted domains,
3908 * if we dont do that, the client might not call
3909 * _lsa_EnumTrustedDomains() afterwards - gd */
3911 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX
)) {
3912 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3913 return NT_STATUS_NOT_IMPLEMENTED
;
3916 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3917 return NT_STATUS_INVALID_HANDLE
;
3919 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3920 return NT_STATUS_INVALID_HANDLE
;
3923 /* check if the user has enough rights */
3924 if (!(info
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
3925 return NT_STATUS_ACCESS_DENIED
;
3928 nt_status
= pdb_enum_trusted_domains(p
->mem_ctx
, &count
, &domains
);
3931 if (!NT_STATUS_IS_OK(nt_status
)) {
3935 entries
= talloc_zero_array(p
->mem_ctx
, struct lsa_TrustDomainInfoInfoEx
,
3938 return NT_STATUS_NO_MEMORY
;
3941 for (i
=0; i
<count
; i
++) {
3942 init_lsa_StringLarge(&entries
[i
].domain_name
,
3943 domains
[i
]->domain_name
);
3944 init_lsa_StringLarge(&entries
[i
].netbios_name
,
3945 domains
[i
]->netbios_name
);
3946 entries
[i
].sid
= &domains
[i
]->security_identifier
;
3947 entries
[i
].trust_direction
= domains
[i
]->trust_direction
;
3948 entries
[i
].trust_type
= domains
[i
]->trust_type
;
3949 entries
[i
].trust_attributes
= domains
[i
]->trust_attributes
;
3952 if (*r
->in
.resume_handle
>= count
) {
3953 *r
->out
.resume_handle
= -1;
3954 TALLOC_FREE(entries
);
3955 return NT_STATUS_NO_MORE_ENTRIES
;
3958 /* return the rest, limit by max_size. Note that we
3959 use the w2k3 element size value of 60 */
3960 r
->out
.domains
->count
= count
- *r
->in
.resume_handle
;
3961 r
->out
.domains
->count
= MIN(r
->out
.domains
->count
,
3962 (r
->in
.max_size
/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER
));
3964 r
->out
.domains
->domains
= entries
+ *r
->in
.resume_handle
;
3966 if (r
->out
.domains
->count
< count
- *r
->in
.resume_handle
) {
3967 *r
->out
.resume_handle
= *r
->in
.resume_handle
+ r
->out
.domains
->count
;
3968 return STATUS_MORE_ENTRIES
;
3971 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3972 * always be larger than the previous input resume handle, in
3973 * particular when hitting the last query it is vital to set the
3974 * resume handle correctly to avoid infinite client loops, as
3975 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3976 * status is NT_STATUS_OK - gd */
3978 *r
->out
.resume_handle
= (uint32_t)-1;
3980 return NT_STATUS_OK
;
3983 NTSTATUS
_lsa_QueryDomainInformationPolicy(struct pipes_struct
*p
,
3984 struct lsa_QueryDomainInformationPolicy
*r
)
3986 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3987 return NT_STATUS_NOT_IMPLEMENTED
;
3990 NTSTATUS
_lsa_SetDomainInformationPolicy(struct pipes_struct
*p
,
3991 struct lsa_SetDomainInformationPolicy
*r
)
3993 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
3994 return NT_STATUS_NOT_IMPLEMENTED
;
3997 NTSTATUS
_lsa_TestCall(struct pipes_struct
*p
, struct lsa_TestCall
*r
)
3999 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4000 return NT_STATUS_NOT_IMPLEMENTED
;
4003 NTSTATUS
_lsa_CREDRWRITE(struct pipes_struct
*p
, struct lsa_CREDRWRITE
*r
)
4005 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4006 return NT_STATUS_NOT_IMPLEMENTED
;
4009 NTSTATUS
_lsa_CREDRREAD(struct pipes_struct
*p
, struct lsa_CREDRREAD
*r
)
4011 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4012 return NT_STATUS_NOT_IMPLEMENTED
;
4015 NTSTATUS
_lsa_CREDRENUMERATE(struct pipes_struct
*p
, struct lsa_CREDRENUMERATE
*r
)
4017 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4018 return NT_STATUS_NOT_IMPLEMENTED
;
4021 NTSTATUS
_lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct
*p
,
4022 struct lsa_CREDRWRITEDOMAINCREDENTIALS
*r
)
4024 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4025 return NT_STATUS_NOT_IMPLEMENTED
;
4028 NTSTATUS
_lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct
*p
,
4029 struct lsa_CREDRREADDOMAINCREDENTIALS
*r
)
4031 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4032 return NT_STATUS_NOT_IMPLEMENTED
;
4035 NTSTATUS
_lsa_CREDRDELETE(struct pipes_struct
*p
, struct lsa_CREDRDELETE
*r
)
4037 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4038 return NT_STATUS_NOT_IMPLEMENTED
;
4041 NTSTATUS
_lsa_CREDRGETTARGETINFO(struct pipes_struct
*p
,
4042 struct lsa_CREDRGETTARGETINFO
*r
)
4044 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4045 return NT_STATUS_NOT_IMPLEMENTED
;
4048 NTSTATUS
_lsa_CREDRPROFILELOADED(struct pipes_struct
*p
,
4049 struct lsa_CREDRPROFILELOADED
*r
)
4051 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4052 return NT_STATUS_NOT_IMPLEMENTED
;
4055 NTSTATUS
_lsa_CREDRGETSESSIONTYPES(struct pipes_struct
*p
,
4056 struct lsa_CREDRGETSESSIONTYPES
*r
)
4058 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4059 return NT_STATUS_NOT_IMPLEMENTED
;
4062 NTSTATUS
_lsa_LSARREGISTERAUDITEVENT(struct pipes_struct
*p
,
4063 struct lsa_LSARREGISTERAUDITEVENT
*r
)
4065 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4066 return NT_STATUS_NOT_IMPLEMENTED
;
4069 NTSTATUS
_lsa_LSARGENAUDITEVENT(struct pipes_struct
*p
,
4070 struct lsa_LSARGENAUDITEVENT
*r
)
4072 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4073 return NT_STATUS_NOT_IMPLEMENTED
;
4076 NTSTATUS
_lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct
*p
,
4077 struct lsa_LSARUNREGISTERAUDITEVENT
*r
)
4079 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4080 return NT_STATUS_NOT_IMPLEMENTED
;
4083 NTSTATUS
_lsa_lsaRQueryForestTrustInformation(struct pipes_struct
*p
,
4084 struct lsa_lsaRQueryForestTrustInformation
*r
)
4086 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4087 return NT_STATUS_NOT_IMPLEMENTED
;
4090 #define DNS_CMP_MATCH 0
4091 #define DNS_CMP_FIRST_IS_CHILD 1
4092 #define DNS_CMP_SECOND_IS_CHILD 2
4093 #define DNS_CMP_NO_MATCH 3
4095 /* this function assumes names are well formed DNS names.
4096 * it doesn't validate them */
4097 static int dns_cmp(const char *s1
, size_t l1
,
4098 const char *s2
, size_t l2
)
4100 const char *p1
, *p2
;
4105 if (strcasecmp_m(s1
, s2
) == 0) {
4106 return DNS_CMP_MATCH
;
4108 return DNS_CMP_NO_MATCH
;
4116 cret
= DNS_CMP_FIRST_IS_CHILD
;
4122 cret
= DNS_CMP_SECOND_IS_CHILD
;
4125 if (p1
[t1
- t2
- 1] != '.') {
4126 return DNS_CMP_NO_MATCH
;
4129 if (strcasecmp_m(&p1
[t1
- t2
], p2
) == 0) {
4133 return DNS_CMP_NO_MATCH
;
4136 static NTSTATUS
make_ft_info(TALLOC_CTX
*mem_ctx
,
4137 struct lsa_ForestTrustInformation
*lfti
,
4138 struct ForestTrustInfo
*fti
)
4140 struct lsa_ForestTrustRecord
*lrec
;
4141 struct ForestTrustInfoRecord
*rec
;
4142 struct lsa_StringLarge
*tln
;
4143 struct lsa_ForestTrustDomainInfo
*info
;
4147 fti
->count
= lfti
->count
;
4148 fti
->records
= talloc_array(mem_ctx
,
4149 struct ForestTrustInfoRecordArmor
,
4151 if (!fti
->records
) {
4152 return NT_STATUS_NO_MEMORY
;
4154 for (i
= 0; i
< fti
->count
; i
++) {
4155 lrec
= lfti
->entries
[i
];
4156 rec
= &fti
->records
[i
].record
;
4158 rec
->flags
= lrec
->flags
;
4159 rec
->timestamp
= lrec
->time
;
4160 rec
->type
= lrec
->type
;
4162 switch (lrec
->type
) {
4163 case LSA_FOREST_TRUST_TOP_LEVEL_NAME
:
4164 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX
:
4165 tln
= &lrec
->forest_trust_data
.top_level_name
;
4166 rec
->data
.name
.string
=
4167 talloc_strdup(mem_ctx
, tln
->string
);
4168 if (!rec
->data
.name
.string
) {
4169 return NT_STATUS_NO_MEMORY
;
4171 rec
->data
.name
.size
= strlen(rec
->data
.name
.string
);
4173 case LSA_FOREST_TRUST_DOMAIN_INFO
:
4174 info
= &lrec
->forest_trust_data
.domain_info
;
4175 rec
->data
.info
.sid
= *info
->domain_sid
;
4176 rec
->data
.info
.dns_name
.string
=
4177 talloc_strdup(mem_ctx
,
4178 info
->dns_domain_name
.string
);
4179 if (!rec
->data
.info
.dns_name
.string
) {
4180 return NT_STATUS_NO_MEMORY
;
4182 rec
->data
.info
.dns_name
.size
=
4183 strlen(rec
->data
.info
.dns_name
.string
);
4184 rec
->data
.info
.netbios_name
.string
=
4185 talloc_strdup(mem_ctx
,
4186 info
->netbios_domain_name
.string
);
4187 if (!rec
->data
.info
.netbios_name
.string
) {
4188 return NT_STATUS_NO_MEMORY
;
4190 rec
->data
.info
.netbios_name
.size
=
4191 strlen(rec
->data
.info
.netbios_name
.string
);
4194 return NT_STATUS_INVALID_DOMAIN_STATE
;
4198 return NT_STATUS_OK
;
4201 static NTSTATUS
add_collision(struct lsa_ForestTrustCollisionInfo
*c_info
,
4202 uint32_t index
, uint32_t collision_type
,
4203 uint32_t conflict_type
, const char *tdo_name
);
4205 static NTSTATUS
check_ft_info(TALLOC_CTX
*mem_ctx
,
4206 const char *tdo_name
,
4207 struct ForestTrustInfo
*tdo_fti
,
4208 struct ForestTrustInfo
*new_fti
,
4209 struct lsa_ForestTrustCollisionInfo
*c_info
)
4211 struct ForestTrustInfoRecord
*nrec
;
4212 struct ForestTrustInfoRecord
*trec
;
4213 const char *dns_name
;
4214 const char *nb_name
= NULL
;
4215 struct dom_sid
*sid
= NULL
;
4216 const char *tname
= NULL
;
4219 uint32_t new_fti_idx
;
4221 /* use always TDO type, until we understand when Xref can be used */
4222 uint32_t collision_type
= LSA_FOREST_TRUST_COLLISION_TDO
;
4227 bool ex_rule
= false;
4230 for (new_fti_idx
= 0; new_fti_idx
< new_fti
->count
; new_fti_idx
++) {
4232 nrec
= &new_fti
->records
[new_fti_idx
].record
;
4234 tln_conflict
= false;
4235 sid_conflict
= false;
4236 nb_conflict
= false;
4239 switch (nrec
->type
) {
4240 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX
:
4241 /* exclusions do not conflict by definition */
4244 case FOREST_TRUST_TOP_LEVEL_NAME
:
4245 dns_name
= nrec
->data
.name
.string
;
4246 dns_len
= nrec
->data
.name
.size
;
4249 case LSA_FOREST_TRUST_DOMAIN_INFO
:
4250 dns_name
= nrec
->data
.info
.dns_name
.string
;
4251 dns_len
= nrec
->data
.info
.dns_name
.size
;
4252 nb_name
= nrec
->data
.info
.netbios_name
.string
;
4253 sid
= &nrec
->data
.info
.sid
;
4257 if (!dns_name
) continue;
4259 /* check if this is already taken and not excluded */
4260 for (i
= 0; i
< tdo_fti
->count
; i
++) {
4261 trec
= &tdo_fti
->records
[i
].record
;
4263 switch (trec
->type
) {
4264 case FOREST_TRUST_TOP_LEVEL_NAME
:
4266 tname
= trec
->data
.name
.string
;
4267 tlen
= trec
->data
.name
.size
;
4269 case FOREST_TRUST_TOP_LEVEL_NAME_EX
:
4271 tname
= trec
->data
.name
.string
;
4272 tlen
= trec
->data
.name
.size
;
4274 case FOREST_TRUST_DOMAIN_INFO
:
4276 tname
= trec
->data
.info
.dns_name
.string
;
4277 tlen
= trec
->data
.info
.dns_name
.size
;
4280 return NT_STATUS_INVALID_PARAMETER
;
4282 ret
= dns_cmp(dns_name
, dns_len
, tname
, tlen
);
4285 /* if it matches exclusion,
4286 * it doesn't conflict */
4292 case DNS_CMP_FIRST_IS_CHILD
:
4293 case DNS_CMP_SECOND_IS_CHILD
:
4294 tln_conflict
= true;
4300 /* explicit exclusion, no dns name conflict here */
4302 tln_conflict
= false;
4305 if (trec
->type
!= FOREST_TRUST_DOMAIN_INFO
) {
4309 /* also test for domain info */
4310 if (!(trec
->flags
& LSA_SID_DISABLED_ADMIN
) &&
4311 dom_sid_compare(&trec
->data
.info
.sid
, sid
) == 0) {
4312 sid_conflict
= true;
4314 if (!(trec
->flags
& LSA_NB_DISABLED_ADMIN
) &&
4315 strcasecmp_m(trec
->data
.info
.netbios_name
.string
,
4322 (void)add_collision(c_info
, new_fti_idx
,
4324 LSA_TLN_DISABLED_CONFLICT
,
4328 (void)add_collision(c_info
, new_fti_idx
,
4330 LSA_SID_DISABLED_CONFLICT
,
4334 (void)add_collision(c_info
, new_fti_idx
,
4336 LSA_NB_DISABLED_CONFLICT
,
4341 return NT_STATUS_OK
;
4344 static NTSTATUS
add_collision(struct lsa_ForestTrustCollisionInfo
*c_info
,
4345 uint32_t idx
, uint32_t collision_type
,
4346 uint32_t conflict_type
, const char *tdo_name
)
4348 struct lsa_ForestTrustCollisionRecord
**es
;
4349 uint32_t i
= c_info
->count
;
4351 es
= talloc_realloc(c_info
, c_info
->entries
,
4352 struct lsa_ForestTrustCollisionRecord
*, i
+ 1);
4354 return NT_STATUS_NO_MEMORY
;
4356 c_info
->entries
= es
;
4357 c_info
->count
= i
+ 1;
4359 es
[i
] = talloc(es
, struct lsa_ForestTrustCollisionRecord
);
4361 return NT_STATUS_NO_MEMORY
;
4365 es
[i
]->type
= collision_type
;
4366 es
[i
]->flags
= conflict_type
;
4367 es
[i
]->name
.string
= talloc_strdup(es
[i
], tdo_name
);
4368 if (!es
[i
]->name
.string
) {
4369 return NT_STATUS_NO_MEMORY
;
4371 es
[i
]->name
.size
= strlen(es
[i
]->name
.string
);
4373 return NT_STATUS_OK
;
4376 static NTSTATUS
get_ft_info(TALLOC_CTX
*mem_ctx
,
4377 struct pdb_trusted_domain
*td
,
4378 struct ForestTrustInfo
*info
)
4380 enum ndr_err_code ndr_err
;
4382 if (td
->trust_forest_trust_info
.length
== 0 ||
4383 td
->trust_forest_trust_info
.data
== NULL
) {
4384 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4386 ndr_err
= ndr_pull_struct_blob_all(&td
->trust_forest_trust_info
, mem_ctx
,
4388 (ndr_pull_flags_fn_t
)ndr_pull_ForestTrustInfo
);
4389 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
4390 return NT_STATUS_INVALID_DOMAIN_STATE
;
4393 return NT_STATUS_OK
;
4396 static NTSTATUS
own_ft_info(struct pdb_domain_info
*dom_info
,
4397 struct ForestTrustInfo
*fti
)
4399 struct ForestTrustDataDomainInfo
*info
;
4400 struct ForestTrustInfoRecord
*rec
;
4404 fti
->records
= talloc_array(fti
,
4405 struct ForestTrustInfoRecordArmor
, 2);
4406 if (!fti
->records
) {
4407 return NT_STATUS_NO_MEMORY
;
4411 rec
= &fti
->records
[0].record
;
4415 rec
->type
= LSA_FOREST_TRUST_TOP_LEVEL_NAME
;
4417 rec
->data
.name
.string
= talloc_strdup(fti
, dom_info
->dns_forest
);
4418 if (!rec
->data
.name
.string
) {
4419 return NT_STATUS_NO_MEMORY
;
4421 rec
->data
.name
.size
= strlen(rec
->data
.name
.string
);
4424 rec
= &fti
->records
[1].record
;
4428 rec
->type
= LSA_FOREST_TRUST_DOMAIN_INFO
;
4430 info
= &rec
->data
.info
;
4432 info
->sid
= dom_info
->sid
;
4433 info
->dns_name
.string
= talloc_strdup(fti
, dom_info
->dns_domain
);
4434 if (!info
->dns_name
.string
) {
4435 return NT_STATUS_NO_MEMORY
;
4437 info
->dns_name
.size
= strlen(info
->dns_name
.string
);
4438 info
->netbios_name
.string
= talloc_strdup(fti
, dom_info
->name
);
4439 if (!info
->netbios_name
.string
) {
4440 return NT_STATUS_NO_MEMORY
;
4442 info
->netbios_name
.size
= strlen(info
->netbios_name
.string
);
4444 return NT_STATUS_OK
;
4447 NTSTATUS
_lsa_lsaRSetForestTrustInformation(struct pipes_struct
*p
,
4448 struct lsa_lsaRSetForestTrustInformation
*r
)
4453 struct lsa_info
*handle
;
4454 uint32_t num_domains
;
4455 struct pdb_trusted_domain
**domains
;
4456 struct ForestTrustInfo
*nfti
;
4457 struct ForestTrustInfo
*fti
;
4458 struct lsa_ForestTrustCollisionInfo
*c_info
;
4459 struct pdb_domain_info
*dom_info
;
4460 enum ndr_err_code ndr_err
;
4463 return NT_STATUS_NOT_SUPPORTED
;
4466 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
4467 return NT_STATUS_INVALID_HANDLE
;
4470 if (handle
->type
!= LSA_HANDLE_TRUST_TYPE
) {
4471 return NT_STATUS_INVALID_HANDLE
;
4474 if (!(handle
->access
& LSA_TRUSTED_SET_AUTH
)) {
4475 return NT_STATUS_ACCESS_DENIED
;
4478 status
= pdb_enum_trusted_domains(p
->mem_ctx
, &num_domains
, &domains
);
4479 if (!NT_STATUS_IS_OK(status
)) {
4482 if (num_domains
== 0) {
4483 return NT_STATUS_NO_SUCH_DOMAIN
;
4486 for (i
= 0; i
< num_domains
; i
++) {
4487 if (domains
[i
]->domain_name
== NULL
) {
4488 return NT_STATUS_INVALID_DOMAIN_STATE
;
4490 if (strcasecmp_m(domains
[i
]->domain_name
,
4491 r
->in
.trusted_domain_name
->string
) == 0) {
4495 if (i
>= num_domains
) {
4496 return NT_STATUS_NO_SUCH_DOMAIN
;
4499 if (!(domains
[i
]->trust_attributes
&
4500 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE
)) {
4501 return NT_STATUS_INVALID_PARAMETER
;
4504 if (r
->in
.highest_record_type
>= LSA_FOREST_TRUST_RECORD_TYPE_LAST
) {
4505 return NT_STATUS_INVALID_PARAMETER
;
4508 /* The following section until COPY_END is a copy from
4509 * source4/rpmc_server/lsa/scesrc_lsa.c */
4510 nfti
= talloc(p
->mem_ctx
, struct ForestTrustInfo
);
4512 return NT_STATUS_NO_MEMORY
;
4515 status
= make_ft_info(nfti
, r
->in
.forest_trust_info
, nfti
);
4516 if (!NT_STATUS_IS_OK(status
)) {
4520 c_info
= talloc_zero(r
->out
.collision_info
,
4521 struct lsa_ForestTrustCollisionInfo
);
4523 return NT_STATUS_NO_MEMORY
;
4526 /* first check own info, then other domains */
4527 fti
= talloc(p
->mem_ctx
, struct ForestTrustInfo
);
4529 return NT_STATUS_NO_MEMORY
;
4532 dom_info
= pdb_get_domain_info(p
->mem_ctx
);
4534 status
= own_ft_info(dom_info
, fti
);
4535 if (!NT_STATUS_IS_OK(status
)) {
4539 status
= check_ft_info(c_info
, dom_info
->dns_domain
, fti
, nfti
, c_info
);
4540 if (!NT_STATUS_IS_OK(status
)) {
4544 for (j
= 0; j
< num_domains
; j
++) {
4545 fti
= talloc(p
->mem_ctx
, struct ForestTrustInfo
);
4547 return NT_STATUS_NO_MEMORY
;
4550 status
= get_ft_info(p
->mem_ctx
, domains
[j
], fti
);
4551 if (!NT_STATUS_IS_OK(status
)) {
4552 if (NT_STATUS_EQUAL(status
,
4553 NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4559 if (domains
[j
]->domain_name
== NULL
) {
4560 return NT_STATUS_INVALID_DOMAIN_STATE
;
4563 status
= check_ft_info(c_info
, domains
[j
]->domain_name
,
4565 if (!NT_STATUS_IS_OK(status
)) {
4570 if (c_info
->count
!= 0) {
4571 *r
->out
.collision_info
= c_info
;
4574 if (r
->in
.check_only
!= 0) {
4575 return NT_STATUS_OK
;
4580 ndr_err
= ndr_push_struct_blob(&domains
[i
]->trust_forest_trust_info
,
4582 (ndr_push_flags_fn_t
)ndr_push_ForestTrustInfo
);
4583 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
4584 return NT_STATUS_INVALID_PARAMETER
;
4587 status
= pdb_set_trusted_domain(domains
[i
]->domain_name
, domains
[i
]);
4588 if (!NT_STATUS_IS_OK(status
)) {
4592 return NT_STATUS_OK
;
4595 NTSTATUS
_lsa_CREDRRENAME(struct pipes_struct
*p
,
4596 struct lsa_CREDRRENAME
*r
)
4598 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4599 return NT_STATUS_NOT_IMPLEMENTED
;
4602 NTSTATUS
_lsa_LSAROPENPOLICYSCE(struct pipes_struct
*p
,
4603 struct lsa_LSAROPENPOLICYSCE
*r
)
4605 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4606 return NT_STATUS_NOT_IMPLEMENTED
;
4609 NTSTATUS
_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct
*p
,
4610 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE
*r
)
4612 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4613 return NT_STATUS_NOT_IMPLEMENTED
;
4616 NTSTATUS
_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct
*p
,
4617 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
*r
)
4619 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4620 return NT_STATUS_NOT_IMPLEMENTED
;
4623 NTSTATUS
_lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct
*p
,
4624 struct lsa_LSARADTREPORTSECURITYEVENT
*r
)
4626 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
4627 return NT_STATUS_NOT_IMPLEMENTED
;