2 * Unix SMB/CIFS implementation.
4 * Copyright (C) Guenther Deschner 2008
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "lib/netapi/netapi.h"
22 #include "lib/netapi/netapi_private.h"
23 #include "rpc_client/rpc_client.h"
24 #include "../librpc/gen_ndr/ndr_samr_c.h"
25 #include "rpc_client/cli_samr.h"
26 #include "rpc_client/init_lsa.h"
27 #include "../libcli/security/security.h"
29 /****************************************************************
30 ****************************************************************/
32 WERROR
libnetapi_samr_open_domain(struct libnetapi_ctx
*mem_ctx
,
33 struct rpc_pipe_client
*pipe_cli
,
34 uint32_t connect_mask
,
36 struct policy_handle
*connect_handle
,
37 struct policy_handle
*domain_handle
,
38 struct dom_sid2
**domain_sid
)
40 NTSTATUS status
, result
;
42 struct libnetapi_private_ctx
*priv
;
43 uint32_t resume_handle
= 0;
44 uint32_t num_entries
= 0;
45 struct samr_SamArray
*sam
= NULL
;
46 const char *domain_name
= NULL
;
47 struct lsa_String lsa_domain_name
;
48 bool domain_found
= true;
50 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
52 priv
= talloc_get_type_abort(mem_ctx
->private_data
,
53 struct libnetapi_private_ctx
);
55 if (is_valid_policy_hnd(&priv
->samr
.connect_handle
)) {
56 if ((priv
->samr
.connect_mask
& connect_mask
) == connect_mask
) {
57 *connect_handle
= priv
->samr
.connect_handle
;
59 libnetapi_samr_close_connect_handle(mem_ctx
,
60 &priv
->samr
.connect_handle
);
64 if (is_valid_policy_hnd(&priv
->samr
.domain_handle
)) {
65 if ((priv
->samr
.domain_mask
& domain_mask
) == domain_mask
) {
66 *domain_handle
= priv
->samr
.domain_handle
;
68 libnetapi_samr_close_domain_handle(mem_ctx
,
69 &priv
->samr
.domain_handle
);
73 if (priv
->samr
.domain_sid
) {
74 *domain_sid
= priv
->samr
.domain_sid
;
77 if (is_valid_policy_hnd(&priv
->samr
.connect_handle
) &&
78 ((priv
->samr
.connect_mask
& connect_mask
) == connect_mask
) &&
79 is_valid_policy_hnd(&priv
->samr
.domain_handle
) &&
80 (priv
->samr
.domain_mask
& domain_mask
) == domain_mask
) {
84 if (!is_valid_policy_hnd(connect_handle
)) {
85 status
= dcerpc_try_samr_connects(pipe_cli
->binding_handle
, mem_ctx
,
86 pipe_cli
->srv_name_slash
,
90 if (!NT_STATUS_IS_OK(status
)) {
91 werr
= ntstatus_to_werror(status
);
94 if (!NT_STATUS_IS_OK(result
)) {
95 werr
= ntstatus_to_werror(result
);
100 status
= dcerpc_samr_EnumDomains(b
, mem_ctx
,
107 if (!NT_STATUS_IS_OK(status
)) {
108 werr
= ntstatus_to_werror(status
);
111 if (!NT_STATUS_IS_OK(result
)) {
112 werr
= ntstatus_to_werror(result
);
116 for (i
=0; i
<num_entries
; i
++) {
118 domain_name
= sam
->entries
[i
].name
.string
;
120 if (strequal(domain_name
, builtin_domain_name())) {
129 werr
= WERR_NO_SUCH_DOMAIN
;
133 init_lsa_String(&lsa_domain_name
, domain_name
);
135 status
= dcerpc_samr_LookupDomain(b
, mem_ctx
,
140 if (!NT_STATUS_IS_OK(status
)) {
141 werr
= ntstatus_to_werror(status
);
144 if (!NT_STATUS_IS_OK(result
)) {
145 werr
= ntstatus_to_werror(result
);
149 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
155 if (!NT_STATUS_IS_OK(status
)) {
156 werr
= ntstatus_to_werror(status
);
159 if (!NT_STATUS_IS_OK(result
)) {
160 werr
= ntstatus_to_werror(result
);
164 priv
->samr
.cli
= pipe_cli
;
166 priv
->samr
.domain_name
= domain_name
;
167 priv
->samr
.domain_sid
= *domain_sid
;
169 priv
->samr
.connect_mask
= connect_mask
;
170 priv
->samr
.connect_handle
= *connect_handle
;
172 priv
->samr
.domain_mask
= domain_mask
;
173 priv
->samr
.domain_handle
= *domain_handle
;
181 /****************************************************************
182 ****************************************************************/
184 WERROR
libnetapi_samr_open_builtin_domain(struct libnetapi_ctx
*mem_ctx
,
185 struct rpc_pipe_client
*pipe_cli
,
186 uint32_t connect_mask
,
187 uint32_t builtin_mask
,
188 struct policy_handle
*connect_handle
,
189 struct policy_handle
*builtin_handle
)
191 NTSTATUS status
, result
;
193 struct libnetapi_private_ctx
*priv
;
194 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
196 priv
= talloc_get_type_abort(mem_ctx
->private_data
,
197 struct libnetapi_private_ctx
);
199 if (is_valid_policy_hnd(&priv
->samr
.connect_handle
)) {
200 if ((priv
->samr
.connect_mask
& connect_mask
) == connect_mask
) {
201 *connect_handle
= priv
->samr
.connect_handle
;
203 libnetapi_samr_close_connect_handle(mem_ctx
,
204 &priv
->samr
.connect_handle
);
208 if (is_valid_policy_hnd(&priv
->samr
.builtin_handle
)) {
209 if ((priv
->samr
.builtin_mask
& builtin_mask
) == builtin_mask
) {
210 *builtin_handle
= priv
->samr
.builtin_handle
;
212 libnetapi_samr_close_builtin_handle(mem_ctx
,
213 &priv
->samr
.builtin_handle
);
217 if (is_valid_policy_hnd(&priv
->samr
.connect_handle
) &&
218 ((priv
->samr
.connect_mask
& connect_mask
) == connect_mask
) &&
219 is_valid_policy_hnd(&priv
->samr
.builtin_handle
) &&
220 (priv
->samr
.builtin_mask
& builtin_mask
) == builtin_mask
) {
224 if (!is_valid_policy_hnd(connect_handle
)) {
225 status
= dcerpc_try_samr_connects(pipe_cli
->binding_handle
, mem_ctx
,
226 pipe_cli
->srv_name_slash
,
230 if (!NT_STATUS_IS_OK(status
)) {
231 werr
= ntstatus_to_werror(status
);
234 if (!NT_STATUS_IS_OK(result
)) {
235 werr
= ntstatus_to_werror(result
);
240 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
243 CONST_DISCARD(struct dom_sid
*, &global_sid_Builtin
),
246 if (!NT_STATUS_IS_OK(status
)) {
247 werr
= ntstatus_to_werror(status
);
250 if (!NT_STATUS_IS_OK(result
)) {
251 werr
= ntstatus_to_werror(result
);
255 priv
->samr
.cli
= pipe_cli
;
257 priv
->samr
.connect_mask
= connect_mask
;
258 priv
->samr
.connect_handle
= *connect_handle
;
260 priv
->samr
.builtin_mask
= builtin_mask
;
261 priv
->samr
.builtin_handle
= *builtin_handle
;
269 /****************************************************************
270 ****************************************************************/
272 void libnetapi_samr_close_domain_handle(struct libnetapi_ctx
*ctx
,
273 struct policy_handle
*handle
)
275 struct libnetapi_private_ctx
*priv
;
276 struct dcerpc_binding_handle
*b
;
279 if (!is_valid_policy_hnd(handle
)) {
283 priv
= talloc_get_type_abort(ctx
->private_data
,
284 struct libnetapi_private_ctx
);
286 if (!policy_handle_equal(handle
, &priv
->samr
.domain_handle
)) {
290 b
= priv
->samr
.cli
->binding_handle
;
292 dcerpc_samr_Close(b
, ctx
, handle
, &result
);
294 ZERO_STRUCT(priv
->samr
.domain_handle
);
297 /****************************************************************
298 ****************************************************************/
300 void libnetapi_samr_close_builtin_handle(struct libnetapi_ctx
*ctx
,
301 struct policy_handle
*handle
)
303 struct libnetapi_private_ctx
*priv
;
304 struct dcerpc_binding_handle
*b
;
307 if (!is_valid_policy_hnd(handle
)) {
311 priv
= talloc_get_type_abort(ctx
->private_data
,
312 struct libnetapi_private_ctx
);
314 if (!policy_handle_equal(handle
, &priv
->samr
.builtin_handle
)) {
318 b
= priv
->samr
.cli
->binding_handle
;
320 dcerpc_samr_Close(b
, ctx
, handle
, &result
);
322 ZERO_STRUCT(priv
->samr
.builtin_handle
);
325 /****************************************************************
326 ****************************************************************/
328 void libnetapi_samr_close_connect_handle(struct libnetapi_ctx
*ctx
,
329 struct policy_handle
*handle
)
331 struct libnetapi_private_ctx
*priv
;
332 struct dcerpc_binding_handle
*b
;
335 if (!is_valid_policy_hnd(handle
)) {
339 priv
= talloc_get_type_abort(ctx
->private_data
,
340 struct libnetapi_private_ctx
);
342 if (!policy_handle_equal(handle
, &priv
->samr
.connect_handle
)) {
346 b
= priv
->samr
.cli
->binding_handle
;
348 dcerpc_samr_Close(b
, ctx
, handle
, &result
);
350 ZERO_STRUCT(priv
->samr
.connect_handle
);
353 /****************************************************************
354 ****************************************************************/
356 void libnetapi_samr_free(struct libnetapi_ctx
*ctx
)
358 struct libnetapi_private_ctx
*priv
;
360 if (!ctx
->private_data
) {
364 priv
= talloc_get_type_abort(ctx
->private_data
,
365 struct libnetapi_private_ctx
);
367 libnetapi_samr_close_domain_handle(ctx
, &priv
->samr
.domain_handle
);
368 libnetapi_samr_close_builtin_handle(ctx
, &priv
->samr
.builtin_handle
);
369 libnetapi_samr_close_connect_handle(ctx
, &priv
->samr
.connect_handle
);