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);