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 "libnet/libnet.h"
25 #include "librpc/gen_ndr/ndr_samr_c.h"
26 #include "librpc/gen_ndr/ndr_lsa_c.h"
27 #include "torture/rpc/rpc.h"
28 #include "param/param.h"
31 static bool test_opendomain_samr(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
32 struct policy_handle
*handle
, struct lsa_String
*domname
,
33 uint32_t *access_mask
, struct dom_sid
**sid_p
)
36 struct policy_handle h
, domain_handle
;
37 struct samr_Connect r1
;
38 struct samr_LookupDomain r2
;
39 struct dom_sid2
*sid
= NULL
;
40 struct samr_OpenDomain r3
;
42 printf("connecting\n");
44 *access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
46 r1
.in
.system_name
= 0;
47 r1
.in
.access_mask
= *access_mask
;
48 r1
.out
.connect_handle
= &h
;
50 status
= dcerpc_samr_Connect(p
, mem_ctx
, &r1
);
51 if (!NT_STATUS_IS_OK(status
)) {
52 printf("Connect failed - %s\n", nt_errstr(status
));
56 r2
.in
.connect_handle
= &h
;
57 r2
.in
.domain_name
= domname
;
60 printf("domain lookup on %s\n", domname
->string
);
62 status
= dcerpc_samr_LookupDomain(p
, mem_ctx
, &r2
);
63 if (!NT_STATUS_IS_OK(status
)) {
64 printf("LookupDomain failed - %s\n", nt_errstr(status
));
68 r3
.in
.connect_handle
= &h
;
69 r3
.in
.access_mask
= *access_mask
;
70 r3
.in
.sid
= *sid_p
= *r2
.out
.sid
;
71 r3
.out
.domain_handle
= &domain_handle
;
73 printf("opening domain\n");
75 status
= dcerpc_samr_OpenDomain(p
, mem_ctx
, &r3
);
76 if (!NT_STATUS_IS_OK(status
)) {
77 printf("OpenDomain failed - %s\n", nt_errstr(status
));
80 *handle
= domain_handle
;
87 static bool test_opendomain_lsa(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
88 struct policy_handle
*handle
, struct lsa_String
*domname
,
89 uint32_t *access_mask
)
92 struct lsa_OpenPolicy2 open
;
93 struct lsa_ObjectAttribute attr
;
94 struct lsa_QosInfo qos
;
96 *access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
102 qos
.impersonation_level
= 2;
103 qos
.context_mode
= 1;
104 qos
.effective_only
= 0;
108 open
.in
.system_name
= domname
->string
;
109 open
.in
.attr
= &attr
;
110 open
.in
.access_mask
= *access_mask
;
111 open
.out
.handle
= handle
;
113 status
= dcerpc_lsa_OpenPolicy2(p
, mem_ctx
, &open
);
114 if (!NT_STATUS_IS_OK(status
)) {
121 bool torture_domain_open_lsa(struct torture_context
*torture
)
125 struct libnet_context
*ctx
;
126 struct libnet_DomainOpen r
;
127 struct lsa_Close lsa_close
;
128 struct policy_handle h
;
129 const char *domain_name
;
131 /* we're accessing domain controller so the domain name should be
132 passed (it's going to be resolved to dc name and address) instead
133 of specific server name. */
134 domain_name
= lp_workgroup(torture
->lp_ctx
);
136 ctx
= libnet_context_init(torture
->ev
, torture
->lp_ctx
);
138 d_printf("failed to create libnet context\n");
142 ctx
->cred
= cmdline_credentials
;
145 r
.in
.type
= DOMAIN_LSA
;
146 r
.in
.domain_name
= domain_name
;
147 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
149 status
= libnet_DomainOpen(ctx
, torture
, &r
);
150 if (!NT_STATUS_IS_OK(status
)) {
151 d_printf("failed to open domain on lsa service: %s\n", nt_errstr(status
));
156 ZERO_STRUCT(lsa_close
);
157 lsa_close
.in
.handle
= &ctx
->lsa
.handle
;
158 lsa_close
.out
.handle
= &h
;
160 status
= dcerpc_lsa_Close(ctx
->lsa
.pipe
, ctx
, &lsa_close
);
161 if (!NT_STATUS_IS_OK(status
)) {
162 d_printf("failed to close domain on lsa service: %s\n", nt_errstr(status
));
172 bool torture_domain_close_lsa(struct torture_context
*torture
)
176 TALLOC_CTX
*mem_ctx
=NULL
;
177 struct libnet_context
*ctx
;
178 struct lsa_String domain_name
;
179 struct dcerpc_binding
*binding
;
180 uint32_t access_mask
;
181 struct policy_handle h
;
182 struct dcerpc_pipe
*p
;
183 struct libnet_DomainClose r
;
185 status
= torture_rpc_binding(torture
, &binding
);
186 if (!NT_STATUS_IS_OK(status
)) {
190 ctx
= libnet_context_init(torture
->ev
, torture
->lp_ctx
);
192 d_printf("failed to create libnet context\n");
197 ctx
->cred
= cmdline_credentials
;
199 mem_ctx
= talloc_init("torture_domain_close_lsa");
200 status
= dcerpc_pipe_connect_b(mem_ctx
, &p
, binding
, &ndr_table_lsarpc
,
201 cmdline_credentials
, torture
->ev
, torture
->lp_ctx
);
202 if (!NT_STATUS_IS_OK(status
)) {
203 d_printf("failed to connect to server: %s\n", nt_errstr(status
));
208 domain_name
.string
= lp_workgroup(torture
->lp_ctx
);
210 if (!test_opendomain_lsa(p
, torture
, &h
, &domain_name
, &access_mask
)) {
211 d_printf("failed to open domain on lsa service\n");
217 ctx
->lsa
.name
= domain_name
.string
;
218 ctx
->lsa
.access_mask
= access_mask
;
220 /* we have to use pipe's event context, otherwise the call will
222 ctx
->event_ctx
= p
->conn
->event_ctx
;
225 r
.in
.type
= DOMAIN_LSA
;
226 r
.in
.domain_name
= domain_name
.string
;
228 status
= libnet_DomainClose(ctx
, mem_ctx
, &r
);
229 if (!NT_STATUS_IS_OK(status
)) {
235 talloc_free(mem_ctx
);
241 bool torture_domain_open_samr(struct torture_context
*torture
)
244 struct libnet_context
*ctx
;
246 struct policy_handle domain_handle
, handle
;
247 struct libnet_DomainOpen io
;
249 const char *domain_name
;
252 mem_ctx
= talloc_init("test_domainopen_lsa");
254 ctx
= libnet_context_init(torture
->ev
, torture
->lp_ctx
);
255 ctx
->cred
= cmdline_credentials
;
257 /* we're accessing domain controller so the domain name should be
258 passed (it's going to be resolved to dc name and address) instead
259 of specific server name. */
260 domain_name
= lp_workgroup(torture
->lp_ctx
);
263 * Testing synchronous version
265 printf("opening domain\n");
267 io
.in
.type
= DOMAIN_SAMR
;
268 io
.in
.domain_name
= domain_name
;
269 io
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
271 status
= libnet_DomainOpen(ctx
, mem_ctx
, &io
);
272 if (!NT_STATUS_IS_OK(status
)) {
273 printf("Composite domain open failed - %s\n", nt_errstr(status
));
278 domain_handle
= ctx
->samr
.handle
;
280 r
.in
.handle
= &domain_handle
;
281 r
.out
.handle
= &handle
;
283 printf("closing domain handle\n");
285 status
= dcerpc_samr_Close(ctx
->samr
.pipe
, mem_ctx
, &r
);
286 if (!NT_STATUS_IS_OK(status
)) {
287 printf("Close failed - %s\n", nt_errstr(status
));
293 talloc_free(mem_ctx
);
300 bool torture_domain_close_samr(struct torture_context
*torture
)
304 TALLOC_CTX
*mem_ctx
= NULL
;
305 struct libnet_context
*ctx
;
306 struct lsa_String domain_name
;
307 struct dcerpc_binding
*binding
;
308 uint32_t access_mask
;
309 struct policy_handle h
;
310 struct dcerpc_pipe
*p
;
311 struct libnet_DomainClose r
;
314 status
= torture_rpc_binding(torture
, &binding
);
315 if (!NT_STATUS_IS_OK(status
)) {
319 ctx
= libnet_context_init(torture
->ev
, torture
->lp_ctx
);
321 d_printf("failed to create libnet context\n");
326 ctx
->cred
= cmdline_credentials
;
328 mem_ctx
= talloc_init("torture_domain_close_samr");
329 status
= dcerpc_pipe_connect_b(mem_ctx
, &p
, binding
, &ndr_table_samr
,
330 ctx
->cred
, torture
->ev
, torture
->lp_ctx
);
331 if (!NT_STATUS_IS_OK(status
)) {
332 d_printf("failed to connect to server: %s\n", nt_errstr(status
));
337 domain_name
.string
= talloc_strdup(mem_ctx
, lp_workgroup(torture
->lp_ctx
));
339 if (!test_opendomain_samr(p
, torture
, &h
, &domain_name
, &access_mask
, &sid
)) {
340 d_printf("failed to open domain on samr service\n");
346 ctx
->samr
.name
= talloc_steal(ctx
, domain_name
.string
);
347 ctx
->samr
.access_mask
= access_mask
;
348 ctx
->samr
.handle
= h
;
349 ctx
->samr
.sid
= talloc_steal(ctx
, sid
);
350 /* we have to use pipe's event context, otherwise the call will
351 hang indefinitely - this wouldn't be the case if pipe was opened
352 by means of libnet call */
353 ctx
->event_ctx
= p
->conn
->event_ctx
;
356 r
.in
.type
= DOMAIN_SAMR
;
357 r
.in
.domain_name
= domain_name
.string
;
359 status
= libnet_DomainClose(ctx
, mem_ctx
, &r
);
360 if (!NT_STATUS_IS_OK(status
)) {
366 talloc_free(mem_ctx
);
372 bool torture_domain_list(struct torture_context
*torture
)
376 TALLOC_CTX
*mem_ctx
= NULL
;
377 struct dcerpc_binding
*binding
;
378 struct libnet_context
*ctx
;
379 struct libnet_DomainList r
;
382 status
= torture_rpc_binding(torture
, &binding
);
383 if (!NT_STATUS_IS_OK(status
)) {
387 ctx
= libnet_context_init(torture
->ev
, torture
->lp_ctx
);
389 d_printf("failed to create libnet context\n");
394 ctx
->cred
= cmdline_credentials
;
396 mem_ctx
= talloc_init("torture_domain_close_samr");
399 * querying the domain list using default buffer size
403 r
.in
.hostname
= binding
->host
;
405 status
= libnet_DomainList(ctx
, mem_ctx
, &r
);
406 if (!NT_STATUS_IS_OK(status
)) {
411 d_printf("Received list or domains (everything in one piece):\n");
413 for (i
= 0; i
< r
.out
.count
; i
++) {
414 d_printf("Name[%d]: %s\n", i
, r
.out
.domains
[i
].name
);
418 * querying the domain list using specified (much smaller) buffer size
421 ctx
->samr
.buf_size
= 32;
424 r
.in
.hostname
= binding
->host
;
426 status
= libnet_DomainList(ctx
, mem_ctx
, &r
);
427 if (!NT_STATUS_IS_OK(status
)) {
432 d_printf("Received list or domains (collected in more than one round):\n");
434 for (i
= 0; i
< r
.out
.count
; i
++) {
435 d_printf("Name[%d]: %s\n", i
, r
.out
.domains
[i
].name
);
439 d_printf("\nStatus: %s\n", nt_errstr(status
));
441 talloc_free(mem_ctx
);