/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- test_opendomain_samr
- test_opendomain_lsa
- torture_domain_open_lsa
- torture_domain_close_lsa
- torture_domain_open_samr
- torture_domain_close_samr
- torture_domain_list
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
36 static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
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
92 static bool test_opendomain_lsa(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
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
126 bool torture_domain_open_lsa(struct torture_context *torture)
/* [<][>][^][v][top][bottom][index][help] */
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
171 done:
172 talloc_free(ctx);
173 return ret;
174 }
175
176
177 bool torture_domain_close_lsa(struct torture_context *torture)
/* [<][>][^][v][top][bottom][index][help] */
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
239 done:
240 talloc_free(mem_ctx);
241 talloc_free(ctx);
242 return ret;
243 }
244
245
246 bool torture_domain_open_samr(struct torture_context *torture)
/* [<][>][^][v][top][bottom][index][help] */
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
297 done:
298 talloc_free(mem_ctx);
299 talloc_free(ctx);
300
301 return ret;
302 }
303
304
305 bool torture_domain_close_samr(struct torture_context *torture)
/* [<][>][^][v][top][bottom][index][help] */
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
370 done:
371 talloc_free(mem_ctx);
372 talloc_free(ctx);
373 return ret;
374 }
375
376
377 bool torture_domain_list(struct torture_context *torture)
/* [<][>][^][v][top][bottom][index][help] */
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
443 done:
444 d_printf("\nStatus: %s\n", nt_errstr(status));
445
446 talloc_free(mem_ctx);
447 talloc_free(ctx);
448 return ret;
449 }