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