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_p)
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;
47
printf("connecting\n");
49
*access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
51
r1.in.system_name = 0;
52
r1.in.access_mask = *access_mask;
53
r1.out.connect_handle = &h;
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));
61
r2.in.connect_handle = &h;
62
r2.in.domain_name = domname;
65
printf("domain lookup on %s\n", domname->string);
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));
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;
78
printf("opening domain\n");
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));
85
*handle = domain_handle;
92
static 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)
97
struct lsa_OpenPolicy2 open;
98
struct lsa_ObjectAttribute attr;
99
struct lsa_QosInfo qos;
101
*access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
107
qos.impersonation_level = 2;
108
qos.context_mode = 1;
109
qos.effective_only = 0;
113
open.in.system_name = domname->string;
114
open.in.attr = &attr;
115
open.in.access_mask = *access_mask;
116
open.out.handle = handle;
118
status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &open);
119
if (!NT_STATUS_IS_OK(status)) {
126
bool torture_domain_open_lsa(struct torture_context *torture)
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;
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);
141
ctx = libnet_context_init(torture->ev, torture->lp_ctx);
143
d_printf("failed to create libnet context\n");
147
ctx->cred = cmdline_credentials;
150
r.in.type = DOMAIN_LSA;
151
r.in.domain_name = domain_name;
152
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
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));
161
ZERO_STRUCT(lsa_close);
162
lsa_close.in.handle = &ctx->lsa.handle;
163
lsa_close.out.handle = &h;
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));
177
bool torture_domain_close_lsa(struct torture_context *torture)
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;
190
status = torture_rpc_binding(torture, &binding);
191
if (!NT_STATUS_IS_OK(status)) {
195
ctx = libnet_context_init(torture->ev, torture->lp_ctx);
197
d_printf("failed to create libnet context\n");
202
ctx->cred = cmdline_credentials;
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));
213
domain_name.string = lp_workgroup(torture->lp_ctx);
215
if (!test_opendomain_lsa(p, torture, &h, &domain_name, &access_mask)) {
216
d_printf("failed to open domain on lsa service\n");
222
ctx->lsa.name = domain_name.string;
223
ctx->lsa.access_mask = access_mask;
225
/* we have to use pipe's event context, otherwise the call will
227
ctx->event_ctx = p->conn->event_ctx;
230
r.in.type = DOMAIN_LSA;
231
r.in.domain_name = domain_name.string;
233
status = libnet_DomainClose(ctx, mem_ctx, &r);
234
if (!NT_STATUS_IS_OK(status)) {
240
talloc_free(mem_ctx);
246
bool torture_domain_open_samr(struct torture_context *torture)
249
struct libnet_context *ctx;
251
struct policy_handle domain_handle, handle;
252
struct libnet_DomainOpen io;
254
const char *domain_name;
257
mem_ctx = talloc_init("test_domainopen_lsa");
259
ctx = libnet_context_init(torture->ev, torture->lp_ctx);
260
ctx->cred = cmdline_credentials;
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);
268
* Testing synchronous version
270
printf("opening domain\n");
272
io.in.type = DOMAIN_SAMR;
273
io.in.domain_name = domain_name;
274
io.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
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));
283
domain_handle = ctx->samr.handle;
285
r.in.handle = &domain_handle;
286
r.out.handle = &handle;
288
printf("closing domain handle\n");
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));
298
talloc_free(mem_ctx);
305
bool torture_domain_close_samr(struct torture_context *torture)
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;
319
status = torture_rpc_binding(torture, &binding);
320
if (!NT_STATUS_IS_OK(status)) {
324
ctx = libnet_context_init(torture->ev, torture->lp_ctx);
326
d_printf("failed to create libnet context\n");
331
ctx->cred = cmdline_credentials;
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));
342
domain_name.string = talloc_strdup(mem_ctx, lp_workgroup(torture->lp_ctx));
344
if (!test_opendomain_samr(p, torture, &h, &domain_name, &access_mask, &sid)) {
345
d_printf("failed to open domain on samr service\n");
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;
361
r.in.type = DOMAIN_SAMR;
362
r.in.domain_name = domain_name.string;
364
status = libnet_DomainClose(ctx, mem_ctx, &r);
365
if (!NT_STATUS_IS_OK(status)) {
371
talloc_free(mem_ctx);
377
bool torture_domain_list(struct torture_context *torture)
381
TALLOC_CTX *mem_ctx = NULL;
382
struct dcerpc_binding *binding;
383
struct libnet_context *ctx;
384
struct libnet_DomainList r;
387
status = torture_rpc_binding(torture, &binding);
388
if (!NT_STATUS_IS_OK(status)) {
392
ctx = libnet_context_init(torture->ev, torture->lp_ctx);
394
d_printf("failed to create libnet context\n");
399
ctx->cred = cmdline_credentials;
401
mem_ctx = talloc_init("torture_domain_close_samr");
404
* querying the domain list using default buffer size
408
r.in.hostname = binding->host;
410
status = libnet_DomainList(ctx, mem_ctx, &r);
411
if (!NT_STATUS_IS_OK(status)) {
416
d_printf("Received list or domains (everything in one piece):\n");
418
for (i = 0; i < r.out.count; i++) {
419
d_printf("Name[%d]: %s\n", i, r.out.domains[i].name);
423
* querying the domain list using specified (much smaller) buffer size
426
ctx->samr.buf_size = 32;
429
r.in.hostname = binding->host;
431
status = libnet_DomainList(ctx, mem_ctx, &r);
432
if (!NT_STATUS_IS_OK(status)) {
437
d_printf("Received list or domains (collected in more than one round):\n");
439
for (i = 0; i < r.out.count; i++) {
440
d_printf("Name[%d]: %s\n", i, r.out.domains[i].name);
444
d_printf("\nStatus: %s\n", nt_errstr(status));
446
talloc_free(mem_ctx);