2 Unix SMB/CIFS implementation.
3 Test suite for libnet calls.
5 Copyright (C) Rafal Szczesniak 2006
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.
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.
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/>.
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"
36 static 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)
41 struct policy_handle h, domain_handle;
42 struct samr_Connect r1;
43 struct samr_LookupDomain r2;
44 struct samr_OpenDomain r3;
46 printf("connecting\n");
48 *access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
50 r1.in.system_name = 0;
51 r1.in.access_mask = *access_mask;
52 r1.out.connect_handle = &h;
54 status = dcerpc_samr_Connect(p, mem_ctx, &r1);
55 if (!NT_STATUS_IS_OK(status)) {
56 printf("Connect failed - %s\n", nt_errstr(status));
60 r2.in.connect_handle = &h;
61 r2.in.domain_name = domname;
63 printf("domain lookup on %s\n", domname->string);
65 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r2);
66 if (!NT_STATUS_IS_OK(status)) {
67 printf("LookupDomain failed - %s\n", nt_errstr(status));
71 r3.in.connect_handle = &h;
72 r3.in.access_mask = *access_mask;
73 r3.in.sid = *sid = r2.out.sid;
74 r3.out.domain_handle = &domain_handle;
76 printf("opening domain\n");
78 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r3);
79 if (!NT_STATUS_IS_OK(status)) {
80 printf("OpenDomain failed - %s\n", nt_errstr(status));
83 *handle = domain_handle;
90 static bool test_opendomain_lsa(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
91 struct policy_handle *handle, struct lsa_String *domname,
92 uint32_t *access_mask)
95 struct lsa_OpenPolicy2 open;
96 struct lsa_ObjectAttribute attr;
97 struct lsa_QosInfo qos;
99 *access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
105 qos.impersonation_level = 2;
106 qos.context_mode = 1;
107 qos.effective_only = 0;
111 open.in.system_name = domname->string;
112 open.in.attr = &attr;
113 open.in.access_mask = *access_mask;
114 open.out.handle = handle;
116 status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &open);
117 if (!NT_STATUS_IS_OK(status)) {
124 bool torture_domain_open_lsa(struct torture_context *torture)
128 struct libnet_context *ctx;
129 struct libnet_DomainOpen r;
130 struct lsa_Close lsa_close;
131 struct policy_handle h;
132 const char *domain_name;
134 /* we're accessing domain controller so the domain name should be
135 passed (it's going to be resolved to dc name and address) instead
136 of specific server name. */
137 domain_name = lp_workgroup(global_loadparm);
139 ctx = libnet_context_init(NULL);
141 d_printf("failed to create libnet context\n");
145 ctx->cred = cmdline_credentials;
148 r.in.type = DOMAIN_LSA;
149 r.in.domain_name = domain_name;
150 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
152 status = libnet_DomainOpen(ctx, torture, &r);
153 if (!NT_STATUS_IS_OK(status)) {
154 d_printf("failed to open domain on lsa service: %s\n", nt_errstr(status));
159 ZERO_STRUCT(lsa_close);
160 lsa_close.in.handle = &ctx->lsa.handle;
161 lsa_close.out.handle = &h;
163 status = dcerpc_lsa_Close(ctx->lsa.pipe, ctx, &lsa_close);
164 if (!NT_STATUS_IS_OK(status)) {
165 d_printf("failed to close domain on lsa service: %s\n", nt_errstr(status));
175 bool torture_domain_close_lsa(struct torture_context *torture)
179 TALLOC_CTX *mem_ctx=NULL;
180 struct libnet_context *ctx;
181 struct lsa_String domain_name;
182 struct dcerpc_binding *binding;
183 uint32_t access_mask;
184 struct policy_handle h;
185 struct dcerpc_pipe *p;
186 struct libnet_DomainClose r;
188 status = torture_rpc_binding(torture, &binding);
189 if (!NT_STATUS_IS_OK(status)) {
193 ctx = libnet_context_init(NULL);
195 d_printf("failed to create libnet context\n");
200 ctx->cred = cmdline_credentials;
202 mem_ctx = talloc_init("torture_domain_close_lsa");
203 status = dcerpc_pipe_connect_b(mem_ctx, &p, binding, &ndr_table_lsarpc,
204 cmdline_credentials, NULL);
205 if (!NT_STATUS_IS_OK(status)) {
206 d_printf("failed to connect to server: %s\n", nt_errstr(status));
211 domain_name.string = lp_workgroup(global_loadparm);
213 if (!test_opendomain_lsa(p, torture, &h, &domain_name, &access_mask)) {
214 d_printf("failed to open domain on lsa service\n");
220 ctx->lsa.name = domain_name.string;
221 ctx->lsa.access_mask = access_mask;
223 /* we have to use pipe's event context, otherwise the call will
225 ctx->event_ctx = p->conn->event_ctx;
228 r.in.type = DOMAIN_LSA;
229 r.in.domain_name = domain_name.string;
231 status = libnet_DomainClose(ctx, mem_ctx, &r);
232 if (!NT_STATUS_IS_OK(status)) {
238 talloc_free(mem_ctx);
244 bool torture_domain_open_samr(struct torture_context *torture)
247 struct libnet_context *ctx;
248 struct event_context *evt_ctx=NULL;
250 struct policy_handle domain_handle, handle;
251 struct libnet_DomainOpen io;
253 const char *domain_name;
256 mem_ctx = talloc_init("test_domainopen_lsa");
258 ctx = libnet_context_init(evt_ctx);
259 ctx->cred = cmdline_credentials;
261 /* we're accessing domain controller so the domain name should be
262 passed (it's going to be resolved to dc name and address) instead
263 of specific server name. */
264 domain_name = lp_workgroup(global_loadparm);
267 * Testing synchronous version
269 printf("opening domain\n");
271 io.in.type = DOMAIN_SAMR;
272 io.in.domain_name = domain_name;
273 io.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
275 status = libnet_DomainOpen(ctx, mem_ctx, &io);
276 if (!NT_STATUS_IS_OK(status)) {
277 printf("Composite domain open failed - %s\n", nt_errstr(status));
282 domain_handle = ctx->samr.handle;
284 r.in.handle = &domain_handle;
285 r.out.handle = &handle;
287 printf("closing domain handle\n");
289 status = dcerpc_samr_Close(ctx->samr.pipe, mem_ctx, &r);
290 if (!NT_STATUS_IS_OK(status)) {
291 printf("Close failed - %s\n", nt_errstr(status));
297 talloc_free(mem_ctx);
304 bool torture_domain_close_samr(struct torture_context *torture)
308 TALLOC_CTX *mem_ctx = NULL;
309 struct libnet_context *ctx;
310 struct lsa_String domain_name;
311 struct dcerpc_binding *binding;
312 uint32_t access_mask;
313 struct policy_handle h;
314 struct dcerpc_pipe *p;
315 struct libnet_DomainClose r;
318 status = torture_rpc_binding(torture, &binding);
319 if (!NT_STATUS_IS_OK(status)) {
323 ctx = libnet_context_init(NULL);
325 d_printf("failed to create libnet context\n");
330 ctx->cred = cmdline_credentials;
332 mem_ctx = talloc_init("torture_domain_close_samr");
333 status = dcerpc_pipe_connect_b(mem_ctx, &p, binding, &ndr_table_samr,
335 if (!NT_STATUS_IS_OK(status)) {
336 d_printf("failed to connect to server: %s\n", nt_errstr(status));
341 domain_name.string = talloc_strdup(mem_ctx, lp_workgroup(global_loadparm));
343 if (!test_opendomain_samr(p, torture, &h, &domain_name, &access_mask, &sid)) {
344 d_printf("failed to open domain on samr service\n");
350 ctx->samr.name = talloc_steal(ctx, domain_name.string);
351 ctx->samr.access_mask = access_mask;
352 ctx->samr.handle = h;
353 ctx->samr.sid = talloc_steal(ctx, sid);
354 /* we have to use pipe's event context, otherwise the call will
355 hang indefinitely - this wouldn't be the case if pipe was opened
356 by means of libnet call */
357 ctx->event_ctx = p->conn->event_ctx;
360 r.in.type = DOMAIN_SAMR;
361 r.in.domain_name = domain_name.string;
363 status = libnet_DomainClose(ctx, mem_ctx, &r);
364 if (!NT_STATUS_IS_OK(status)) {
370 talloc_free(mem_ctx);
376 bool torture_domain_list(struct torture_context *torture)
380 TALLOC_CTX *mem_ctx = NULL;
381 struct dcerpc_binding *binding;
382 struct libnet_context *ctx;
383 struct libnet_DomainList r;
386 status = torture_rpc_binding(torture, &binding);
387 if (!NT_STATUS_IS_OK(status)) {
391 ctx = libnet_context_init(NULL);
393 d_printf("failed to create libnet context\n");
398 ctx->cred = cmdline_credentials;
400 mem_ctx = talloc_init("torture_domain_close_samr");
403 * querying the domain list using default buffer size
407 r.in.hostname = binding->host;
409 status = libnet_DomainList(ctx, mem_ctx, &r);
410 if (!NT_STATUS_IS_OK(status)) {
415 d_printf("Received list or domains (everything in one piece):\n");
417 for (i = 0; i < r.out.count; i++) {
418 d_printf("Name[%d]: %s\n", i, r.out.domains[i].name);
422 * querying the domain list using specified (much smaller) buffer size
425 ctx->samr.buf_size = 32;
428 r.in.hostname = binding->host;
430 status = libnet_DomainList(ctx, mem_ctx, &r);
431 if (!NT_STATUS_IS_OK(status)) {
436 d_printf("Received list or domains (collected in more than one round):\n");
438 for (i = 0; i < r.out.count; i++) {
439 d_printf("Name[%d]: %s\n", i, r.out.domains[i].name);
443 d_printf("\nStatus: %s\n", nt_errstr(status));
445 talloc_free(mem_ctx);