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 "../librpc/gen_ndr/cli_samr.h"
24 #include "rpc_client/cli_samr.h"
26 /****************************************************************
27 ****************************************************************/
29 WERROR libnetapi_samr_open_domain(struct libnetapi_ctx *mem_ctx,
30 struct rpc_pipe_client *pipe_cli,
31 uint32_t connect_mask,
33 struct policy_handle *connect_handle,
34 struct policy_handle *domain_handle,
35 struct dom_sid2 **domain_sid)
39 struct libnetapi_private_ctx *priv;
40 uint32_t resume_handle = 0;
41 uint32_t num_entries = 0;
42 struct samr_SamArray *sam = NULL;
43 const char *domain_name = NULL;
44 struct lsa_String lsa_domain_name;
45 bool domain_found = true;
48 priv = talloc_get_type_abort(mem_ctx->private_data,
49 struct libnetapi_private_ctx);
51 if (is_valid_policy_hnd(&priv->samr.connect_handle)) {
52 if ((priv->samr.connect_mask & connect_mask) == connect_mask) {
53 *connect_handle = priv->samr.connect_handle;
55 libnetapi_samr_close_connect_handle(mem_ctx,
56 &priv->samr.connect_handle);
60 if (is_valid_policy_hnd(&priv->samr.domain_handle)) {
61 if ((priv->samr.domain_mask & domain_mask) == domain_mask) {
62 *domain_handle = priv->samr.domain_handle;
64 libnetapi_samr_close_domain_handle(mem_ctx,
65 &priv->samr.domain_handle);
69 if (priv->samr.domain_sid) {
70 *domain_sid = priv->samr.domain_sid;
73 if (is_valid_policy_hnd(&priv->samr.connect_handle) &&
74 ((priv->samr.connect_mask & connect_mask) == connect_mask) &&
75 is_valid_policy_hnd(&priv->samr.domain_handle) &&
76 (priv->samr.domain_mask & domain_mask) == domain_mask) {
80 if (!is_valid_policy_hnd(connect_handle)) {
81 status = rpccli_try_samr_connects(pipe_cli, mem_ctx,
84 if (!NT_STATUS_IS_OK(status)) {
85 werr = ntstatus_to_werror(status);
90 status = rpccli_samr_EnumDomains(pipe_cli, mem_ctx,
96 if (!NT_STATUS_IS_OK(status)) {
97 werr = ntstatus_to_werror(status);
101 for (i=0; i<num_entries; i++) {
103 domain_name = sam->entries[i].name.string;
105 if (strequal(domain_name, builtin_domain_name())) {
114 werr = WERR_NO_SUCH_DOMAIN;
118 init_lsa_String(&lsa_domain_name, domain_name);
120 status = rpccli_samr_LookupDomain(pipe_cli, mem_ctx,
124 if (!NT_STATUS_IS_OK(status)) {
125 werr = ntstatus_to_werror(status);
129 status = rpccli_samr_OpenDomain(pipe_cli, mem_ctx,
134 if (!NT_STATUS_IS_OK(status)) {
135 werr = ntstatus_to_werror(status);
139 priv->samr.cli = pipe_cli;
141 priv->samr.domain_name = domain_name;
142 priv->samr.domain_sid = *domain_sid;
144 priv->samr.connect_mask = connect_mask;
145 priv->samr.connect_handle = *connect_handle;
147 priv->samr.domain_mask = domain_mask;
148 priv->samr.domain_handle = *domain_handle;
156 /****************************************************************
157 ****************************************************************/
159 WERROR libnetapi_samr_open_builtin_domain(struct libnetapi_ctx *mem_ctx,
160 struct rpc_pipe_client *pipe_cli,
161 uint32_t connect_mask,
162 uint32_t builtin_mask,
163 struct policy_handle *connect_handle,
164 struct policy_handle *builtin_handle)
168 struct libnetapi_private_ctx *priv;
170 priv = talloc_get_type_abort(mem_ctx->private_data,
171 struct libnetapi_private_ctx);
173 if (is_valid_policy_hnd(&priv->samr.connect_handle)) {
174 if ((priv->samr.connect_mask & connect_mask) == connect_mask) {
175 *connect_handle = priv->samr.connect_handle;
177 libnetapi_samr_close_connect_handle(mem_ctx,
178 &priv->samr.connect_handle);
182 if (is_valid_policy_hnd(&priv->samr.builtin_handle)) {
183 if ((priv->samr.builtin_mask & builtin_mask) == builtin_mask) {
184 *builtin_handle = priv->samr.builtin_handle;
186 libnetapi_samr_close_builtin_handle(mem_ctx,
187 &priv->samr.builtin_handle);
191 if (is_valid_policy_hnd(&priv->samr.connect_handle) &&
192 ((priv->samr.connect_mask & connect_mask) == connect_mask) &&
193 is_valid_policy_hnd(&priv->samr.builtin_handle) &&
194 (priv->samr.builtin_mask & builtin_mask) == builtin_mask) {
198 if (!is_valid_policy_hnd(connect_handle)) {
199 status = rpccli_try_samr_connects(pipe_cli, mem_ctx,
202 if (!NT_STATUS_IS_OK(status)) {
203 werr = ntstatus_to_werror(status);
208 status = rpccli_samr_OpenDomain(pipe_cli, mem_ctx,
211 CONST_DISCARD(struct dom_sid *, &global_sid_Builtin),
213 if (!NT_STATUS_IS_OK(status)) {
214 werr = ntstatus_to_werror(status);
218 priv->samr.cli = pipe_cli;
220 priv->samr.connect_mask = connect_mask;
221 priv->samr.connect_handle = *connect_handle;
223 priv->samr.builtin_mask = builtin_mask;
224 priv->samr.builtin_handle = *builtin_handle;
232 /****************************************************************
233 ****************************************************************/
235 void libnetapi_samr_close_domain_handle(struct libnetapi_ctx *ctx,
236 struct policy_handle *handle)
238 struct libnetapi_private_ctx *priv;
240 if (!is_valid_policy_hnd(handle)) {
244 priv = talloc_get_type_abort(ctx->private_data,
245 struct libnetapi_private_ctx);
247 if (!policy_hnd_equal(handle, &priv->samr.domain_handle)) {
251 rpccli_samr_Close(priv->samr.cli, ctx, handle);
253 ZERO_STRUCT(priv->samr.domain_handle);
256 /****************************************************************
257 ****************************************************************/
259 void libnetapi_samr_close_builtin_handle(struct libnetapi_ctx *ctx,
260 struct policy_handle *handle)
262 struct libnetapi_private_ctx *priv;
264 if (!is_valid_policy_hnd(handle)) {
268 priv = talloc_get_type_abort(ctx->private_data,
269 struct libnetapi_private_ctx);
271 if (!policy_hnd_equal(handle, &priv->samr.builtin_handle)) {
275 rpccli_samr_Close(priv->samr.cli, ctx, handle);
277 ZERO_STRUCT(priv->samr.builtin_handle);
280 /****************************************************************
281 ****************************************************************/
283 void libnetapi_samr_close_connect_handle(struct libnetapi_ctx *ctx,
284 struct policy_handle *handle)
286 struct libnetapi_private_ctx *priv;
288 if (!is_valid_policy_hnd(handle)) {
292 priv = talloc_get_type_abort(ctx->private_data,
293 struct libnetapi_private_ctx);
295 if (!policy_hnd_equal(handle, &priv->samr.connect_handle)) {
299 rpccli_samr_Close(priv->samr.cli, ctx, handle);
301 ZERO_STRUCT(priv->samr.connect_handle);
304 /****************************************************************
305 ****************************************************************/
307 void libnetapi_samr_free(struct libnetapi_ctx *ctx)
309 struct libnetapi_private_ctx *priv;
311 if (!ctx->private_data) {
315 priv = talloc_get_type_abort(ctx->private_data,
316 struct libnetapi_private_ctx);
318 libnetapi_samr_close_domain_handle(ctx, &priv->samr.domain_handle);
319 libnetapi_samr_close_builtin_handle(ctx, &priv->samr.builtin_handle);
320 libnetapi_samr_close_connect_handle(ctx, &priv->samr.connect_handle);