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"
25 NTSTATUS
dcesrv_lsa_get_policy_state(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
26 struct lsa_policy_state
**_state
)
28 struct lsa_policy_state
*state
;
29 struct ldb_dn
*partitions_basedn
;
30 struct ldb_result
*dom_res
;
31 const char *dom_attrs
[] = {
38 struct ldb_result
*ref_res
;
39 struct ldb_result
*forest_ref_res
;
40 const char *ref_attrs
[] = {
47 state
= talloc(mem_ctx
, struct lsa_policy_state
);
49 return NT_STATUS_NO_MEMORY
;
52 /* make sure the sam database is accessible */
53 state
->sam_ldb
= samdb_connect(state
, dce_call
->event_ctx
, dce_call
->conn
->dce_ctx
->lp_ctx
, dce_call
->conn
->auth_state
.session_info
);
54 if (state
->sam_ldb
== NULL
) {
55 return NT_STATUS_INVALID_SYSTEM_SERVICE
;
58 partitions_basedn
= samdb_partitions_dn(state
->sam_ldb
, mem_ctx
);
60 /* work out the domain_dn - useful for so many calls its worth
62 state
->domain_dn
= samdb_base_dn(state
->sam_ldb
);
63 if (!state
->domain_dn
) {
64 return NT_STATUS_NO_MEMORY
;
67 /* work out the forest root_dn - useful for so many calls its worth
69 state
->forest_dn
= samdb_root_dn(state
->sam_ldb
);
70 if (!state
->forest_dn
) {
71 return NT_STATUS_NO_MEMORY
;
74 ret
= ldb_search(state
->sam_ldb
, mem_ctx
, &dom_res
,
75 state
->domain_dn
, LDB_SCOPE_BASE
, dom_attrs
, NULL
);
76 if (ret
!= LDB_SUCCESS
) {
77 return NT_STATUS_INVALID_SYSTEM_SERVICE
;
79 if (dom_res
->count
!= 1) {
80 return NT_STATUS_NO_SUCH_DOMAIN
;
83 state
->domain_sid
= samdb_result_dom_sid(state
, dom_res
->msgs
[0], "objectSid");
84 if (!state
->domain_sid
) {
85 return NT_STATUS_NO_SUCH_DOMAIN
;
88 state
->domain_guid
= samdb_result_guid(dom_res
->msgs
[0], "objectGUID");
89 if (!state
->domain_sid
) {
90 return NT_STATUS_NO_SUCH_DOMAIN
;
93 state
->mixed_domain
= ldb_msg_find_attr_as_uint(dom_res
->msgs
[0], "nTMixedDomain", 0);
97 ret
= ldb_search(state
->sam_ldb
, state
, &ref_res
,
98 partitions_basedn
, LDB_SCOPE_SUBTREE
, ref_attrs
,
99 "(&(objectclass=crossRef)(ncName=%s))",
100 ldb_dn_get_linearized(state
->domain_dn
));
102 if (ret
!= LDB_SUCCESS
) {
103 talloc_free(ref_res
);
104 return NT_STATUS_INVALID_SYSTEM_SERVICE
;
106 if (ref_res
->count
!= 1) {
107 talloc_free(ref_res
);
108 return NT_STATUS_NO_SUCH_DOMAIN
;
111 state
->domain_name
= ldb_msg_find_attr_as_string(ref_res
->msgs
[0], "nETBIOSName", NULL
);
112 if (!state
->domain_name
) {
113 talloc_free(ref_res
);
114 return NT_STATUS_NO_SUCH_DOMAIN
;
116 talloc_steal(state
, state
->domain_name
);
118 state
->domain_dns
= ldb_msg_find_attr_as_string(ref_res
->msgs
[0], "dnsRoot", NULL
);
119 if (!state
->domain_dns
) {
120 talloc_free(ref_res
);
121 return NT_STATUS_NO_SUCH_DOMAIN
;
123 talloc_steal(state
, state
->domain_dns
);
125 talloc_free(ref_res
);
127 ret
= ldb_search(state
->sam_ldb
, state
, &forest_ref_res
,
128 partitions_basedn
, LDB_SCOPE_SUBTREE
, ref_attrs
,
129 "(&(objectclass=crossRef)(ncName=%s))",
130 ldb_dn_get_linearized(state
->forest_dn
));
132 if (ret
!= LDB_SUCCESS
) {
133 talloc_free(forest_ref_res
);
134 return NT_STATUS_INVALID_SYSTEM_SERVICE
;
136 if (forest_ref_res
->count
!= 1) {
137 talloc_free(forest_ref_res
);
138 return NT_STATUS_NO_SUCH_DOMAIN
;
141 state
->forest_dns
= ldb_msg_find_attr_as_string(forest_ref_res
->msgs
[0], "dnsRoot", NULL
);
142 if (!state
->forest_dns
) {
143 talloc_free(forest_ref_res
);
144 return NT_STATUS_NO_SUCH_DOMAIN
;
146 talloc_steal(state
, state
->forest_dns
);
148 talloc_free(forest_ref_res
);
150 /* work out the builtin_dn - useful for so many calls its worth
152 state
->builtin_dn
= samdb_search_dn(state
->sam_ldb
, state
, state
->domain_dn
, "(objectClass=builtinDomain)");
153 if (!state
->builtin_dn
) {
154 return NT_STATUS_NO_SUCH_DOMAIN
;
157 /* work out the system_dn - useful for so many calls its worth
159 state
->system_dn
= samdb_search_dn(state
->sam_ldb
, state
,
160 state
->domain_dn
, "(&(objectClass=container)(cn=System))");
161 if (!state
->system_dn
) {
162 return NT_STATUS_NO_SUCH_DOMAIN
;
165 state
->builtin_sid
= dom_sid_parse_talloc(state
, SID_BUILTIN
);
166 if (!state
->builtin_sid
) {
167 return NT_STATUS_NO_SUCH_DOMAIN
;
170 state
->nt_authority_sid
= dom_sid_parse_talloc(state
, SID_NT_AUTHORITY
);
171 if (!state
->nt_authority_sid
) {
172 return NT_STATUS_NO_SUCH_DOMAIN
;
175 state
->creator_owner_domain_sid
= dom_sid_parse_talloc(state
, SID_CREATOR_OWNER_DOMAIN
);
176 if (!state
->creator_owner_domain_sid
) {
177 return NT_STATUS_NO_SUCH_DOMAIN
;
180 state
->world_domain_sid
= dom_sid_parse_talloc(state
, SID_WORLD_DOMAIN
);
181 if (!state
->world_domain_sid
) {
182 return NT_STATUS_NO_SUCH_DOMAIN
;
193 NTSTATUS
dcesrv_lsa_OpenPolicy2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
194 struct lsa_OpenPolicy2
*r
)
197 struct lsa_policy_state
*state
;
198 struct dcesrv_handle
*handle
;
200 ZERO_STRUCTP(r
->out
.handle
);
202 status
= dcesrv_lsa_get_policy_state(dce_call
, mem_ctx
, &state
);
203 if (!NT_STATUS_IS_OK(status
)) {
207 handle
= dcesrv_handle_new(dce_call
->context
, LSA_HANDLE_POLICY
);
209 return NT_STATUS_NO_MEMORY
;
212 handle
->data
= talloc_steal(handle
, state
);
214 state
->access_mask
= r
->in
.access_mask
;
215 state
->handle
= handle
;
216 *r
->out
.handle
= handle
->wire_handle
;
218 /* note that we have completely ignored the attr element of
219 the OpenPolicy. As far as I can tell, this is what w2k3
227 a wrapper around lsa_OpenPolicy2
229 NTSTATUS
dcesrv_lsa_OpenPolicy(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
230 struct lsa_OpenPolicy
*r
)
232 struct lsa_OpenPolicy2 r2
;
234 r2
.in
.system_name
= NULL
;
235 r2
.in
.attr
= r
->in
.attr
;
236 r2
.in
.access_mask
= r
->in
.access_mask
;
237 r2
.out
.handle
= r
->out
.handle
;
239 return dcesrv_lsa_OpenPolicy2(dce_call
, mem_ctx
, &r2
);