2 Unix SMB/CIFS implementation.
4 local testing of registry library - registry backend
6 Copyright (C) Jelmer Vernooij 2005-2007
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.
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.
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.
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"
31 * Test obtaining a predefined key.
33 static bool test_get_predefined(struct torture_context *tctx,
36 const struct registry_context *rctx =
37 (const struct registry_context *)_data;
38 struct registry_key *root;
41 error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
42 torture_assert_werr_ok(tctx, error,
43 "getting predefined key failed");
48 * Test obtaining a predefined key.
50 static bool test_get_predefined_unknown(struct torture_context *tctx,
53 const struct registry_context *rctx = _data;
54 struct registry_key *root;
57 error = reg_get_predefined_key(rctx, 1337, &root);
58 torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND,
59 "getting predefined key failed");
63 static bool test_predef_key_by_name(struct torture_context *tctx,
66 const struct registry_context *rctx =
67 (const struct registry_context *)_data;
68 struct registry_key *root;
71 error = reg_get_predefined_key_by_name(rctx, "HKEY_CLASSES_ROOT",
73 torture_assert_werr_ok(tctx, error,
74 "getting predefined key failed");
76 error = reg_get_predefined_key_by_name(rctx, "HKEY_classes_ROOT",
78 torture_assert_werr_ok(tctx, error,
79 "getting predefined key case insensitively failed");
84 static bool test_predef_key_by_name_invalid(struct torture_context *tctx,
87 const struct registry_context *rctx =
88 (const struct registry_context *)_data;
89 struct registry_key *root;
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");
99 * Test creating a new subkey
101 static bool test_create_subkey(struct torture_context *tctx,
104 const struct registry_context *rctx =
105 (const struct registry_context *)_data;
106 struct registry_key *root, *newkey;
109 error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
110 torture_assert_werr_ok(tctx, error,
111 "getting predefined key failed");
113 error = reg_key_add_name(rctx, root, "Bad Bentheim", NULL, NULL,
115 torture_assert_werr_ok(tctx, error, "Creating key return code");
116 torture_assert(tctx, newkey != NULL, "Creating new key");
122 * Test creating a new nested subkey
124 static bool test_create_nested_subkey(struct torture_context *tctx,
127 const struct registry_context *rctx =
128 (const struct registry_context *)_data;
129 struct registry_key *root, *newkey1, *newkey2;
132 error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
133 torture_assert_werr_ok(tctx, error,
134 "getting predefined key failed");
136 error = reg_key_add_name(rctx, root, "Hamburg", NULL, NULL,
138 torture_assert_werr_ok(tctx, error, "Creating key return code");
139 torture_assert(tctx, newkey1 != NULL, "Creating new key");
141 error = reg_key_add_name(rctx, root, "Hamburg\\Hamburg", NULL, NULL,
143 torture_assert_werr_ok(tctx, error, "Creating key return code");
144 torture_assert(tctx, newkey2 != NULL, "Creating new key");
150 * Test creating a new subkey
152 static bool test_key_add_abs_top(struct torture_context *tctx,
155 const struct registry_context *rctx =
156 (const struct registry_context *)_data;
157 struct registry_key *root;
160 error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT", 0, NULL,
162 torture_assert_werr_equal(tctx, error, WERR_ALREADY_EXISTS,
169 * Test creating a new subkey
171 static bool test_key_add_abs(struct torture_context *tctx,
175 const struct registry_context *rctx =
176 (const struct registry_context *)_data;
177 struct registry_key *root, *result1, *result2;
179 error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT\\bloe", 0, NULL,
181 torture_assert_werr_ok(tctx, error, "create lowest");
183 error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT\\bloe\\bla", 0,
185 torture_assert_werr_ok(tctx, error, "create nested");
187 error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
188 torture_assert_werr_ok(tctx, error,
189 "getting predefined key failed");
191 error = reg_open_key(tctx, root, "bloe", &result2);
192 torture_assert_werr_ok(tctx, error, "opening key");
194 error = reg_open_key(tctx, root, "bloe\\bla", &result2);
195 torture_assert_werr_ok(tctx, error, "opening key");
201 static bool test_del_key(struct torture_context *tctx, const void *_data)
203 const struct registry_context *rctx =
204 (const struct registry_context *)_data;
205 struct registry_key *root, *newkey;
208 error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
209 torture_assert_werr_ok(tctx, error,
210 "getting predefined key failed");
212 error = reg_key_add_name(rctx, root, "Hamburg", NULL, NULL, &newkey);
214 torture_assert_werr_ok(tctx, error, "Creating key return code");
215 torture_assert(tctx, newkey != NULL, "Creating new key");
217 error = reg_key_del(root, "Hamburg");
218 torture_assert_werr_ok(tctx, error, "Delete key");
220 error = reg_key_del(root, "Hamburg");
221 torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND,
222 "Delete missing key");
228 * Convenience function for opening the HKEY_CLASSES_ROOT hive and
229 * creating a single key for testing purposes.
231 static bool create_test_key(struct torture_context *tctx,
232 const struct registry_context *rctx,
234 struct registry_key **root,
235 struct registry_key **subkey)
239 error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, root);
240 torture_assert_werr_ok(tctx, error,
241 "getting predefined key failed");
243 error = reg_key_add_name(rctx, *root, name, NULL, NULL, subkey);
244 torture_assert_werr_ok(tctx, error, "Creating key return code");
250 static bool test_flush_key(struct torture_context *tctx, const void *_data)
252 const struct registry_context *rctx =
253 (const struct registry_context *)_data;
254 struct registry_key *root, *subkey;
257 if (!create_test_key(tctx, rctx, "Munchen", &root, &subkey))
260 error = reg_key_flush(subkey);
261 torture_assert_werr_ok(tctx, error, "flush key");
263 torture_assert_werr_equal(tctx, reg_key_flush(NULL),
264 WERR_INVALID_PARAM, "flush key");
269 static bool test_query_key(struct torture_context *tctx, const void *_data)
271 const struct registry_context *rctx =
272 (const struct registry_context *)_data;
273 struct registry_key *root, *subkey;
275 NTTIME last_changed_time;
276 uint32_t num_subkeys, num_values;
277 const char *classname;
279 if (!create_test_key(tctx, rctx, "Munchen", &root, &subkey))
282 error = reg_key_get_info(tctx, subkey, &classname,
283 &num_subkeys, &num_values,
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");
294 static bool test_query_key_nums(struct torture_context *tctx, const void *_data)
296 const struct registry_context *rctx =
297 (const struct registry_context *)_data;
298 struct registry_key *root, *subkey1, *subkey2;
300 uint32_t num_subkeys, num_values;
303 if (!create_test_key(tctx, rctx, "Berlin", &root, &subkey1))
306 error = reg_key_add_name(rctx, subkey1, "Bentheim", NULL, NULL,
308 torture_assert_werr_ok(tctx, error, "Creating key return code");
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");
314 error = reg_key_get_info(tctx, subkey1, NULL, &num_subkeys,
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");
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.
329 static bool test_list_subkeys(struct torture_context *tctx, const void *_data)
331 const struct registry_context *rctx =
332 (const struct registry_context *)_data;
333 struct registry_key *subkey = NULL, *root;
335 NTTIME last_mod_time;
336 const char *classname, *name;
338 if (!create_test_key(tctx, rctx, "Goettingen", &root, &subkey))
341 error = reg_key_get_subkey_by_index(tctx, root, 0, &name, &classname,
344 torture_assert_werr_ok(tctx, error, "Enum keys return code");
345 torture_assert_str_equal(tctx, name, "Goettingen", "Enum keys data");
348 error = reg_key_get_subkey_by_index(tctx, root, 0, NULL, NULL, NULL);
350 torture_assert_werr_ok(tctx, error,
351 "Enum keys with NULL arguments return code");
353 error = reg_key_get_subkey_by_index(tctx, root, 1, NULL, NULL, NULL);
355 torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS,
356 "Invalid error for no more items");
358 error = reg_key_get_subkey_by_index(tctx, subkey, 0, NULL, NULL, NULL);
360 torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS,
361 "Invalid error for no more items");
367 * Test setting a value
369 static bool test_set_value(struct torture_context *tctx, const void *_data)
371 const struct registry_context *rctx =
372 (const struct registry_context *)_data;
373 struct registry_key *subkey = NULL, *root;
377 if (!create_test_key(tctx, rctx, "Dusseldorf", &root, &subkey))
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");
388 * Test getting/setting security descriptors
390 static bool test_security(struct torture_context *tctx, const void *_data)
392 const struct registry_context *rctx =
393 (const struct registry_context *)_data;
394 struct registry_key *subkey = NULL, *root;
396 struct security_descriptor *osd, *nsd;
398 if (!create_test_key(tctx, rctx, "Düsseldorf", &root, &subkey))
401 osd = security_descriptor_dacl_create(tctx,
404 SID_NT_AUTHENTICATED_USERS,
405 SEC_ACE_TYPE_ACCESS_ALLOWED,
407 SEC_ACE_FLAG_OBJECT_INHERIT,
410 error = reg_set_security(subkey, osd);
411 torture_assert_werr_ok(tctx, error, "setting security");
413 error = reg_get_security(tctx, subkey, &nsd);
414 torture_assert_werr_ok (tctx, error, "setting security");
416 torture_assert(tctx, security_descriptor_equal(osd, nsd),
417 "security descriptor changed!");
423 * Test getting a value
425 static bool test_get_value(struct torture_context *tctx, const void *_data)
427 const struct registry_context *rctx =
428 (const struct registry_context *)_data;
429 struct registry_key *subkey = NULL, *root;
435 if (!create_test_key(tctx, rctx, "Duisburg", &root, &subkey))
438 error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type,
440 torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND,
441 "getting missing value");
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");
447 error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type,
449 torture_assert_werr_ok(tctx, error, "getting value");
451 torture_assert_int_equal(tctx, 4, data.length, "value length ok");
452 torture_assert(tctx, memcmp(data.data, &value, 4) == 0,
454 torture_assert_int_equal(tctx, REG_DWORD, type, "value type");
460 * Test unsetting a value
462 static bool test_del_value(struct torture_context *tctx, const void *_data)
464 const struct registry_context *rctx =
465 (const struct registry_context *)_data;
466 struct registry_key *subkey = NULL, *root;
472 if (!create_test_key(tctx, rctx, "Duisburg", &root, &subkey))
475 error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type,
477 torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND,
478 "getting missing value");
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");
484 error = reg_del_value(subkey, __FUNCTION__);
485 torture_assert_werr_ok (tctx, error, "unsetting value");
487 error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__,
489 torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND,
490 "getting missing value");
496 * Test listing values
498 static bool test_list_values(struct torture_context *tctx, const void *_data)
500 const struct registry_context *rctx =
501 (const struct registry_context *)_data;
502 struct registry_key *subkey = NULL, *root;
509 if (!create_test_key(tctx, rctx, "Bonn", &root, &subkey))
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");
516 error = reg_key_get_value_by_index(tctx, subkey, 0, &name,
518 torture_assert_werr_ok(tctx, error, "getting value");
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,
524 torture_assert_int_equal(tctx, REG_DWORD, type, "value type");
526 error = reg_key_get_value_by_index(tctx, subkey, 1, &name,
528 torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS,
529 "getting missing value");
534 static bool setup_local_registry(struct torture_context *tctx, void **data)
536 struct registry_context *rctx;
540 struct hive_key *hive_key;
541 const char *filename;
543 error = reg_open_local(tctx, &rctx, NULL, NULL);
544 torture_assert_werr_ok(tctx, error, "Opening local registry failed");
546 status = torture_temp_dir(tctx, "registry-local", &tempdir);
547 torture_assert_ntstatus_ok(tctx, status, "Creating temp dir failed");
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");
553 error = reg_mount_hive(rctx, hive_key, HKEY_CLASSES_ROOT, NULL);
554 torture_assert_werr_ok(tctx, error, "Mounting hive failed");
561 static void tcase_add_tests(struct torture_tcase *tcase)
563 torture_tcase_add_simple_test(tcase, "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",
571 torture_tcase_add_simple_test(tcase, "create_key",
572 test_create_nested_subkey);
573 torture_tcase_add_simple_test(tcase, "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",
579 torture_tcase_add_simple_test(tcase, "get_value",
581 torture_tcase_add_simple_test(tcase, "list_values",
583 torture_tcase_add_simple_test(tcase, "del_key",
585 torture_tcase_add_simple_test(tcase, "del_value",
587 torture_tcase_add_simple_test(tcase, "flush_key",
589 torture_tcase_add_simple_test(tcase, "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",
597 torture_tcase_add_simple_test(tcase, "test_predef_key_by_name_invalid",
598 test_predef_key_by_name_invalid);
601 struct torture_suite *torture_registry_registry(TALLOC_CTX *mem_ctx)
603 struct torture_tcase *tcase;
604 struct torture_suite *suite = torture_suite_create(mem_ctx, "REGISTRY");
606 tcase = torture_suite_add_tcase(suite, "local");
607 torture_tcase_set_fixture(tcase, setup_local_registry, NULL);
608 tcase_add_tests(tcase);