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"
26 #include "../libcli/security/security.h"
28 /****************************************************************
29 ****************************************************************/
31 WERROR libnetapi_samr_open_domain(struct libnetapi_ctx *mem_ctx,
32 struct rpc_pipe_client *pipe_cli,
33 uint32_t connect_mask,
35 struct policy_handle *connect_handle,
36 struct policy_handle *domain_handle,
37 struct dom_sid2 **domain_sid)
41 struct libnetapi_private_ctx *priv;
42 uint32_t resume_handle = 0;
43 uint32_t num_entries = 0;
44 struct samr_SamArray *sam = NULL;
45 const char *domain_name = NULL;
46 struct lsa_String lsa_domain_name;
47 bool domain_found = true;
50 priv = talloc_get_type_abort(mem_ctx->private_data,
51 struct libnetapi_private_ctx);
53 if (is_valid_policy_hnd(&priv->samr.connect_handle)) {
54 if ((priv->samr.connect_mask & connect_mask) == connect_mask) {
55 *connect_handle = priv->samr.connect_handle;
57 libnetapi_samr_close_connect_handle(mem_ctx,
58 &priv->samr.connect_handle);
62 if (is_valid_policy_hnd(&priv->samr.domain_handle)) {
63 if ((priv->samr.domain_mask & domain_mask) == domain_mask) {
64 *domain_handle = priv->samr.domain_handle;
66 libnetapi_samr_close_domain_handle(mem_ctx,
67 &priv->samr.domain_handle);
71 if (priv->samr.domain_sid) {
72 *domain_sid = priv->samr.domain_sid;
75 if (is_valid_policy_hnd(&priv->samr.connect_handle) &&
76 ((priv->samr.connect_mask & connect_mask) == connect_mask) &&
77 is_valid_policy_hnd(&priv->samr.domain_handle) &&
78 (priv->samr.domain_mask & domain_mask) == domain_mask) {
82 if (!is_valid_policy_hnd(connect_handle)) {
83 status = rpccli_try_samr_connects(pipe_cli, mem_ctx,
86 if (!NT_STATUS_IS_OK(status)) {
87 werr = ntstatus_to_werror(status);
92 status = rpccli_samr_EnumDomains(pipe_cli, mem_ctx,
98 if (!NT_STATUS_IS_OK(status)) {
99 werr = ntstatus_to_werror(status);
103 for (i=0; i<num_entries; i++) {
105 domain_name = sam->entries[i].name.string;
107 if (strequal(domain_name, builtin_domain_name())) {
116 werr = WERR_NO_SUCH_DOMAIN;
120 init_lsa_String(&lsa_domain_name, domain_name);
122 status = rpccli_samr_LookupDomain(pipe_cli, mem_ctx,
126 if (!NT_STATUS_IS_OK(status)) {
127 werr = ntstatus_to_werror(status);
131 status = rpccli_samr_OpenDomain(pipe_cli, mem_ctx,
136 if (!NT_STATUS_IS_OK(status)) {
137 werr = ntstatus_to_werror(status);
141 priv->samr.cli = pipe_cli;
143 priv->samr.domain_name = domain_name;
144 priv->samr.domain_sid = *domain_sid;
146 priv->samr.connect_mask = connect_mask;
147 priv->samr.connect_handle = *connect_handle;
149 priv->samr.domain_mask = domain_mask;
150 priv->samr.domain_handle = *domain_handle;
158 /****************************************************************
159 ****************************************************************/
161 WERROR libnetapi_samr_open_builtin_domain(struct libnetapi_ctx *mem_ctx,
162 struct rpc_pipe_client *pipe_cli,
163 uint32_t connect_mask,
164 uint32_t builtin_mask,
165 struct policy_handle *connect_handle,
166 struct policy_handle *builtin_handle)
170 struct libnetapi_private_ctx *priv;
172 priv = talloc_get_type_abort(mem_ctx->private_data,
173 struct libnetapi_private_ctx);
175 if (is_valid_policy_hnd(&priv->samr.connect_handle)) {
176 if ((priv->samr.connect_mask & connect_mask) == connect_mask) {
177 *connect_handle = priv->samr.connect_handle;
179 libnetapi_samr_close_connect_handle(mem_ctx,
180 &priv->samr.connect_handle);
184 if (is_valid_policy_hnd(&priv->samr.builtin_handle)) {
185 if ((priv->samr.builtin_mask & builtin_mask) == builtin_mask) {
186 *builtin_handle = priv->samr.builtin_handle;
188 libnetapi_samr_close_builtin_handle(mem_ctx,
189 &priv->samr.builtin_handle);
193 if (is_valid_policy_hnd(&priv->samr.connect_handle) &&
194 ((priv->samr.connect_mask & connect_mask) == connect_mask) &&
195 is_valid_policy_hnd(&priv->samr.builtin_handle) &&
196 (priv->samr.builtin_mask & builtin_mask) == builtin_mask) {
200 if (!is_valid_policy_hnd(connect_handle)) {
201 status = rpccli_try_samr_connects(pipe_cli, mem_ctx,
204 if (!NT_STATUS_IS_OK(status)) {
205 werr = ntstatus_to_werror(status);
210 status = rpccli_samr_OpenDomain(pipe_cli, mem_ctx,
213 CONST_DISCARD(struct dom_sid *, &global_sid_Builtin),
215 if (!NT_STATUS_IS_OK(status)) {
216 werr = ntstatus_to_werror(status);
220 priv->samr.cli = pipe_cli;
222 priv->samr.connect_mask = connect_mask;
223 priv->samr.connect_handle = *connect_handle;
225 priv->samr.builtin_mask = builtin_mask;
226 priv->samr.builtin_handle = *builtin_handle;
234 /****************************************************************
235 ****************************************************************/
237 void libnetapi_samr_close_domain_handle(struct libnetapi_ctx *ctx,
238 struct policy_handle *handle)
240 struct libnetapi_private_ctx *priv;
242 if (!is_valid_policy_hnd(handle)) {
246 priv = talloc_get_type_abort(ctx->private_data,
247 struct libnetapi_private_ctx);
249 if (!policy_hnd_equal(handle, &priv->samr.domain_handle)) {
253 rpccli_samr_Close(priv->samr.cli, ctx, handle);
255 ZERO_STRUCT(priv->samr.domain_handle);
258 /****************************************************************
259 ****************************************************************/
261 void libnetapi_samr_close_builtin_handle(struct libnetapi_ctx *ctx,
262 struct policy_handle *handle)
264 struct libnetapi_private_ctx *priv;
266 if (!is_valid_policy_hnd(handle)) {
270 priv = talloc_get_type_abort(ctx->private_data,
271 struct libnetapi_private_ctx);
273 if (!policy_hnd_equal(handle, &priv->samr.builtin_handle)) {
277 rpccli_samr_Close(priv->samr.cli, ctx, handle);
279 ZERO_STRUCT(priv->samr.builtin_handle);
282 /****************************************************************
283 ****************************************************************/
285 void libnetapi_samr_close_connect_handle(struct libnetapi_ctx *ctx,
286 struct policy_handle *handle)
288 struct libnetapi_private_ctx *priv;
290 if (!is_valid_policy_hnd(handle)) {
294 priv = talloc_get_type_abort(ctx->private_data,
295 struct libnetapi_private_ctx);
297 if (!policy_hnd_equal(handle, &priv->samr.connect_handle)) {
301 rpccli_samr_Close(priv->samr.cli, ctx, handle);
303 ZERO_STRUCT(priv->samr.connect_handle);
306 /****************************************************************
307 ****************************************************************/
309 void libnetapi_samr_free(struct libnetapi_ctx *ctx)
311 struct libnetapi_private_ctx *priv;
313 if (!ctx->private_data) {
317 priv = talloc_get_type_abort(ctx->private_data,
318 struct libnetapi_private_ctx);
320 libnetapi_samr_close_domain_handle(ctx, &priv->samr.domain_handle);
321 libnetapi_samr_close_builtin_handle(ctx, &priv->samr.builtin_handle);
322 libnetapi_samr_close_connect_handle(ctx, &priv->samr.connect_handle);