675ab9f0996fe97b3e028bd81304bf5778fdc1ef
[kai/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 "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
34
35 static BOOL test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
36                                  struct policy_handle *handle, struct lsa_String *domname,
37                                  uint32_t *access_mask, struct dom_sid **sid)
38 {
39         NTSTATUS status;
40         struct policy_handle h, domain_handle;
41         struct samr_Connect r1;
42         struct samr_LookupDomain r2;
43         struct samr_OpenDomain r3;
44         
45         printf("connecting\n");
46
47         *access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
48         
49         r1.in.system_name = 0;
50         r1.in.access_mask = *access_mask;
51         r1.out.connect_handle = &h;
52         
53         status = dcerpc_samr_Connect(p, mem_ctx, &r1);
54         if (!NT_STATUS_IS_OK(status)) {
55                 printf("Connect failed - %s\n", nt_errstr(status));
56                 return False;
57         }
58         
59         r2.in.connect_handle = &h;
60         r2.in.domain_name = domname;
61
62         printf("domain lookup on %s\n", domname->string);
63
64         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r2);
65         if (!NT_STATUS_IS_OK(status)) {
66                 printf("LookupDomain failed - %s\n", nt_errstr(status));
67                 return False;
68         }
69
70         r3.in.connect_handle = &h;
71         r3.in.access_mask = *access_mask;
72         r3.in.sid = *sid = r2.out.sid;
73         r3.out.domain_handle = &domain_handle;
74
75         printf("opening domain\n");
76
77         status = dcerpc_samr_OpenDomain(p, mem_ctx, &r3);
78         if (!NT_STATUS_IS_OK(status)) {
79                 printf("OpenDomain failed - %s\n", nt_errstr(status));
80                 return False;
81         } else {
82                 *handle = domain_handle;
83         }
84
85         return True;
86 }
87
88
89 static BOOL test_opendomain_lsa(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
90                                 struct policy_handle *handle, struct lsa_String *domname,
91                                 uint32_t *access_mask)
92 {
93         NTSTATUS status;
94         struct lsa_OpenPolicy2 open;
95         struct lsa_ObjectAttribute attr;
96         struct lsa_QosInfo qos;
97
98         *access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
99
100         ZERO_STRUCT(attr);
101         ZERO_STRUCT(qos);
102
103         qos.len                 = 0;
104         qos.impersonation_level = 2;
105         qos.context_mode        = 1;
106         qos.effective_only      = 0;
107         
108         attr.sec_qos = &qos;
109
110         open.in.system_name = domname->string;
111         open.in.attr        = &attr;
112         open.in.access_mask = *access_mask;
113         open.out.handle     = handle;
114         
115         status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &open);
116         if (!NT_STATUS_IS_OK(status)) {
117                 return False;
118         }
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 = lp_workgroup();
137
138         ctx = libnet_context_init(NULL);
139         if (ctx == NULL) {
140                 d_printf("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                 d_printf("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         status = dcerpc_lsa_Close(ctx->lsa.pipe, ctx, &lsa_close);
163         if (!NT_STATUS_IS_OK(status)) {
164                 d_printf("failed to close domain on lsa service: %s\n", nt_errstr(status));
165                 ret = False;
166         }
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(NULL);
193         if (ctx == NULL) {
194                 d_printf("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, NULL);
204         if (!NT_STATUS_IS_OK(status)) {
205                 d_printf("failed to connect to server: %s\n", nt_errstr(status));
206                 ret = False;
207                 goto done;
208         }
209
210         domain_name.string = lp_workgroup();
211         
212         if (!test_opendomain_lsa(p, torture, &h, &domain_name, &access_mask)) {
213                 d_printf("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         /* we have to use pipe's event context, otherwise the call will
223            hang indefinitely */
224         ctx->event_ctx       = p->conn->event_ctx;
225
226         ZERO_STRUCT(r);
227         r.in.type = DOMAIN_LSA;
228         r.in.domain_name = domain_name.string;
229         
230         status = libnet_DomainClose(ctx, mem_ctx, &r);
231         if (!NT_STATUS_IS_OK(status)) {
232                 ret = False;
233                 goto done;
234         }
235
236 done:
237         talloc_free(mem_ctx);
238         talloc_free(ctx);
239         return ret;
240 }
241
242
243 BOOL torture_domain_open_samr(struct torture_context *torture)
244 {
245         NTSTATUS status;
246         struct libnet_context *ctx;
247         struct event_context *evt_ctx=NULL;
248         TALLOC_CTX *mem_ctx;
249         struct policy_handle domain_handle, handle;
250         struct libnet_DomainOpen io;
251         struct samr_Close r;
252         const char *domain_name;
253         BOOL ret = True;
254
255         mem_ctx = talloc_init("test_domainopen_lsa");
256
257         ctx = libnet_context_init(evt_ctx);
258         ctx->cred = cmdline_credentials;
259
260         /* we're accessing domain controller so the domain name should be
261            passed (it's going to be resolved to dc name and address) instead
262            of specific server name. */
263         domain_name = lp_workgroup();
264
265         /*
266          * Testing synchronous version
267          */
268         printf("opening domain\n");
269         
270         io.in.type         = DOMAIN_SAMR;
271         io.in.domain_name  = domain_name;
272         io.in.access_mask  = SEC_FLAG_MAXIMUM_ALLOWED;
273
274         status = libnet_DomainOpen(ctx, mem_ctx, &io);
275         if (!NT_STATUS_IS_OK(status)) {
276                 printf("Composite domain open failed - %s\n", nt_errstr(status));
277                 ret = False;
278                 goto done;
279         }
280
281         domain_handle = ctx->samr.handle;
282
283         r.in.handle   = &domain_handle;
284         r.out.handle  = &handle;
285         
286         printf("closing domain handle\n");
287         
288         status = dcerpc_samr_Close(ctx->samr.pipe, mem_ctx, &r);
289         if (!NT_STATUS_IS_OK(status)) {
290                 printf("Close failed - %s\n", nt_errstr(status));
291                 ret = False;
292                 goto done;
293         }
294
295 done:
296         talloc_free(mem_ctx);
297         talloc_free(ctx);
298
299         return ret;
300 }
301
302
303 BOOL torture_domain_close_samr(struct torture_context *torture)
304 {
305         BOOL ret = True;
306         NTSTATUS status;
307         TALLOC_CTX *mem_ctx = NULL;
308         struct libnet_context *ctx;
309         struct lsa_String domain_name;
310         struct dcerpc_binding *binding;
311         uint32_t access_mask;
312         struct policy_handle h;
313         struct dcerpc_pipe *p;
314         struct libnet_DomainClose r;
315         struct dom_sid *sid;
316
317         status = torture_rpc_binding(torture, &binding);
318         if (!NT_STATUS_IS_OK(status)) {
319                 return false;
320         }
321
322         ctx = libnet_context_init(NULL);
323         if (ctx == NULL) {
324                 d_printf("failed to create libnet context\n");
325                 ret = False;
326                 goto done;
327         }
328
329         ctx->cred = cmdline_credentials;
330
331         mem_ctx = talloc_init("torture_domain_close_samr");
332         status = dcerpc_pipe_connect_b(mem_ctx, &p, binding, &ndr_table_samr,
333                                      ctx->cred, NULL);
334         if (!NT_STATUS_IS_OK(status)) {
335                 d_printf("failed to connect to server: %s\n", nt_errstr(status));
336                 ret = False;
337                 goto done;
338         }
339
340         domain_name.string = talloc_strdup(mem_ctx, lp_workgroup());
341         
342         if (!test_opendomain_samr(p, torture, &h, &domain_name, &access_mask, &sid)) {
343                 d_printf("failed to open domain on samr service\n");
344                 ret = False;
345                 goto done;
346         }
347         
348         ctx->samr.pipe        = p;
349         ctx->samr.name        = talloc_steal(ctx, domain_name.string);
350         ctx->samr.access_mask = access_mask;
351         ctx->samr.handle      = h;
352         ctx->samr.sid         = talloc_steal(ctx, sid);
353         /* we have to use pipe's event context, otherwise the call will
354            hang indefinitely - this wouldn't be the case if pipe was opened
355            by means of libnet call */
356         ctx->event_ctx       = p->conn->event_ctx;
357
358         ZERO_STRUCT(r);
359         r.in.type = DOMAIN_SAMR;
360         r.in.domain_name = domain_name.string;
361         
362         status = libnet_DomainClose(ctx, mem_ctx, &r);
363         if (!NT_STATUS_IS_OK(status)) {
364                 ret = False;
365                 goto done;
366         }
367
368 done:
369         talloc_free(mem_ctx);
370         talloc_free(ctx);
371         return ret;
372 }
373
374
375 BOOL torture_domain_list(struct torture_context *torture)
376 {
377         BOOL ret = True;
378         NTSTATUS status;
379         TALLOC_CTX *mem_ctx = NULL;
380         struct dcerpc_binding *binding;
381         struct libnet_context *ctx;
382         struct libnet_DomainList r;
383         int i;
384
385         status = torture_rpc_binding(torture, &binding);
386         if (!NT_STATUS_IS_OK(status)) {
387                 return false;
388         }
389
390         ctx = libnet_context_init(NULL);
391         if (ctx == NULL) {
392                 d_printf("failed to create libnet context\n");
393                 ret = False;
394                 goto done;
395         }
396
397         ctx->cred = cmdline_credentials;
398         
399         mem_ctx = talloc_init("torture_domain_close_samr");
400
401         /*
402          * querying the domain list using default buffer size
403          */
404
405         ZERO_STRUCT(r);
406         r.in.hostname = binding->host;
407
408         status = libnet_DomainList(ctx, mem_ctx, &r);
409         if (!NT_STATUS_IS_OK(status)) {
410                 ret = False;
411                 goto done;
412         }
413
414         d_printf("Received list or domains (everything in one piece):\n");
415         
416         for (i = 0; i < r.out.count; i++) {
417                 d_printf("Name[%d]: %s\n", i, r.out.domains[i].name);
418         }
419
420         /*
421          * querying the domain list using specified (much smaller) buffer size
422          */
423
424         ctx->samr.buf_size = 32;
425
426         ZERO_STRUCT(r);
427         r.in.hostname = binding->host;
428
429         status = libnet_DomainList(ctx, mem_ctx, &r);
430         if (!NT_STATUS_IS_OK(status)) {
431                 ret = False;
432                 goto done;
433         }
434
435         d_printf("Received list or domains (collected in more than one round):\n");
436         
437         for (i = 0; i < r.out.count; i++) {
438                 d_printf("Name[%d]: %s\n", i, r.out.domains[i].name);
439         }
440
441 done:
442         d_printf("\nStatus: %s\n", nt_errstr(status));
443
444         talloc_free(mem_ctx);
445         talloc_free(ctx);
446         return ret;
447 }