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
);