3864de650325d5ed2d67f27389fce976f81d8ae6
[kai/samba.git] / source / 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    
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 2 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, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 static void init_winreg_String(struct winreg_String *name, const char *s)
25 {
26         name->name = s;
27         if (s) {
28                 name->name_len = 2 * (strlen_m(s) + 1);
29                 name->name_size = name->name_len;
30         } else {
31                 name->name_len = 0;
32                 name->name_size = 0;
33         }
34 }
35
36 static BOOL test_GetVersion(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
37                             struct policy_handle *handle)
38 {
39         NTSTATUS status;
40         struct winreg_GetVersion r;
41
42         printf("\ntesting GetVersion\n");
43
44         r.in.handle = handle;
45
46         status = dcerpc_winreg_GetVersion(p, mem_ctx, &r);
47
48         if (!NT_STATUS_IS_OK(status)) {
49                 printf("GetVersion failed - %s\n", nt_errstr(status));
50                 return False;
51         }
52
53         return True;
54 }
55
56 static BOOL test_CreateKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
57                           struct policy_handle *handle, char *name, const char *class)
58 {
59         struct winreg_CreateKey r;
60         struct policy_handle newhandle;
61         NTSTATUS status;
62         struct sec_desc_buf sec_desc;
63         uint32 sec_info = 0;
64
65         printf("\ntesting CreateKey\n");
66
67         r.in.handle = handle;
68         r.out.handle = &newhandle;
69         init_winreg_String(&r.in.key, name);    
70         init_winreg_String(&r.in.class, class);
71         r.in.reserved = 0x0;
72         r.in.access_mask = 0x02000000;
73         r.in.sec_info = &sec_info;
74         r.in.sec_desc = NULL;
75
76         status = dcerpc_winreg_CreateKey(p, mem_ctx, &r);
77
78         if (!NT_STATUS_IS_OK(status)) {
79                 printf("CreateKey failed - %s\n", nt_errstr(status));
80                 return False;
81         }
82
83         if (!W_ERROR_IS_OK(r.out.result)) {
84                 printf("CreateKey failed - %s\n", win_errstr(r.out.result));
85                 return False;
86         }
87
88         return True;
89 }
90
91 static BOOL test_CloseKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
92                           struct policy_handle *handle)
93 {
94         NTSTATUS status;
95         struct winreg_CloseKey r;
96
97         printf("\ntesting CloseKey\n");
98
99         r.in.handle = r.out.handle = handle;
100
101         status = dcerpc_winreg_CloseKey(p, mem_ctx, &r);
102
103         if (!NT_STATUS_IS_OK(status)) {
104                 printf("CloseKey failed - %s\n", nt_errstr(status));
105                 return False;
106         }
107
108         return True;
109 }
110
111 static BOOL test_FlushKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
112                           struct policy_handle *handle)
113 {
114         NTSTATUS status;
115         struct winreg_FlushKey r;
116
117         printf("\ntesting FlushKey\n");
118
119         r.in.handle = handle;
120
121         status = dcerpc_winreg_FlushKey(p, mem_ctx, &r);
122
123         if (!NT_STATUS_IS_OK(status)) {
124                 printf("FlushKey failed - %s\n", nt_errstr(status));
125                 return False;
126         }
127
128         return True;
129 }
130
131 static BOOL test_OpenKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
132                          struct policy_handle *hive_handle,
133                          const char *keyname, struct policy_handle *key_handle)
134 {
135         NTSTATUS status;
136         struct winreg_OpenKey r;
137
138         printf("\ntesting OpenKey\n");
139
140         r.in.handle = hive_handle;
141         init_winreg_String(&r.in.keyname, keyname);
142         r.in.unknown = 0x00000000;
143         r.in.access_mask = 0x02000000;
144         r.out.handle = key_handle;
145
146         status = dcerpc_winreg_OpenKey(p, mem_ctx, &r);
147
148         if (!NT_STATUS_IS_OK(status)) {
149                 printf("OpenKey failed - %s\n", nt_errstr(status));
150                 return False;
151         }
152
153         if (!W_ERROR_IS_OK(r.out.result)) {
154                 printf("OpenKey failed - %s\n", win_errstr(r.out.result));
155                 return False;
156         }
157
158         return True;
159 }
160
161 static BOOL test_DeleteKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
162                            struct policy_handle *handle, const char *key)
163 {
164         NTSTATUS status;
165         struct winreg_DeleteKey r;
166
167         printf("\ntesting DeleteKey\n");
168
169         r.in.handle = handle;
170         init_winreg_String(&r.in.key, key);     
171
172         status = dcerpc_winreg_DeleteKey(p, mem_ctx, &r);
173
174         if (!NT_STATUS_IS_OK(status)) {
175                 printf("DeleteKey failed - %s\n", nt_errstr(status));
176                 return False;
177         }
178
179         if (!W_ERROR_IS_OK(r.out.result)) {
180                 printf("DeleteKey failed - %s\n", win_errstr(r.out.result));
181                 return False;
182         }
183
184         return True;
185 }
186
187 static BOOL test_QueryInfoKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
188                               struct policy_handle *handle, char *class)
189 {
190         NTSTATUS status;
191         struct winreg_QueryInfoKey r;
192
193         printf("\ntesting QueryInfoKey\n");
194
195         r.in.handle = handle;
196         init_winreg_String(&r.in.class, class);
197         
198         status = dcerpc_winreg_QueryInfoKey(p, mem_ctx, &r);
199
200         if (!NT_STATUS_IS_OK(status)) {
201                 printf("QueryInfoKey failed - %s\n", nt_errstr(status));
202                 return False;
203         }
204
205         if (!W_ERROR_IS_OK(r.out.result)) {
206                 printf("QueryInfoKey failed - %s\n", win_errstr(r.out.result));
207                 return False;
208         }
209
210         return True;
211 }
212
213 static BOOL test_key(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
214                      struct policy_handle *handle, int depth);
215
216 static BOOL test_EnumKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
217                          struct policy_handle *handle, int depth)
218 {
219         struct winreg_EnumKey r;
220         struct winreg_EnumKeyNameRequest keyname;
221         struct winreg_String classname;
222         struct winreg_Time tm;
223         NTSTATUS status;
224
225         r.in.handle = handle;
226         r.in.enum_index = 0;
227         r.in.key_name_len = r.out.key_name_len = 0;
228         r.in.unknown = r.out.unknown = 0x0414;
229         keyname.unknown = 0x0000020a;
230         init_winreg_String(&keyname.key_name, NULL);
231         init_winreg_String(&classname, NULL);
232         r.in.in_name = &keyname;
233         r.in.class = &classname;
234         tm.low = tm.high = 0x7fffffff;
235         r.in.last_changed_time = &tm;
236
237         do {
238                 status = dcerpc_winreg_EnumKey(p, mem_ctx, &r);
239
240                 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
241                         struct policy_handle key_handle;
242
243                         if (!test_OpenKey(
244                                     p, mem_ctx, handle, r.out.out_name->name,
245                                     &key_handle)) {
246                                 printf("OpenKey(%s) failed - %s\n",
247                                        r.out.out_name->name, 
248                                        win_errstr(r.out.result));
249                                 goto next_key;
250                         }
251
252                         test_key(p, mem_ctx, &key_handle, depth + 1);
253                 }
254
255         next_key:
256
257                 r.in.enum_index++;
258
259         } while (W_ERROR_IS_OK(r.out.result));
260
261         return True;
262 }
263
264 static BOOL test_EnumValue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
265                            struct policy_handle *handle)
266 {
267         struct winreg_EnumValue r;
268         struct winreg_Uint8buf value;
269         struct winreg_String name;
270         uint32 type, requested_len, returned_len;
271         NTSTATUS status;
272
273         r.in.handle = handle;
274         r.in.enum_index = 0;
275
276         init_winreg_String(&name, NULL);
277         r.in.name = r.out.name = &name;
278         
279         type = 0;
280         r.in.type = &type;
281
282         value.max_len = 0xffff;
283         value.offset = 0;
284         value.len = 0;
285         value.buffer = NULL;
286
287         r.in.value = &value;
288
289         requested_len = value.max_len;
290         r.in.requested_len = &requested_len;
291         returned_len = 0;
292         r.in.returned_len = &returned_len;
293
294         do {
295
296                 status = dcerpc_winreg_EnumValue(p, mem_ctx, &r);
297                 r.in.enum_index++;
298         } while (W_ERROR_IS_OK(r.out.result));
299                         
300         return True;
301 }
302
303 static BOOL test_OpenHKLM(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
304                           struct policy_handle *handle)
305 {
306         NTSTATUS status;
307         struct winreg_OpenHKLM r;
308         struct winreg_OpenUnknown unknown;
309         BOOL ret = True;
310
311         printf("\ntesting OpenHKLM\n");
312
313         unknown.unknown0 = 0x84e0;
314         unknown.unknown1 = 0x0000;
315         r.in.unknown = &unknown;
316         r.in.access_required = SEC_RIGHTS_MAXIMUM_ALLOWED;
317         r.out.handle = handle;
318
319         status = dcerpc_winreg_OpenHKLM(p, mem_ctx, &r);
320
321         if (!NT_STATUS_IS_OK(status)) {
322                 printf("OpenHKLM failed - %s\n", nt_errstr(status));
323                 return False;
324         }
325
326         return ret;
327 }
328
329 static BOOL test_OpenHKU(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
330                          struct policy_handle *handle)
331 {
332         NTSTATUS status;
333         struct winreg_OpenHKU r;
334         struct winreg_OpenUnknown unknown;
335         BOOL ret = True;
336
337         printf("\ntesting OpenHKU\n");
338
339         unknown.unknown0 = 0x84e0;
340         unknown.unknown1 = 0x0000;
341         r.in.unknown = &unknown;
342         r.in.access_required = SEC_RIGHTS_MAXIMUM_ALLOWED;
343         r.out.handle = handle;
344
345         status = dcerpc_winreg_OpenHKU(p, mem_ctx, &r);
346
347         if (!NT_STATUS_IS_OK(status)) {
348                 printf("OpenHKU failed - %s\n", nt_errstr(status));
349                 return False;
350         }
351
352         return ret;
353 }
354
355 static BOOL test_OpenHKCR(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
356                           struct policy_handle *handle)
357 {
358         NTSTATUS status;
359         struct winreg_OpenHKCR r;
360         struct winreg_OpenUnknown unknown;
361         BOOL ret = True;
362
363         printf("\ntesting OpenHKCR\n");
364
365         unknown.unknown0 = 0x84e0;
366         unknown.unknown1 = 0x0000;
367         r.in.unknown = &unknown;
368         r.in.access_required = SEC_RIGHTS_MAXIMUM_ALLOWED;
369         r.out.handle = handle;
370
371         status = dcerpc_winreg_OpenHKCR(p, mem_ctx, &r);
372
373         if (!NT_STATUS_IS_OK(status)) {
374                 printf("OpenHKCR failed - %s\n", nt_errstr(status));
375                 return False;
376         }
377
378         return ret;
379 }
380
381 static BOOL test_InitiateSystemShutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
382                         const char *msg, uint32 timeout)
383 {
384         struct winreg_InitiateSystemShutdown r;
385         NTSTATUS status;
386         
387         init_winreg_String(&r.in.message, msg);
388         r.in.flags = 0;
389         r.in.timeout = timeout;
390
391         status = dcerpc_winreg_InitiateSystemShutdown(p, mem_ctx, &r);
392
393         if (!NT_STATUS_IS_OK(status)) {
394                 printf("InitiateSystemShutdown failed - %s\n", nt_errstr(status));
395                 return False;
396         }
397
398         if (!W_ERROR_IS_OK(r.out.result)) {
399                 printf("InitiateSystemShutdown failed - %s\n", win_errstr(r.out.result));
400                 return False;
401         }
402
403         return True;
404 }
405
406 static BOOL test_AbortSystemShutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
407 {
408         struct winreg_AbortSystemShutdown r;
409         NTSTATUS status;
410         uint16 server = 0x0;
411
412         r.in.server = &server;
413         
414         status = dcerpc_winreg_AbortSystemShutdown(p, mem_ctx, &r);
415
416         if (!NT_STATUS_IS_OK(status)) {
417                 printf("AbortSystemShutdown failed - %s\n", nt_errstr(status));
418                 return False;
419         }
420
421         if (!W_ERROR_IS_OK(r.out.result)) {
422                 printf("AbortSystemShutdown failed - %s\n", win_errstr(r.out.result));
423                 return False;
424         }
425
426         return True;
427 }
428
429 static BOOL test_OpenHKCU(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
430                           struct policy_handle *handle)
431 {
432         NTSTATUS status;
433         struct winreg_OpenHKCU r;
434         struct winreg_OpenUnknown unknown;
435         BOOL ret = True;
436
437         printf("\ntesting OpenHKCU\n");
438
439         unknown.unknown0 = 0x84e0;
440         unknown.unknown1 = 0x0000;
441         r.in.unknown = &unknown;
442         r.in.access_required = SEC_RIGHTS_MAXIMUM_ALLOWED;
443         r.out.handle = handle;
444
445         status = dcerpc_winreg_OpenHKCU(p, mem_ctx, &r);
446
447         if (!NT_STATUS_IS_OK(status)) {
448                 printf("OpenHKCU failed - %s\n", nt_errstr(status));
449                 return False;
450         }
451
452         return ret;
453 }
454
455 #define MAX_DEPTH 2             /* Only go this far down the tree */
456
457 static BOOL test_key(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
458                      struct policy_handle *handle, int depth)
459 {
460         if (depth == MAX_DEPTH)
461                 return True;
462
463         if (!test_QueryInfoKey(p, mem_ctx, handle, NULL)) {
464         }
465
466         if (!test_EnumKey(p, mem_ctx, handle, depth)) {
467         }
468
469         if (!test_EnumValue(p, mem_ctx, handle)) {
470         }
471
472         /* Enumerate values */
473
474         test_CloseKey(p, mem_ctx, handle);
475
476         return True;
477 }
478
479 typedef BOOL winreg_open_fn(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
480                             struct policy_handle *handle);
481
482 static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
483 {
484         struct policy_handle handle, newhandle;
485         BOOL ret = True;
486         winreg_open_fn *open_fn = (winreg_open_fn *)fn;
487
488         if (!open_fn(p, mem_ctx, &handle))
489                 return False;
490
491         if (!test_CreateKey(p, mem_ctx, &handle, "spottyfoot", NULL)) {
492                 printf("CreateKey failed\n");
493                 ret = False;
494         }
495
496         if (!test_FlushKey(p, mem_ctx, &handle)) {
497                 printf("FlushKey failed\n");
498                 ret = False;
499         }
500
501         if (!test_OpenKey(p, mem_ctx, &handle, "spottyfoot", &newhandle)) {
502                 printf("CreateKey failed (OpenKey after Create didn't work)\n");
503                 ret = False;
504         }
505
506         if (!test_DeleteKey(p, mem_ctx, &handle, "spottyfoot")) {
507                 printf("DeleteKey failed\n");
508                 ret = False;
509         }
510
511         if (!test_FlushKey(p, mem_ctx, &handle)) {
512                 printf("FlushKey failed\n");
513                 ret = False;
514         }
515
516         if (test_OpenKey(p, mem_ctx, &handle, "spottyfoot", &newhandle)) {
517                 printf("DeleteKey failed (OpenKey after Delete didn't work)\n");
518                 ret = False;
519         }
520
521         if (!test_GetVersion(p, mem_ctx, &handle)) {
522                 printf("GetVersion failed\n");
523                 ret = False;
524         }
525
526         /* The HKCR hive has a very large fanout */
527
528         if (open_fn == test_OpenHKCR) {
529                 if(!test_key(p, mem_ctx, &handle, MAX_DEPTH - 1)) {
530                         ret = False;
531                 }
532         }
533
534         if(!test_key(p, mem_ctx, &handle, 0)) {
535                 ret = False;
536         }
537
538         return ret;
539 }
540
541 BOOL torture_rpc_winreg(int dummy)
542 {
543         NTSTATUS status;
544        struct dcerpc_pipe *p;
545         TALLOC_CTX *mem_ctx;
546         BOOL ret = True;
547         winreg_open_fn *open_fns[] = { test_OpenHKLM, test_OpenHKU,
548                                        test_OpenHKCR, test_OpenHKCU };
549         int i;
550
551         mem_ctx = talloc_init("torture_rpc_winreg");
552
553         status = torture_rpc_connection(&p, 
554                                         DCERPC_WINREG_NAME, 
555                                         DCERPC_WINREG_UUID, 
556                                         DCERPC_WINREG_VERSION);
557
558         if (!NT_STATUS_IS_OK(status)) {
559                 return False;
560         }
561
562         if(!test_InitiateSystemShutdown(p, mem_ctx, "spottyfood", 30))
563                 ret = False;
564
565         if(!test_AbortSystemShutdown(p, mem_ctx))
566                 ret = False;
567
568         for (i = 0; i < ARRAY_SIZE(open_fns); i++) {
569                 if (!test_Open(p, mem_ctx, open_fns[i]))
570                         ret = False;
571         }
572
573         talloc_destroy(mem_ctx);
574
575         torture_rpc_close(p);
576
577         return ret;
578 }