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