r4138: initialise 'type' in RPC-WINREG EnumValue test
[samba.git] / source4 / torture / rpc / winreg.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for winreg rpc operations
4
5    Copyright (C) Tim Potter 2003
6    Copyright (C) Jelmer Vernooij 2004
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "librpc/gen_ndr/ndr_winreg.h"
25
26 static void init_winreg_String(struct winreg_String *name, const char *s)
27 {
28         name->name = s;
29         if (s) {
30                 name->name_len = 2 * (strlen_m(s) + 1);
31                 name->name_size = name->name_len;
32         } else {
33                 name->name_len = 0;
34                 name->name_size = 0;
35         }
36 }
37
38 static BOOL test_GetVersion(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
39                             struct policy_handle *handle)
40 {
41         NTSTATUS status;
42         struct winreg_GetVersion r;
43
44         printf("\ntesting GetVersion\n");
45
46         r.in.handle = handle;
47
48         status = dcerpc_winreg_GetVersion(p, mem_ctx, &r);
49
50         if (!NT_STATUS_IS_OK(status)) {
51                 printf("GetVersion failed - %s\n", nt_errstr(status));
52                 return False;
53         }
54
55         if (!W_ERROR_IS_OK(r.out.result)) {
56                 printf("GetVersion failed - %s\n", win_errstr(r.out.result));
57                 return False;
58         }
59
60         return True;
61 }
62
63 static BOOL test_CreateKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
64                           struct policy_handle *handle, const char *name, 
65                            const char *class)
66 {
67         struct winreg_CreateKey r;
68         struct policy_handle newhandle;
69         NTSTATUS status;
70         uint32_t sec_info = 0;
71
72         printf("\ntesting CreateKey\n");
73
74         r.in.handle = handle;
75         r.out.handle = &newhandle;
76         init_winreg_String(&r.in.key, name);    
77         init_winreg_String(&r.in.class, class);
78         r.in.reserved = 0x0;
79         r.in.access_mask = 0x02000000;
80         r.in.sec_info = &sec_info;
81         r.in.sec_desc = NULL;
82
83         status = dcerpc_winreg_CreateKey(p, mem_ctx, &r);
84
85         if (!NT_STATUS_IS_OK(status)) {
86                 printf("CreateKey failed - %s\n", nt_errstr(status));
87                 return False;
88         }
89
90         if (!W_ERROR_IS_OK(r.out.result)) {
91                 printf("CreateKey failed - %s\n", win_errstr(r.out.result));
92                 return False;
93         }
94
95         return True;
96 }
97
98 static BOOL test_CloseKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
99                           struct policy_handle *handle)
100 {
101         NTSTATUS status;
102         struct winreg_CloseKey r;
103
104         printf("\ntesting CloseKey\n");
105
106         r.in.handle = r.out.handle = handle;
107
108         status = dcerpc_winreg_CloseKey(p, mem_ctx, &r);
109
110         if (!NT_STATUS_IS_OK(status)) {
111                 printf("CloseKey failed - %s\n", nt_errstr(status));
112                 return False;
113         }
114
115         if (!W_ERROR_IS_OK(r.out.result)) {
116                 printf("CloseKey failed - %s\n", win_errstr(r.out.result));
117                 return False;
118         }
119
120         return True;
121 }
122
123 static BOOL test_FlushKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
124                           struct policy_handle *handle)
125 {
126         NTSTATUS status;
127         struct winreg_FlushKey r;
128
129         printf("\ntesting FlushKey\n");
130
131         r.in.handle = handle;
132
133         status = dcerpc_winreg_FlushKey(p, mem_ctx, &r);
134
135         if (!NT_STATUS_IS_OK(status)) {
136                 printf("FlushKey failed - %s\n", nt_errstr(status));
137                 return False;
138         }
139
140         if (!W_ERROR_IS_OK(r.out.result)) {
141                 printf("FlushKey failed - %s\n", win_errstr(r.out.result));
142                 return False;
143         }
144
145         return True;
146 }
147
148 static BOOL test_OpenKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
149                          struct policy_handle *hive_handle,
150                          const char *keyname, struct policy_handle *key_handle)
151 {
152         NTSTATUS status;
153         struct winreg_OpenKey r;
154
155         printf("\ntesting OpenKey\n");
156
157         r.in.handle = hive_handle;
158         init_winreg_String(&r.in.keyname, keyname);
159         r.in.unknown = 0x00000000;
160         r.in.access_mask = 0x02000000;
161         r.out.handle = key_handle;
162
163         status = dcerpc_winreg_OpenKey(p, mem_ctx, &r);
164
165         if (!NT_STATUS_IS_OK(status)) {
166                 printf("OpenKey failed - %s\n", nt_errstr(status));
167                 return False;
168         }
169
170         if (!W_ERROR_IS_OK(r.out.result)) {
171                 printf("OpenKey failed - %s\n", win_errstr(r.out.result));
172
173                 return False;
174         }
175
176         return True;
177 }
178
179 static BOOL test_DeleteKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
180                            struct policy_handle *handle, const char *key)
181 {
182         NTSTATUS status;
183         struct winreg_DeleteKey r;
184
185         printf("\ntesting DeleteKey\n");
186
187         r.in.handle = handle;
188         init_winreg_String(&r.in.key, key);     
189
190         status = dcerpc_winreg_DeleteKey(p, mem_ctx, &r);
191
192         if (!NT_STATUS_IS_OK(status)) {
193                 printf("DeleteKey failed - %s\n", nt_errstr(status));
194                 return False;
195         }
196
197         if (!W_ERROR_IS_OK(r.out.result)) {
198                 printf("DeleteKey failed - %s\n", win_errstr(r.out.result));
199                 return False;
200         }
201
202         return True;
203 }
204
205 static BOOL test_QueryInfoKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
206                               struct policy_handle *handle, char *class)
207 {
208         NTSTATUS status;
209         struct winreg_QueryInfoKey r;
210
211         printf("\ntesting QueryInfoKey\n");
212
213         r.in.handle = handle;
214         init_winreg_String(&r.in.class, class);
215         
216         status = dcerpc_winreg_QueryInfoKey(p, mem_ctx, &r);
217
218         if (!NT_STATUS_IS_OK(status)) {
219                 printf("QueryInfoKey failed - %s\n", nt_errstr(status));
220                 return False;
221         }
222
223         if (!W_ERROR_IS_OK(r.out.result)) {
224                 printf("QueryInfoKey failed - %s\n", win_errstr(r.out.result));
225                 return False;
226         }
227
228         return True;
229 }
230
231 static BOOL test_key(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
232                      struct policy_handle *handle, int depth);
233
234 static BOOL test_EnumKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
235                          struct policy_handle *handle, int depth)
236 {
237         struct winreg_EnumKey r;
238         struct winreg_EnumKeyNameRequest keyname;
239         struct winreg_String classname;
240         struct winreg_Time tm;
241         NTSTATUS status;
242
243         printf("Testing EnumKey\n\n");
244
245         r.in.handle = handle;
246         r.in.enum_index = 0;
247         r.in.key_name_len = r.out.key_name_len = 0;
248         r.in.unknown = r.out.unknown = 0x0414;
249         keyname.unknown = 0x0000020a;
250         init_winreg_String(&keyname.key_name, NULL);
251         init_winreg_String(&classname, NULL);
252         r.in.in_name = &keyname;
253         r.in.class = &classname;
254         tm.low = tm.high = 0x7fffffff;
255         r.in.last_changed_time = &tm;
256
257         do {
258                 status = dcerpc_winreg_EnumKey(p, mem_ctx, &r);
259
260                 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
261                         struct policy_handle key_handle;
262
263                         printf("EnumKey: %d: %s\n", r.in.enum_index, r.out.out_name->name);
264
265                         if (!test_OpenKey(
266                                     p, mem_ctx, handle, r.out.out_name->name,
267                                     &key_handle)) {
268                         } else {
269                                 test_key(p, mem_ctx, &key_handle, depth + 1);
270                         }
271                 }
272
273                 r.in.enum_index++;
274
275         } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
276
277         if (!NT_STATUS_IS_OK(status)) {
278                 printf("EnumKey failed - %s\n", nt_errstr(status));
279                 return False;
280         }
281
282         if (!W_ERROR_IS_OK(r.out.result) && !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
283                 printf("EnumKey failed - %s\n", win_errstr(r.out.result));
284                 return False;
285         }
286
287
288
289         return True;
290 }
291
292 static BOOL test_QueryValue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle, const char *valuename)
293 {
294         struct winreg_QueryValue r;
295         NTSTATUS status;
296         uint32 zero = 0;
297         uint32 offered = 0xfff;
298
299         printf("Testing QueryValue\n");
300
301         r.in.handle = handle;
302         r.in.value_name.name = valuename;
303         r.in.type = &zero;
304         r.in.size = &offered;
305         r.in.length = &zero;
306
307         status = dcerpc_winreg_QueryValue(p, mem_ctx, &r);
308         if(NT_STATUS_IS_ERR(status)) {
309                 printf("QueryValue failed - %s\n", nt_errstr(status));
310                 return False;
311         }
312
313         if (!W_ERROR_IS_OK(r.out.result)) {
314                 printf("QueryValue failed - %s\n", win_errstr(r.out.result));
315                 return False;
316         }
317
318         return True;
319 }
320
321 static BOOL test_EnumValue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
322                            struct policy_handle *handle, int max_valnamelen, int max_valbufsize)
323 {
324         struct winreg_EnumValue r;
325         uint32 type = 0;
326         uint32 size = max_valbufsize, zero = 0;
327         BOOL ret = True;
328         uint8_t buf8;
329         uint16_t buf16;
330
331         printf("testing EnumValue\n");
332
333         r.in.handle = handle;
334         r.in.enum_index = 0;
335         r.in.name_in.length = 0;
336         r.in.name_in.size = 0x200;
337         r.in.name_in.name = &buf16;
338         r.in.type = &type;
339         r.in.value = &buf8;
340         r.in.length = &zero;
341         r.in.size = &size;
342         
343         do {
344                 NTSTATUS status = dcerpc_winreg_EnumValue(p, mem_ctx, &r);
345                 if(NT_STATUS_IS_ERR(status)) {
346                         printf("EnumValue failed - %s\n", nt_errstr(status));
347                         return False;
348                 }
349
350                 if (W_ERROR_IS_OK(r.out.result)) {
351                         ret &= test_QueryValue(p, mem_ctx, handle, r.out.name_out.name);
352                 }
353
354                 r.in.enum_index++;
355         } while (W_ERROR_IS_OK(r.out.result));
356
357         if(!W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
358                 printf("EnumValue failed - %s\n", win_errstr(r.out.result));
359                 return False;
360         }
361
362         return ret;
363 }
364
365 static BOOL test_OpenHKLM(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
366                           struct policy_handle *handle)
367 {
368         NTSTATUS status;
369         struct winreg_OpenHKLM r;
370         struct winreg_OpenUnknown unknown;
371         BOOL ret = True;
372
373         printf("\ntesting OpenHKLM\n");
374
375         unknown.unknown0 = 0x84e0;
376         unknown.unknown1 = 0x0000;
377         r.in.unknown = &unknown;
378         r.in.access_required = SEC_FLAG_MAXIMUM_ALLOWED;
379         r.out.handle = handle;
380
381         status = dcerpc_winreg_OpenHKLM(p, mem_ctx, &r);
382
383         if (!NT_STATUS_IS_OK(status)) {
384                 printf("OpenHKLM failed - %s\n", nt_errstr(status));
385                 return False;
386         }
387
388         if (!W_ERROR_IS_OK(r.out.result)) {
389                 printf("OpenHKLM failed - %s\n", win_errstr(r.out.result));
390                 return False;
391         }
392
393         return ret;
394 }
395
396 static BOOL test_OpenHKU(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
397                          struct policy_handle *handle)
398 {
399         NTSTATUS status;
400         struct winreg_OpenHKU r;
401         struct winreg_OpenUnknown unknown;
402         BOOL ret = True;
403
404         printf("\ntesting OpenHKU\n");
405
406         unknown.unknown0 = 0x84e0;
407         unknown.unknown1 = 0x0000;
408         r.in.unknown = &unknown;
409         r.in.access_required = SEC_FLAG_MAXIMUM_ALLOWED;
410         r.out.handle = handle;
411
412         status = dcerpc_winreg_OpenHKU(p, mem_ctx, &r);
413
414         if (!NT_STATUS_IS_OK(status)) {
415                 printf("OpenHKU failed - %s\n", nt_errstr(status));
416                 return False;
417         }
418
419         return ret;
420 }
421
422 static BOOL test_OpenHKCR(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
423                           struct policy_handle *handle)
424 {
425         NTSTATUS status;
426         struct winreg_OpenHKCR r;
427         struct winreg_OpenUnknown unknown;
428         BOOL ret = True;
429
430         printf("\ntesting OpenHKCR\n");
431
432         unknown.unknown0 = 0x84e0;
433         unknown.unknown1 = 0x0000;
434         r.in.unknown = &unknown;
435         r.in.access_required = SEC_FLAG_MAXIMUM_ALLOWED;
436         r.out.handle = handle;
437
438         status = dcerpc_winreg_OpenHKCR(p, mem_ctx, &r);
439
440         if (!NT_STATUS_IS_OK(status)) {
441                 printf("OpenHKCR failed - %s\n", nt_errstr(status));
442                 return False;
443         }
444
445         return ret;
446 }
447
448 static BOOL test_InitiateSystemShutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
449                         const char *msg, uint32_t timeout)
450 {
451         struct winreg_InitiateSystemShutdown r;
452         NTSTATUS status;
453         
454         init_winreg_String(&r.in.hostname, NULL);
455         init_winreg_String(&r.in.message, msg);
456         r.in.flags = 0;
457         r.in.timeout = timeout;
458
459         status = dcerpc_winreg_InitiateSystemShutdown(p, mem_ctx, &r);
460
461         if (!NT_STATUS_IS_OK(status)) {
462                 printf("InitiateSystemShutdown failed - %s\n", nt_errstr(status));
463                 return False;
464         }
465
466         if (!W_ERROR_IS_OK(r.out.result)) {
467                 printf("InitiateSystemShutdown failed - %s\n", win_errstr(r.out.result));
468                 return False;
469         }
470
471         return True;
472 }
473
474 static BOOL test_AbortSystemShutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
475 {
476         struct winreg_AbortSystemShutdown r;
477         NTSTATUS status;
478         uint16_t server = 0x0;
479
480         r.in.server = &server;
481         
482         status = dcerpc_winreg_AbortSystemShutdown(p, mem_ctx, &r);
483
484         if (!NT_STATUS_IS_OK(status)) {
485                 printf("AbortSystemShutdown failed - %s\n", nt_errstr(status));
486                 return False;
487         }
488
489         if (!W_ERROR_IS_OK(r.out.result)) {
490                 printf("AbortSystemShutdown failed - %s\n", win_errstr(r.out.result));
491                 return False;
492         }
493
494         return True;
495 }
496
497 static BOOL test_OpenHKCU(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
498                           struct policy_handle *handle)
499 {
500         NTSTATUS status;
501         struct winreg_OpenHKCU r;
502         struct winreg_OpenUnknown unknown;
503         BOOL ret = True;
504
505         printf("\ntesting OpenHKCU\n");
506
507         unknown.unknown0 = 0x84e0;
508         unknown.unknown1 = 0x0000;
509         r.in.unknown = &unknown;
510         r.in.access_required = SEC_FLAG_MAXIMUM_ALLOWED;
511         r.out.handle = handle;
512
513         status = dcerpc_winreg_OpenHKCU(p, mem_ctx, &r);
514
515         if (!NT_STATUS_IS_OK(status)) {
516                 printf("OpenHKCU failed - %s\n", nt_errstr(status));
517                 return False;
518         }
519
520         return ret;
521 }
522
523 #define MAX_DEPTH 2             /* Only go this far down the tree */
524
525 static BOOL test_key(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
526                      struct policy_handle *handle, int depth)
527 {
528         if (depth == MAX_DEPTH)
529                 return True;
530
531         if (!test_QueryInfoKey(p, mem_ctx, handle, NULL)) {
532         }
533
534         if (!test_EnumKey(p, mem_ctx, handle, depth)) {
535         }
536
537         if (!test_EnumValue(p, mem_ctx, handle, 0xFF, 0xFFFF)) {
538         }
539
540         test_CloseKey(p, mem_ctx, handle);
541
542         return True;
543 }
544
545 typedef BOOL winreg_open_fn(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
546                             struct policy_handle *handle);
547
548 static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
549 {
550         struct policy_handle handle, newhandle;
551         BOOL ret = True;
552         winreg_open_fn *open_fn = (winreg_open_fn *)fn;
553
554         if (!open_fn(p, mem_ctx, &handle)) {
555                 return False;
556         }
557
558         if (!test_CreateKey(p, mem_ctx, &handle, "spottyfoot", NULL)) {
559                 printf("CreateKey failed\n");
560                 ret = False;
561         }
562
563         if (!test_FlushKey(p, mem_ctx, &handle)) {
564                 printf("FlushKey failed\n");
565                 ret = False;
566         }
567
568         if (!test_OpenKey(p, mem_ctx, &handle, "spottyfoot", &newhandle)) {
569                 printf("CreateKey failed (OpenKey after Create didn't work)\n");
570                 ret = False;
571         }
572
573         if (!test_DeleteKey(p, mem_ctx, &handle, "spottyfoot")) {
574                 printf("DeleteKey failed\n");
575                 ret = False;
576         }
577
578         if (!test_FlushKey(p, mem_ctx, &handle)) {
579                 printf("FlushKey failed\n");
580                 ret = False;
581         }
582
583         if (test_OpenKey(p, mem_ctx, &handle, "spottyfoot", &newhandle)) {
584                 printf("DeleteKey failed (OpenKey after Delete didn't work)\n");
585                 ret = False;
586         }
587
588         if (!test_GetVersion(p, mem_ctx, &handle)) {
589                 printf("GetVersion failed\n");
590                 ret = False;
591         }
592
593         /* The HKCR hive has a very large fanout */
594
595         if (open_fn == test_OpenHKCR) {
596                 if(!test_key(p, mem_ctx, &handle, MAX_DEPTH - 1)) {
597                         ret = False;
598                 }
599         }
600
601         if(!test_key(p, mem_ctx, &handle, 0)) {
602                 ret = False;
603         }
604
605         return ret;
606 }
607
608 BOOL torture_rpc_winreg(void)
609 {
610         NTSTATUS status;
611        struct dcerpc_pipe *p;
612         TALLOC_CTX *mem_ctx;
613         BOOL ret = True;
614         winreg_open_fn *open_fns[] = { test_OpenHKLM, test_OpenHKU,
615                                        test_OpenHKCR, test_OpenHKCU };
616         int i;
617
618         mem_ctx = talloc_init("torture_rpc_winreg");
619
620         status = torture_rpc_connection(&p, 
621                                         DCERPC_WINREG_NAME, 
622                                         DCERPC_WINREG_UUID, 
623                                         DCERPC_WINREG_VERSION);
624
625         if (!NT_STATUS_IS_OK(status)) {
626                 return False;
627         }
628
629         if(!test_InitiateSystemShutdown(p, mem_ctx, "spottyfood", 30))
630                 ret = False;
631
632         if(!test_AbortSystemShutdown(p, mem_ctx))
633                 ret = False;
634
635         for (i = 0; i < ARRAY_SIZE(open_fns); i++) {
636                 if (!test_Open(p, mem_ctx, open_fns[i]))
637                         ret = False;
638         }
639
640         talloc_destroy(mem_ctx);
641
642         torture_rpc_close(p);
643
644         return ret;
645 }