2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Jeremy Allison 2001, 2006.
8 * Copyright (C) Rafal Szczesniak 2002,
9 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
10 * Copyright (C) Simo Sorce 2003.
11 * Copyright (C) Gerald (Jerry) Carter 2005.
12 * Copyright (C) Volker Lendecke 2005.
13 * Copyright (C) Guenther Deschner 2008.
14 * Copyright (C) Andrew Bartlett 2010.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
30 /* This is the implementation of the lsa server code. */
34 #include "../librpc/gen_ndr/srv_lsa.h"
36 #include "../librpc/gen_ndr/netlogon.h"
37 #include "rpc_client/init_lsa.h"
38 #include "../libcli/security/security.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../librpc/gen_ndr/drsblobs.h"
41 #include "../librpc/gen_ndr/ndr_drsblobs.h"
42 #include "../lib/crypto/arcfour.h"
43 #include "../libcli/security/dom_sid.h"
44 #include "../librpc/gen_ndr/ndr_security.h"
47 #include "lib/privileges.h"
48 #include "rpc_server/srv_access_check.h"
51 #define DBGC_CLASS DBGC_RPC_SRV
53 #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
55 enum lsa_handle_type
{
56 LSA_HANDLE_POLICY_TYPE
= 1,
57 LSA_HANDLE_ACCOUNT_TYPE
= 2,
58 LSA_HANDLE_TRUST_TYPE
= 3,
59 LSA_HANDLE_SECRET_TYPE
= 4};
65 enum lsa_handle_type type
;
66 struct security_descriptor
*sd
;
69 const struct generic_mapping lsa_account_mapping
= {
73 LSA_ACCOUNT_ALL_ACCESS
76 const struct generic_mapping lsa_policy_mapping
= {
83 const struct generic_mapping lsa_secret_mapping
= {
90 const struct generic_mapping lsa_trusted_domain_mapping
= {
91 LSA_TRUSTED_DOMAIN_READ
,
92 LSA_TRUSTED_DOMAIN_WRITE
,
93 LSA_TRUSTED_DOMAIN_EXECUTE
,
94 LSA_TRUSTED_DOMAIN_ALL_ACCESS
97 /***************************************************************************
98 init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index.
99 ***************************************************************************/
101 static int init_lsa_ref_domain_list(TALLOC_CTX
*mem_ctx
,
102 struct lsa_RefDomainList
*ref
,
103 const char *dom_name
,
104 struct dom_sid
*dom_sid
)
108 if (dom_name
!= NULL
) {
109 for (num
= 0; num
< ref
->count
; num
++) {
110 if (dom_sid_equal(dom_sid
, ref
->domains
[num
].sid
)) {
118 if (num
>= LSA_REF_DOMAIN_LIST_MULTIPLIER
) {
119 /* index not found, already at maximum domain limit */
123 ref
->count
= num
+ 1;
124 ref
->max_size
= LSA_REF_DOMAIN_LIST_MULTIPLIER
;
126 ref
->domains
= talloc_realloc(mem_ctx
, ref
->domains
,
127 struct lsa_DomainInfo
, ref
->count
);
132 ZERO_STRUCT(ref
->domains
[num
]);
134 init_lsa_StringLarge(&ref
->domains
[num
].name
, dom_name
);
135 ref
->domains
[num
].sid
= dom_sid_dup(mem_ctx
, dom_sid
);
136 if (!ref
->domains
[num
].sid
) {
144 /***************************************************************************
145 initialize a lsa_DomainInfo structure.
146 ***************************************************************************/
148 static void init_dom_query_3(struct lsa_DomainInfo
*r
,
152 init_lsa_StringLarge(&r
->name
, name
);
156 /***************************************************************************
157 initialize a lsa_DomainInfo structure.
158 ***************************************************************************/
160 static void init_dom_query_5(struct lsa_DomainInfo
*r
,
164 init_lsa_StringLarge(&r
->name
, name
);
168 /***************************************************************************
169 lookup_lsa_rids. Must be called as root for lookup_name to work.
170 ***************************************************************************/
172 static NTSTATUS
lookup_lsa_rids(TALLOC_CTX
*mem_ctx
,
173 struct lsa_RefDomainList
*ref
,
174 struct lsa_TranslatedSid
*prid
,
175 uint32_t num_entries
,
176 struct lsa_String
*name
,
178 uint32_t *pmapped_count
)
180 uint32 mapped_count
, i
;
182 SMB_ASSERT(num_entries
<= MAX_LOOKUP_SIDS
);
187 for (i
= 0; i
< num_entries
; i
++) {
191 const char *full_name
;
193 enum lsa_SidType type
;
195 /* Split name into domain and user component */
197 /* follow w2k8 behavior and return the builtin domain when no
198 * input has been passed in */
200 if (name
[i
].string
) {
201 full_name
= name
[i
].string
;
203 full_name
= "BUILTIN";
206 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name
));
208 if (!lookup_name(mem_ctx
, full_name
, flags
, &domain
, NULL
,
210 type
= SID_NAME_UNKNOWN
;
215 case SID_NAME_DOM_GRP
:
216 case SID_NAME_DOMAIN
:
218 case SID_NAME_WKN_GRP
:
219 DEBUG(5, ("init_lsa_rids: %s found\n", full_name
));
220 /* Leave these unchanged */
223 /* Don't hand out anything but the list above */
224 DEBUG(5, ("init_lsa_rids: %s not found\n", full_name
));
225 type
= SID_NAME_UNKNOWN
;
232 if (type
!= SID_NAME_UNKNOWN
) {
233 if (type
== SID_NAME_DOMAIN
) {
236 sid_split_rid(&sid
, &rid
);
238 dom_idx
= init_lsa_ref_domain_list(mem_ctx
, ref
, domain
, &sid
);
242 prid
[i
].sid_type
= type
;
244 prid
[i
].sid_index
= dom_idx
;
247 *pmapped_count
= mapped_count
;
251 /***************************************************************************
252 lookup_lsa_sids. Must be called as root for lookup_name to work.
253 ***************************************************************************/
255 static NTSTATUS
lookup_lsa_sids(TALLOC_CTX
*mem_ctx
,
256 struct lsa_RefDomainList
*ref
,
257 struct lsa_TranslatedSid3
*trans_sids
,
258 uint32_t num_entries
,
259 struct lsa_String
*name
,
261 uint32
*pmapped_count
)
263 uint32 mapped_count
, i
;
265 SMB_ASSERT(num_entries
<= MAX_LOOKUP_SIDS
);
270 for (i
= 0; i
< num_entries
; i
++) {
274 const char *full_name
;
276 enum lsa_SidType type
;
280 /* Split name into domain and user component */
282 full_name
= name
[i
].string
;
283 if (full_name
== NULL
) {
284 return NT_STATUS_NO_MEMORY
;
287 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name
));
289 if (!lookup_name(mem_ctx
, full_name
, flags
, &domain
, NULL
,
291 type
= SID_NAME_UNKNOWN
;
296 case SID_NAME_DOM_GRP
:
297 case SID_NAME_DOMAIN
:
299 case SID_NAME_WKN_GRP
:
300 DEBUG(5, ("init_lsa_sids: %s found\n", full_name
));
301 /* Leave these unchanged */
304 /* Don't hand out anything but the list above */
305 DEBUG(5, ("init_lsa_sids: %s not found\n", full_name
));
306 type
= SID_NAME_UNKNOWN
;
313 if (type
!= SID_NAME_UNKNOWN
) {
314 struct dom_sid domain_sid
;
315 sid_copy(&domain_sid
, &sid
);
316 sid_split_rid(&domain_sid
, &rid
);
317 dom_idx
= init_lsa_ref_domain_list(mem_ctx
, ref
, domain
, &domain_sid
);
321 /* Initialize the lsa_TranslatedSid3 return. */
322 trans_sids
[i
].sid_type
= type
;
323 trans_sids
[i
].sid
= dom_sid_dup(mem_ctx
, &sid
);
324 trans_sids
[i
].sid_index
= dom_idx
;
327 *pmapped_count
= mapped_count
;
331 static NTSTATUS
make_lsa_object_sd(TALLOC_CTX
*mem_ctx
, struct security_descriptor
**sd
, size_t *sd_size
,
332 const struct generic_mapping
*map
,
333 struct dom_sid
*sid
, uint32_t sid_access
)
335 struct dom_sid adm_sid
;
336 struct security_ace ace
[5];
339 struct security_acl
*psa
= NULL
;
341 /* READ|EXECUTE access for Everyone */
343 init_sec_ace(&ace
[i
++], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
344 map
->generic_execute
| map
->generic_read
, 0);
346 /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
348 init_sec_ace(&ace
[i
++], &global_sid_Builtin_Administrators
,
349 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
350 init_sec_ace(&ace
[i
++], &global_sid_Builtin_Account_Operators
,
351 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
353 /* Add Full Access for Domain Admins */
354 sid_compose(&adm_sid
, get_global_sam_sid(), DOMAIN_RID_ADMINS
);
355 init_sec_ace(&ace
[i
++], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
356 map
->generic_all
, 0);
358 /* If we have a sid, give it some special access */
361 init_sec_ace(&ace
[i
++], sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
365 if((psa
= make_sec_acl(mem_ctx
, NT4_ACL_REVISION
, i
, ace
)) == NULL
)
366 return NT_STATUS_NO_MEMORY
;
368 if((*sd
= make_sec_desc(mem_ctx
, SECURITY_DESCRIPTOR_REVISION_1
,
369 SEC_DESC_SELF_RELATIVE
, &adm_sid
, NULL
, NULL
,
370 psa
, sd_size
)) == NULL
)
371 return NT_STATUS_NO_MEMORY
;
376 /***************************************************************************
377 ***************************************************************************/
379 static NTSTATUS
create_lsa_policy_handle(TALLOC_CTX
*mem_ctx
,
380 struct pipes_struct
*p
,
381 enum lsa_handle_type type
,
382 uint32_t acc_granted
,
385 const struct security_descriptor
*sd
,
386 struct policy_handle
*handle
)
388 struct lsa_info
*info
;
390 ZERO_STRUCTP(handle
);
392 info
= talloc_zero(mem_ctx
, struct lsa_info
);
394 return NT_STATUS_NO_MEMORY
;
398 info
->access
= acc_granted
;
401 sid_copy(&info
->sid
, sid
);
404 info
->name
= talloc_strdup(info
, name
);
407 info
->sd
= dup_sec_desc(info
, sd
);
410 return NT_STATUS_NO_MEMORY
;
414 if (!create_policy_hnd(p
, handle
, info
)) {
416 ZERO_STRUCTP(handle
);
417 return NT_STATUS_NO_MEMORY
;
423 /***************************************************************************
425 ***************************************************************************/
427 NTSTATUS
_lsa_OpenPolicy2(struct pipes_struct
*p
,
428 struct lsa_OpenPolicy2
*r
)
430 struct security_descriptor
*psd
= NULL
;
432 uint32 des_access
= r
->in
.access_mask
;
436 /* Work out max allowed. */
437 map_max_allowed_access(p
->session_info
->security_token
,
438 p
->session_info
->unix_token
,
441 /* map the generic bits to the lsa policy ones */
442 se_map_generic(&des_access
, &lsa_policy_mapping
);
444 /* get the generic lsa policy SD until we store it */
445 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &lsa_policy_mapping
,
447 if (!NT_STATUS_IS_OK(status
)) {
451 status
= access_check_object(psd
, p
->session_info
->security_token
,
452 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0, des_access
,
453 &acc_granted
, "_lsa_OpenPolicy2" );
454 if (!NT_STATUS_IS_OK(status
)) {
458 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
459 LSA_HANDLE_POLICY_TYPE
,
461 get_global_sam_sid(),
465 if (!NT_STATUS_IS_OK(status
)) {
466 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
472 /***************************************************************************
474 ***************************************************************************/
476 NTSTATUS
_lsa_OpenPolicy(struct pipes_struct
*p
,
477 struct lsa_OpenPolicy
*r
)
479 struct lsa_OpenPolicy2 o
;
481 o
.in
.system_name
= NULL
; /* should be ignored */
482 o
.in
.attr
= r
->in
.attr
;
483 o
.in
.access_mask
= r
->in
.access_mask
;
485 o
.out
.handle
= r
->out
.handle
;
487 return _lsa_OpenPolicy2(p
, &o
);
490 /***************************************************************************
491 _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
493 ***************************************************************************/
495 NTSTATUS
_lsa_EnumTrustDom(struct pipes_struct
*p
,
496 struct lsa_EnumTrustDom
*r
)
498 struct lsa_info
*info
;
500 struct trustdom_info
**domains
;
501 struct lsa_DomainInfo
*entries
;
505 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
506 return NT_STATUS_INVALID_HANDLE
;
508 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
509 return NT_STATUS_INVALID_HANDLE
;
512 /* check if the user has enough rights */
513 if (!(info
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
514 return NT_STATUS_ACCESS_DENIED
;
517 nt_status
= pdb_enum_trusteddoms(p
->mem_ctx
, &count
, &domains
);
520 if (!NT_STATUS_IS_OK(nt_status
)) {
524 entries
= talloc_zero_array(p
->mem_ctx
, struct lsa_DomainInfo
, count
);
526 return NT_STATUS_NO_MEMORY
;
529 for (i
=0; i
<count
; i
++) {
530 init_lsa_StringLarge(&entries
[i
].name
, domains
[i
]->name
);
531 entries
[i
].sid
= &domains
[i
]->sid
;
534 if (*r
->in
.resume_handle
>= count
) {
535 *r
->out
.resume_handle
= -1;
536 TALLOC_FREE(entries
);
537 return NT_STATUS_NO_MORE_ENTRIES
;
540 /* return the rest, limit by max_size. Note that we
541 use the w2k3 element size value of 60 */
542 r
->out
.domains
->count
= count
- *r
->in
.resume_handle
;
543 r
->out
.domains
->count
= MIN(r
->out
.domains
->count
,
544 1+(r
->in
.max_size
/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER
));
546 r
->out
.domains
->domains
= entries
+ *r
->in
.resume_handle
;
548 if (r
->out
.domains
->count
< count
- *r
->in
.resume_handle
) {
549 *r
->out
.resume_handle
= *r
->in
.resume_handle
+ r
->out
.domains
->count
;
550 return STATUS_MORE_ENTRIES
;
553 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
554 * always be larger than the previous input resume handle, in
555 * particular when hitting the last query it is vital to set the
556 * resume handle correctly to avoid infinite client loops, as
557 * seen e.g. with Windows XP SP3 when resume handle is 0 and
558 * status is NT_STATUS_OK - gd */
560 *r
->out
.resume_handle
= (uint32_t)-1;
565 #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
566 #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
567 #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
569 /***************************************************************************
571 ***************************************************************************/
573 NTSTATUS
_lsa_QueryInfoPolicy(struct pipes_struct
*p
,
574 struct lsa_QueryInfoPolicy
*r
)
576 NTSTATUS status
= NT_STATUS_OK
;
577 struct lsa_info
*handle
;
578 struct dom_sid domain_sid
;
580 struct dom_sid
*sid
= NULL
;
581 union lsa_PolicyInformation
*info
= NULL
;
582 uint32_t acc_required
= 0;
584 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
585 return NT_STATUS_INVALID_HANDLE
;
587 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
588 return NT_STATUS_INVALID_HANDLE
;
591 switch (r
->in
.level
) {
592 case LSA_POLICY_INFO_AUDIT_LOG
:
593 case LSA_POLICY_INFO_AUDIT_EVENTS
:
594 acc_required
= LSA_POLICY_VIEW_AUDIT_INFORMATION
;
596 case LSA_POLICY_INFO_DOMAIN
:
597 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
599 case LSA_POLICY_INFO_PD
:
600 acc_required
= LSA_POLICY_GET_PRIVATE_INFORMATION
;
602 case LSA_POLICY_INFO_ACCOUNT_DOMAIN
:
603 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
605 case LSA_POLICY_INFO_ROLE
:
606 case LSA_POLICY_INFO_REPLICA
:
607 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
609 case LSA_POLICY_INFO_QUOTA
:
610 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
612 case LSA_POLICY_INFO_MOD
:
613 case LSA_POLICY_INFO_AUDIT_FULL_SET
:
614 /* according to MS-LSAD 3.1.4.4.3 */
615 return NT_STATUS_INVALID_PARAMETER
;
616 case LSA_POLICY_INFO_AUDIT_FULL_QUERY
:
617 acc_required
= LSA_POLICY_VIEW_AUDIT_INFORMATION
;
619 case LSA_POLICY_INFO_DNS
:
620 case LSA_POLICY_INFO_DNS_INT
:
621 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN
:
622 acc_required
= LSA_POLICY_VIEW_LOCAL_INFORMATION
;
628 if (!(handle
->access
& acc_required
)) {
629 /* return NT_STATUS_ACCESS_DENIED; */
632 info
= talloc_zero(p
->mem_ctx
, union lsa_PolicyInformation
);
634 return NT_STATUS_NO_MEMORY
;
637 switch (r
->in
.level
) {
638 /* according to MS-LSAD 3.1.4.4.3 */
639 case LSA_POLICY_INFO_MOD
:
640 case LSA_POLICY_INFO_AUDIT_FULL_SET
:
641 case LSA_POLICY_INFO_AUDIT_FULL_QUERY
:
642 return NT_STATUS_INVALID_PARAMETER
;
643 case LSA_POLICY_INFO_AUDIT_LOG
:
644 info
->audit_log
.percent_full
= 0;
645 info
->audit_log
.maximum_log_size
= 0;
646 info
->audit_log
.retention_time
= 0;
647 info
->audit_log
.shutdown_in_progress
= 0;
648 info
->audit_log
.time_to_shutdown
= 0;
649 info
->audit_log
.next_audit_record
= 0;
650 status
= NT_STATUS_OK
;
652 case LSA_POLICY_INFO_PD
:
653 info
->pd
.name
.string
= NULL
;
654 status
= NT_STATUS_OK
;
656 case LSA_POLICY_INFO_REPLICA
:
657 info
->replica
.source
.string
= NULL
;
658 info
->replica
.account
.string
= NULL
;
659 status
= NT_STATUS_OK
;
661 case LSA_POLICY_INFO_QUOTA
:
662 info
->quota
.paged_pool
= 0;
663 info
->quota
.non_paged_pool
= 0;
664 info
->quota
.min_wss
= 0;
665 info
->quota
.max_wss
= 0;
666 info
->quota
.pagefile
= 0;
667 info
->quota
.unknown
= 0;
668 status
= NT_STATUS_OK
;
670 case LSA_POLICY_INFO_AUDIT_EVENTS
:
673 uint32 policy_def
= LSA_AUDIT_POLICY_ALL
;
675 /* check if the user has enough rights */
676 if (!(handle
->access
& LSA_POLICY_VIEW_AUDIT_INFORMATION
)) {
677 DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
678 return NT_STATUS_ACCESS_DENIED
;
681 /* fake info: We audit everything. ;) */
683 info
->audit_events
.auditing_mode
= true;
684 info
->audit_events
.count
= LSA_AUDIT_NUM_CATEGORIES
;
685 info
->audit_events
.settings
= talloc_zero_array(p
->mem_ctx
,
686 enum lsa_PolicyAuditPolicy
,
687 info
->audit_events
.count
);
688 if (!info
->audit_events
.settings
) {
689 return NT_STATUS_NO_MEMORY
;
692 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT
] = policy_def
;
693 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS
] = policy_def
;
694 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_LOGON
] = policy_def
;
695 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING
] = policy_def
;
696 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES
] = policy_def
;
697 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_SYSTEM
] = policy_def
;
698 info
->audit_events
.settings
[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS
] = policy_def
;
702 case LSA_POLICY_INFO_DOMAIN
:
703 /* check if the user has enough rights */
704 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
705 return NT_STATUS_ACCESS_DENIED
;
707 /* Request PolicyPrimaryDomainInformation. */
708 switch (lp_server_role()) {
709 case ROLE_DOMAIN_PDC
:
710 case ROLE_DOMAIN_BDC
:
711 name
= get_global_sam_name();
712 sid
= dom_sid_dup(p
->mem_ctx
, get_global_sam_sid());
714 return NT_STATUS_NO_MEMORY
;
717 case ROLE_DOMAIN_MEMBER
:
718 name
= lp_workgroup();
719 /* We need to return the Domain SID here. */
720 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid
)) {
721 sid
= dom_sid_dup(p
->mem_ctx
, &domain_sid
);
723 return NT_STATUS_NO_MEMORY
;
726 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
729 case ROLE_STANDALONE
:
730 name
= lp_workgroup();
734 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
736 init_dom_query_3(&info
->domain
, name
, sid
);
738 case LSA_POLICY_INFO_ACCOUNT_DOMAIN
:
739 /* check if the user has enough rights */
740 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
741 return NT_STATUS_ACCESS_DENIED
;
743 /* Request PolicyAccountDomainInformation. */
744 name
= get_global_sam_name();
745 sid
= get_global_sam_sid();
747 init_dom_query_5(&info
->account_domain
, name
, sid
);
749 case LSA_POLICY_INFO_ROLE
:
750 /* check if the user has enough rights */
751 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
752 return NT_STATUS_ACCESS_DENIED
;
754 switch (lp_server_role()) {
755 case ROLE_DOMAIN_BDC
:
757 * only a BDC is a backup controller
758 * of the domain, it controls.
760 info
->role
.role
= LSA_ROLE_BACKUP
;
764 * any other role is a primary
765 * of the domain, it controls.
767 info
->role
.role
= LSA_ROLE_PRIMARY
;
771 case LSA_POLICY_INFO_DNS
:
772 case LSA_POLICY_INFO_DNS_INT
: {
773 struct pdb_domain_info
*dominfo
;
775 if ((pdb_capabilities() & PDB_CAP_ADS
) == 0) {
776 DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
777 "without ADS passdb backend\n"));
778 status
= NT_STATUS_INVALID_INFO_CLASS
;
782 dominfo
= pdb_get_domain_info(info
);
783 if (dominfo
== NULL
) {
784 status
= NT_STATUS_NO_MEMORY
;
788 init_lsa_StringLarge(&info
->dns
.name
,
790 init_lsa_StringLarge(&info
->dns
.dns_domain
,
791 dominfo
->dns_domain
);
792 init_lsa_StringLarge(&info
->dns
.dns_forest
,
793 dominfo
->dns_forest
);
794 info
->dns
.domain_guid
= dominfo
->guid
;
795 info
->dns
.sid
= &dominfo
->sid
;
799 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
801 status
= NT_STATUS_INVALID_INFO_CLASS
;
810 /***************************************************************************
811 _lsa_QueryInfoPolicy2
812 ***************************************************************************/
814 NTSTATUS
_lsa_QueryInfoPolicy2(struct pipes_struct
*p
,
815 struct lsa_QueryInfoPolicy2
*r2
)
817 struct lsa_QueryInfoPolicy r
;
819 if ((pdb_capabilities() & PDB_CAP_ADS
) == 0) {
820 p
->rng_fault_state
= True
;
821 return NT_STATUS_NOT_IMPLEMENTED
;
825 r
.in
.handle
= r2
->in
.handle
;
826 r
.in
.level
= r2
->in
.level
;
827 r
.out
.info
= r2
->out
.info
;
829 return _lsa_QueryInfoPolicy(p
, &r
);
832 /***************************************************************************
833 _lsa_lookup_sids_internal
834 ***************************************************************************/
836 static NTSTATUS
_lsa_lookup_sids_internal(struct pipes_struct
*p
,
838 uint16_t level
, /* input */
839 int num_sids
, /* input */
840 struct lsa_SidPtr
*sid
, /* input */
841 struct lsa_RefDomainList
**pp_ref
, /* input/output */
842 struct lsa_TranslatedName2
**pp_names
,/* input/output */
843 uint32_t *pp_mapped_count
) /* input/output */
847 const struct dom_sid
**sids
= NULL
;
848 struct lsa_RefDomainList
*ref
= NULL
;
849 uint32 mapped_count
= 0;
850 struct lsa_dom_info
*dom_infos
= NULL
;
851 struct lsa_name_info
*name_infos
= NULL
;
852 struct lsa_TranslatedName2
*names
= NULL
;
854 *pp_mapped_count
= 0;
862 sids
= talloc_array(p
->mem_ctx
, const struct dom_sid
*, num_sids
);
863 ref
= talloc_zero(p
->mem_ctx
, struct lsa_RefDomainList
);
865 if (sids
== NULL
|| ref
== NULL
) {
866 return NT_STATUS_NO_MEMORY
;
869 for (i
=0; i
<num_sids
; i
++) {
870 sids
[i
] = sid
[i
].sid
;
873 status
= lookup_sids(p
->mem_ctx
, num_sids
, sids
, level
,
874 &dom_infos
, &name_infos
);
876 if (!NT_STATUS_IS_OK(status
)) {
880 names
= talloc_array(p
->mem_ctx
, struct lsa_TranslatedName2
, num_sids
);
882 return NT_STATUS_NO_MEMORY
;
885 for (i
=0; i
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; i
++) {
887 if (!dom_infos
[i
].valid
) {
891 if (init_lsa_ref_domain_list(mem_ctx
, ref
,
893 &dom_infos
[i
].sid
) != i
) {
894 DEBUG(0, ("Domain %s mentioned twice??\n",
896 return NT_STATUS_INTERNAL_ERROR
;
900 for (i
=0; i
<num_sids
; i
++) {
901 struct lsa_name_info
*name
= &name_infos
[i
];
903 if (name
->type
== SID_NAME_UNKNOWN
) {
905 /* Unknown sids should return the string
906 * representation of the SID. Windows 2003 behaves
907 * rather erratic here, in many cases it returns the
908 * RID as 8 bytes hex, in others it returns the full
909 * SID. We (Jerry/VL) could not figure out which the
910 * hard cases are, so leave it with the SID. */
911 name
->name
= dom_sid_string(p
->mem_ctx
, sids
[i
]);
912 if (name
->name
== NULL
) {
913 return NT_STATUS_NO_MEMORY
;
919 names
[i
].sid_type
= name
->type
;
920 names
[i
].name
.string
= name
->name
;
921 names
[i
].sid_index
= name
->dom_idx
;
922 names
[i
].unknown
= 0;
925 status
= NT_STATUS_NONE_MAPPED
;
926 if (mapped_count
> 0) {
927 status
= (mapped_count
< num_sids
) ?
928 STATUS_SOME_UNMAPPED
: NT_STATUS_OK
;
931 DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
932 num_sids
, mapped_count
, nt_errstr(status
)));
934 *pp_mapped_count
= mapped_count
;
941 /***************************************************************************
943 ***************************************************************************/
945 NTSTATUS
_lsa_LookupSids(struct pipes_struct
*p
,
946 struct lsa_LookupSids
*r
)
949 struct lsa_info
*handle
;
950 int num_sids
= r
->in
.sids
->num_sids
;
951 uint32 mapped_count
= 0;
952 struct lsa_RefDomainList
*domains
= NULL
;
953 struct lsa_TranslatedName
*names_out
= NULL
;
954 struct lsa_TranslatedName2
*names
= NULL
;
957 if ((r
->in
.level
< 1) || (r
->in
.level
> 6)) {
958 return NT_STATUS_INVALID_PARAMETER
;
961 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
962 return NT_STATUS_INVALID_HANDLE
;
965 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
966 return NT_STATUS_INVALID_HANDLE
;
969 /* check if the user has enough rights */
970 if (!(handle
->access
& LSA_POLICY_LOOKUP_NAMES
)) {
971 return NT_STATUS_ACCESS_DENIED
;
974 if (num_sids
> MAX_LOOKUP_SIDS
) {
975 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
976 MAX_LOOKUP_SIDS
, num_sids
));
977 return NT_STATUS_NONE_MAPPED
;
980 status
= _lsa_lookup_sids_internal(p
,
989 /* Only return here when there is a real error.
990 NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
991 the requested sids could be resolved. Older versions of XP (pre SP3)
992 rely that we return with the string representations of those SIDs in
993 that case. If we don't, XP crashes - Guenther
996 if (NT_STATUS_IS_ERR(status
) &&
997 !NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
1001 /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
1002 names_out
= talloc_array(p
->mem_ctx
, struct lsa_TranslatedName
,
1005 return NT_STATUS_NO_MEMORY
;
1008 for (i
=0; i
<num_sids
; i
++) {
1009 names_out
[i
].sid_type
= names
[i
].sid_type
;
1010 names_out
[i
].name
= names
[i
].name
;
1011 names_out
[i
].sid_index
= names
[i
].sid_index
;
1014 *r
->out
.domains
= domains
;
1015 r
->out
.names
->count
= num_sids
;
1016 r
->out
.names
->names
= names_out
;
1017 *r
->out
.count
= mapped_count
;
1022 /***************************************************************************
1024 ***************************************************************************/
1026 NTSTATUS
_lsa_LookupSids2(struct pipes_struct
*p
,
1027 struct lsa_LookupSids2
*r
)
1030 struct lsa_info
*handle
;
1031 int num_sids
= r
->in
.sids
->num_sids
;
1032 uint32 mapped_count
= 0;
1033 struct lsa_RefDomainList
*domains
= NULL
;
1034 struct lsa_TranslatedName2
*names
= NULL
;
1035 bool check_policy
= true;
1038 case NDR_LSA_LOOKUPSIDS3
:
1039 check_policy
= false;
1041 case NDR_LSA_LOOKUPSIDS2
:
1043 check_policy
= true;
1046 if ((r
->in
.level
< 1) || (r
->in
.level
> 6)) {
1047 return NT_STATUS_INVALID_PARAMETER
;
1051 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1052 return NT_STATUS_INVALID_HANDLE
;
1055 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1056 return NT_STATUS_INVALID_HANDLE
;
1059 /* check if the user has enough rights */
1060 if (!(handle
->access
& LSA_POLICY_LOOKUP_NAMES
)) {
1061 return NT_STATUS_ACCESS_DENIED
;
1065 if (num_sids
> MAX_LOOKUP_SIDS
) {
1066 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1067 MAX_LOOKUP_SIDS
, num_sids
));
1068 return NT_STATUS_NONE_MAPPED
;
1071 status
= _lsa_lookup_sids_internal(p
,
1080 *r
->out
.domains
= domains
;
1081 r
->out
.names
->count
= num_sids
;
1082 r
->out
.names
->names
= names
;
1083 *r
->out
.count
= mapped_count
;
1088 /***************************************************************************
1090 ***************************************************************************/
1092 NTSTATUS
_lsa_LookupSids3(struct pipes_struct
*p
,
1093 struct lsa_LookupSids3
*r
)
1095 struct lsa_LookupSids2 q
;
1097 /* No policy handle on this call. Restrict to crypto connections. */
1098 if (p
->auth
.auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
) {
1099 DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n",
1100 get_remote_machine_name() ));
1101 return NT_STATUS_INVALID_PARAMETER
;
1105 q
.in
.sids
= r
->in
.sids
;
1106 q
.in
.level
= r
->in
.level
;
1107 q
.in
.lookup_options
= r
->in
.lookup_options
;
1108 q
.in
.client_revision
= r
->in
.client_revision
;
1109 q
.in
.names
= r
->in
.names
;
1110 q
.in
.count
= r
->in
.count
;
1112 q
.out
.domains
= r
->out
.domains
;
1113 q
.out
.names
= r
->out
.names
;
1114 q
.out
.count
= r
->out
.count
;
1116 return _lsa_LookupSids2(p
, &q
);
1119 /***************************************************************************
1120 ***************************************************************************/
1122 static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level
)
1127 case LSA_LOOKUP_NAMES_ALL
: /* 1 */
1128 flags
= LOOKUP_NAME_ALL
;
1130 case LSA_LOOKUP_NAMES_DOMAINS_ONLY
: /* 2 */
1131 flags
= LOOKUP_NAME_DOMAIN
|LOOKUP_NAME_REMOTE
|LOOKUP_NAME_ISOLATED
;
1133 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY
: /* 3 */
1134 flags
= LOOKUP_NAME_DOMAIN
|LOOKUP_NAME_ISOLATED
;
1136 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY
: /* 4 */
1137 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY
: /* 5 */
1138 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2
: /* 6 */
1139 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC
: /* 7 */
1141 flags
= LOOKUP_NAME_NONE
;
1148 /***************************************************************************
1150 ***************************************************************************/
1152 NTSTATUS
_lsa_LookupNames(struct pipes_struct
*p
,
1153 struct lsa_LookupNames
*r
)
1155 NTSTATUS status
= NT_STATUS_NONE_MAPPED
;
1156 struct lsa_info
*handle
;
1157 struct lsa_String
*names
= r
->in
.names
;
1158 uint32 num_entries
= r
->in
.num_names
;
1159 struct lsa_RefDomainList
*domains
= NULL
;
1160 struct lsa_TranslatedSid
*rids
= NULL
;
1161 uint32 mapped_count
= 0;
1164 if (num_entries
> MAX_LOOKUP_SIDS
) {
1165 num_entries
= MAX_LOOKUP_SIDS
;
1166 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1170 flags
= lsa_lookup_level_to_flags(r
->in
.level
);
1172 domains
= talloc_zero(p
->mem_ctx
, struct lsa_RefDomainList
);
1174 return NT_STATUS_NO_MEMORY
;
1178 rids
= talloc_zero_array(p
->mem_ctx
, struct lsa_TranslatedSid
,
1181 return NT_STATUS_NO_MEMORY
;
1187 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1188 status
= NT_STATUS_INVALID_HANDLE
;
1192 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1193 return NT_STATUS_INVALID_HANDLE
;
1196 /* check if the user has enough rights */
1197 if (!(handle
->access
& LSA_POLICY_LOOKUP_NAMES
)) {
1198 status
= NT_STATUS_ACCESS_DENIED
;
1202 /* set up the LSA Lookup RIDs response */
1203 become_root(); /* lookup_name can require root privs */
1204 status
= lookup_lsa_rids(p
->mem_ctx
, domains
, rids
, num_entries
,
1205 names
, flags
, &mapped_count
);
1210 if (NT_STATUS_IS_OK(status
) && (num_entries
!= 0) ) {
1211 if (mapped_count
== 0) {
1212 status
= NT_STATUS_NONE_MAPPED
;
1213 } else if (mapped_count
!= num_entries
) {
1214 status
= STATUS_SOME_UNMAPPED
;
1218 *r
->out
.count
= mapped_count
;
1219 *r
->out
.domains
= domains
;
1220 r
->out
.sids
->sids
= rids
;
1221 r
->out
.sids
->count
= num_entries
;
1226 /***************************************************************************
1228 ***************************************************************************/
1230 NTSTATUS
_lsa_LookupNames2(struct pipes_struct
*p
,
1231 struct lsa_LookupNames2
*r
)
1234 struct lsa_LookupNames q
;
1235 struct lsa_TransSidArray2
*sid_array2
= r
->in
.sids
;
1236 struct lsa_TransSidArray
*sid_array
= NULL
;
1239 sid_array
= talloc_zero(p
->mem_ctx
, struct lsa_TransSidArray
);
1241 return NT_STATUS_NO_MEMORY
;
1244 q
.in
.handle
= r
->in
.handle
;
1245 q
.in
.num_names
= r
->in
.num_names
;
1246 q
.in
.names
= r
->in
.names
;
1247 q
.in
.level
= r
->in
.level
;
1248 q
.in
.sids
= sid_array
;
1249 q
.in
.count
= r
->in
.count
;
1250 /* we do not know what this is for */
1251 /* = r->in.unknown1; */
1252 /* = r->in.unknown2; */
1254 q
.out
.domains
= r
->out
.domains
;
1255 q
.out
.sids
= sid_array
;
1256 q
.out
.count
= r
->out
.count
;
1258 status
= _lsa_LookupNames(p
, &q
);
1260 sid_array2
->count
= sid_array
->count
;
1261 sid_array2
->sids
= talloc_array(p
->mem_ctx
, struct lsa_TranslatedSid2
, sid_array
->count
);
1262 if (!sid_array2
->sids
) {
1263 return NT_STATUS_NO_MEMORY
;
1266 for (i
=0; i
<sid_array
->count
; i
++) {
1267 sid_array2
->sids
[i
].sid_type
= sid_array
->sids
[i
].sid_type
;
1268 sid_array2
->sids
[i
].rid
= sid_array
->sids
[i
].rid
;
1269 sid_array2
->sids
[i
].sid_index
= sid_array
->sids
[i
].sid_index
;
1270 sid_array2
->sids
[i
].unknown
= 0;
1273 r
->out
.sids
= sid_array2
;
1278 /***************************************************************************
1280 ***************************************************************************/
1282 NTSTATUS
_lsa_LookupNames3(struct pipes_struct
*p
,
1283 struct lsa_LookupNames3
*r
)
1286 struct lsa_info
*handle
;
1287 struct lsa_String
*names
= r
->in
.names
;
1288 uint32 num_entries
= r
->in
.num_names
;
1289 struct lsa_RefDomainList
*domains
= NULL
;
1290 struct lsa_TranslatedSid3
*trans_sids
= NULL
;
1291 uint32 mapped_count
= 0;
1293 bool check_policy
= true;
1296 case NDR_LSA_LOOKUPNAMES4
:
1297 check_policy
= false;
1299 case NDR_LSA_LOOKUPNAMES3
:
1301 check_policy
= true;
1304 if (num_entries
> MAX_LOOKUP_SIDS
) {
1305 num_entries
= MAX_LOOKUP_SIDS
;
1306 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries
));
1309 /* Probably the lookup_level is some sort of bitmask. */
1310 if (r
->in
.level
== 1) {
1311 flags
= LOOKUP_NAME_ALL
;
1314 domains
= talloc_zero(p
->mem_ctx
, struct lsa_RefDomainList
);
1316 return NT_STATUS_NO_MEMORY
;
1320 trans_sids
= talloc_zero_array(p
->mem_ctx
, struct lsa_TranslatedSid3
,
1323 return NT_STATUS_NO_MEMORY
;
1331 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1332 status
= NT_STATUS_INVALID_HANDLE
;
1336 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1337 return NT_STATUS_INVALID_HANDLE
;
1340 /* check if the user has enough rights */
1341 if (!(handle
->access
& LSA_POLICY_LOOKUP_NAMES
)) {
1342 status
= NT_STATUS_ACCESS_DENIED
;
1347 /* set up the LSA Lookup SIDs response */
1348 become_root(); /* lookup_name can require root privs */
1349 status
= lookup_lsa_sids(p
->mem_ctx
, domains
, trans_sids
, num_entries
,
1350 names
, flags
, &mapped_count
);
1355 if (NT_STATUS_IS_OK(status
)) {
1356 if (mapped_count
== 0) {
1357 status
= NT_STATUS_NONE_MAPPED
;
1358 } else if (mapped_count
!= num_entries
) {
1359 status
= STATUS_SOME_UNMAPPED
;
1363 *r
->out
.count
= mapped_count
;
1364 *r
->out
.domains
= domains
;
1365 r
->out
.sids
->sids
= trans_sids
;
1366 r
->out
.sids
->count
= num_entries
;
1371 /***************************************************************************
1373 ***************************************************************************/
1375 NTSTATUS
_lsa_LookupNames4(struct pipes_struct
*p
,
1376 struct lsa_LookupNames4
*r
)
1378 struct lsa_LookupNames3 q
;
1380 /* No policy handle on this call. Restrict to crypto connections. */
1381 if (p
->auth
.auth_type
!= DCERPC_AUTH_TYPE_SCHANNEL
) {
1382 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
1383 get_remote_machine_name() ));
1384 return NT_STATUS_INVALID_PARAMETER
;
1388 q
.in
.num_names
= r
->in
.num_names
;
1389 q
.in
.names
= r
->in
.names
;
1390 q
.in
.level
= r
->in
.level
;
1391 q
.in
.lookup_options
= r
->in
.lookup_options
;
1392 q
.in
.client_revision
= r
->in
.client_revision
;
1393 q
.in
.sids
= r
->in
.sids
;
1394 q
.in
.count
= r
->in
.count
;
1396 q
.out
.domains
= r
->out
.domains
;
1397 q
.out
.sids
= r
->out
.sids
;
1398 q
.out
.count
= r
->out
.count
;
1400 return _lsa_LookupNames3(p
, &q
);
1403 /***************************************************************************
1404 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1405 ***************************************************************************/
1407 NTSTATUS
_lsa_Close(struct pipes_struct
*p
, struct lsa_Close
*r
)
1409 if (!find_policy_by_hnd(p
, r
->in
.handle
, NULL
)) {
1410 return NT_STATUS_INVALID_HANDLE
;
1413 close_policy_hnd(p
, r
->in
.handle
);
1414 ZERO_STRUCTP(r
->out
.handle
);
1415 return NT_STATUS_OK
;
1418 /***************************************************************************
1419 ***************************************************************************/
1421 static NTSTATUS
lsa_lookup_trusted_domain_by_sid(TALLOC_CTX
*mem_ctx
,
1422 const struct dom_sid
*sid
,
1423 struct trustdom_info
**info
)
1426 uint32_t num_domains
= 0;
1427 struct trustdom_info
**domains
= NULL
;
1430 status
= pdb_enum_trusteddoms(mem_ctx
, &num_domains
, &domains
);
1431 if (!NT_STATUS_IS_OK(status
)) {
1435 for (i
=0; i
< num_domains
; i
++) {
1436 if (dom_sid_equal(&domains
[i
]->sid
, sid
)) {
1441 if (i
== num_domains
) {
1442 return NT_STATUS_INVALID_PARAMETER
;
1447 return NT_STATUS_OK
;
1450 /***************************************************************************
1451 ***************************************************************************/
1453 static NTSTATUS
lsa_lookup_trusted_domain_by_name(TALLOC_CTX
*mem_ctx
,
1454 const char *netbios_domain_name
,
1455 struct trustdom_info
**info_p
)
1458 struct trustdom_info
*info
;
1459 struct pdb_trusted_domain
*td
;
1461 status
= pdb_get_trusted_domain(mem_ctx
, netbios_domain_name
, &td
);
1462 if (!NT_STATUS_IS_OK(status
)) {
1466 info
= talloc(mem_ctx
, struct trustdom_info
);
1468 return NT_STATUS_NO_MEMORY
;
1471 info
->name
= talloc_strdup(info
, netbios_domain_name
);
1472 NT_STATUS_HAVE_NO_MEMORY(info
->name
);
1474 sid_copy(&info
->sid
, &td
->security_identifier
);
1478 return NT_STATUS_OK
;
1481 /***************************************************************************
1483 ***************************************************************************/
1485 NTSTATUS
_lsa_OpenSecret(struct pipes_struct
*p
,
1486 struct lsa_OpenSecret
*r
)
1488 struct lsa_info
*handle
;
1489 struct security_descriptor
*psd
;
1491 uint32_t acc_granted
;
1493 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1494 return NT_STATUS_INVALID_HANDLE
;
1497 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1498 return NT_STATUS_INVALID_HANDLE
;
1501 if (!r
->in
.name
.string
) {
1502 return NT_STATUS_INVALID_PARAMETER
;
1505 /* Work out max allowed. */
1506 map_max_allowed_access(p
->session_info
->security_token
,
1507 p
->session_info
->unix_token
,
1508 &r
->in
.access_mask
);
1510 /* map the generic bits to the lsa policy ones */
1511 se_map_generic(&r
->in
.access_mask
, &lsa_secret_mapping
);
1513 status
= pdb_get_secret(p
->mem_ctx
, r
->in
.name
.string
,
1519 if (!NT_STATUS_IS_OK(status
)) {
1523 status
= access_check_object(psd
, p
->session_info
->security_token
,
1524 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
1526 &acc_granted
, "_lsa_OpenSecret");
1527 if (!NT_STATUS_IS_OK(status
)) {
1531 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
1532 LSA_HANDLE_SECRET_TYPE
,
1538 if (!NT_STATUS_IS_OK(status
)) {
1539 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1542 return NT_STATUS_OK
;
1545 /***************************************************************************
1546 _lsa_OpenTrustedDomain_base
1547 ***************************************************************************/
1549 static NTSTATUS
_lsa_OpenTrustedDomain_base(struct pipes_struct
*p
,
1550 uint32_t access_mask
,
1551 struct trustdom_info
*info
,
1552 struct policy_handle
*handle
)
1554 struct security_descriptor
*psd
= NULL
;
1556 uint32_t acc_granted
;
1559 /* des_access is for the account here, not the policy
1560 * handle - so don't check against policy handle. */
1562 /* Work out max allowed. */
1563 map_max_allowed_access(p
->session_info
->security_token
,
1564 p
->session_info
->unix_token
,
1567 /* map the generic bits to the lsa account ones */
1568 se_map_generic(&access_mask
, &lsa_account_mapping
);
1570 /* get the generic lsa account SD until we store it */
1571 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
1572 &lsa_trusted_domain_mapping
,
1574 if (!NT_STATUS_IS_OK(status
)) {
1578 status
= access_check_object(psd
, p
->session_info
->security_token
,
1579 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
1580 access_mask
, &acc_granted
,
1581 "_lsa_OpenTrustedDomain");
1582 if (!NT_STATUS_IS_OK(status
)) {
1586 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
1587 LSA_HANDLE_TRUST_TYPE
,
1593 if (!NT_STATUS_IS_OK(status
)) {
1594 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1597 return NT_STATUS_OK
;
1600 /***************************************************************************
1601 _lsa_OpenTrustedDomain
1602 ***************************************************************************/
1604 NTSTATUS
_lsa_OpenTrustedDomain(struct pipes_struct
*p
,
1605 struct lsa_OpenTrustedDomain
*r
)
1607 struct lsa_info
*handle
= NULL
;
1608 struct trustdom_info
*info
= NULL
;
1611 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1612 return NT_STATUS_INVALID_HANDLE
;
1615 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1616 return NT_STATUS_INVALID_HANDLE
;
1619 status
= lsa_lookup_trusted_domain_by_sid(p
->mem_ctx
,
1622 if (!NT_STATUS_IS_OK(status
)) {
1626 return _lsa_OpenTrustedDomain_base(p
, r
->in
.access_mask
, info
,
1627 r
->out
.trustdom_handle
);
1630 /***************************************************************************
1631 _lsa_OpenTrustedDomainByName
1632 ***************************************************************************/
1634 NTSTATUS
_lsa_OpenTrustedDomainByName(struct pipes_struct
*p
,
1635 struct lsa_OpenTrustedDomainByName
*r
)
1637 struct lsa_info
*handle
= NULL
;
1638 struct trustdom_info
*info
= NULL
;
1641 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1642 return NT_STATUS_INVALID_HANDLE
;
1645 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1646 return NT_STATUS_INVALID_HANDLE
;
1649 status
= lsa_lookup_trusted_domain_by_name(p
->mem_ctx
,
1652 if (!NT_STATUS_IS_OK(status
)) {
1656 return _lsa_OpenTrustedDomain_base(p
, r
->in
.access_mask
, info
,
1657 r
->out
.trustdom_handle
);
1660 static NTSTATUS
add_trusted_domain_user(TALLOC_CTX
*mem_ctx
,
1661 const char *netbios_name
,
1662 const char *domain_name
,
1663 const struct trustDomainPasswords
*auth_struct
)
1666 struct samu
*sam_acct
;
1669 struct dom_sid user_sid
;
1674 sam_acct
= samu_new(mem_ctx
);
1675 if (sam_acct
== NULL
) {
1676 return NT_STATUS_NO_MEMORY
;
1679 acct_name
= talloc_asprintf(mem_ctx
, "%s$", netbios_name
);
1680 if (acct_name
== NULL
) {
1681 return NT_STATUS_NO_MEMORY
;
1683 if (!pdb_set_username(sam_acct
, acct_name
, PDB_SET
)) {
1684 return NT_STATUS_UNSUCCESSFUL
;
1687 if (!pdb_set_domain(sam_acct
, domain_name
, PDB_SET
)) {
1688 return NT_STATUS_UNSUCCESSFUL
;
1691 if (!pdb_set_acct_ctrl(sam_acct
, ACB_DOMTRUST
, PDB_SET
)) {
1692 return NT_STATUS_UNSUCCESSFUL
;
1695 if (!pdb_new_rid(&rid
)) {
1696 return NT_STATUS_DS_NO_MORE_RIDS
;
1698 sid_compose(&user_sid
, get_global_sam_sid(), rid
);
1699 if (!pdb_set_user_sid(sam_acct
, &user_sid
, PDB_SET
)) {
1700 return NT_STATUS_UNSUCCESSFUL
;
1703 for (i
= 0; i
< auth_struct
->incoming
.count
; i
++) {
1704 switch (auth_struct
->incoming
.current
.array
[i
].AuthType
) {
1705 case TRUST_AUTH_TYPE_CLEAR
:
1706 if (!convert_string_talloc(mem_ctx
,
1709 auth_struct
->incoming
.current
.array
[i
].AuthInfo
.clear
.password
,
1710 auth_struct
->incoming
.current
.array
[i
].AuthInfo
.clear
.size
,
1713 return NT_STATUS_UNSUCCESSFUL
;
1715 if (!pdb_set_plaintext_passwd(sam_acct
, dummy
)) {
1716 return NT_STATUS_UNSUCCESSFUL
;
1724 status
= pdb_add_sam_account(sam_acct
);
1725 if (!NT_STATUS_IS_OK(status
)) {
1729 return NT_STATUS_OK
;
1732 /***************************************************************************
1733 _lsa_CreateTrustedDomainEx2
1734 ***************************************************************************/
1736 NTSTATUS
_lsa_CreateTrustedDomainEx2(struct pipes_struct
*p
,
1737 struct lsa_CreateTrustedDomainEx2
*r
)
1739 struct lsa_info
*policy
;
1741 uint32_t acc_granted
;
1742 struct security_descriptor
*psd
;
1744 struct pdb_trusted_domain td
;
1745 struct trustDomainPasswords auth_struct
;
1746 enum ndr_err_code ndr_err
;
1747 DATA_BLOB auth_blob
;
1750 return NT_STATUS_NOT_SUPPORTED
;
1753 if (!find_policy_by_hnd(p
, r
->in
.policy_handle
, (void **)(void *)&policy
)) {
1754 return NT_STATUS_INVALID_HANDLE
;
1757 if (!(policy
->access
& LSA_POLICY_TRUST_ADMIN
)) {
1758 return NT_STATUS_ACCESS_DENIED
;
1761 if (p
->session_info
->unix_token
->uid
!= sec_initial_uid() &&
1762 !nt_token_check_domain_rid(p
->session_info
->security_token
, DOMAIN_RID_ADMINS
)) {
1763 return NT_STATUS_ACCESS_DENIED
;
1766 /* Work out max allowed. */
1767 map_max_allowed_access(p
->session_info
->security_token
,
1768 p
->session_info
->unix_token
,
1769 &r
->in
.access_mask
);
1771 /* map the generic bits to the lsa policy ones */
1772 se_map_generic(&r
->in
.access_mask
, &lsa_account_mapping
);
1774 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
1775 &lsa_trusted_domain_mapping
,
1777 if (!NT_STATUS_IS_OK(status
)) {
1781 status
= access_check_object(psd
, p
->session_info
->security_token
,
1782 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
1783 r
->in
.access_mask
, &acc_granted
,
1784 "_lsa_CreateTrustedDomainEx2");
1785 if (!NT_STATUS_IS_OK(status
)) {
1791 td
.domain_name
= talloc_strdup(p
->mem_ctx
,
1792 r
->in
.info
->domain_name
.string
);
1793 if (td
.domain_name
== NULL
) {
1794 return NT_STATUS_NO_MEMORY
;
1796 td
.netbios_name
= talloc_strdup(p
->mem_ctx
,
1797 r
->in
.info
->netbios_name
.string
);
1798 if (td
.netbios_name
== NULL
) {
1799 return NT_STATUS_NO_MEMORY
;
1801 sid_copy(&td
.security_identifier
, r
->in
.info
->sid
);
1802 td
.trust_direction
= r
->in
.info
->trust_direction
;
1803 td
.trust_type
= r
->in
.info
->trust_type
;
1804 td
.trust_attributes
= r
->in
.info
->trust_attributes
;
1806 if (r
->in
.auth_info_internal
->auth_blob
.size
!= 0) {
1807 auth_blob
.length
= r
->in
.auth_info_internal
->auth_blob
.size
;
1808 auth_blob
.data
= r
->in
.auth_info_internal
->auth_blob
.data
;
1810 arcfour_crypt_blob(auth_blob
.data
, auth_blob
.length
,
1811 &p
->session_info
->session_key
);
1813 ndr_err
= ndr_pull_struct_blob(&auth_blob
, p
->mem_ctx
,
1815 (ndr_pull_flags_fn_t
) ndr_pull_trustDomainPasswords
);
1816 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1817 return NT_STATUS_UNSUCCESSFUL
;
1820 ndr_err
= ndr_push_struct_blob(&td
.trust_auth_incoming
, p
->mem_ctx
,
1821 &auth_struct
.incoming
,
1822 (ndr_push_flags_fn_t
) ndr_push_trustAuthInOutBlob
);
1823 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1824 return NT_STATUS_UNSUCCESSFUL
;
1827 ndr_err
= ndr_push_struct_blob(&td
.trust_auth_outgoing
, p
->mem_ctx
,
1828 &auth_struct
.outgoing
,
1829 (ndr_push_flags_fn_t
) ndr_push_trustAuthInOutBlob
);
1830 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1831 return NT_STATUS_UNSUCCESSFUL
;
1834 td
.trust_auth_incoming
.data
= NULL
;
1835 td
.trust_auth_incoming
.length
= 0;
1836 td
.trust_auth_outgoing
.data
= NULL
;
1837 td
.trust_auth_outgoing
.length
= 0;
1840 status
= pdb_set_trusted_domain(r
->in
.info
->domain_name
.string
, &td
);
1841 if (!NT_STATUS_IS_OK(status
)) {
1845 if (r
->in
.info
->trust_direction
& LSA_TRUST_DIRECTION_INBOUND
) {
1846 status
= add_trusted_domain_user(p
->mem_ctx
,
1847 r
->in
.info
->netbios_name
.string
,
1848 r
->in
.info
->domain_name
.string
,
1850 if (!NT_STATUS_IS_OK(status
)) {
1855 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
1856 LSA_HANDLE_TRUST_TYPE
,
1859 r
->in
.info
->netbios_name
.string
,
1861 r
->out
.trustdom_handle
);
1862 if (!NT_STATUS_IS_OK(status
)) {
1863 pdb_del_trusteddom_pw(r
->in
.info
->netbios_name
.string
);
1864 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1867 return NT_STATUS_OK
;
1870 /***************************************************************************
1871 _lsa_CreateTrustedDomainEx
1872 ***************************************************************************/
1874 NTSTATUS
_lsa_CreateTrustedDomainEx(struct pipes_struct
*p
,
1875 struct lsa_CreateTrustedDomainEx
*r
)
1877 struct lsa_CreateTrustedDomainEx2 q
;
1878 struct lsa_TrustDomainInfoAuthInfoInternal auth_info
;
1880 ZERO_STRUCT(auth_info
);
1882 q
.in
.policy_handle
= r
->in
.policy_handle
;
1883 q
.in
.info
= r
->in
.info
;
1884 q
.in
.auth_info_internal
= &auth_info
;
1885 q
.in
.access_mask
= r
->in
.access_mask
;
1886 q
.out
.trustdom_handle
= r
->out
.trustdom_handle
;
1888 return _lsa_CreateTrustedDomainEx2(p
, &q
);
1891 /***************************************************************************
1892 _lsa_CreateTrustedDomain
1893 ***************************************************************************/
1895 NTSTATUS
_lsa_CreateTrustedDomain(struct pipes_struct
*p
,
1896 struct lsa_CreateTrustedDomain
*r
)
1898 struct lsa_CreateTrustedDomainEx2 c
;
1899 struct lsa_TrustDomainInfoInfoEx info
;
1900 struct lsa_TrustDomainInfoAuthInfoInternal auth_info
;
1902 ZERO_STRUCT(auth_info
);
1904 info
.domain_name
= r
->in
.info
->name
;
1905 info
.netbios_name
= r
->in
.info
->name
;
1906 info
.sid
= r
->in
.info
->sid
;
1907 info
.trust_direction
= LSA_TRUST_DIRECTION_OUTBOUND
;
1908 info
.trust_type
= LSA_TRUST_TYPE_DOWNLEVEL
;
1909 info
.trust_attributes
= 0;
1911 c
.in
.policy_handle
= r
->in
.policy_handle
;
1913 c
.in
.auth_info_internal
= &auth_info
;
1914 c
.in
.access_mask
= r
->in
.access_mask
;
1915 c
.out
.trustdom_handle
= r
->out
.trustdom_handle
;
1917 return _lsa_CreateTrustedDomainEx2(p
, &c
);
1920 /***************************************************************************
1921 _lsa_DeleteTrustedDomain
1922 ***************************************************************************/
1924 NTSTATUS
_lsa_DeleteTrustedDomain(struct pipes_struct
*p
,
1925 struct lsa_DeleteTrustedDomain
*r
)
1928 struct lsa_info
*handle
;
1929 struct pdb_trusted_domain
*td
;
1930 struct samu
*sam_acct
;
1933 /* find the connection policy handle. */
1934 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
1935 return NT_STATUS_INVALID_HANDLE
;
1938 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
1939 return NT_STATUS_INVALID_HANDLE
;
1942 if (!(handle
->access
& LSA_POLICY_TRUST_ADMIN
)) {
1943 return NT_STATUS_ACCESS_DENIED
;
1946 status
= pdb_get_trusted_domain_by_sid(p
->mem_ctx
, r
->in
.dom_sid
, &td
);
1947 if (!NT_STATUS_IS_OK(status
)) {
1951 if (td
->netbios_name
== NULL
|| *td
->netbios_name
== '\0') {
1952 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
1953 sid_string_tos(r
->in
.dom_sid
)));
1954 return NT_STATUS_UNSUCCESSFUL
;
1957 if (td
->trust_direction
& LSA_TRUST_DIRECTION_INBOUND
) {
1958 sam_acct
= samu_new(p
->mem_ctx
);
1959 if (sam_acct
== NULL
) {
1960 return NT_STATUS_NO_MEMORY
;
1963 acct_name
= talloc_asprintf(p
->mem_ctx
, "%s$", td
->netbios_name
);
1964 if (acct_name
== NULL
) {
1965 return NT_STATUS_NO_MEMORY
;
1967 if (!pdb_set_username(sam_acct
, acct_name
, PDB_SET
)) {
1968 return NT_STATUS_UNSUCCESSFUL
;
1970 status
= pdb_delete_sam_account(sam_acct
);
1971 if (!NT_STATUS_IS_OK(status
)) {
1976 status
= pdb_del_trusted_domain(td
->netbios_name
);
1977 if (!NT_STATUS_IS_OK(status
)) {
1981 return NT_STATUS_OK
;
1984 /***************************************************************************
1985 _lsa_CloseTrustedDomainEx
1986 ***************************************************************************/
1988 NTSTATUS
_lsa_CloseTrustedDomainEx(struct pipes_struct
*p
,
1989 struct lsa_CloseTrustedDomainEx
*r
)
1991 return NT_STATUS_NOT_IMPLEMENTED
;
1994 /***************************************************************************
1995 _lsa_QueryTrustedDomainInfo
1996 ***************************************************************************/
1998 NTSTATUS
_lsa_QueryTrustedDomainInfo(struct pipes_struct
*p
,
1999 struct lsa_QueryTrustedDomainInfo
*r
)
2002 struct lsa_info
*handle
;
2003 union lsa_TrustedDomainInfo
*info
;
2004 struct pdb_trusted_domain
*td
;
2005 uint32_t acc_required
;
2007 /* find the connection policy handle. */
2008 if (!find_policy_by_hnd(p
, r
->in
.trustdom_handle
, (void **)(void *)&handle
)) {
2009 return NT_STATUS_INVALID_HANDLE
;
2012 if (handle
->type
!= LSA_HANDLE_TRUST_TYPE
) {
2013 return NT_STATUS_INVALID_HANDLE
;
2016 switch (r
->in
.level
) {
2017 case LSA_TRUSTED_DOMAIN_INFO_NAME
:
2018 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
2020 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS
:
2021 acc_required
= LSA_TRUSTED_QUERY_CONTROLLERS
;
2023 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET
:
2024 acc_required
= LSA_TRUSTED_QUERY_POSIX
;
2026 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD
:
2027 acc_required
= LSA_TRUSTED_QUERY_AUTH
;
2029 case LSA_TRUSTED_DOMAIN_INFO_BASIC
:
2030 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
2032 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX
:
2033 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
2035 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO
:
2036 acc_required
= LSA_TRUSTED_QUERY_AUTH
;
2038 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
:
2039 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
|
2040 LSA_TRUSTED_QUERY_POSIX
|
2041 LSA_TRUSTED_QUERY_AUTH
;
2043 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL
:
2044 acc_required
= LSA_TRUSTED_QUERY_AUTH
;
2046 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL
:
2047 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
|
2048 LSA_TRUSTED_QUERY_POSIX
|
2049 LSA_TRUSTED_QUERY_AUTH
;
2051 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL
:
2052 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
;
2054 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL
:
2055 acc_required
= LSA_TRUSTED_QUERY_DOMAIN_NAME
|
2056 LSA_TRUSTED_QUERY_POSIX
|
2057 LSA_TRUSTED_QUERY_AUTH
;
2059 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES
:
2060 acc_required
= LSA_TRUSTED_QUERY_POSIX
;
2063 return NT_STATUS_INVALID_PARAMETER
;
2066 if (!(handle
->access
& acc_required
)) {
2067 return NT_STATUS_ACCESS_DENIED
;
2070 status
= pdb_get_trusted_domain_by_sid(p
->mem_ctx
, &handle
->sid
, &td
);
2071 if (!NT_STATUS_IS_OK(status
)) {
2075 info
= talloc_zero(p
->mem_ctx
, union lsa_TrustedDomainInfo
);
2077 return NT_STATUS_NO_MEMORY
;
2080 switch (r
->in
.level
) {
2081 case LSA_TRUSTED_DOMAIN_INFO_NAME
:
2082 init_lsa_StringLarge(&info
->name
.netbios_name
, td
->netbios_name
);
2084 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS
:
2085 return NT_STATUS_INVALID_PARAMETER
;
2086 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET
:
2088 case LSA_TRUSTED_DOMAIN_INFO_PASSWORD
:
2089 return NT_STATUS_INVALID_INFO_CLASS
;
2090 case LSA_TRUSTED_DOMAIN_INFO_BASIC
:
2091 return NT_STATUS_INVALID_PARAMETER
;
2092 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX
:
2093 init_lsa_StringLarge(&info
->info_ex
.domain_name
, td
->domain_name
);
2094 init_lsa_StringLarge(&info
->info_ex
.netbios_name
, td
->netbios_name
);
2095 info
->info_ex
.sid
= dom_sid_dup(info
, &td
->security_identifier
);
2096 if (!info
->info_ex
.sid
) {
2097 return NT_STATUS_NO_MEMORY
;
2099 info
->info_ex
.trust_direction
= td
->trust_direction
;
2100 info
->info_ex
.trust_type
= td
->trust_type
;
2101 info
->info_ex
.trust_attributes
= td
->trust_attributes
;
2103 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO
:
2104 return NT_STATUS_INVALID_INFO_CLASS
;
2105 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
:
2107 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL
:
2108 return NT_STATUS_INVALID_INFO_CLASS
;
2109 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL
:
2110 return NT_STATUS_INVALID_INFO_CLASS
;
2111 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL
:
2112 return NT_STATUS_INVALID_PARAMETER
;
2113 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL
:
2115 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES
:
2118 return NT_STATUS_INVALID_PARAMETER
;
2121 *r
->out
.info
= info
;
2123 return NT_STATUS_OK
;
2126 /***************************************************************************
2127 _lsa_QueryTrustedDomainInfoBySid
2128 ***************************************************************************/
2130 NTSTATUS
_lsa_QueryTrustedDomainInfoBySid(struct pipes_struct
*p
,
2131 struct lsa_QueryTrustedDomainInfoBySid
*r
)
2134 struct policy_handle trustdom_handle
;
2135 struct lsa_OpenTrustedDomain o
;
2136 struct lsa_QueryTrustedDomainInfo q
;
2139 o
.in
.handle
= r
->in
.handle
;
2140 o
.in
.sid
= r
->in
.dom_sid
;
2141 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2142 o
.out
.trustdom_handle
= &trustdom_handle
;
2144 status
= _lsa_OpenTrustedDomain(p
, &o
);
2145 if (!NT_STATUS_IS_OK(status
)) {
2149 q
.in
.trustdom_handle
= &trustdom_handle
;
2150 q
.in
.level
= r
->in
.level
;
2151 q
.out
.info
= r
->out
.info
;
2153 status
= _lsa_QueryTrustedDomainInfo(p
, &q
);
2154 if (!NT_STATUS_IS_OK(status
)) {
2158 c
.in
.handle
= &trustdom_handle
;
2159 c
.out
.handle
= &trustdom_handle
;
2161 return _lsa_Close(p
, &c
);
2164 /***************************************************************************
2165 _lsa_QueryTrustedDomainInfoByName
2166 ***************************************************************************/
2168 NTSTATUS
_lsa_QueryTrustedDomainInfoByName(struct pipes_struct
*p
,
2169 struct lsa_QueryTrustedDomainInfoByName
*r
)
2172 struct policy_handle trustdom_handle
;
2173 struct lsa_OpenTrustedDomainByName o
;
2174 struct lsa_QueryTrustedDomainInfo q
;
2177 o
.in
.handle
= r
->in
.handle
;
2178 o
.in
.name
.string
= r
->in
.trusted_domain
->string
;
2179 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2180 o
.out
.trustdom_handle
= &trustdom_handle
;
2182 status
= _lsa_OpenTrustedDomainByName(p
, &o
);
2183 if (!NT_STATUS_IS_OK(status
)) {
2184 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_DOMAIN
)) {
2185 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2190 q
.in
.trustdom_handle
= &trustdom_handle
;
2191 q
.in
.level
= r
->in
.level
;
2192 q
.out
.info
= r
->out
.info
;
2194 status
= _lsa_QueryTrustedDomainInfo(p
, &q
);
2195 if (!NT_STATUS_IS_OK(status
)) {
2199 c
.in
.handle
= &trustdom_handle
;
2200 c
.out
.handle
= &trustdom_handle
;
2202 return _lsa_Close(p
, &c
);
2205 /***************************************************************************
2207 ***************************************************************************/
2209 NTSTATUS
_lsa_CreateSecret(struct pipes_struct
*p
,
2210 struct lsa_CreateSecret
*r
)
2213 struct lsa_info
*handle
;
2214 uint32_t acc_granted
;
2215 struct security_descriptor
*psd
;
2218 /* find the connection policy handle. */
2219 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
2220 return NT_STATUS_INVALID_HANDLE
;
2223 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2224 return NT_STATUS_INVALID_HANDLE
;
2227 /* check if the user has enough rights */
2229 if (!(handle
->access
& LSA_POLICY_CREATE_SECRET
)) {
2230 return NT_STATUS_ACCESS_DENIED
;
2233 /* Work out max allowed. */
2234 map_max_allowed_access(p
->session_info
->security_token
,
2235 p
->session_info
->unix_token
,
2236 &r
->in
.access_mask
);
2238 /* map the generic bits to the lsa policy ones */
2239 se_map_generic(&r
->in
.access_mask
, &lsa_secret_mapping
);
2241 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
2242 &lsa_secret_mapping
,
2244 if (!NT_STATUS_IS_OK(status
)) {
2248 status
= access_check_object(psd
, p
->session_info
->security_token
,
2249 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
2251 &acc_granted
, "_lsa_CreateSecret");
2252 if (!NT_STATUS_IS_OK(status
)) {
2256 if (!r
->in
.name
.string
) {
2257 return NT_STATUS_INVALID_PARAMETER
;
2260 if (strlen(r
->in
.name
.string
) > 128) {
2261 return NT_STATUS_NAME_TOO_LONG
;
2264 status
= pdb_get_secret(p
->mem_ctx
, r
->in
.name
.string
,
2265 NULL
, NULL
, NULL
, NULL
, NULL
);
2266 if (NT_STATUS_IS_OK(status
)) {
2267 return NT_STATUS_OBJECT_NAME_COLLISION
;
2270 status
= pdb_set_secret(r
->in
.name
.string
, NULL
, NULL
, psd
);
2271 if (!NT_STATUS_IS_OK(status
)) {
2275 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
2276 LSA_HANDLE_SECRET_TYPE
,
2282 if (!NT_STATUS_IS_OK(status
)) {
2283 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2286 return NT_STATUS_OK
;
2289 /***************************************************************************
2290 ***************************************************************************/
2292 NTSTATUS
_lsa_SetSecret(struct pipes_struct
*p
, struct lsa_SetSecret
*r
)
2294 return NT_STATUS_ACCESS_DENIED
;
2297 /***************************************************************************
2299 ***************************************************************************/
2301 NTSTATUS
_lsa_DeleteObject(struct pipes_struct
*p
,
2302 struct lsa_DeleteObject
*r
)
2305 struct lsa_info
*info
= NULL
;
2307 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
)) {
2308 return NT_STATUS_INVALID_HANDLE
;
2311 if (!(info
->access
& SEC_STD_DELETE
)) {
2312 return NT_STATUS_ACCESS_DENIED
;
2315 switch (info
->type
) {
2316 case LSA_HANDLE_ACCOUNT_TYPE
:
2317 status
= privilege_delete_account(&info
->sid
);
2318 if (!NT_STATUS_IS_OK(status
)) {
2319 DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2320 nt_errstr(status
)));
2324 case LSA_HANDLE_TRUST_TYPE
:
2325 if (!pdb_del_trusteddom_pw(info
->name
)) {
2326 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2328 status
= NT_STATUS_OK
;
2331 return NT_STATUS_INVALID_HANDLE
;
2334 close_policy_hnd(p
, r
->in
.handle
);
2335 ZERO_STRUCTP(r
->out
.handle
);
2340 /***************************************************************************
2342 ***************************************************************************/
2344 NTSTATUS
_lsa_EnumPrivs(struct pipes_struct
*p
,
2345 struct lsa_EnumPrivs
*r
)
2347 struct lsa_info
*handle
;
2349 uint32 enum_context
= *r
->in
.resume_handle
;
2350 int num_privs
= num_privileges_in_short_list();
2351 struct lsa_PrivEntry
*entries
= NULL
;
2353 /* remember that the enum_context starts at 0 and not 1 */
2355 if ( enum_context
>= num_privs
)
2356 return NT_STATUS_NO_MORE_ENTRIES
;
2358 DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2359 enum_context
, num_privs
));
2361 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2362 return NT_STATUS_INVALID_HANDLE
;
2364 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2365 return NT_STATUS_INVALID_HANDLE
;
2368 /* check if the user has enough rights
2369 I don't know if it's the right one. not documented. */
2371 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
2372 return NT_STATUS_ACCESS_DENIED
;
2375 entries
= talloc_zero_array(p
->mem_ctx
, struct lsa_PrivEntry
, num_privs
);
2377 return NT_STATUS_NO_MEMORY
;
2383 for (i
= 0; i
< num_privs
; i
++) {
2384 if( i
< enum_context
) {
2386 init_lsa_StringLarge(&entries
[i
].name
, NULL
);
2388 entries
[i
].luid
.low
= 0;
2389 entries
[i
].luid
.high
= 0;
2392 init_lsa_StringLarge(&entries
[i
].name
, sec_privilege_name_from_index(i
));
2394 entries
[i
].luid
.low
= sec_privilege_from_index(i
);
2395 entries
[i
].luid
.high
= 0;
2399 enum_context
= num_privs
;
2401 *r
->out
.resume_handle
= enum_context
;
2402 r
->out
.privs
->count
= num_privs
;
2403 r
->out
.privs
->privs
= entries
;
2405 return NT_STATUS_OK
;
2408 /***************************************************************************
2409 _lsa_LookupPrivDisplayName
2410 ***************************************************************************/
2412 NTSTATUS
_lsa_LookupPrivDisplayName(struct pipes_struct
*p
,
2413 struct lsa_LookupPrivDisplayName
*r
)
2415 struct lsa_info
*handle
;
2416 const char *description
;
2417 struct lsa_StringLarge
*lsa_name
;
2419 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2420 return NT_STATUS_INVALID_HANDLE
;
2422 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2423 return NT_STATUS_INVALID_HANDLE
;
2426 /* check if the user has enough rights */
2429 * I don't know if it's the right one. not documented.
2431 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
2432 return NT_STATUS_ACCESS_DENIED
;
2434 DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r
->in
.name
->string
));
2436 description
= get_privilege_dispname(r
->in
.name
->string
);
2438 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2439 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2442 DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description
));
2444 lsa_name
= talloc_zero(p
->mem_ctx
, struct lsa_StringLarge
);
2446 return NT_STATUS_NO_MEMORY
;
2449 init_lsa_StringLarge(lsa_name
, description
);
2451 *r
->out
.returned_language_id
= r
->in
.language_id
;
2452 *r
->out
.disp_name
= lsa_name
;
2454 return NT_STATUS_OK
;
2457 /***************************************************************************
2459 ***************************************************************************/
2461 NTSTATUS
_lsa_EnumAccounts(struct pipes_struct
*p
,
2462 struct lsa_EnumAccounts
*r
)
2464 struct lsa_info
*handle
;
2465 struct dom_sid
*sid_list
;
2466 int i
, j
, num_entries
;
2468 struct lsa_SidPtr
*sids
= NULL
;
2470 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2471 return NT_STATUS_INVALID_HANDLE
;
2473 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2474 return NT_STATUS_INVALID_HANDLE
;
2477 if (!(handle
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
2478 return NT_STATUS_ACCESS_DENIED
;
2483 /* The only way we can currently find out all the SIDs that have been
2484 privileged is to scan all privileges */
2486 status
= privilege_enumerate_accounts(&sid_list
, &num_entries
);
2487 if (!NT_STATUS_IS_OK(status
)) {
2491 if (*r
->in
.resume_handle
>= num_entries
) {
2492 return NT_STATUS_NO_MORE_ENTRIES
;
2495 if (num_entries
- *r
->in
.resume_handle
) {
2496 sids
= talloc_zero_array(p
->mem_ctx
, struct lsa_SidPtr
,
2497 num_entries
- *r
->in
.resume_handle
);
2499 talloc_free(sid_list
);
2500 return NT_STATUS_NO_MEMORY
;
2503 for (i
= *r
->in
.resume_handle
, j
= 0; i
< num_entries
; i
++, j
++) {
2504 sids
[j
].sid
= dom_sid_dup(p
->mem_ctx
, &sid_list
[i
]);
2506 talloc_free(sid_list
);
2507 return NT_STATUS_NO_MEMORY
;
2512 talloc_free(sid_list
);
2514 *r
->out
.resume_handle
= num_entries
;
2515 r
->out
.sids
->num_sids
= num_entries
;
2516 r
->out
.sids
->sids
= sids
;
2518 return NT_STATUS_OK
;
2521 /***************************************************************************
2523 ***************************************************************************/
2525 NTSTATUS
_lsa_GetUserName(struct pipes_struct
*p
,
2526 struct lsa_GetUserName
*r
)
2528 const char *username
, *domname
;
2529 struct lsa_String
*account_name
= NULL
;
2530 struct lsa_String
*authority_name
= NULL
;
2532 if (r
->in
.account_name
&&
2533 *r
->in
.account_name
) {
2534 return NT_STATUS_INVALID_PARAMETER
;
2537 if (r
->in
.authority_name
&&
2538 *r
->in
.authority_name
) {
2539 return NT_STATUS_INVALID_PARAMETER
;
2542 if (security_session_user_level(p
->session_info
, NULL
) < SECURITY_USER
) {
2544 * I'm 99% sure this is not the right place to do this,
2545 * global_sid_Anonymous should probably be put into the token
2546 * instead of the guest id -- vl
2548 if (!lookup_sid(p
->mem_ctx
, &global_sid_Anonymous
,
2549 &domname
, &username
, NULL
)) {
2550 return NT_STATUS_NO_MEMORY
;
2553 username
= p
->session_info
->unix_info
->sanitized_username
;
2554 domname
= p
->session_info
->info
->domain_name
;
2557 account_name
= talloc(p
->mem_ctx
, struct lsa_String
);
2558 if (!account_name
) {
2559 return NT_STATUS_NO_MEMORY
;
2561 init_lsa_String(account_name
, username
);
2563 if (r
->out
.authority_name
) {
2564 authority_name
= talloc(p
->mem_ctx
, struct lsa_String
);
2565 if (!authority_name
) {
2566 return NT_STATUS_NO_MEMORY
;
2568 init_lsa_String(authority_name
, domname
);
2571 *r
->out
.account_name
= account_name
;
2572 if (r
->out
.authority_name
) {
2573 *r
->out
.authority_name
= authority_name
;
2576 return NT_STATUS_OK
;
2579 /***************************************************************************
2581 ***************************************************************************/
2583 NTSTATUS
_lsa_CreateAccount(struct pipes_struct
*p
,
2584 struct lsa_CreateAccount
*r
)
2587 struct lsa_info
*handle
;
2588 uint32_t acc_granted
;
2589 struct security_descriptor
*psd
;
2592 /* find the connection policy handle. */
2593 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2594 return NT_STATUS_INVALID_HANDLE
;
2596 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2597 return NT_STATUS_INVALID_HANDLE
;
2600 /* check if the user has enough rights */
2602 if (!(handle
->access
& LSA_POLICY_CREATE_ACCOUNT
)) {
2603 return NT_STATUS_ACCESS_DENIED
;
2606 /* Work out max allowed. */
2607 map_max_allowed_access(p
->session_info
->security_token
,
2608 p
->session_info
->unix_token
,
2609 &r
->in
.access_mask
);
2611 /* map the generic bits to the lsa policy ones */
2612 se_map_generic(&r
->in
.access_mask
, &lsa_account_mapping
);
2614 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
2615 &lsa_account_mapping
,
2616 r
->in
.sid
, LSA_POLICY_ALL_ACCESS
);
2617 if (!NT_STATUS_IS_OK(status
)) {
2621 status
= access_check_object(psd
, p
->session_info
->security_token
,
2622 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0, r
->in
.access_mask
,
2623 &acc_granted
, "_lsa_CreateAccount");
2624 if (!NT_STATUS_IS_OK(status
)) {
2628 if ( is_privileged_sid( r
->in
.sid
) )
2629 return NT_STATUS_OBJECT_NAME_COLLISION
;
2631 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
2632 LSA_HANDLE_ACCOUNT_TYPE
,
2637 r
->out
.acct_handle
);
2638 if (!NT_STATUS_IS_OK(status
)) {
2639 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2642 return privilege_create_account(r
->in
.sid
);
2645 /***************************************************************************
2647 ***************************************************************************/
2649 NTSTATUS
_lsa_OpenAccount(struct pipes_struct
*p
,
2650 struct lsa_OpenAccount
*r
)
2652 struct lsa_info
*handle
;
2653 struct security_descriptor
*psd
= NULL
;
2655 uint32_t des_access
= r
->in
.access_mask
;
2656 uint32_t acc_granted
;
2659 /* find the connection policy handle. */
2660 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2661 return NT_STATUS_INVALID_HANDLE
;
2663 if (handle
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2664 return NT_STATUS_INVALID_HANDLE
;
2667 /* des_access is for the account here, not the policy
2668 * handle - so don't check against policy handle. */
2670 /* Work out max allowed. */
2671 map_max_allowed_access(p
->session_info
->security_token
,
2672 p
->session_info
->unix_token
,
2675 /* map the generic bits to the lsa account ones */
2676 se_map_generic(&des_access
, &lsa_account_mapping
);
2678 /* get the generic lsa account SD until we store it */
2679 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
2680 &lsa_account_mapping
,
2681 r
->in
.sid
, LSA_ACCOUNT_ALL_ACCESS
);
2682 if (!NT_STATUS_IS_OK(status
)) {
2686 status
= access_check_object(psd
, p
->session_info
->security_token
,
2687 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0, des_access
,
2688 &acc_granted
, "_lsa_OpenAccount" );
2689 if (!NT_STATUS_IS_OK(status
)) {
2693 /* TODO: Fis the parsing routine before reenabling this check! */
2695 if (!lookup_sid(&handle
->sid
, dom_name
, name
, &type
))
2696 return NT_STATUS_ACCESS_DENIED
;
2699 status
= create_lsa_policy_handle(p
->mem_ctx
, p
,
2700 LSA_HANDLE_ACCOUNT_TYPE
,
2705 r
->out
.acct_handle
);
2706 if (!NT_STATUS_IS_OK(status
)) {
2707 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2710 return NT_STATUS_OK
;
2713 /***************************************************************************
2714 _lsa_EnumPrivsAccount
2715 For a given SID, enumerate all the privilege this account has.
2716 ***************************************************************************/
2718 NTSTATUS
_lsa_EnumPrivsAccount(struct pipes_struct
*p
,
2719 struct lsa_EnumPrivsAccount
*r
)
2721 NTSTATUS status
= NT_STATUS_OK
;
2722 struct lsa_info
*info
=NULL
;
2723 PRIVILEGE_SET
*privileges
;
2724 struct lsa_PrivilegeSet
*priv_set
= NULL
;
2726 /* find the connection policy handle. */
2727 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
2728 return NT_STATUS_INVALID_HANDLE
;
2730 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
2731 return NT_STATUS_INVALID_HANDLE
;
2734 if (!(info
->access
& LSA_ACCOUNT_VIEW
))
2735 return NT_STATUS_ACCESS_DENIED
;
2737 status
= get_privileges_for_sid_as_set(p
->mem_ctx
, &privileges
, &info
->sid
);
2738 if (!NT_STATUS_IS_OK(status
)) {
2742 *r
->out
.privs
= priv_set
= talloc_zero(p
->mem_ctx
, struct lsa_PrivilegeSet
);
2744 return NT_STATUS_NO_MEMORY
;
2747 DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
2748 sid_string_dbg(&info
->sid
),
2749 privileges
->count
));
2751 priv_set
->count
= privileges
->count
;
2752 priv_set
->unknown
= 0;
2753 priv_set
->set
= talloc_move(priv_set
, &privileges
->set
);
2758 /***************************************************************************
2759 _lsa_GetSystemAccessAccount
2760 ***************************************************************************/
2762 NTSTATUS
_lsa_GetSystemAccessAccount(struct pipes_struct
*p
,
2763 struct lsa_GetSystemAccessAccount
*r
)
2766 struct lsa_info
*info
= NULL
;
2767 struct lsa_EnumPrivsAccount e
;
2768 struct lsa_PrivilegeSet
*privset
;
2770 /* find the connection policy handle. */
2772 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
2773 return NT_STATUS_INVALID_HANDLE
;
2775 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
2776 return NT_STATUS_INVALID_HANDLE
;
2779 if (!(info
->access
& LSA_ACCOUNT_VIEW
))
2780 return NT_STATUS_ACCESS_DENIED
;
2782 privset
= talloc_zero(p
->mem_ctx
, struct lsa_PrivilegeSet
);
2784 return NT_STATUS_NO_MEMORY
;
2787 e
.in
.handle
= r
->in
.handle
;
2788 e
.out
.privs
= &privset
;
2790 status
= _lsa_EnumPrivsAccount(p
, &e
);
2791 if (!NT_STATUS_IS_OK(status
)) {
2792 DEBUG(10,("_lsa_GetSystemAccessAccount: "
2793 "failed to call _lsa_EnumPrivsAccount(): %s\n",
2794 nt_errstr(status
)));
2798 /* Samba4 would iterate over the privset to merge the policy mode bits,
2799 * not sure samba3 can do the same here, so just return what we did in
2803 0x01 -> Log on locally
2804 0x02 -> Access this computer from network
2805 0x04 -> Log on as a batch job
2806 0x10 -> Log on as a service
2808 they can be ORed together
2811 *r
->out
.access_mask
= LSA_POLICY_MODE_INTERACTIVE
|
2812 LSA_POLICY_MODE_NETWORK
;
2814 return NT_STATUS_OK
;
2817 /***************************************************************************
2818 update the systemaccount information
2819 ***************************************************************************/
2821 NTSTATUS
_lsa_SetSystemAccessAccount(struct pipes_struct
*p
,
2822 struct lsa_SetSystemAccessAccount
*r
)
2824 struct lsa_info
*info
=NULL
;
2827 /* find the connection policy handle. */
2828 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
2829 return NT_STATUS_INVALID_HANDLE
;
2831 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
2832 return NT_STATUS_INVALID_HANDLE
;
2835 if (!(info
->access
& LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS
)) {
2836 return NT_STATUS_ACCESS_DENIED
;
2839 if (!pdb_getgrsid(&map
, info
->sid
))
2840 return NT_STATUS_NO_SUCH_GROUP
;
2842 return pdb_update_group_mapping_entry(&map
);
2845 /***************************************************************************
2846 _lsa_AddPrivilegesToAccount
2847 For a given SID, add some privileges.
2848 ***************************************************************************/
2850 NTSTATUS
_lsa_AddPrivilegesToAccount(struct pipes_struct
*p
,
2851 struct lsa_AddPrivilegesToAccount
*r
)
2853 struct lsa_info
*info
= NULL
;
2854 struct lsa_PrivilegeSet
*set
= NULL
;
2856 /* find the connection policy handle. */
2857 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
2858 return NT_STATUS_INVALID_HANDLE
;
2860 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
2861 return NT_STATUS_INVALID_HANDLE
;
2864 if (!(info
->access
& LSA_ACCOUNT_ADJUST_PRIVILEGES
)) {
2865 return NT_STATUS_ACCESS_DENIED
;
2870 if ( !grant_privilege_set( &info
->sid
, set
) ) {
2871 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
2872 sid_string_dbg(&info
->sid
) ));
2873 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2876 return NT_STATUS_OK
;
2879 /***************************************************************************
2880 _lsa_RemovePrivilegesFromAccount
2881 For a given SID, remove some privileges.
2882 ***************************************************************************/
2884 NTSTATUS
_lsa_RemovePrivilegesFromAccount(struct pipes_struct
*p
,
2885 struct lsa_RemovePrivilegesFromAccount
*r
)
2887 struct lsa_info
*info
= NULL
;
2888 struct lsa_PrivilegeSet
*set
= NULL
;
2890 /* find the connection policy handle. */
2891 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
2892 return NT_STATUS_INVALID_HANDLE
;
2894 if (info
->type
!= LSA_HANDLE_ACCOUNT_TYPE
) {
2895 return NT_STATUS_INVALID_HANDLE
;
2898 if (!(info
->access
& LSA_ACCOUNT_ADJUST_PRIVILEGES
)) {
2899 return NT_STATUS_ACCESS_DENIED
;
2904 if ( !revoke_privilege_set( &info
->sid
, set
) ) {
2905 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
2906 sid_string_dbg(&info
->sid
) ));
2907 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2910 return NT_STATUS_OK
;
2913 /***************************************************************************
2915 ***************************************************************************/
2917 NTSTATUS
_lsa_LookupPrivName(struct pipes_struct
*p
,
2918 struct lsa_LookupPrivName
*r
)
2920 struct lsa_info
*info
= NULL
;
2922 struct lsa_StringLarge
*lsa_name
;
2924 /* find the connection policy handle. */
2925 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
)) {
2926 return NT_STATUS_INVALID_HANDLE
;
2929 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
2930 return NT_STATUS_INVALID_HANDLE
;
2933 if (!(info
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
)) {
2934 return NT_STATUS_ACCESS_DENIED
;
2937 if (r
->in
.luid
->high
!= 0) {
2938 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2941 name
= sec_privilege_name(r
->in
.luid
->low
);
2943 return NT_STATUS_NO_SUCH_PRIVILEGE
;
2946 lsa_name
= talloc_zero(p
->mem_ctx
, struct lsa_StringLarge
);
2948 return NT_STATUS_NO_MEMORY
;
2951 lsa_name
->string
= talloc_strdup(lsa_name
, name
);
2952 if (!lsa_name
->string
) {
2953 TALLOC_FREE(lsa_name
);
2954 return NT_STATUS_NO_MEMORY
;
2957 *r
->out
.name
= lsa_name
;
2959 return NT_STATUS_OK
;
2962 /***************************************************************************
2964 ***************************************************************************/
2966 NTSTATUS
_lsa_QuerySecurity(struct pipes_struct
*p
,
2967 struct lsa_QuerySecurity
*r
)
2969 struct lsa_info
*handle
=NULL
;
2970 struct security_descriptor
*psd
= NULL
;
2974 /* find the connection policy handle. */
2975 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
))
2976 return NT_STATUS_INVALID_HANDLE
;
2978 switch (handle
->type
) {
2979 case LSA_HANDLE_POLICY_TYPE
:
2980 case LSA_HANDLE_ACCOUNT_TYPE
:
2981 case LSA_HANDLE_TRUST_TYPE
:
2983 sd_size
= ndr_size_security_descriptor(psd
, 0);
2984 status
= NT_STATUS_OK
;
2987 status
= NT_STATUS_INVALID_HANDLE
;
2991 if (!NT_STATUS_IS_OK(status
)) {
2995 *r
->out
.sdbuf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
);
2996 if (!*r
->out
.sdbuf
) {
2997 return NT_STATUS_NO_MEMORY
;
3003 /***************************************************************************
3004 _lsa_AddAccountRights
3005 ***************************************************************************/
3007 NTSTATUS
_lsa_AddAccountRights(struct pipes_struct
*p
,
3008 struct lsa_AddAccountRights
*r
)
3010 struct lsa_info
*info
= NULL
;
3012 uint32_t acc_granted
= 0;
3013 struct security_descriptor
*psd
= NULL
;
3018 /* find the connection policy handle. */
3019 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3020 return NT_STATUS_INVALID_HANDLE
;
3022 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3023 return NT_STATUS_INVALID_HANDLE
;
3026 /* get the generic lsa account SD for this SID until we store it */
3027 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
3028 &lsa_account_mapping
,
3029 r
->in
.sid
, LSA_ACCOUNT_ALL_ACCESS
);
3030 if (!NT_STATUS_IS_OK(status
)) {
3035 * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3036 * on the policy handle. If it does, ask for
3037 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3038 * on the account sid. We don't check here so just use the latter. JRA.
3041 status
= access_check_object(psd
, p
->session_info
->security_token
,
3042 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
3043 LSA_ACCOUNT_ADJUST_PRIVILEGES
|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS
|LSA_ACCOUNT_VIEW
,
3044 &acc_granted
, "_lsa_AddAccountRights" );
3045 if (!NT_STATUS_IS_OK(status
)) {
3049 /* according to an NT4 PDC, you can add privileges to SIDs even without
3050 call_lsa_create_account() first. And you can use any arbitrary SID. */
3052 sid_copy( &sid
, r
->in
.sid
);
3054 for ( i
=0; i
< r
->in
.rights
->count
; i
++ ) {
3056 const char *privname
= r
->in
.rights
->names
[i
].string
;
3058 /* only try to add non-null strings */
3063 if ( !grant_privilege_by_name( &sid
, privname
) ) {
3064 DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3066 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3070 return NT_STATUS_OK
;
3073 /***************************************************************************
3074 _lsa_RemoveAccountRights
3075 ***************************************************************************/
3077 NTSTATUS
_lsa_RemoveAccountRights(struct pipes_struct
*p
,
3078 struct lsa_RemoveAccountRights
*r
)
3080 struct lsa_info
*info
= NULL
;
3082 struct security_descriptor
*psd
= NULL
;
3085 const char *privname
= NULL
;
3086 uint32_t acc_granted
= 0;
3089 /* find the connection policy handle. */
3090 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3091 return NT_STATUS_INVALID_HANDLE
;
3093 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3094 return NT_STATUS_INVALID_HANDLE
;
3097 /* get the generic lsa account SD for this SID until we store it */
3098 status
= make_lsa_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
3099 &lsa_account_mapping
,
3100 r
->in
.sid
, LSA_ACCOUNT_ALL_ACCESS
);
3101 if (!NT_STATUS_IS_OK(status
)) {
3106 * From the MS DOCs. We need
3107 * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3108 * and DELETE on the account sid.
3111 status
= access_check_object(psd
, p
->session_info
->security_token
,
3112 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
, 0,
3113 LSA_ACCOUNT_ADJUST_PRIVILEGES
|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS
|
3114 LSA_ACCOUNT_VIEW
|SEC_STD_DELETE
,
3115 &acc_granted
, "_lsa_RemoveAccountRights");
3116 if (!NT_STATUS_IS_OK(status
)) {
3120 sid_copy( &sid
, r
->in
.sid
);
3122 if ( r
->in
.remove_all
) {
3123 if ( !revoke_all_privileges( &sid
) )
3124 return NT_STATUS_ACCESS_DENIED
;
3126 return NT_STATUS_OK
;
3129 for ( i
=0; i
< r
->in
.rights
->count
; i
++ ) {
3131 privname
= r
->in
.rights
->names
[i
].string
;
3133 /* only try to add non-null strings */
3138 if ( !revoke_privilege_by_name( &sid
, privname
) ) {
3139 DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3141 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3145 return NT_STATUS_OK
;
3148 /*******************************************************************
3149 ********************************************************************/
3151 static NTSTATUS
init_lsa_right_set(TALLOC_CTX
*mem_ctx
,
3152 struct lsa_RightSet
*r
,
3153 PRIVILEGE_SET
*privileges
)
3156 const char *privname
;
3157 const char **privname_array
= NULL
;
3160 for (i
=0; i
<privileges
->count
; i
++) {
3161 if (privileges
->set
[i
].luid
.high
) {
3164 privname
= sec_privilege_name(privileges
->set
[i
].luid
.low
);
3166 if (!add_string_to_array(mem_ctx
, privname
,
3167 &privname_array
, &num_priv
)) {
3168 return NT_STATUS_NO_MEMORY
;
3175 r
->names
= talloc_zero_array(mem_ctx
, struct lsa_StringLarge
,
3178 return NT_STATUS_NO_MEMORY
;
3181 for (i
=0; i
<num_priv
; i
++) {
3182 init_lsa_StringLarge(&r
->names
[i
], privname_array
[i
]);
3185 r
->count
= num_priv
;
3188 return NT_STATUS_OK
;
3191 /***************************************************************************
3192 _lsa_EnumAccountRights
3193 ***************************************************************************/
3195 NTSTATUS
_lsa_EnumAccountRights(struct pipes_struct
*p
,
3196 struct lsa_EnumAccountRights
*r
)
3199 struct lsa_info
*info
= NULL
;
3200 PRIVILEGE_SET
*privileges
;
3202 /* find the connection policy handle. */
3204 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3205 return NT_STATUS_INVALID_HANDLE
;
3207 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3208 return NT_STATUS_INVALID_HANDLE
;
3211 if (!(info
->access
& LSA_ACCOUNT_VIEW
)) {
3212 return NT_STATUS_ACCESS_DENIED
;
3215 /* according to an NT4 PDC, you can add privileges to SIDs even without
3216 call_lsa_create_account() first. And you can use any arbitrary SID. */
3218 /* according to MS-LSAD 3.1.4.5.10 it is required to return
3219 * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3220 * the lsa database */
3222 status
= get_privileges_for_sid_as_set(p
->mem_ctx
, &privileges
, r
->in
.sid
);
3223 if (!NT_STATUS_IS_OK(status
)) {
3227 DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3228 sid_string_dbg(r
->in
.sid
), privileges
->count
));
3230 status
= init_lsa_right_set(p
->mem_ctx
, r
->out
.rights
, privileges
);
3235 /***************************************************************************
3236 _lsa_LookupPrivValue
3237 ***************************************************************************/
3239 NTSTATUS
_lsa_LookupPrivValue(struct pipes_struct
*p
,
3240 struct lsa_LookupPrivValue
*r
)
3242 struct lsa_info
*info
= NULL
;
3243 const char *name
= NULL
;
3245 /* find the connection policy handle. */
3247 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3248 return NT_STATUS_INVALID_HANDLE
;
3250 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3251 return NT_STATUS_INVALID_HANDLE
;
3254 if (!(info
->access
& LSA_POLICY_LOOKUP_NAMES
))
3255 return NT_STATUS_ACCESS_DENIED
;
3257 name
= r
->in
.name
->string
;
3259 DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name
));
3261 r
->out
.luid
->low
= sec_privilege_id(name
);
3262 r
->out
.luid
->high
= 0;
3263 if (r
->out
.luid
->low
== SEC_PRIV_INVALID
) {
3264 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3266 return NT_STATUS_OK
;
3269 /***************************************************************************
3270 _lsa_EnumAccountsWithUserRight
3271 ***************************************************************************/
3273 NTSTATUS
_lsa_EnumAccountsWithUserRight(struct pipes_struct
*p
,
3274 struct lsa_EnumAccountsWithUserRight
*r
)
3277 struct lsa_info
*info
= NULL
;
3278 struct dom_sid
*sids
= NULL
;
3281 enum sec_privilege privilege
;
3283 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
)) {
3284 return NT_STATUS_INVALID_HANDLE
;
3287 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3288 return NT_STATUS_INVALID_HANDLE
;
3291 if (!(info
->access
& LSA_POLICY_LOOKUP_NAMES
)) {
3292 return NT_STATUS_ACCESS_DENIED
;
3295 if (!r
->in
.name
|| !r
->in
.name
->string
) {
3296 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3299 privilege
= sec_privilege_id(r
->in
.name
->string
);
3300 if (privilege
== SEC_PRIV_INVALID
) {
3301 return NT_STATUS_NO_SUCH_PRIVILEGE
;
3304 status
= privilege_enum_sids(privilege
, p
->mem_ctx
,
3306 if (!NT_STATUS_IS_OK(status
)) {
3310 r
->out
.sids
->num_sids
= num_sids
;
3311 r
->out
.sids
->sids
= talloc_array(p
->mem_ctx
, struct lsa_SidPtr
,
3312 r
->out
.sids
->num_sids
);
3314 for (i
=0; i
< r
->out
.sids
->num_sids
; i
++) {
3315 r
->out
.sids
->sids
[i
].sid
= dom_sid_dup(r
->out
.sids
->sids
,
3317 if (!r
->out
.sids
->sids
[i
].sid
) {
3318 TALLOC_FREE(r
->out
.sids
->sids
);
3319 r
->out
.sids
->num_sids
= 0;
3320 return NT_STATUS_NO_MEMORY
;
3324 return NT_STATUS_OK
;
3327 /***************************************************************************
3329 ***************************************************************************/
3331 NTSTATUS
_lsa_Delete(struct pipes_struct
*p
,
3332 struct lsa_Delete
*r
)
3334 return NT_STATUS_NOT_SUPPORTED
;
3338 * From here on the server routines are just dummy ones to make smbd link with
3339 * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3340 * pulling the server stubs across one by one.
3343 NTSTATUS
_lsa_SetSecObj(struct pipes_struct
*p
, struct lsa_SetSecObj
*r
)
3345 p
->rng_fault_state
= True
;
3346 return NT_STATUS_NOT_IMPLEMENTED
;
3349 NTSTATUS
_lsa_ChangePassword(struct pipes_struct
*p
,
3350 struct lsa_ChangePassword
*r
)
3352 p
->rng_fault_state
= True
;
3353 return NT_STATUS_NOT_IMPLEMENTED
;
3356 NTSTATUS
_lsa_SetInfoPolicy(struct pipes_struct
*p
, struct lsa_SetInfoPolicy
*r
)
3358 p
->rng_fault_state
= True
;
3359 return NT_STATUS_NOT_IMPLEMENTED
;
3362 NTSTATUS
_lsa_ClearAuditLog(struct pipes_struct
*p
, struct lsa_ClearAuditLog
*r
)
3364 p
->rng_fault_state
= True
;
3365 return NT_STATUS_NOT_IMPLEMENTED
;
3368 NTSTATUS
_lsa_GetQuotasForAccount(struct pipes_struct
*p
,
3369 struct lsa_GetQuotasForAccount
*r
)
3371 p
->rng_fault_state
= True
;
3372 return NT_STATUS_NOT_IMPLEMENTED
;
3375 NTSTATUS
_lsa_SetQuotasForAccount(struct pipes_struct
*p
,
3376 struct lsa_SetQuotasForAccount
*r
)
3378 p
->rng_fault_state
= True
;
3379 return NT_STATUS_NOT_IMPLEMENTED
;
3382 NTSTATUS
_lsa_SetInformationTrustedDomain(struct pipes_struct
*p
,
3383 struct lsa_SetInformationTrustedDomain
*r
)
3385 p
->rng_fault_state
= True
;
3386 return NT_STATUS_NOT_IMPLEMENTED
;
3389 NTSTATUS
_lsa_QuerySecret(struct pipes_struct
*p
, struct lsa_QuerySecret
*r
)
3391 p
->rng_fault_state
= True
;
3392 return NT_STATUS_NOT_IMPLEMENTED
;
3395 NTSTATUS
_lsa_SetTrustedDomainInfo(struct pipes_struct
*p
,
3396 struct lsa_SetTrustedDomainInfo
*r
)
3398 p
->rng_fault_state
= True
;
3399 return NT_STATUS_NOT_IMPLEMENTED
;
3402 NTSTATUS
_lsa_StorePrivateData(struct pipes_struct
*p
,
3403 struct lsa_StorePrivateData
*r
)
3405 p
->rng_fault_state
= True
;
3406 return NT_STATUS_NOT_IMPLEMENTED
;
3409 NTSTATUS
_lsa_RetrievePrivateData(struct pipes_struct
*p
,
3410 struct lsa_RetrievePrivateData
*r
)
3412 p
->rng_fault_state
= True
;
3413 return NT_STATUS_NOT_IMPLEMENTED
;
3416 NTSTATUS
_lsa_SetInfoPolicy2(struct pipes_struct
*p
,
3417 struct lsa_SetInfoPolicy2
*r
)
3419 p
->rng_fault_state
= True
;
3420 return NT_STATUS_NOT_IMPLEMENTED
;
3423 NTSTATUS
_lsa_SetTrustedDomainInfoByName(struct pipes_struct
*p
,
3424 struct lsa_SetTrustedDomainInfoByName
*r
)
3426 p
->rng_fault_state
= True
;
3427 return NT_STATUS_NOT_IMPLEMENTED
;
3430 NTSTATUS
_lsa_EnumTrustedDomainsEx(struct pipes_struct
*p
,
3431 struct lsa_EnumTrustedDomainsEx
*r
)
3433 struct lsa_info
*info
;
3435 struct pdb_trusted_domain
**domains
;
3436 struct lsa_TrustDomainInfoInfoEx
*entries
;
3440 /* bail out early if pdb backend is not capable of ex trusted domains,
3441 * if we dont do that, the client might not call
3442 * _lsa_EnumTrustedDomains() afterwards - gd */
3444 if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX
)) {
3445 p
->rng_fault_state
= True
;
3446 return NT_STATUS_NOT_IMPLEMENTED
;
3449 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&info
))
3450 return NT_STATUS_INVALID_HANDLE
;
3452 if (info
->type
!= LSA_HANDLE_POLICY_TYPE
) {
3453 return NT_STATUS_INVALID_HANDLE
;
3456 /* check if the user has enough rights */
3457 if (!(info
->access
& LSA_POLICY_VIEW_LOCAL_INFORMATION
))
3458 return NT_STATUS_ACCESS_DENIED
;
3461 nt_status
= pdb_enum_trusted_domains(p
->mem_ctx
, &count
, &domains
);
3464 if (!NT_STATUS_IS_OK(nt_status
)) {
3468 entries
= talloc_zero_array(p
->mem_ctx
, struct lsa_TrustDomainInfoInfoEx
,
3471 return NT_STATUS_NO_MEMORY
;
3474 for (i
=0; i
<count
; i
++) {
3475 init_lsa_StringLarge(&entries
[i
].netbios_name
,
3476 domains
[i
]->netbios_name
);
3477 entries
[i
].sid
= &domains
[i
]->security_identifier
;
3480 if (*r
->in
.resume_handle
>= count
) {
3481 *r
->out
.resume_handle
= -1;
3482 TALLOC_FREE(entries
);
3483 return NT_STATUS_NO_MORE_ENTRIES
;
3486 /* return the rest, limit by max_size. Note that we
3487 use the w2k3 element size value of 60 */
3488 r
->out
.domains
->count
= count
- *r
->in
.resume_handle
;
3489 r
->out
.domains
->count
= MIN(r
->out
.domains
->count
,
3490 (r
->in
.max_size
/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER
));
3492 r
->out
.domains
->domains
= entries
+ *r
->in
.resume_handle
;
3494 if (r
->out
.domains
->count
< count
- *r
->in
.resume_handle
) {
3495 *r
->out
.resume_handle
= *r
->in
.resume_handle
+ r
->out
.domains
->count
;
3496 return STATUS_MORE_ENTRIES
;
3499 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
3500 * always be larger than the previous input resume handle, in
3501 * particular when hitting the last query it is vital to set the
3502 * resume handle correctly to avoid infinite client loops, as
3503 * seen e.g. with Windows XP SP3 when resume handle is 0 and
3504 * status is NT_STATUS_OK - gd */
3506 *r
->out
.resume_handle
= (uint32_t)-1;
3508 return NT_STATUS_OK
;
3511 NTSTATUS
_lsa_QueryDomainInformationPolicy(struct pipes_struct
*p
,
3512 struct lsa_QueryDomainInformationPolicy
*r
)
3514 p
->rng_fault_state
= True
;
3515 return NT_STATUS_NOT_IMPLEMENTED
;
3518 NTSTATUS
_lsa_SetDomainInformationPolicy(struct pipes_struct
*p
,
3519 struct lsa_SetDomainInformationPolicy
*r
)
3521 p
->rng_fault_state
= True
;
3522 return NT_STATUS_NOT_IMPLEMENTED
;
3525 NTSTATUS
_lsa_TestCall(struct pipes_struct
*p
, struct lsa_TestCall
*r
)
3527 p
->rng_fault_state
= True
;
3528 return NT_STATUS_NOT_IMPLEMENTED
;
3531 NTSTATUS
_lsa_CREDRWRITE(struct pipes_struct
*p
, struct lsa_CREDRWRITE
*r
)
3533 p
->rng_fault_state
= True
;
3534 return NT_STATUS_NOT_IMPLEMENTED
;
3537 NTSTATUS
_lsa_CREDRREAD(struct pipes_struct
*p
, struct lsa_CREDRREAD
*r
)
3539 p
->rng_fault_state
= True
;
3540 return NT_STATUS_NOT_IMPLEMENTED
;
3543 NTSTATUS
_lsa_CREDRENUMERATE(struct pipes_struct
*p
, struct lsa_CREDRENUMERATE
*r
)
3545 p
->rng_fault_state
= True
;
3546 return NT_STATUS_NOT_IMPLEMENTED
;
3549 NTSTATUS
_lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct
*p
,
3550 struct lsa_CREDRWRITEDOMAINCREDENTIALS
*r
)
3552 p
->rng_fault_state
= True
;
3553 return NT_STATUS_NOT_IMPLEMENTED
;
3556 NTSTATUS
_lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct
*p
,
3557 struct lsa_CREDRREADDOMAINCREDENTIALS
*r
)
3559 p
->rng_fault_state
= True
;
3560 return NT_STATUS_NOT_IMPLEMENTED
;
3563 NTSTATUS
_lsa_CREDRDELETE(struct pipes_struct
*p
, struct lsa_CREDRDELETE
*r
)
3565 p
->rng_fault_state
= True
;
3566 return NT_STATUS_NOT_IMPLEMENTED
;
3569 NTSTATUS
_lsa_CREDRGETTARGETINFO(struct pipes_struct
*p
,
3570 struct lsa_CREDRGETTARGETINFO
*r
)
3572 p
->rng_fault_state
= True
;
3573 return NT_STATUS_NOT_IMPLEMENTED
;
3576 NTSTATUS
_lsa_CREDRPROFILELOADED(struct pipes_struct
*p
,
3577 struct lsa_CREDRPROFILELOADED
*r
)
3579 p
->rng_fault_state
= True
;
3580 return NT_STATUS_NOT_IMPLEMENTED
;
3583 NTSTATUS
_lsa_CREDRGETSESSIONTYPES(struct pipes_struct
*p
,
3584 struct lsa_CREDRGETSESSIONTYPES
*r
)
3586 p
->rng_fault_state
= True
;
3587 return NT_STATUS_NOT_IMPLEMENTED
;
3590 NTSTATUS
_lsa_LSARREGISTERAUDITEVENT(struct pipes_struct
*p
,
3591 struct lsa_LSARREGISTERAUDITEVENT
*r
)
3593 p
->rng_fault_state
= True
;
3594 return NT_STATUS_NOT_IMPLEMENTED
;
3597 NTSTATUS
_lsa_LSARGENAUDITEVENT(struct pipes_struct
*p
,
3598 struct lsa_LSARGENAUDITEVENT
*r
)
3600 p
->rng_fault_state
= True
;
3601 return NT_STATUS_NOT_IMPLEMENTED
;
3604 NTSTATUS
_lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct
*p
,
3605 struct lsa_LSARUNREGISTERAUDITEVENT
*r
)
3607 p
->rng_fault_state
= True
;
3608 return NT_STATUS_NOT_IMPLEMENTED
;
3611 NTSTATUS
_lsa_lsaRQueryForestTrustInformation(struct pipes_struct
*p
,
3612 struct lsa_lsaRQueryForestTrustInformation
*r
)
3614 p
->rng_fault_state
= True
;
3615 return NT_STATUS_NOT_IMPLEMENTED
;
3618 #define DNS_CMP_MATCH 0
3619 #define DNS_CMP_FIRST_IS_CHILD 1
3620 #define DNS_CMP_SECOND_IS_CHILD 2
3621 #define DNS_CMP_NO_MATCH 3
3623 /* this function assumes names are well formed DNS names.
3624 * it doesn't validate them */
3625 static int dns_cmp(const char *s1
, size_t l1
,
3626 const char *s2
, size_t l2
)
3628 const char *p1
, *p2
;
3633 if (strcasecmp_m(s1
, s2
) == 0) {
3634 return DNS_CMP_MATCH
;
3636 return DNS_CMP_NO_MATCH
;
3644 cret
= DNS_CMP_FIRST_IS_CHILD
;
3650 cret
= DNS_CMP_SECOND_IS_CHILD
;
3653 if (p1
[t1
- t2
- 1] != '.') {
3654 return DNS_CMP_NO_MATCH
;
3657 if (strcasecmp_m(&p1
[t1
- t2
], p2
) == 0) {
3661 return DNS_CMP_NO_MATCH
;
3664 static NTSTATUS
make_ft_info(TALLOC_CTX
*mem_ctx
,
3665 struct lsa_ForestTrustInformation
*lfti
,
3666 struct ForestTrustInfo
*fti
)
3668 struct lsa_ForestTrustRecord
*lrec
;
3669 struct ForestTrustInfoRecord
*rec
;
3670 struct lsa_StringLarge
*tln
;
3671 struct lsa_ForestTrustDomainInfo
*info
;
3675 fti
->count
= lfti
->count
;
3676 fti
->records
= talloc_array(mem_ctx
,
3677 struct ForestTrustInfoRecordArmor
,
3679 if (!fti
->records
) {
3680 return NT_STATUS_NO_MEMORY
;
3682 for (i
= 0; i
< fti
->count
; i
++) {
3683 lrec
= lfti
->entries
[i
];
3684 rec
= &fti
->records
[i
].record
;
3686 rec
->flags
= lrec
->flags
;
3687 rec
->timestamp
= lrec
->time
;
3688 rec
->type
= lrec
->type
;
3690 switch (lrec
->type
) {
3691 case LSA_FOREST_TRUST_TOP_LEVEL_NAME
:
3692 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX
:
3693 tln
= &lrec
->forest_trust_data
.top_level_name
;
3694 rec
->data
.name
.string
=
3695 talloc_strdup(mem_ctx
, tln
->string
);
3696 if (!rec
->data
.name
.string
) {
3697 return NT_STATUS_NO_MEMORY
;
3699 rec
->data
.name
.size
= strlen(rec
->data
.name
.string
);
3701 case LSA_FOREST_TRUST_DOMAIN_INFO
:
3702 info
= &lrec
->forest_trust_data
.domain_info
;
3703 rec
->data
.info
.sid
= *info
->domain_sid
;
3704 rec
->data
.info
.dns_name
.string
=
3705 talloc_strdup(mem_ctx
,
3706 info
->dns_domain_name
.string
);
3707 if (!rec
->data
.info
.dns_name
.string
) {
3708 return NT_STATUS_NO_MEMORY
;
3710 rec
->data
.info
.dns_name
.size
=
3711 strlen(rec
->data
.info
.dns_name
.string
);
3712 rec
->data
.info
.netbios_name
.string
=
3713 talloc_strdup(mem_ctx
,
3714 info
->netbios_domain_name
.string
);
3715 if (!rec
->data
.info
.netbios_name
.string
) {
3716 return NT_STATUS_NO_MEMORY
;
3718 rec
->data
.info
.netbios_name
.size
=
3719 strlen(rec
->data
.info
.netbios_name
.string
);
3722 return NT_STATUS_INVALID_DOMAIN_STATE
;
3726 return NT_STATUS_OK
;
3729 static NTSTATUS
add_collision(struct lsa_ForestTrustCollisionInfo
*c_info
,
3730 uint32_t index
, uint32_t collision_type
,
3731 uint32_t conflict_type
, const char *tdo_name
);
3733 static NTSTATUS
check_ft_info(TALLOC_CTX
*mem_ctx
,
3734 const char *tdo_name
,
3735 struct ForestTrustInfo
*tdo_fti
,
3736 struct ForestTrustInfo
*new_fti
,
3737 struct lsa_ForestTrustCollisionInfo
*c_info
)
3739 struct ForestTrustInfoRecord
*nrec
;
3740 struct ForestTrustInfoRecord
*trec
;
3741 const char *dns_name
;
3742 const char *nb_name
= NULL
;
3743 struct dom_sid
*sid
= NULL
;
3744 const char *tname
= NULL
;
3749 uint32_t new_fti_idx
;
3751 /* use always TDO type, until we understand when Xref can be used */
3752 uint32_t collision_type
= LSA_FOREST_TRUST_COLLISION_TDO
;
3757 bool ex_rule
= false;
3760 for (new_fti_idx
= 0; new_fti_idx
< new_fti
->count
; new_fti_idx
++) {
3762 nrec
= &new_fti
->records
[new_fti_idx
].record
;
3764 tln_conflict
= false;
3765 sid_conflict
= false;
3766 nb_conflict
= false;
3769 switch (nrec
->type
) {
3770 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX
:
3771 /* exclusions do not conflict by definition */
3774 case FOREST_TRUST_TOP_LEVEL_NAME
:
3775 dns_name
= nrec
->data
.name
.string
;
3776 dns_len
= nrec
->data
.name
.size
;
3779 case LSA_FOREST_TRUST_DOMAIN_INFO
:
3780 dns_name
= nrec
->data
.info
.dns_name
.string
;
3781 dns_len
= nrec
->data
.info
.dns_name
.size
;
3782 nb_name
= nrec
->data
.info
.netbios_name
.string
;
3783 nb_len
= nrec
->data
.info
.netbios_name
.size
;
3784 sid
= &nrec
->data
.info
.sid
;
3788 if (!dns_name
) continue;
3790 /* check if this is already taken and not excluded */
3791 for (i
= 0; i
< tdo_fti
->count
; i
++) {
3792 trec
= &tdo_fti
->records
[i
].record
;
3794 switch (trec
->type
) {
3795 case FOREST_TRUST_TOP_LEVEL_NAME
:
3797 tname
= trec
->data
.name
.string
;
3798 tlen
= trec
->data
.name
.size
;
3800 case FOREST_TRUST_TOP_LEVEL_NAME_EX
:
3802 tname
= trec
->data
.name
.string
;
3803 tlen
= trec
->data
.name
.size
;
3805 case FOREST_TRUST_DOMAIN_INFO
:
3807 tname
= trec
->data
.info
.dns_name
.string
;
3808 tlen
= trec
->data
.info
.dns_name
.size
;
3811 return NT_STATUS_INVALID_PARAMETER
;
3813 ret
= dns_cmp(dns_name
, dns_len
, tname
, tlen
);
3816 /* if it matches exclusion,
3817 * it doesn't conflict */
3823 case DNS_CMP_FIRST_IS_CHILD
:
3824 case DNS_CMP_SECOND_IS_CHILD
:
3825 tln_conflict
= true;
3831 /* explicit exclusion, no dns name conflict here */
3833 tln_conflict
= false;
3836 if (trec
->type
!= FOREST_TRUST_DOMAIN_INFO
) {
3840 /* also test for domain info */
3841 if (!(trec
->flags
& LSA_SID_DISABLED_ADMIN
) &&
3842 dom_sid_compare(&trec
->data
.info
.sid
, sid
) == 0) {
3843 sid_conflict
= true;
3845 if (!(trec
->flags
& LSA_NB_DISABLED_ADMIN
) &&
3846 strcasecmp_m(trec
->data
.info
.netbios_name
.string
,
3853 nt_status
= add_collision(c_info
, new_fti_idx
,
3855 LSA_TLN_DISABLED_CONFLICT
,
3859 nt_status
= add_collision(c_info
, new_fti_idx
,
3861 LSA_SID_DISABLED_CONFLICT
,
3865 nt_status
= add_collision(c_info
, new_fti_idx
,
3867 LSA_NB_DISABLED_CONFLICT
,
3872 return NT_STATUS_OK
;
3875 static NTSTATUS
add_collision(struct lsa_ForestTrustCollisionInfo
*c_info
,
3876 uint32_t idx
, uint32_t collision_type
,
3877 uint32_t conflict_type
, const char *tdo_name
)
3879 struct lsa_ForestTrustCollisionRecord
**es
;
3880 uint32_t i
= c_info
->count
;
3882 es
= talloc_realloc(c_info
, c_info
->entries
,
3883 struct lsa_ForestTrustCollisionRecord
*, i
+ 1);
3885 return NT_STATUS_NO_MEMORY
;
3887 c_info
->entries
= es
;
3888 c_info
->count
= i
+ 1;
3890 es
[i
] = talloc(es
, struct lsa_ForestTrustCollisionRecord
);
3892 return NT_STATUS_NO_MEMORY
;
3896 es
[i
]->type
= collision_type
;
3897 es
[i
]->flags
.flags
= conflict_type
;
3898 es
[i
]->name
.string
= talloc_strdup(es
[i
], tdo_name
);
3899 if (!es
[i
]->name
.string
) {
3900 return NT_STATUS_NO_MEMORY
;
3902 es
[i
]->name
.size
= strlen(es
[i
]->name
.string
);
3904 return NT_STATUS_OK
;
3907 static NTSTATUS
get_ft_info(TALLOC_CTX
*mem_ctx
,
3908 struct pdb_trusted_domain
*td
,
3909 struct ForestTrustInfo
*info
)
3911 enum ndr_err_code ndr_err
;
3913 if (td
->trust_forest_trust_info
.length
== 0 ||
3914 td
->trust_forest_trust_info
.data
== NULL
) {
3915 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3917 ndr_err
= ndr_pull_struct_blob_all(&td
->trust_forest_trust_info
, mem_ctx
,
3919 (ndr_pull_flags_fn_t
)ndr_pull_ForestTrustInfo
);
3920 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
3921 return NT_STATUS_INVALID_DOMAIN_STATE
;
3924 return NT_STATUS_OK
;
3927 static NTSTATUS
own_ft_info(struct pdb_domain_info
*dom_info
,
3928 struct ForestTrustInfo
*fti
)
3930 struct ForestTrustDataDomainInfo
*info
;
3931 struct ForestTrustInfoRecord
*rec
;
3935 fti
->records
= talloc_array(fti
,
3936 struct ForestTrustInfoRecordArmor
, 2);
3937 if (!fti
->records
) {
3938 return NT_STATUS_NO_MEMORY
;
3942 rec
= &fti
->records
[0].record
;
3946 rec
->type
= LSA_FOREST_TRUST_TOP_LEVEL_NAME
;
3948 rec
->data
.name
.string
= talloc_strdup(fti
, dom_info
->dns_forest
);
3949 if (!rec
->data
.name
.string
) {
3950 return NT_STATUS_NO_MEMORY
;
3952 rec
->data
.name
.size
= strlen(rec
->data
.name
.string
);
3955 rec
= &fti
->records
[1].record
;
3959 rec
->type
= LSA_FOREST_TRUST_DOMAIN_INFO
;
3961 info
= &rec
->data
.info
;
3963 info
->sid
= dom_info
->sid
;
3964 info
->dns_name
.string
= talloc_strdup(fti
, dom_info
->dns_domain
);
3965 if (!info
->dns_name
.string
) {
3966 return NT_STATUS_NO_MEMORY
;
3968 info
->dns_name
.size
= strlen(info
->dns_name
.string
);
3969 info
->netbios_name
.string
= talloc_strdup(fti
, dom_info
->name
);
3970 if (!info
->netbios_name
.string
) {
3971 return NT_STATUS_NO_MEMORY
;
3973 info
->netbios_name
.size
= strlen(info
->netbios_name
.string
);
3975 return NT_STATUS_OK
;
3978 NTSTATUS
_lsa_lsaRSetForestTrustInformation(struct pipes_struct
*p
,
3979 struct lsa_lsaRSetForestTrustInformation
*r
)
3984 struct lsa_info
*handle
;
3985 uint32_t num_domains
;
3986 struct pdb_trusted_domain
**domains
;
3987 struct ForestTrustInfo
*nfti
;
3988 struct ForestTrustInfo
*fti
;
3989 struct lsa_ForestTrustCollisionInfo
*c_info
;
3990 struct pdb_domain_info
*dom_info
;
3991 enum ndr_err_code ndr_err
;
3994 return NT_STATUS_NOT_SUPPORTED
;
3997 if (!find_policy_by_hnd(p
, r
->in
.handle
, (void **)(void *)&handle
)) {
3998 return NT_STATUS_INVALID_HANDLE
;
4001 if (handle
->type
!= LSA_HANDLE_TRUST_TYPE
) {
4002 return NT_STATUS_INVALID_HANDLE
;
4005 if (!(handle
->access
& LSA_TRUSTED_SET_AUTH
)) {
4006 return NT_STATUS_ACCESS_DENIED
;
4009 status
= pdb_enum_trusted_domains(p
->mem_ctx
, &num_domains
, &domains
);
4010 if (!NT_STATUS_IS_OK(status
)) {
4013 if (num_domains
== 0) {
4014 return NT_STATUS_NO_SUCH_DOMAIN
;
4017 for (i
= 0; i
< num_domains
; i
++) {
4018 if (domains
[i
]->domain_name
== NULL
) {
4019 return NT_STATUS_INVALID_DOMAIN_STATE
;
4021 if (strcasecmp_m(domains
[i
]->domain_name
,
4022 r
->in
.trusted_domain_name
->string
) == 0) {
4026 if (i
>= num_domains
) {
4027 return NT_STATUS_NO_SUCH_DOMAIN
;
4030 if (!(domains
[i
]->trust_attributes
&
4031 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE
)) {
4032 return NT_STATUS_INVALID_PARAMETER
;
4035 if (r
->in
.highest_record_type
>= LSA_FOREST_TRUST_RECORD_TYPE_LAST
) {
4036 return NT_STATUS_INVALID_PARAMETER
;
4039 /* The following section until COPY_END is a copy from
4040 * source4/rpmc_server/lsa/scesrc_lsa.c */
4041 nfti
= talloc(p
->mem_ctx
, struct ForestTrustInfo
);
4043 return NT_STATUS_NO_MEMORY
;
4046 status
= make_ft_info(nfti
, r
->in
.forest_trust_info
, nfti
);
4047 if (!NT_STATUS_IS_OK(status
)) {
4051 c_info
= talloc_zero(r
->out
.collision_info
,
4052 struct lsa_ForestTrustCollisionInfo
);
4054 return NT_STATUS_NO_MEMORY
;
4057 /* first check own info, then other domains */
4058 fti
= talloc(p
->mem_ctx
, struct ForestTrustInfo
);
4060 return NT_STATUS_NO_MEMORY
;
4063 dom_info
= pdb_get_domain_info(p
->mem_ctx
);
4065 status
= own_ft_info(dom_info
, fti
);
4066 if (!NT_STATUS_IS_OK(status
)) {
4070 status
= check_ft_info(c_info
, dom_info
->dns_domain
, fti
, nfti
, c_info
);
4071 if (!NT_STATUS_IS_OK(status
)) {
4075 for (j
= 0; j
< num_domains
; j
++) {
4076 fti
= talloc(p
->mem_ctx
, struct ForestTrustInfo
);
4078 return NT_STATUS_NO_MEMORY
;
4081 status
= get_ft_info(p
->mem_ctx
, domains
[j
], fti
);
4082 if (!NT_STATUS_IS_OK(status
)) {
4083 if (NT_STATUS_EQUAL(status
,
4084 NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4090 if (domains
[j
]->domain_name
== NULL
) {
4091 return NT_STATUS_INVALID_DOMAIN_STATE
;
4094 status
= check_ft_info(c_info
, domains
[j
]->domain_name
,
4096 if (!NT_STATUS_IS_OK(status
)) {
4101 *r
->out
.collision_info
= c_info
;
4103 if (r
->in
.check_only
!= 0) {
4104 return NT_STATUS_OK
;
4109 ndr_err
= ndr_push_struct_blob(&domains
[i
]->trust_forest_trust_info
,
4111 (ndr_push_flags_fn_t
)ndr_push_ForestTrustInfo
);
4112 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
4113 return NT_STATUS_INVALID_PARAMETER
;
4116 status
= pdb_set_trusted_domain(domains
[i
]->domain_name
, domains
[i
]);
4117 if (!NT_STATUS_IS_OK(status
)) {
4121 return NT_STATUS_OK
;
4124 NTSTATUS
_lsa_CREDRRENAME(struct pipes_struct
*p
,
4125 struct lsa_CREDRRENAME
*r
)
4127 p
->rng_fault_state
= True
;
4128 return NT_STATUS_NOT_IMPLEMENTED
;
4131 NTSTATUS
_lsa_LSAROPENPOLICYSCE(struct pipes_struct
*p
,
4132 struct lsa_LSAROPENPOLICYSCE
*r
)
4134 p
->rng_fault_state
= True
;
4135 return NT_STATUS_NOT_IMPLEMENTED
;
4138 NTSTATUS
_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct
*p
,
4139 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE
*r
)
4141 p
->rng_fault_state
= True
;
4142 return NT_STATUS_NOT_IMPLEMENTED
;
4145 NTSTATUS
_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct
*p
,
4146 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
*r
)
4148 p
->rng_fault_state
= True
;
4149 return NT_STATUS_NOT_IMPLEMENTED
;
4152 NTSTATUS
_lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct
*p
,
4153 struct lsa_LSARADTREPORTSECURITYEVENT
*r
)
4155 p
->rng_fault_state
= True
;
4156 return NT_STATUS_NOT_IMPLEMENTED
;