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"
25 #include "rpc_client/init_lsa.h"
27 /****************************************************************
28 ****************************************************************/
30 WERROR libnetapi_samr_open_domain(struct libnetapi_ctx *mem_ctx,
31 struct rpc_pipe_client *pipe_cli,
32 uint32_t connect_mask,
34 struct policy_handle *connect_handle,
35 struct policy_handle *domain_handle,
36 struct dom_sid2 **domain_sid)
40 struct libnetapi_private_ctx *priv;
41 uint32_t resume_handle = 0;
42 uint32_t num_entries = 0;
43 struct samr_SamArray *sam = NULL;
44 const char *domain_name = NULL;
45 struct lsa_String lsa_domain_name;
46 bool domain_found = true;
49 priv = talloc_get_type_abort(mem_ctx->private_data,
50 struct libnetapi_private_ctx);
52 if (is_valid_policy_hnd(&priv->samr.connect_handle)) {
53 if ((priv->samr.connect_mask & connect_mask) == connect_mask) {
54 *connect_handle = priv->samr.connect_handle;
56 libnetapi_samr_close_connect_handle(mem_ctx,
57 &priv->samr.connect_handle);
61 if (is_valid_policy_hnd(&priv->samr.domain_handle)) {
62 if ((priv->samr.domain_mask & domain_mask) == domain_mask) {
63 *domain_handle = priv->samr.domain_handle;
65 libnetapi_samr_close_domain_handle(mem_ctx,
66 &priv->samr.domain_handle);
70 if (priv->samr.domain_sid) {
71 *domain_sid = priv->samr.domain_sid;
74 if (is_valid_policy_hnd(&priv->samr.connect_handle) &&
75 ((priv->samr.connect_mask & connect_mask) == connect_mask) &&
76 is_valid_policy_hnd(&priv->samr.domain_handle) &&
77 (priv->samr.domain_mask & domain_mask) == domain_mask) {
81 if (!is_valid_policy_hnd(connect_handle)) {
82 status = rpccli_try_samr_connects(pipe_cli, mem_ctx,
85 if (!NT_STATUS_IS_OK(status)) {
86 werr = ntstatus_to_werror(status);
91 status = rpccli_samr_EnumDomains(pipe_cli, mem_ctx,
97 if (!NT_STATUS_IS_OK(status)) {
98 werr = ntstatus_to_werror(status);
102 for (i=0; i<num_entries; i++) {
104 domain_name = sam->entries[i].name.string;
106 if (strequal(domain_name, builtin_domain_name())) {
115 werr = WERR_NO_SUCH_DOMAIN;
119 init_lsa_String(&lsa_domain_name, domain_name);
121 status = rpccli_samr_LookupDomain(pipe_cli, mem_ctx,
125 if (!NT_STATUS_IS_OK(status)) {
126 werr = ntstatus_to_werror(status);
130 status = rpccli_samr_OpenDomain(pipe_cli, mem_ctx,
135 if (!NT_STATUS_IS_OK(status)) {
136 werr = ntstatus_to_werror(status);
140 priv->samr.cli = pipe_cli;
142 priv->samr.domain_name = domain_name;
143 priv->samr.domain_sid = *domain_sid;
145 priv->samr.connect_mask = connect_mask;
146 priv->samr.connect_handle = *connect_handle;
148 priv->samr.domain_mask = domain_mask;
149 priv->samr.domain_handle = *domain_handle;
157 /****************************************************************
158 ****************************************************************/
160 WERROR libnetapi_samr_open_builtin_domain(struct libnetapi_ctx *mem_ctx,
161 struct rpc_pipe_client *pipe_cli,
162 uint32_t connect_mask,
163 uint32_t builtin_mask,
164 struct policy_handle *connect_handle,
165 struct policy_handle *builtin_handle)
169 struct libnetapi_private_ctx *priv;
171 priv = talloc_get_type_abort(mem_ctx->private_data,
172 struct libnetapi_private_ctx);
174 if (is_valid_policy_hnd(&priv->samr.connect_handle)) {
175 if ((priv->samr.connect_mask & connect_mask) == connect_mask) {
176 *connect_handle = priv->samr.connect_handle;
178 libnetapi_samr_close_connect_handle(mem_ctx,
179 &priv->samr.connect_handle);
183 if (is_valid_policy_hnd(&priv->samr.builtin_handle)) {
184 if ((priv->samr.builtin_mask & builtin_mask) == builtin_mask) {
185 *builtin_handle = priv->samr.builtin_handle;
187 libnetapi_samr_close_builtin_handle(mem_ctx,
188 &priv->samr.builtin_handle);
192 if (is_valid_policy_hnd(&priv->samr.connect_handle) &&
193 ((priv->samr.connect_mask & connect_mask) == connect_mask) &&
194 is_valid_policy_hnd(&priv->samr.builtin_handle) &&
195 (priv->samr.builtin_mask & builtin_mask) == builtin_mask) {
199 if (!is_valid_policy_hnd(connect_handle)) {
200 status = rpccli_try_samr_connects(pipe_cli, mem_ctx,
203 if (!NT_STATUS_IS_OK(status)) {
204 werr = ntstatus_to_werror(status);
209 status = rpccli_samr_OpenDomain(pipe_cli, mem_ctx,
212 CONST_DISCARD(struct dom_sid *, &global_sid_Builtin),
214 if (!NT_STATUS_IS_OK(status)) {
215 werr = ntstatus_to_werror(status);
219 priv->samr.cli = pipe_cli;
221 priv->samr.connect_mask = connect_mask;
222 priv->samr.connect_handle = *connect_handle;
224 priv->samr.builtin_mask = builtin_mask;
225 priv->samr.builtin_handle = *builtin_handle;
233 /****************************************************************
234 ****************************************************************/
236 void libnetapi_samr_close_domain_handle(struct libnetapi_ctx *ctx,
237 struct policy_handle *handle)
239 struct libnetapi_private_ctx *priv;
241 if (!is_valid_policy_hnd(handle)) {
245 priv = talloc_get_type_abort(ctx->private_data,
246 struct libnetapi_private_ctx);
248 if (!policy_hnd_equal(handle, &priv->samr.domain_handle)) {
252 rpccli_samr_Close(priv->samr.cli, ctx, handle);
254 ZERO_STRUCT(priv->samr.domain_handle);
257 /****************************************************************
258 ****************************************************************/
260 void libnetapi_samr_close_builtin_handle(struct libnetapi_ctx *ctx,
261 struct policy_handle *handle)
263 struct libnetapi_private_ctx *priv;
265 if (!is_valid_policy_hnd(handle)) {
269 priv = talloc_get_type_abort(ctx->private_data,
270 struct libnetapi_private_ctx);
272 if (!policy_hnd_equal(handle, &priv->samr.builtin_handle)) {
276 rpccli_samr_Close(priv->samr.cli, ctx, handle);
278 ZERO_STRUCT(priv->samr.builtin_handle);
281 /****************************************************************
282 ****************************************************************/
284 void libnetapi_samr_close_connect_handle(struct libnetapi_ctx *ctx,
285 struct policy_handle *handle)
287 struct libnetapi_private_ctx *priv;
289 if (!is_valid_policy_hnd(handle)) {
293 priv = talloc_get_type_abort(ctx->private_data,
294 struct libnetapi_private_ctx);
296 if (!policy_hnd_equal(handle, &priv->samr.connect_handle)) {
300 rpccli_samr_Close(priv->samr.cli, ctx, handle);
302 ZERO_STRUCT(priv->samr.connect_handle);
305 /****************************************************************
306 ****************************************************************/
308 void libnetapi_samr_free(struct libnetapi_ctx *ctx)
310 struct libnetapi_private_ctx *priv;
312 if (!ctx->private_data) {
316 priv = talloc_get_type_abort(ctx->private_data,
317 struct libnetapi_private_ctx);
319 libnetapi_samr_close_domain_handle(ctx, &priv->samr.domain_handle);
320 libnetapi_samr_close_builtin_handle(ctx, &priv->samr.builtin_handle);
321 libnetapi_samr_close_connect_handle(ctx, &priv->samr.connect_handle);