• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.5.8/source3/lib/netapi/
1/*
2 *  Unix SMB/CIFS implementation.
3 *  NetApi Samr Support
4 *  Copyright (C) Guenther Deschner 2008
5 *
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.
10 *
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.
15 *
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/>.
18 */
19
20#include "includes.h"
21#include "lib/netapi/netapi.h"
22#include "lib/netapi/netapi_private.h"
23#include "../librpc/gen_ndr/cli_samr.h"
24
25/****************************************************************
26****************************************************************/
27
28WERROR libnetapi_samr_open_domain(struct libnetapi_ctx *mem_ctx,
29				  struct rpc_pipe_client *pipe_cli,
30				  uint32_t connect_mask,
31				  uint32_t domain_mask,
32				  struct policy_handle *connect_handle,
33				  struct policy_handle *domain_handle,
34				  struct dom_sid2 **domain_sid)
35{
36	NTSTATUS status;
37	WERROR werr;
38	struct libnetapi_private_ctx *priv;
39	uint32_t resume_handle = 0;
40	uint32_t num_entries = 0;
41	struct samr_SamArray *sam = NULL;
42	const char *domain_name = NULL;
43	struct lsa_String lsa_domain_name;
44	bool domain_found = true;
45	int i;
46
47	priv = talloc_get_type_abort(mem_ctx->private_data,
48		struct libnetapi_private_ctx);
49
50	if (is_valid_policy_hnd(&priv->samr.connect_handle)) {
51		if ((priv->samr.connect_mask & connect_mask) == connect_mask) {
52			*connect_handle = priv->samr.connect_handle;
53		} else {
54			libnetapi_samr_close_connect_handle(mem_ctx,
55				&priv->samr.connect_handle);
56		}
57	}
58
59	if (is_valid_policy_hnd(&priv->samr.domain_handle)) {
60		if ((priv->samr.domain_mask & domain_mask) == domain_mask) {
61			*domain_handle = priv->samr.domain_handle;
62		} else {
63			libnetapi_samr_close_domain_handle(mem_ctx,
64				&priv->samr.domain_handle);
65		}
66	}
67
68	if (priv->samr.domain_sid) {
69		*domain_sid = priv->samr.domain_sid;
70	}
71
72	if (is_valid_policy_hnd(&priv->samr.connect_handle) &&
73	    ((priv->samr.connect_mask & connect_mask) == connect_mask) &&
74	    is_valid_policy_hnd(&priv->samr.domain_handle) &&
75	    (priv->samr.domain_mask & domain_mask) == domain_mask) {
76		return WERR_OK;
77	}
78
79	if (!is_valid_policy_hnd(connect_handle)) {
80		status = rpccli_try_samr_connects(pipe_cli, mem_ctx,
81						  connect_mask,
82						  connect_handle);
83		if (!NT_STATUS_IS_OK(status)) {
84			werr = ntstatus_to_werror(status);
85			goto done;
86		}
87	}
88
89	status = rpccli_samr_EnumDomains(pipe_cli, mem_ctx,
90					 connect_handle,
91					 &resume_handle,
92					 &sam,
93					 0xffffffff,
94					 &num_entries);
95	if (!NT_STATUS_IS_OK(status)) {
96		werr = ntstatus_to_werror(status);
97		goto done;
98	}
99
100	for (i=0; i<num_entries; i++) {
101
102		domain_name = sam->entries[i].name.string;
103
104		if (strequal(domain_name, builtin_domain_name())) {
105			continue;
106		}
107
108		domain_found = true;
109		break;
110	}
111
112	if (!domain_found) {
113		werr = WERR_NO_SUCH_DOMAIN;
114		goto done;
115	}
116
117	init_lsa_String(&lsa_domain_name, domain_name);
118
119	status = rpccli_samr_LookupDomain(pipe_cli, mem_ctx,
120					  connect_handle,
121					  &lsa_domain_name,
122					  domain_sid);
123	if (!NT_STATUS_IS_OK(status)) {
124		werr = ntstatus_to_werror(status);
125		goto done;
126	}
127
128	status = rpccli_samr_OpenDomain(pipe_cli, mem_ctx,
129					connect_handle,
130					domain_mask,
131					*domain_sid,
132					domain_handle);
133	if (!NT_STATUS_IS_OK(status)) {
134		werr = ntstatus_to_werror(status);
135		goto done;
136	}
137
138	priv->samr.cli			= pipe_cli;
139
140	priv->samr.domain_name		= domain_name;
141	priv->samr.domain_sid		= *domain_sid;
142
143	priv->samr.connect_mask		= connect_mask;
144	priv->samr.connect_handle	= *connect_handle;
145
146	priv->samr.domain_mask		= domain_mask;
147	priv->samr.domain_handle	= *domain_handle;
148
149	werr = WERR_OK;
150
151 done:
152	return werr;
153}
154
155/****************************************************************
156****************************************************************/
157
158WERROR libnetapi_samr_open_builtin_domain(struct libnetapi_ctx *mem_ctx,
159					  struct rpc_pipe_client *pipe_cli,
160					  uint32_t connect_mask,
161					  uint32_t builtin_mask,
162					  struct policy_handle *connect_handle,
163					  struct policy_handle *builtin_handle)
164{
165	NTSTATUS status;
166	WERROR werr;
167	struct libnetapi_private_ctx *priv;
168
169	priv = talloc_get_type_abort(mem_ctx->private_data,
170		struct libnetapi_private_ctx);
171
172	if (is_valid_policy_hnd(&priv->samr.connect_handle)) {
173		if ((priv->samr.connect_mask & connect_mask) == connect_mask) {
174			*connect_handle = priv->samr.connect_handle;
175		} else {
176			libnetapi_samr_close_connect_handle(mem_ctx,
177				&priv->samr.connect_handle);
178		}
179	}
180
181	if (is_valid_policy_hnd(&priv->samr.builtin_handle)) {
182		if ((priv->samr.builtin_mask & builtin_mask) == builtin_mask) {
183			*builtin_handle = priv->samr.builtin_handle;
184		} else {
185			libnetapi_samr_close_builtin_handle(mem_ctx,
186				&priv->samr.builtin_handle);
187		}
188	}
189
190	if (is_valid_policy_hnd(&priv->samr.connect_handle) &&
191	    ((priv->samr.connect_mask & connect_mask) == connect_mask) &&
192	    is_valid_policy_hnd(&priv->samr.builtin_handle) &&
193	    (priv->samr.builtin_mask & builtin_mask) == builtin_mask) {
194		return WERR_OK;
195	}
196
197	if (!is_valid_policy_hnd(connect_handle)) {
198		status = rpccli_try_samr_connects(pipe_cli, mem_ctx,
199						  connect_mask,
200						  connect_handle);
201		if (!NT_STATUS_IS_OK(status)) {
202			werr = ntstatus_to_werror(status);
203			goto done;
204		}
205	}
206
207	status = rpccli_samr_OpenDomain(pipe_cli, mem_ctx,
208					connect_handle,
209					builtin_mask,
210					CONST_DISCARD(DOM_SID *, &global_sid_Builtin),
211					builtin_handle);
212	if (!NT_STATUS_IS_OK(status)) {
213		werr = ntstatus_to_werror(status);
214		goto done;
215	}
216
217	priv->samr.cli			= pipe_cli;
218
219	priv->samr.connect_mask		= connect_mask;
220	priv->samr.connect_handle	= *connect_handle;
221
222	priv->samr.builtin_mask		= builtin_mask;
223	priv->samr.builtin_handle	= *builtin_handle;
224
225	werr = WERR_OK;
226
227 done:
228	return werr;
229}
230
231/****************************************************************
232****************************************************************/
233
234void libnetapi_samr_close_domain_handle(struct libnetapi_ctx *ctx,
235					struct policy_handle *handle)
236{
237	struct libnetapi_private_ctx *priv;
238
239	if (!is_valid_policy_hnd(handle)) {
240		return;
241	}
242
243	priv = talloc_get_type_abort(ctx->private_data,
244		struct libnetapi_private_ctx);
245
246	if (!policy_hnd_equal(handle, &priv->samr.domain_handle)) {
247		return;
248	}
249
250	rpccli_samr_Close(priv->samr.cli, ctx, handle);
251
252	ZERO_STRUCT(priv->samr.domain_handle);
253}
254
255/****************************************************************
256****************************************************************/
257
258void libnetapi_samr_close_builtin_handle(struct libnetapi_ctx *ctx,
259					 struct policy_handle *handle)
260{
261	struct libnetapi_private_ctx *priv;
262
263	if (!is_valid_policy_hnd(handle)) {
264		return;
265	}
266
267	priv = talloc_get_type_abort(ctx->private_data,
268		struct libnetapi_private_ctx);
269
270	if (!policy_hnd_equal(handle, &priv->samr.builtin_handle)) {
271		return;
272	}
273
274	rpccli_samr_Close(priv->samr.cli, ctx, handle);
275
276	ZERO_STRUCT(priv->samr.builtin_handle);
277}
278
279/****************************************************************
280****************************************************************/
281
282void libnetapi_samr_close_connect_handle(struct libnetapi_ctx *ctx,
283					 struct policy_handle *handle)
284{
285	struct libnetapi_private_ctx *priv;
286
287	if (!is_valid_policy_hnd(handle)) {
288		return;
289	}
290
291	priv = talloc_get_type_abort(ctx->private_data,
292		struct libnetapi_private_ctx);
293
294	if (!policy_hnd_equal(handle, &priv->samr.connect_handle)) {
295		return;
296	}
297
298	rpccli_samr_Close(priv->samr.cli, ctx, handle);
299
300	ZERO_STRUCT(priv->samr.connect_handle);
301}
302
303/****************************************************************
304****************************************************************/
305
306void libnetapi_samr_free(struct libnetapi_ctx *ctx)
307{
308	struct libnetapi_private_ctx *priv;
309
310	if (!ctx->private_data) {
311		return;
312	}
313
314	priv = talloc_get_type_abort(ctx->private_data,
315		struct libnetapi_private_ctx);
316
317	libnetapi_samr_close_domain_handle(ctx, &priv->samr.domain_handle);
318	libnetapi_samr_close_builtin_handle(ctx, &priv->samr.builtin_handle);
319	libnetapi_samr_close_connect_handle(ctx, &priv->samr.connect_handle);
320}
321