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