Line data Source code
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/cmdline.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/torture_rpc.h"
28 : #include "param/param.h"
29 : #include "torture/libnet/proto.h"
30 :
31 :
32 1 : static bool test_opendomain_samr(struct torture_context *tctx,
33 : struct dcerpc_binding_handle *b, TALLOC_CTX *mem_ctx,
34 : struct policy_handle *handle, struct lsa_String *domname,
35 : uint32_t *access_mask, struct dom_sid **sid_p)
36 : {
37 0 : struct policy_handle h, domain_handle;
38 0 : struct samr_Connect r1;
39 0 : struct samr_LookupDomain r2;
40 1 : struct dom_sid2 *sid = NULL;
41 0 : struct samr_OpenDomain r3;
42 :
43 1 : torture_comment(tctx, "connecting\n");
44 :
45 1 : *access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
46 :
47 1 : r1.in.system_name = 0;
48 1 : r1.in.access_mask = *access_mask;
49 1 : r1.out.connect_handle = &h;
50 :
51 1 : torture_assert_ntstatus_ok(tctx,
52 : dcerpc_samr_Connect_r(b, mem_ctx, &r1),
53 : "Connect failed");
54 1 : torture_assert_ntstatus_ok(tctx, r1.out.result,
55 : "Connect failed");
56 :
57 1 : r2.in.connect_handle = &h;
58 1 : r2.in.domain_name = domname;
59 1 : r2.out.sid = &sid;
60 :
61 1 : torture_comment(tctx, "domain lookup on %s\n", domname->string);
62 :
63 1 : torture_assert_ntstatus_ok(tctx,
64 : dcerpc_samr_LookupDomain_r(b, mem_ctx, &r2),
65 : "LookupDomain failed");
66 1 : torture_assert_ntstatus_ok(tctx, r2.out.result,
67 : "LookupDomain failed");
68 :
69 1 : r3.in.connect_handle = &h;
70 1 : r3.in.access_mask = *access_mask;
71 1 : r3.in.sid = *sid_p = *r2.out.sid;
72 1 : r3.out.domain_handle = &domain_handle;
73 :
74 1 : torture_comment(tctx, "opening domain\n");
75 :
76 1 : torture_assert_ntstatus_ok(tctx,
77 : dcerpc_samr_OpenDomain_r(b, mem_ctx, &r3),
78 : "OpenDomain failed");
79 1 : torture_assert_ntstatus_ok(tctx, r3.out.result,
80 : "OpenDomain failed");
81 :
82 1 : *handle = domain_handle;
83 :
84 1 : return true;
85 : }
86 :
87 :
88 1 : static bool test_opendomain_lsa(struct torture_context *tctx,
89 : struct dcerpc_binding_handle *b, TALLOC_CTX *mem_ctx,
90 : struct policy_handle *handle, struct lsa_String *domname,
91 : uint32_t *access_mask)
92 : {
93 0 : struct lsa_OpenPolicy2 open;
94 0 : struct lsa_ObjectAttribute attr;
95 0 : struct lsa_QosInfo qos;
96 :
97 1 : *access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
98 :
99 1 : ZERO_STRUCT(attr);
100 1 : ZERO_STRUCT(qos);
101 :
102 1 : qos.len = 0;
103 1 : qos.impersonation_level = 2;
104 1 : qos.context_mode = 1;
105 1 : qos.effective_only = 0;
106 :
107 1 : attr.sec_qos = &qos;
108 :
109 1 : open.in.system_name = domname->string;
110 1 : open.in.attr = &attr;
111 1 : open.in.access_mask = *access_mask;
112 1 : open.out.handle = handle;
113 :
114 1 : torture_assert_ntstatus_ok(tctx,
115 : dcerpc_lsa_OpenPolicy2_r(b, mem_ctx, &open),
116 : "OpenPolicy2 failed");
117 1 : torture_assert_ntstatus_ok(tctx, open.out.result,
118 : "OpenPolicy2 failed");
119 :
120 1 : return true;
121 : }
122 :
123 1 : bool torture_domain_open_lsa(struct torture_context *torture)
124 : {
125 0 : NTSTATUS status;
126 1 : bool ret = true;
127 0 : struct libnet_context *ctx;
128 0 : struct libnet_DomainOpen r;
129 0 : struct lsa_Close lsa_close;
130 0 : struct policy_handle h;
131 0 : const char *domain_name;
132 :
133 : /* we're accessing domain controller so the domain name should be
134 : passed (it's going to be resolved to dc name and address) instead
135 : of specific server name. */
136 1 : domain_name = lpcfg_workgroup(torture->lp_ctx);
137 :
138 1 : ctx = libnet_context_init(torture->ev, torture->lp_ctx);
139 1 : if (ctx == NULL) {
140 0 : torture_comment(torture, "failed to create libnet context\n");
141 0 : return false;
142 : }
143 :
144 1 : ctx->cred = samba_cmdline_get_creds();
145 :
146 1 : ZERO_STRUCT(r);
147 1 : r.in.type = DOMAIN_LSA;
148 1 : r.in.domain_name = domain_name;
149 1 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
150 :
151 1 : status = libnet_DomainOpen(ctx, torture, &r);
152 1 : if (!NT_STATUS_IS_OK(status)) {
153 0 : torture_comment(torture, "failed to open domain on lsa service: %s\n", nt_errstr(status));
154 0 : ret = false;
155 0 : goto done;
156 : }
157 :
158 1 : ZERO_STRUCT(lsa_close);
159 1 : lsa_close.in.handle = &ctx->lsa.handle;
160 1 : lsa_close.out.handle = &h;
161 :
162 1 : torture_assert_ntstatus_ok(torture,
163 : dcerpc_lsa_Close_r(ctx->lsa.pipe->binding_handle, ctx, &lsa_close),
164 : "failed to close domain on lsa service");
165 1 : torture_assert_ntstatus_ok(torture, lsa_close.out.result,
166 : "failed to close domain on lsa service");
167 :
168 1 : done:
169 1 : talloc_free(ctx);
170 1 : return ret;
171 : }
172 :
173 :
174 1 : bool torture_domain_close_lsa(struct torture_context *torture)
175 : {
176 1 : bool ret = true;
177 0 : NTSTATUS status;
178 1 : TALLOC_CTX *mem_ctx=NULL;
179 0 : struct libnet_context *ctx;
180 0 : struct lsa_String domain_name;
181 0 : struct dcerpc_binding *binding;
182 0 : uint32_t access_mask;
183 0 : struct policy_handle h;
184 0 : struct dcerpc_pipe *p;
185 0 : struct libnet_DomainClose r;
186 :
187 1 : status = torture_rpc_binding(torture, &binding);
188 1 : if (!NT_STATUS_IS_OK(status)) {
189 0 : return false;
190 : }
191 :
192 1 : ctx = libnet_context_init(torture->ev, torture->lp_ctx);
193 1 : if (ctx == NULL) {
194 0 : torture_comment(torture, "failed to create libnet context\n");
195 0 : ret = false;
196 0 : goto done;
197 : }
198 :
199 1 : ctx->cred = samba_cmdline_get_creds();
200 :
201 1 : mem_ctx = talloc_init("torture_domain_close_lsa");
202 1 : status = dcerpc_pipe_connect_b(mem_ctx, &p, binding, &ndr_table_lsarpc,
203 : samba_cmdline_get_creds(),
204 : torture->ev, torture->lp_ctx);
205 1 : if (!NT_STATUS_IS_OK(status)) {
206 0 : torture_comment(torture, "failed to connect to server: %s\n", nt_errstr(status));
207 0 : ret = false;
208 0 : goto done;
209 : }
210 :
211 1 : domain_name.string = lpcfg_workgroup(torture->lp_ctx);
212 :
213 1 : if (!test_opendomain_lsa(torture, p->binding_handle, torture, &h, &domain_name, &access_mask)) {
214 0 : torture_comment(torture, "failed to open domain on lsa service\n");
215 0 : ret = false;
216 0 : goto done;
217 : }
218 :
219 1 : ctx->lsa.pipe = p;
220 1 : ctx->lsa.name = domain_name.string;
221 1 : ctx->lsa.access_mask = access_mask;
222 1 : ctx->lsa.handle = h;
223 :
224 1 : ZERO_STRUCT(r);
225 1 : r.in.type = DOMAIN_LSA;
226 1 : r.in.domain_name = domain_name.string;
227 :
228 1 : status = libnet_DomainClose(ctx, mem_ctx, &r);
229 1 : if (!NT_STATUS_IS_OK(status)) {
230 0 : ret = false;
231 0 : goto done;
232 : }
233 :
234 1 : done:
235 1 : talloc_free(mem_ctx);
236 1 : talloc_free(ctx);
237 1 : return ret;
238 : }
239 :
240 :
241 1 : bool torture_domain_open_samr(struct torture_context *torture)
242 : {
243 0 : NTSTATUS status;
244 0 : struct libnet_context *ctx;
245 0 : TALLOC_CTX *mem_ctx;
246 0 : struct policy_handle domain_handle, handle;
247 0 : struct libnet_DomainOpen io;
248 0 : struct samr_Close r;
249 0 : const char *domain_name;
250 1 : bool ret = true;
251 :
252 1 : mem_ctx = talloc_init("test_domainopen_lsa");
253 :
254 1 : ctx = libnet_context_init(torture->ev, torture->lp_ctx);
255 1 : ctx->cred = samba_cmdline_get_creds();
256 :
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 1 : domain_name = lpcfg_workgroup(torture->lp_ctx);
261 :
262 : /*
263 : * Testing synchronous version
264 : */
265 1 : torture_comment(torture, "opening domain\n");
266 :
267 1 : io.in.type = DOMAIN_SAMR;
268 1 : io.in.domain_name = domain_name;
269 1 : io.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
270 :
271 1 : status = libnet_DomainOpen(ctx, mem_ctx, &io);
272 1 : if (!NT_STATUS_IS_OK(status)) {
273 0 : torture_comment(torture, "Composite domain open failed for domain '%s' - %s\n",
274 : domain_name, nt_errstr(status));
275 0 : ret = false;
276 0 : goto done;
277 : }
278 :
279 1 : domain_handle = ctx->samr.handle;
280 :
281 1 : r.in.handle = &domain_handle;
282 1 : r.out.handle = &handle;
283 :
284 1 : torture_comment(torture, "closing domain handle\n");
285 :
286 1 : torture_assert_ntstatus_ok(torture,
287 : dcerpc_samr_Close_r(ctx->samr.pipe->binding_handle, mem_ctx, &r),
288 : "Close failed");
289 1 : torture_assert_ntstatus_ok(torture, r.out.result,
290 : "Close failed");
291 :
292 1 : done:
293 1 : talloc_free(mem_ctx);
294 1 : talloc_free(ctx);
295 :
296 1 : return ret;
297 : }
298 :
299 :
300 1 : bool torture_domain_close_samr(struct torture_context *torture)
301 : {
302 1 : bool ret = true;
303 0 : NTSTATUS status;
304 1 : TALLOC_CTX *mem_ctx = NULL;
305 0 : struct libnet_context *ctx;
306 0 : struct lsa_String domain_name;
307 0 : struct dcerpc_binding *binding;
308 0 : uint32_t access_mask;
309 0 : struct policy_handle h;
310 0 : struct dcerpc_pipe *p;
311 0 : struct libnet_DomainClose r;
312 0 : struct dom_sid *sid;
313 :
314 1 : status = torture_rpc_binding(torture, &binding);
315 1 : if (!NT_STATUS_IS_OK(status)) {
316 0 : return false;
317 : }
318 :
319 1 : ctx = libnet_context_init(torture->ev, torture->lp_ctx);
320 1 : if (ctx == NULL) {
321 0 : torture_comment(torture, "failed to create libnet context\n");
322 0 : ret = false;
323 0 : goto done;
324 : }
325 :
326 1 : ctx->cred = samba_cmdline_get_creds();
327 :
328 1 : mem_ctx = talloc_init("torture_domain_close_samr");
329 1 : status = dcerpc_pipe_connect_b(mem_ctx, &p, binding, &ndr_table_samr,
330 : ctx->cred, torture->ev, torture->lp_ctx);
331 1 : if (!NT_STATUS_IS_OK(status)) {
332 0 : torture_comment(torture, "failed to connect to server: %s\n", nt_errstr(status));
333 0 : ret = false;
334 0 : goto done;
335 : }
336 :
337 1 : domain_name.string = talloc_strdup(mem_ctx, lpcfg_workgroup(torture->lp_ctx));
338 :
339 1 : if (!test_opendomain_samr(torture, p->binding_handle, torture, &h, &domain_name, &access_mask, &sid)) {
340 0 : torture_comment(torture, "failed to open domain on samr service\n");
341 0 : ret = false;
342 0 : goto done;
343 : }
344 :
345 1 : ctx->samr.pipe = p;
346 1 : ctx->samr.name = talloc_steal(ctx, domain_name.string);
347 1 : ctx->samr.access_mask = access_mask;
348 1 : ctx->samr.handle = h;
349 1 : ctx->samr.sid = talloc_steal(ctx, sid);
350 :
351 1 : ZERO_STRUCT(r);
352 1 : r.in.type = DOMAIN_SAMR;
353 1 : r.in.domain_name = domain_name.string;
354 :
355 1 : status = libnet_DomainClose(ctx, mem_ctx, &r);
356 1 : if (!NT_STATUS_IS_OK(status)) {
357 0 : ret = false;
358 0 : goto done;
359 : }
360 :
361 1 : done:
362 1 : talloc_free(mem_ctx);
363 1 : talloc_free(ctx);
364 1 : return ret;
365 : }
366 :
367 :
368 1 : bool torture_domain_list(struct torture_context *torture)
369 : {
370 1 : bool ret = true;
371 0 : NTSTATUS status;
372 1 : TALLOC_CTX *mem_ctx = NULL;
373 0 : struct dcerpc_binding *binding;
374 0 : struct libnet_context *ctx;
375 0 : struct libnet_DomainList r;
376 0 : int i;
377 :
378 1 : status = torture_rpc_binding(torture, &binding);
379 1 : if (!NT_STATUS_IS_OK(status)) {
380 0 : return false;
381 : }
382 :
383 1 : ctx = libnet_context_init(torture->ev, torture->lp_ctx);
384 1 : if (ctx == NULL) {
385 0 : torture_comment(torture, "failed to create libnet context\n");
386 0 : ret = false;
387 0 : goto done;
388 : }
389 :
390 1 : ctx->cred = samba_cmdline_get_creds();
391 :
392 1 : mem_ctx = talloc_init("torture_domain_close_samr");
393 :
394 : /*
395 : * querying the domain list using default buffer size
396 : */
397 :
398 1 : ZERO_STRUCT(r);
399 1 : r.in.hostname = dcerpc_binding_get_string_option(binding, "host");
400 :
401 1 : status = libnet_DomainList(ctx, mem_ctx, &r);
402 1 : if (!NT_STATUS_IS_OK(status)) {
403 0 : ret = false;
404 0 : goto done;
405 : }
406 :
407 1 : torture_comment(torture, "Received list or domains (everything in one piece):\n");
408 :
409 3 : for (i = 0; i < r.out.count; i++) {
410 2 : torture_comment(torture, "Name[%d]: %s\n", i, r.out.domains[i].name);
411 : }
412 :
413 : /*
414 : * querying the domain list using specified (much smaller) buffer size
415 : */
416 :
417 1 : ctx->samr.buf_size = 32;
418 :
419 1 : ZERO_STRUCT(r);
420 1 : r.in.hostname = dcerpc_binding_get_string_option(binding, "host");
421 :
422 1 : status = libnet_DomainList(ctx, mem_ctx, &r);
423 1 : if (!NT_STATUS_IS_OK(status)) {
424 0 : ret = false;
425 0 : goto done;
426 : }
427 :
428 1 : torture_comment(torture, "Received list or domains (collected in more than one round):\n");
429 :
430 3 : for (i = 0; i < r.out.count; i++) {
431 2 : torture_comment(torture, "Name[%d]: %s\n", i, r.out.domains[i].name);
432 : }
433 :
434 1 : done:
435 1 : torture_comment(torture, "\nStatus: %s\n", nt_errstr(status));
436 :
437 1 : talloc_free(mem_ctx);
438 1 : talloc_free(ctx);
439 1 : return ret;
440 : }
|