r128: Another registry update. Changes:
[ira/wip.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    
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
411         r.in.server = 0x0;
412         
413         status = dcerpc_winreg_AbortSystemShutdown(p, mem_ctx, &r);
414
415         if (!NT_STATUS_IS_OK(status)) {
416                 printf("AbortSystemShutdown failed - %s\n", nt_errstr(status));
417                 return False;
418         }
419
420         if (!W_ERROR_IS_OK(r.out.result)) {
421                 printf("AbortSystemShutdown failed - %s\n", win_errstr(r.out.result));
422                 return False;
423         }
424
425         return True;
426 }
427
428 static BOOL test_OpenHKCU(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
429                           struct policy_handle *handle)
430 {
431         NTSTATUS status;
432         struct winreg_OpenHKCU r;
433         struct winreg_OpenUnknown unknown;
434         BOOL ret = True;
435
436         printf("\ntesting OpenHKCU\n");
437
438         unknown.unknown0 = 0x84e0;
439         unknown.unknown1 = 0x0000;
440         r.in.unknown = &unknown;
441         r.in.access_required = SEC_RIGHTS_MAXIMUM_ALLOWED;
442         r.out.handle = handle;
443
444         status = dcerpc_winreg_OpenHKCU(p, mem_ctx, &r);
445
446         if (!NT_STATUS_IS_OK(status)) {
447                 printf("OpenHKCU failed - %s\n", nt_errstr(status));
448                 return False;
449         }
450
451         return ret;
452 }
453
454 #define MAX_DEPTH 2             /* Only go this far down the tree */
455
456 static BOOL test_key(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
457                      struct policy_handle *handle, int depth)
458 {
459         if (depth == MAX_DEPTH)
460                 return True;
461
462         if (!test_QueryInfoKey(p, mem_ctx, handle, NULL)) {
463         }
464
465         if (!test_EnumKey(p, mem_ctx, handle, depth)) {
466         }
467
468         if (!test_EnumValue(p, mem_ctx, handle)) {
469         }
470
471         /* Enumerate values */
472
473         test_CloseKey(p, mem_ctx, handle);
474
475         return True;
476 }
477
478 typedef BOOL winreg_open_fn(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
479                             struct policy_handle *handle);
480
481 static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
482 {
483         struct policy_handle handle, newhandle;
484         BOOL ret = True;
485         winreg_open_fn *open_fn = (winreg_open_fn *)fn;
486
487         if (!open_fn(p, mem_ctx, &handle))
488                 return False;
489
490         if (!test_CreateKey(p, mem_ctx, &handle, "spottyfoot", NULL)) {
491                 printf("CreateKey failed\n");
492                 ret = False;
493         }
494
495         if (!test_OpenKey(p, mem_ctx, &handle, "spottyfoot", &newhandle)) {
496                 printf("CreateKey failed (OpenKey after Create didn't work)\n");
497                 ret = False;
498         }
499
500         if (!test_DeleteKey(p, mem_ctx, &handle, "spottyfoot")) {
501                 printf("DeleteKey failed\n");
502                 ret = False;
503         }
504
505         if (test_OpenKey(p, mem_ctx, &handle, "spottyfoot", &newhandle)) {
506                 printf("DeleteKey failed (OpenKey after Delete didn't work)\n");
507                 ret = False;
508         }
509
510         if (!test_GetVersion(p, mem_ctx, &handle)) {
511                 printf("GetVersion failed\n");
512                 ret = False;
513         }
514
515         if (!test_FlushKey(p, mem_ctx, &handle)) {
516                 printf("FlushKey failed\n");
517                 ret = False;
518         }
519
520
521         /* The HKCR hive has a very large fanout */
522
523         if (open_fn == test_OpenHKCR) {
524                 if(!test_key(p, mem_ctx, &handle, MAX_DEPTH - 1)) {
525                         ret = False;
526                 }
527         }
528
529         if(!test_key(p, mem_ctx, &handle, 0)) {
530                 ret = False;
531         }
532
533         return ret;
534 }
535
536 BOOL torture_rpc_winreg(int dummy)
537 {
538         NTSTATUS status;
539        struct dcerpc_pipe *p;
540         TALLOC_CTX *mem_ctx;
541         BOOL ret = True;
542         winreg_open_fn *open_fns[] = { test_OpenHKLM, test_OpenHKU,
543                                        test_OpenHKCR, test_OpenHKCU };
544         int i;
545
546         mem_ctx = talloc_init("torture_rpc_winreg");
547
548         status = torture_rpc_connection(&p, 
549                                         DCERPC_WINREG_NAME, 
550                                         DCERPC_WINREG_UUID, 
551                                         DCERPC_WINREG_VERSION);
552
553         if (!NT_STATUS_IS_OK(status)) {
554                 return False;
555         }
556
557         if(!test_InitiateSystemShutdown(p, mem_ctx, "spottyfood", 30))
558                 ret = False;
559
560         for (i = 0; i < ARRAY_SIZE(open_fns); i++) {
561                 if (!test_Open(p, mem_ctx, open_fns[i]))
562                         ret = False;
563         }
564
565         talloc_destroy(mem_ctx);
566
567         torture_rpc_close(p);
568
569         return ret;
570 }