3003468b15545f57981847036de0ab455a27beaa
[kai/samba-autobuild/.git] / source4 / lib / registry / tests / registry.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    local testing of registry library - registry backend
5
6    Copyright (C) Jelmer Vernooij 2005-2007
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 3 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 "lib/registry/registry.h"
25 #include "torture/torture.h"
26 #include "librpc/gen_ndr/winreg.h"
27 #include "libcli/security/security.h"
28 #include "system/filesys.h"
29
30 /**
31  * Test obtaining a predefined key.
32  */
33 static bool test_get_predefined(struct torture_context *tctx, void *_data)
34 {
35         struct registry_context *rctx = (struct registry_context *)_data;
36         struct registry_key *root;
37         WERROR error;
38
39         error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
40         torture_assert_werr_ok(tctx, error,
41                                "getting predefined key failed");
42         return true;
43 }
44
45 /**
46  * Test obtaining a predefined key.
47  */
48 static bool test_get_predefined_unknown(struct torture_context *tctx,
49                 void *_data)
50 {
51         struct registry_context *rctx = _data;
52         struct registry_key *root;
53         WERROR error;
54
55         error = reg_get_predefined_key(rctx, 1337, &root);
56         torture_assert_werr_equal(tctx, error, WERR_BADFILE,
57                                   "getting predefined key failed");
58         return true;
59 }
60
61 static bool test_predef_key_by_name(struct torture_context *tctx, void *_data)
62 {
63         struct registry_context *rctx = (struct registry_context *)_data;
64         struct registry_key *root;
65         WERROR error;
66
67         error = reg_get_predefined_key_by_name(rctx, "HKEY_CLASSES_ROOT",
68                                                &root);
69         torture_assert_werr_ok(tctx, error,
70                                "getting predefined key failed");
71
72         error = reg_get_predefined_key_by_name(rctx, "HKEY_classes_ROOT",
73                                                &root);
74         torture_assert_werr_ok(tctx, error,
75                                "getting predefined key case insensitively failed");
76
77         return true;
78 }
79
80 static bool test_predef_key_by_name_invalid(struct torture_context *tctx,
81                 void *_data)
82 {
83         struct registry_context *rctx = (struct registry_context *)_data;
84         struct registry_key *root;
85         WERROR error;
86
87         error = reg_get_predefined_key_by_name(rctx, "BLA", &root);
88         torture_assert_werr_equal(tctx, error, WERR_BADFILE,
89                                   "getting predefined key failed");
90         return true;
91 }
92
93 /**
94  * Test creating a new subkey
95  */
96 static bool test_create_subkey(struct torture_context *tctx, void *_data)
97 {
98         struct registry_context *rctx = (struct registry_context *)_data;
99         struct registry_key *root, *newkey;
100         WERROR error;
101
102         error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
103         torture_assert_werr_ok(tctx, error,
104                                "getting predefined key failed");
105
106         error = reg_key_add_name(rctx, root, "Bad Bentheim", NULL, NULL,
107                                  &newkey);
108         torture_assert_werr_ok(tctx, error, "Creating key return code");
109         torture_assert(tctx, newkey != NULL, "Creating new key");
110
111         return true;
112 }
113
114 /**
115  * Test creating a new nested subkey
116  */
117 static bool test_create_nested_subkey(struct torture_context *tctx, void *_data)
118 {
119         struct registry_context *rctx = (struct registry_context *)_data;
120         struct registry_key *root, *newkey;
121         WERROR error;
122
123         error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
124         torture_assert_werr_ok(tctx, error,
125                                "getting predefined key failed");
126
127         error = reg_key_add_name(rctx, root, "Hamburg\\Hamburg", NULL, NULL,
128                                  &newkey);
129         torture_assert_werr_ok(tctx, error, "Creating key return code");
130         torture_assert(tctx, newkey != NULL, "Creating new key");
131
132         return true;
133 }
134
135 /**
136  * Test creating a new subkey
137  */
138 static bool test_key_add_abs_top(struct torture_context *tctx, void *_data)
139 {
140         struct registry_context *rctx = (struct registry_context *)_data;
141         struct registry_key *root;
142         WERROR error;
143
144         error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT", 0, NULL,
145                                 &root);
146         torture_assert_werr_equal(tctx, error, WERR_ALREADY_EXISTS,
147                                   "create top level");
148
149         return true;
150 }
151
152 /**
153  * Test creating a new subkey
154  */
155 static bool test_key_add_abs(struct torture_context *tctx, void *_data)
156 {
157         WERROR error;
158         struct registry_context *rctx = (struct registry_context *)_data;
159         struct registry_key *root, *result1, *result2;
160
161         error = reg_key_add_abs(tctx, rctx,  "HKEY_CLASSES_ROOT\\bloe", 0, NULL,
162                                 &result1);
163         torture_assert_werr_ok(tctx, error, "create lowest");
164
165         error = reg_key_add_abs(tctx, rctx,  "HKEY_CLASSES_ROOT\\bloe\\bla", 0,
166                                 NULL, &result1);
167         torture_assert_werr_ok(tctx, error, "create nested");
168
169         error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
170         torture_assert_werr_ok(tctx, error,
171                                "getting predefined key failed");
172
173         error = reg_open_key(tctx, root, "bloe", &result2);
174         torture_assert_werr_ok(tctx, error, "opening key");
175
176         error = reg_open_key(tctx, root, "bloe\\bla", &result2);
177         torture_assert_werr_ok(tctx, error, "opening key");
178
179         return true;
180 }
181
182
183 static bool test_del_key(struct torture_context *tctx, void *_data)
184 {
185         struct registry_context *rctx = (struct registry_context *)_data;
186         struct registry_key *root, *newkey;
187         WERROR error;
188
189         error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
190         torture_assert_werr_ok(tctx, error,
191                                "getting predefined key failed");
192
193         error = reg_key_add_name(rctx, root, "Polen", NULL, NULL, &newkey);
194
195         torture_assert_werr_ok(tctx, error, "Creating key return code");
196         torture_assert(tctx, newkey != NULL, "Creating new key");
197
198         error = reg_key_del(tctx, root, "Polen");
199         torture_assert_werr_ok(tctx, error, "Delete key");
200
201         error = reg_key_del(tctx, root, "Polen");
202         torture_assert_werr_equal(tctx, error, WERR_BADFILE,
203                                   "Delete missing key");
204
205         return true;
206 }
207
208 /**
209  * Convenience function for opening the HKEY_CLASSES_ROOT hive and
210  * creating a single key for testing purposes.
211  */
212 static bool create_test_key(struct torture_context *tctx,
213                             struct registry_context *rctx,
214                             const char *name,
215                             struct registry_key **root,
216                             struct registry_key **subkey)
217 {
218         WERROR error;
219
220         error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, root);
221         torture_assert_werr_ok(tctx, error,
222                                "getting predefined key failed");
223
224         error = reg_key_add_name(rctx, *root, name, NULL, NULL, subkey);
225         torture_assert_werr_ok(tctx, error, "Creating key return code");
226
227         return true;
228 }
229
230
231 static bool test_flush_key(struct torture_context *tctx, void *_data)
232 {
233         struct registry_context *rctx = (struct registry_context *)_data;
234         struct registry_key *root, *subkey;
235         WERROR error;
236
237         if (!create_test_key(tctx, rctx, "Bremen", &root, &subkey))
238                 return false;
239
240         error = reg_key_flush(subkey);
241         torture_assert_werr_ok(tctx, error, "flush key");
242
243         torture_assert_werr_equal(tctx, reg_key_flush(NULL),
244                                   WERR_INVALID_PARAM, "flush key");
245
246         return true;
247 }
248
249 static bool test_query_key(struct torture_context *tctx, void *_data)
250 {
251         struct registry_context *rctx = (struct registry_context *)_data;
252         struct registry_key *root, *subkey;
253         WERROR error;
254         NTTIME last_changed_time;
255         uint32_t num_subkeys, num_values;
256         const char *classname;
257
258         if (!create_test_key(tctx, rctx, "Munchen", &root, &subkey))
259                 return false;
260
261         error = reg_key_get_info(tctx, subkey, &classname,
262                                  &num_subkeys, &num_values,
263                                  &last_changed_time, NULL, NULL, NULL);
264
265         torture_assert_werr_ok(tctx, error, "get info key");
266         torture_assert(tctx, classname == NULL, "classname");
267         torture_assert_int_equal(tctx, num_subkeys, 0, "num subkeys");
268         torture_assert_int_equal(tctx, num_values, 0, "num values");
269
270         return true;
271 }
272
273 static bool test_query_key_nums(struct torture_context *tctx, void *_data)
274 {
275         struct registry_context *rctx = (struct registry_context *)_data;
276         struct registry_key *root, *subkey1, *subkey2;
277         WERROR error;
278         uint32_t num_subkeys, num_values;
279         char data[4];
280         SIVAL(data, 0, 42);
281
282         if (!create_test_key(tctx, rctx, "Berlin", &root, &subkey1))
283                 return false;
284
285         error = reg_key_add_name(rctx, subkey1, "Bentheim", NULL, NULL,
286                                  &subkey2);
287         torture_assert_werr_ok(tctx, error, "Creating key return code");
288
289         error = reg_val_set(subkey1, "Answer", REG_DWORD,
290                             data_blob_talloc(tctx, &data, sizeof(data)));
291         torture_assert_werr_ok(tctx, error, "set value");
292
293         error = reg_key_get_info(tctx, subkey1, NULL, &num_subkeys,
294                                  &num_values, NULL, NULL, NULL, NULL);
295
296         torture_assert_werr_ok(tctx, error, "get info key");
297         torture_assert_int_equal(tctx, num_subkeys, 1, "num subkeys");
298         torture_assert_int_equal(tctx, num_values, 1, "num values");
299
300         return true;
301 }
302
303 /**
304  * Test that the subkeys of a key can be enumerated, that
305  * the returned parameters for get_subkey_by_index are optional and
306  * that enumerating the parents of a non-top-level node works.
307  */
308 static bool test_list_subkeys(struct torture_context *tctx, void *_data)
309 {
310         struct registry_context *rctx = (struct registry_context *)_data;
311         struct registry_key *subkey = NULL, *root;
312         WERROR error;
313         NTTIME last_mod_time;
314         const char *classname, *name;
315
316         if (!create_test_key(tctx, rctx, "Goettingen", &root, &subkey))
317                 return false;
318
319         error = reg_key_get_subkey_by_index(tctx, root, 0, &name, &classname,
320                                             &last_mod_time);
321
322         torture_assert_werr_ok(tctx, error, "Enum keys return code");
323         torture_assert_str_equal(tctx, name, "Goettingen", "Enum keys data");
324
325
326         error = reg_key_get_subkey_by_index(tctx, root, 0, NULL, NULL, NULL);
327
328         torture_assert_werr_ok(tctx, error,
329                                "Enum keys with NULL arguments return code");
330
331         error = reg_key_get_subkey_by_index(tctx, root, 1, NULL, NULL, NULL);
332
333         torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS,
334                                   "Invalid error for no more items");
335
336         error = reg_key_get_subkey_by_index(tctx, subkey, 0, NULL, NULL, NULL);
337
338         torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS,
339                                   "Invalid error for no more items");
340
341         return true;
342 }
343
344 /**
345  * Test setting a value
346  */
347 static bool test_set_value(struct torture_context *tctx, void *_data)
348 {
349         struct registry_context *rctx = (struct registry_context *)_data;
350         struct registry_key *subkey = NULL, *root;
351         WERROR error;
352         char data[4];
353
354         SIVAL(data, 0, 42);
355
356         if (!create_test_key(tctx, rctx, "Dusseldorf", &root, &subkey))
357                 return false;
358
359         error = reg_val_set(subkey, "Answer", REG_DWORD,
360                             data_blob_talloc(tctx, data, sizeof(data)));
361         torture_assert_werr_ok (tctx, error, "setting value");
362
363         return true;
364 }
365
366 /**
367  * Test getting/setting security descriptors
368  */
369 static bool test_security(struct torture_context *tctx, void *_data)
370 {
371         struct registry_context *rctx = (struct registry_context *)_data;
372         struct registry_key *subkey = NULL, *root;
373         WERROR error;
374         struct security_descriptor *osd, *nsd;
375
376         if (!create_test_key(tctx, rctx, "Düsseldorf", &root, &subkey))
377                 return false;
378
379         osd = security_descriptor_dacl_create(tctx,
380                                          0,
381                                          NULL, NULL,
382                                          SID_NT_AUTHENTICATED_USERS,
383                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
384                                          SEC_GENERIC_ALL,
385                                          SEC_ACE_FLAG_OBJECT_INHERIT,
386                                          NULL);
387
388         error = reg_set_sec_desc(subkey, osd);
389         torture_assert_werr_ok(tctx, error, "setting security descriptor");
390
391         error = reg_get_sec_desc(tctx, subkey, &nsd);
392         torture_assert_werr_ok (tctx, error, "getting security descriptor");
393
394         torture_assert(tctx, security_descriptor_equal(osd, nsd),
395                        "security descriptor changed!");
396
397         return true;
398 }
399
400 /**
401  * Test getting a value
402  */
403 static bool test_get_value(struct torture_context *tctx, void *_data)
404 {
405         struct registry_context *rctx = (struct registry_context *)_data;
406         struct registry_key *subkey = NULL, *root;
407         WERROR error;
408         DATA_BLOB data;
409         char value[4];
410         uint32_t type;
411         SIVAL(value, 0, 42);
412
413         if (!create_test_key(tctx, rctx, "Duisburg", &root, &subkey))
414                 return false;
415
416         error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type,
417                                           &data);
418         torture_assert_werr_equal(tctx, error, WERR_BADFILE,
419                                   "getting missing value");
420
421         error = reg_val_set(subkey, __FUNCTION__, REG_DWORD,
422                             data_blob_talloc(tctx, value, sizeof(value)));
423         torture_assert_werr_ok(tctx, error, "setting value");
424
425         error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type,
426                                           &data);
427         torture_assert_werr_ok(tctx, error, "getting value");
428
429         torture_assert_int_equal(tctx, sizeof(value), data.length, "value length ok");
430         torture_assert_mem_equal(tctx, data.data, value, sizeof(value),
431                                  "value content ok");
432         torture_assert_int_equal(tctx, REG_DWORD, type, "value type");
433
434         return true;
435 }
436
437 /**
438  * Test unsetting a value
439  */
440 static bool test_del_value(struct torture_context *tctx, void *_data)
441 {
442         struct registry_context *rctx =(struct registry_context *)_data;
443         struct registry_key *subkey = NULL, *root;
444         WERROR error;
445         DATA_BLOB data;
446         uint32_t type;
447         char value[4];
448         SIVAL(value, 0, 42);
449
450         if (!create_test_key(tctx, rctx, "Warschau", &root, &subkey))
451                 return false;
452
453         error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type,
454                                           &data);
455         torture_assert_werr_equal(tctx, error, WERR_BADFILE,
456                                   "getting missing value");
457
458         error = reg_val_set(subkey, __FUNCTION__, REG_DWORD,
459                             data_blob_talloc(tctx, value, sizeof(value)));
460         torture_assert_werr_ok (tctx, error, "setting value");
461
462         error = reg_del_value(tctx, subkey, __FUNCTION__);
463         torture_assert_werr_ok (tctx, error, "unsetting value");
464
465         error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__,
466                                           &type, &data);
467         torture_assert_werr_equal(tctx, error, WERR_BADFILE,
468                                   "getting missing value");
469
470         return true;
471 }
472
473 /**
474  * Test listing values
475  */
476 static bool test_list_values(struct torture_context *tctx, void *_data)
477 {
478         struct registry_context *rctx = (struct registry_context *)_data;
479         struct registry_key *subkey = NULL, *root;
480         WERROR error;
481         DATA_BLOB data;
482         uint32_t type;
483         const char *name;
484         char value[4];
485         SIVAL(value, 0, 42);
486
487         if (!create_test_key(tctx, rctx, "Bonn", &root, &subkey))
488                 return false;
489
490         error = reg_val_set(subkey, "bar", REG_DWORD,
491                             data_blob_talloc(tctx, value, sizeof(value)));
492         torture_assert_werr_ok (tctx, error, "setting value");
493
494         error = reg_key_get_value_by_index(tctx, subkey, 0, &name,
495                                            &type, &data);
496         torture_assert_werr_ok(tctx, error, "getting value");
497
498         torture_assert_str_equal(tctx, name, "bar", "value name");
499         torture_assert_int_equal(tctx, sizeof(value), data.length, "value length");
500         torture_assert_mem_equal(tctx, data.data, value, sizeof(value),
501                        "value content");
502         torture_assert_int_equal(tctx, REG_DWORD, type, "value type");
503
504         error = reg_key_get_value_by_index(tctx, subkey, 1, &name,
505                                            &type, &data);
506         torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS,
507                                   "getting missing value");
508
509         return true;
510 }
511
512 static bool setup_local_registry(struct torture_context *tctx, void **data)
513 {
514         struct registry_context *rctx;
515         WERROR error;
516         char *tempdir;
517         NTSTATUS status;
518         struct hive_key *hive_key;
519         const char *filename;
520
521         error = reg_open_local(tctx, &rctx);
522         torture_assert_werr_ok(tctx, error, "Opening local registry failed");
523
524         status = torture_temp_dir(tctx, "registry-local", &tempdir);
525         torture_assert_ntstatus_ok(tctx, status, "Creating temp dir failed");
526
527         filename = talloc_asprintf(tctx, "%s/classes_root.ldb", tempdir);
528         error = reg_open_ldb_file(tctx, filename, NULL, NULL, tctx->ev, tctx->lp_ctx, &hive_key);
529         torture_assert_werr_ok(tctx, error, "Opening classes_root file failed");
530
531         error = reg_mount_hive(rctx, hive_key, HKEY_CLASSES_ROOT, NULL);
532         torture_assert_werr_ok(tctx, error, "Mounting hive failed");
533
534         *data = rctx;
535
536         return true;
537 }
538
539 static void tcase_add_tests(struct torture_tcase *tcase)
540 {
541         torture_tcase_add_simple_test(tcase, "list_subkeys",
542                                         test_list_subkeys);
543         torture_tcase_add_simple_test(tcase, "get_predefined_key",
544                                         test_get_predefined);
545         torture_tcase_add_simple_test(tcase, "get_predefined_key",
546                                         test_get_predefined_unknown);
547         torture_tcase_add_simple_test(tcase, "create_key",
548                                         test_create_subkey);
549         torture_tcase_add_simple_test(tcase, "create_key",
550                                         test_create_nested_subkey);
551         torture_tcase_add_simple_test(tcase, "key_add_abs",
552                                         test_key_add_abs);
553         torture_tcase_add_simple_test(tcase, "key_add_abs_top",
554                                         test_key_add_abs_top);
555         torture_tcase_add_simple_test(tcase, "set_value",
556                                         test_set_value);
557         torture_tcase_add_simple_test(tcase, "get_value",
558                                         test_get_value);
559         torture_tcase_add_simple_test(tcase, "list_values",
560                                         test_list_values);
561         torture_tcase_add_simple_test(tcase, "del_key",
562                                         test_del_key);
563         torture_tcase_add_simple_test(tcase, "del_value",
564                                         test_del_value);
565         torture_tcase_add_simple_test(tcase, "flush_key",
566                                         test_flush_key);
567         torture_tcase_add_simple_test(tcase, "query_key",
568                                         test_query_key);
569         torture_tcase_add_simple_test(tcase, "query_key_nums",
570                                         test_query_key_nums);
571         torture_tcase_add_simple_test(tcase, "test_predef_key_by_name",
572                                         test_predef_key_by_name);
573         torture_tcase_add_simple_test(tcase, "security",
574                                         test_security);
575         torture_tcase_add_simple_test(tcase,"test_predef_key_by_name_invalid",
576                                         test_predef_key_by_name_invalid);
577 }
578
579 struct torture_suite *torture_registry_registry(TALLOC_CTX *mem_ctx)
580 {
581         struct torture_tcase *tcase;
582         struct torture_suite *suite = torture_suite_create(mem_ctx, "REGISTRY");
583
584         tcase = torture_suite_add_tcase(suite, "local");
585         torture_tcase_set_fixture(tcase, setup_local_registry, NULL);
586         tcase_add_tests(tcase);
587
588         return suite;
589 }