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