• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.5.8/source4/torture/libnet/
1/*
2   Unix SMB/CIFS implementation.
3   Test suite for libnet calls.
4
5   Copyright (C) Rafal Szczesniak 2006
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 3 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19*/
20
21
22#include "includes.h"
23#include "lib/cmdline/popt_common.h"
24#include "lib/events/events.h"
25#include "auth/credentials/credentials.h"
26#include "libnet/libnet.h"
27#include "librpc/gen_ndr/ndr_samr_c.h"
28#include "librpc/gen_ndr/ndr_lsa_c.h"
29#include "libcli/security/security.h"
30#include "librpc/rpc/dcerpc.h"
31#include "torture/torture.h"
32#include "torture/rpc/rpc.h"
33#include "param/param.h"
34
35
36static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
37				 struct policy_handle *handle, struct lsa_String *domname,
38				 uint32_t *access_mask, struct dom_sid **sid_p)
39{
40	NTSTATUS status;
41	struct policy_handle h, domain_handle;
42	struct samr_Connect r1;
43	struct samr_LookupDomain r2;
44	struct dom_sid2 *sid = NULL;
45	struct samr_OpenDomain r3;
46
47	printf("connecting\n");
48
49	*access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
50
51	r1.in.system_name = 0;
52	r1.in.access_mask = *access_mask;
53	r1.out.connect_handle = &h;
54
55	status = dcerpc_samr_Connect(p, mem_ctx, &r1);
56	if (!NT_STATUS_IS_OK(status)) {
57		printf("Connect failed - %s\n", nt_errstr(status));
58		return false;
59	}
60
61	r2.in.connect_handle = &h;
62	r2.in.domain_name = domname;
63	r2.out.sid = &sid;
64
65	printf("domain lookup on %s\n", domname->string);
66
67	status = dcerpc_samr_LookupDomain(p, mem_ctx, &r2);
68	if (!NT_STATUS_IS_OK(status)) {
69		printf("LookupDomain failed - %s\n", nt_errstr(status));
70		return false;
71	}
72
73	r3.in.connect_handle = &h;
74	r3.in.access_mask = *access_mask;
75	r3.in.sid = *sid_p = *r2.out.sid;
76	r3.out.domain_handle = &domain_handle;
77
78	printf("opening domain\n");
79
80	status = dcerpc_samr_OpenDomain(p, mem_ctx, &r3);
81	if (!NT_STATUS_IS_OK(status)) {
82		printf("OpenDomain failed - %s\n", nt_errstr(status));
83		return false;
84	} else {
85		*handle = domain_handle;
86	}
87
88	return true;
89}
90
91
92static bool test_opendomain_lsa(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
93				struct policy_handle *handle, struct lsa_String *domname,
94				uint32_t *access_mask)
95{
96	NTSTATUS status;
97	struct lsa_OpenPolicy2 open;
98	struct lsa_ObjectAttribute attr;
99	struct lsa_QosInfo qos;
100
101	*access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
102
103	ZERO_STRUCT(attr);
104	ZERO_STRUCT(qos);
105
106	qos.len                 = 0;
107	qos.impersonation_level = 2;
108	qos.context_mode        = 1;
109	qos.effective_only      = 0;
110
111	attr.sec_qos = &qos;
112
113	open.in.system_name = domname->string;
114	open.in.attr        = &attr;
115	open.in.access_mask = *access_mask;
116	open.out.handle     = handle;
117
118	status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &open);
119	if (!NT_STATUS_IS_OK(status)) {
120		return false;
121	}
122
123	return true;
124}
125
126bool torture_domain_open_lsa(struct torture_context *torture)
127{
128	NTSTATUS status;
129	bool ret = true;
130	struct libnet_context *ctx;
131	struct libnet_DomainOpen r;
132	struct lsa_Close lsa_close;
133	struct policy_handle h;
134	const char *domain_name;
135
136	/* we're accessing domain controller so the domain name should be
137	   passed (it's going to be resolved to dc name and address) instead
138	   of specific server name. */
139	domain_name = lp_workgroup(torture->lp_ctx);
140
141	ctx = libnet_context_init(torture->ev, torture->lp_ctx);
142	if (ctx == NULL) {
143		d_printf("failed to create libnet context\n");
144		return false;
145	}
146
147	ctx->cred = cmdline_credentials;
148
149	ZERO_STRUCT(r);
150	r.in.type = DOMAIN_LSA;
151	r.in.domain_name = domain_name;
152	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
153
154	status = libnet_DomainOpen(ctx, torture, &r);
155	if (!NT_STATUS_IS_OK(status)) {
156		d_printf("failed to open domain on lsa service: %s\n", nt_errstr(status));
157		ret = false;
158		goto done;
159	}
160
161	ZERO_STRUCT(lsa_close);
162	lsa_close.in.handle  = &ctx->lsa.handle;
163	lsa_close.out.handle = &h;
164
165	status = dcerpc_lsa_Close(ctx->lsa.pipe, ctx, &lsa_close);
166	if (!NT_STATUS_IS_OK(status)) {
167		d_printf("failed to close domain on lsa service: %s\n", nt_errstr(status));
168		ret = false;
169	}
170
171done:
172	talloc_free(ctx);
173	return ret;
174}
175
176
177bool torture_domain_close_lsa(struct torture_context *torture)
178{
179	bool ret = true;
180	NTSTATUS status;
181	TALLOC_CTX *mem_ctx=NULL;
182	struct libnet_context *ctx;
183	struct lsa_String domain_name;
184	struct dcerpc_binding *binding;
185	uint32_t access_mask;
186	struct policy_handle h;
187	struct dcerpc_pipe *p;
188	struct libnet_DomainClose r;
189
190	status = torture_rpc_binding(torture, &binding);
191	if (!NT_STATUS_IS_OK(status)) {
192		return false;
193	}
194
195	ctx = libnet_context_init(torture->ev, torture->lp_ctx);
196	if (ctx == NULL) {
197		d_printf("failed to create libnet context\n");
198		ret = false;
199		goto done;
200	}
201
202	ctx->cred = cmdline_credentials;
203
204	mem_ctx = talloc_init("torture_domain_close_lsa");
205	status = dcerpc_pipe_connect_b(mem_ctx, &p, binding, &ndr_table_lsarpc,
206				     cmdline_credentials, torture->ev, torture->lp_ctx);
207	if (!NT_STATUS_IS_OK(status)) {
208		d_printf("failed to connect to server: %s\n", nt_errstr(status));
209		ret = false;
210		goto done;
211	}
212
213	domain_name.string = lp_workgroup(torture->lp_ctx);
214
215	if (!test_opendomain_lsa(p, torture, &h, &domain_name, &access_mask)) {
216		d_printf("failed to open domain on lsa service\n");
217		ret = false;
218		goto done;
219	}
220
221	ctx->lsa.pipe        = p;
222	ctx->lsa.name        = domain_name.string;
223	ctx->lsa.access_mask = access_mask;
224	ctx->lsa.handle      = h;
225	/* we have to use pipe's event context, otherwise the call will
226	   hang indefinitely */
227	ctx->event_ctx       = p->conn->event_ctx;
228
229	ZERO_STRUCT(r);
230	r.in.type = DOMAIN_LSA;
231	r.in.domain_name = domain_name.string;
232
233	status = libnet_DomainClose(ctx, mem_ctx, &r);
234	if (!NT_STATUS_IS_OK(status)) {
235		ret = false;
236		goto done;
237	}
238
239done:
240	talloc_free(mem_ctx);
241	talloc_free(ctx);
242	return ret;
243}
244
245
246bool torture_domain_open_samr(struct torture_context *torture)
247{
248	NTSTATUS status;
249	struct libnet_context *ctx;
250	TALLOC_CTX *mem_ctx;
251	struct policy_handle domain_handle, handle;
252	struct libnet_DomainOpen io;
253	struct samr_Close r;
254	const char *domain_name;
255	bool ret = true;
256
257	mem_ctx = talloc_init("test_domainopen_lsa");
258
259	ctx = libnet_context_init(torture->ev, torture->lp_ctx);
260	ctx->cred = cmdline_credentials;
261
262	/* we're accessing domain controller so the domain name should be
263	   passed (it's going to be resolved to dc name and address) instead
264	   of specific server name. */
265	domain_name = lp_workgroup(torture->lp_ctx);
266
267	/*
268	 * Testing synchronous version
269	 */
270	printf("opening domain\n");
271
272	io.in.type         = DOMAIN_SAMR;
273	io.in.domain_name  = domain_name;
274	io.in.access_mask  = SEC_FLAG_MAXIMUM_ALLOWED;
275
276	status = libnet_DomainOpen(ctx, mem_ctx, &io);
277	if (!NT_STATUS_IS_OK(status)) {
278		printf("Composite domain open failed - %s\n", nt_errstr(status));
279		ret = false;
280		goto done;
281	}
282
283	domain_handle = ctx->samr.handle;
284
285	r.in.handle   = &domain_handle;
286	r.out.handle  = &handle;
287
288	printf("closing domain handle\n");
289
290	status = dcerpc_samr_Close(ctx->samr.pipe, mem_ctx, &r);
291	if (!NT_STATUS_IS_OK(status)) {
292		printf("Close failed - %s\n", nt_errstr(status));
293		ret = false;
294		goto done;
295	}
296
297done:
298	talloc_free(mem_ctx);
299	talloc_free(ctx);
300
301	return ret;
302}
303
304
305bool torture_domain_close_samr(struct torture_context *torture)
306{
307	bool ret = true;
308	NTSTATUS status;
309	TALLOC_CTX *mem_ctx = NULL;
310	struct libnet_context *ctx;
311	struct lsa_String domain_name;
312	struct dcerpc_binding *binding;
313	uint32_t access_mask;
314	struct policy_handle h;
315	struct dcerpc_pipe *p;
316	struct libnet_DomainClose r;
317	struct dom_sid *sid;
318
319	status = torture_rpc_binding(torture, &binding);
320	if (!NT_STATUS_IS_OK(status)) {
321		return false;
322	}
323
324	ctx = libnet_context_init(torture->ev, torture->lp_ctx);
325	if (ctx == NULL) {
326		d_printf("failed to create libnet context\n");
327		ret = false;
328		goto done;
329	}
330
331	ctx->cred = cmdline_credentials;
332
333	mem_ctx = talloc_init("torture_domain_close_samr");
334	status = dcerpc_pipe_connect_b(mem_ctx, &p, binding, &ndr_table_samr,
335				     ctx->cred, torture->ev, torture->lp_ctx);
336	if (!NT_STATUS_IS_OK(status)) {
337		d_printf("failed to connect to server: %s\n", nt_errstr(status));
338		ret = false;
339		goto done;
340	}
341
342	domain_name.string = talloc_strdup(mem_ctx, lp_workgroup(torture->lp_ctx));
343
344	if (!test_opendomain_samr(p, torture, &h, &domain_name, &access_mask, &sid)) {
345		d_printf("failed to open domain on samr service\n");
346		ret = false;
347		goto done;
348	}
349
350	ctx->samr.pipe        = p;
351	ctx->samr.name        = talloc_steal(ctx, domain_name.string);
352	ctx->samr.access_mask = access_mask;
353	ctx->samr.handle      = h;
354	ctx->samr.sid         = talloc_steal(ctx, sid);
355	/* we have to use pipe's event context, otherwise the call will
356	   hang indefinitely - this wouldn't be the case if pipe was opened
357	   by means of libnet call */
358	ctx->event_ctx       = p->conn->event_ctx;
359
360	ZERO_STRUCT(r);
361	r.in.type = DOMAIN_SAMR;
362	r.in.domain_name = domain_name.string;
363
364	status = libnet_DomainClose(ctx, mem_ctx, &r);
365	if (!NT_STATUS_IS_OK(status)) {
366		ret = false;
367		goto done;
368	}
369
370done:
371	talloc_free(mem_ctx);
372	talloc_free(ctx);
373	return ret;
374}
375
376
377bool torture_domain_list(struct torture_context *torture)
378{
379	bool ret = true;
380	NTSTATUS status;
381	TALLOC_CTX *mem_ctx = NULL;
382	struct dcerpc_binding *binding;
383	struct libnet_context *ctx;
384	struct libnet_DomainList r;
385	int i;
386
387	status = torture_rpc_binding(torture, &binding);
388	if (!NT_STATUS_IS_OK(status)) {
389		return false;
390	}
391
392	ctx = libnet_context_init(torture->ev, torture->lp_ctx);
393	if (ctx == NULL) {
394		d_printf("failed to create libnet context\n");
395		ret = false;
396		goto done;
397	}
398
399	ctx->cred = cmdline_credentials;
400
401	mem_ctx = talloc_init("torture_domain_close_samr");
402
403	/*
404	 * querying the domain list using default buffer size
405	 */
406
407	ZERO_STRUCT(r);
408	r.in.hostname = binding->host;
409
410	status = libnet_DomainList(ctx, mem_ctx, &r);
411	if (!NT_STATUS_IS_OK(status)) {
412		ret = false;
413		goto done;
414	}
415
416	d_printf("Received list or domains (everything in one piece):\n");
417
418	for (i = 0; i < r.out.count; i++) {
419		d_printf("Name[%d]: %s\n", i, r.out.domains[i].name);
420	}
421
422	/*
423	 * querying the domain list using specified (much smaller) buffer size
424	 */
425
426	ctx->samr.buf_size = 32;
427
428	ZERO_STRUCT(r);
429	r.in.hostname = binding->host;
430
431	status = libnet_DomainList(ctx, mem_ctx, &r);
432	if (!NT_STATUS_IS_OK(status)) {
433		ret = false;
434		goto done;
435	}
436
437	d_printf("Received list or domains (collected in more than one round):\n");
438
439	for (i = 0; i < r.out.count; i++) {
440		d_printf("Name[%d]: %s\n", i, r.out.domains[i].name);
441	}
442
443done:
444	d_printf("\nStatus: %s\n", nt_errstr(status));
445
446	talloc_free(mem_ctx);
447	talloc_free(ctx);
448	return ret;
449}
450