2 Unix SMB/CIFS implementation.
4 endpoint server for the lsarpc pipe
6 Copyright (C) Andrew Tridgell 2004
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2007
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "rpc_server/lsa/lsa.h"
26 * This matches a Windows 2012R2 dc in
27 * a domain with function level 2012R2.
29 #define DCESRV_LSA_POLICY_SD_SDDL \
32 "(D;;0x00000800;;;AN)" \
33 "(A;;0x000f1fff;;;BA)" \
34 "(A;;0x00020801;;;WD)" \
35 "(A;;0x00000801;;;AN)" \
36 "(A;;0x00001000;;;LS)" \
37 "(A;;0x00001000;;;NS)" \
38 "(A;;0x00001000;;;S-1-5-17)" \
39 "(A;;0x00000801;;;AC)" \
40 "(A;;0x00000801;;;S-1-15-2-2)"
42 static const struct generic_mapping dcesrv_lsa_policy_mapping
= {
49 NTSTATUS
dcesrv_lsa_get_policy_state(struct dcesrv_call_state
*dce_call
,
51 uint32_t access_desired
,
52 struct lsa_policy_state
**_state
)
54 struct auth_session_info
*session_info
=
55 dcesrv_call_session_info(dce_call
);
56 enum security_user_level security_level
;
57 struct lsa_policy_state
*state
;
58 struct ldb_result
*dom_res
;
59 const char *dom_attrs
[] = {
69 state
= talloc_zero(mem_ctx
, struct lsa_policy_state
);
71 return NT_STATUS_NO_MEMORY
;
74 /* make sure the sam database is accessible */
75 state
->sam_ldb
= dcesrv_samdb_connect_as_user(state
, dce_call
);
76 if (state
->sam_ldb
== NULL
) {
77 return NT_STATUS_INVALID_SYSTEM_SERVICE
;
80 /* and the privilege database */
81 state
->pdb
= privilege_connect(state
, dce_call
->conn
->dce_ctx
->lp_ctx
);
82 if (state
->pdb
== NULL
) {
83 return NT_STATUS_INVALID_SYSTEM_SERVICE
;
86 /* work out the domain_dn - useful for so many calls its worth
88 state
->domain_dn
= ldb_get_default_basedn(state
->sam_ldb
);
89 if (!state
->domain_dn
) {
90 return NT_STATUS_NO_MEMORY
;
93 /* work out the forest root_dn - useful for so many calls its worth
95 state
->forest_dn
= ldb_get_root_basedn(state
->sam_ldb
);
96 if (!state
->forest_dn
) {
97 return NT_STATUS_NO_MEMORY
;
100 ret
= ldb_search(state
->sam_ldb
, mem_ctx
, &dom_res
,
101 state
->domain_dn
, LDB_SCOPE_BASE
, dom_attrs
, NULL
);
102 if (ret
!= LDB_SUCCESS
) {
103 return NT_STATUS_INVALID_SYSTEM_SERVICE
;
105 if (dom_res
->count
!= 1) {
106 return NT_STATUS_NO_SUCH_DOMAIN
;
109 state
->domain_sid
= samdb_result_dom_sid(state
, dom_res
->msgs
[0], "objectSid");
110 if (!state
->domain_sid
) {
111 return NT_STATUS_NO_SUCH_DOMAIN
;
114 state
->domain_guid
= samdb_result_guid(dom_res
->msgs
[0], "objectGUID");
116 state
->mixed_domain
= ldb_msg_find_attr_as_uint(dom_res
->msgs
[0], "nTMixedDomain", 0);
118 talloc_free(dom_res
);
120 state
->domain_name
= lpcfg_sam_name(dce_call
->conn
->dce_ctx
->lp_ctx
);
122 state
->domain_dns
= ldb_dn_canonical_string(state
, state
->domain_dn
);
123 if (!state
->domain_dns
) {
124 return NT_STATUS_NO_SUCH_DOMAIN
;
126 p
= strchr(state
->domain_dns
, '/');
131 state
->forest_dns
= ldb_dn_canonical_string(state
, state
->forest_dn
);
132 if (!state
->forest_dns
) {
133 return NT_STATUS_NO_SUCH_DOMAIN
;
135 p
= strchr(state
->forest_dns
, '/');
140 /* work out the builtin_dn - useful for so many calls its worth
142 state
->builtin_dn
= samdb_search_dn(state
->sam_ldb
, state
, state
->domain_dn
, "(objectClass=builtinDomain)");
143 if (!state
->builtin_dn
) {
144 return NT_STATUS_NO_SUCH_DOMAIN
;
147 /* work out the system_dn - useful for so many calls its worth
149 state
->system_dn
= samdb_system_container_dn(state
->sam_ldb
, state
);
150 if (state
->system_dn
== NULL
) {
151 return NT_STATUS_NO_MEMORY
;
154 state
->builtin_sid
= dom_sid_parse_talloc(state
, SID_BUILTIN
);
155 if (!state
->builtin_sid
) {
156 return NT_STATUS_NO_SUCH_DOMAIN
;
159 state
->nt_authority_sid
= dom_sid_parse_talloc(state
, SID_NT_AUTHORITY
);
160 if (!state
->nt_authority_sid
) {
161 return NT_STATUS_NO_SUCH_DOMAIN
;
164 state
->creator_owner_domain_sid
= dom_sid_parse_talloc(state
, SID_CREATOR_OWNER_DOMAIN
);
165 if (!state
->creator_owner_domain_sid
) {
166 return NT_STATUS_NO_SUCH_DOMAIN
;
169 state
->world_domain_sid
= dom_sid_parse_talloc(state
, SID_WORLD_DOMAIN
);
170 if (!state
->world_domain_sid
) {
171 return NT_STATUS_NO_SUCH_DOMAIN
;
174 state
->sd
= sddl_decode(state
, DCESRV_LSA_POLICY_SD_SDDL
,
176 if (state
->sd
== NULL
) {
177 return NT_STATUS_NO_MEMORY
;
179 state
->sd
->dacl
->revision
= SECURITY_ACL_REVISION_NT4
;
181 se_map_generic(&access_desired
, &dcesrv_lsa_policy_mapping
);
182 security_acl_map_generic(state
->sd
->dacl
, &dcesrv_lsa_policy_mapping
);
184 security_level
= security_session_user_level(session_info
, NULL
);
185 if (security_level
>= SECURITY_SYSTEM
) {
187 * The security descriptor doesn't allow system,
188 * but we want to allow system via ncalrpc as root.
190 state
->access_mask
= access_desired
;
191 if (state
->access_mask
& SEC_FLAG_MAXIMUM_ALLOWED
) {
192 state
->access_mask
&= ~SEC_FLAG_MAXIMUM_ALLOWED
;
193 state
->access_mask
|= LSA_POLICY_ALL_ACCESS
;
198 status
= se_access_check(state
->sd
,
199 session_info
->security_token
,
201 &state
->access_mask
);
202 if (!NT_STATUS_IS_OK(status
)) {
203 DEBUG(2,("%s: access desired[0x%08X] rejected[0x%08X] - %s\n",
205 (unsigned)access_desired
,
206 (unsigned)state
->access_mask
,
212 DEBUG(10,("%s: access desired[0x%08X] granted[0x%08X] - success.\n",
214 (unsigned)access_desired
,
215 (unsigned)state
->access_mask
));
225 NTSTATUS
dcesrv_lsa_OpenPolicy3(struct dcesrv_call_state
*dce_call
,
227 struct lsa_OpenPolicy3
*r
)
229 enum dcerpc_transport_t transport
=
230 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
231 struct lsa_policy_state
*state
= NULL
;
232 struct dcesrv_handle
*handle
= NULL
;
235 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
236 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
239 ZERO_STRUCTP(r
->out
.handle
);
242 * The attributes have no effect and MUST be ignored, except the
243 * root_dir which MUST be NULL.
245 if (r
->in
.attr
!= NULL
&& r
->in
.attr
->root_dir
!= NULL
) {
246 return NT_STATUS_INVALID_PARAMETER
;
249 switch (r
->in
.in_version
) {
251 *r
->out
.out_version
= 1;
253 r
->out
.out_revision_info
->info1
.revision
= 1;
254 r
->out
.out_revision_info
->info1
.supported_features
=
255 LSA_FEATURE_TDO_AUTH_INFO_AES_CIPHER
;
259 return NT_STATUS_NOT_SUPPORTED
;
262 status
= dcesrv_lsa_get_policy_state(dce_call
, mem_ctx
,
265 if (!NT_STATUS_IS_OK(status
)) {
269 handle
= dcesrv_handle_create(dce_call
, LSA_HANDLE_POLICY
);
270 if (handle
== NULL
) {
271 return NT_STATUS_NO_MEMORY
;
273 handle
->data
= talloc_steal(handle
, state
);
275 state
->handle
= handle
;
276 *r
->out
.handle
= handle
->wire_handle
;
284 NTSTATUS
dcesrv_lsa_OpenPolicy2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
285 struct lsa_OpenPolicy2
*r
)
287 enum dcerpc_transport_t transport
=
288 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
290 struct lsa_policy_state
*state
;
291 struct dcesrv_handle
*handle
;
293 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
294 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
297 ZERO_STRUCTP(r
->out
.handle
);
299 if (r
->in
.attr
!= NULL
&&
300 r
->in
.attr
->root_dir
!= NULL
) {
301 /* MS-LSAD 3.1.4.4.1 */
302 return NT_STATUS_INVALID_PARAMETER
;
305 status
= dcesrv_lsa_get_policy_state(dce_call
, mem_ctx
,
308 if (!NT_STATUS_IS_OK(status
)) {
312 handle
= dcesrv_handle_create(dce_call
, LSA_HANDLE_POLICY
);
314 return NT_STATUS_NO_MEMORY
;
317 handle
->data
= talloc_steal(handle
, state
);
319 state
->handle
= handle
;
320 *r
->out
.handle
= handle
->wire_handle
;
322 /* note that we have completely ignored the attr element of
323 the OpenPolicy. As far as I can tell, this is what w2k3
331 a wrapper around lsa_OpenPolicy2
333 NTSTATUS
dcesrv_lsa_OpenPolicy(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
334 struct lsa_OpenPolicy
*r
)
336 enum dcerpc_transport_t transport
=
337 dcerpc_binding_get_transport(dce_call
->conn
->endpoint
->ep_description
);
338 struct lsa_OpenPolicy2 r2
;
340 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
341 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
344 r2
= (struct lsa_OpenPolicy2
) {
345 .in
.attr
= r
->in
.attr
,
346 .in
.access_mask
= r
->in
.access_mask
,
347 .out
.handle
= r
->out
.handle
,
350 return dcesrv_lsa_OpenPolicy2(dce_call
, mem_ctx
, &r2
);