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 3 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"
29 #include "lib/registry/tests/proto.h"
32 * Test obtaining a predefined key.
34 static bool test_get_predefined(struct torture_context
*tctx
, void *_data
)
36 struct registry_context
*rctx
= (struct registry_context
*)_data
;
37 struct registry_key
*root
;
40 error
= reg_get_predefined_key(rctx
, HKEY_CLASSES_ROOT
, &root
);
41 torture_assert_werr_ok(tctx
, error
,
42 "getting predefined key failed");
47 * Test obtaining a predefined key.
49 static bool test_get_predefined_unknown(struct torture_context
*tctx
,
52 struct registry_context
*rctx
= _data
;
53 struct registry_key
*root
;
56 error
= reg_get_predefined_key(rctx
, 1337, &root
);
57 torture_assert_werr_equal(tctx
, error
, WERR_FILE_NOT_FOUND
,
58 "getting predefined key failed");
62 static bool test_predef_key_by_name(struct torture_context
*tctx
, void *_data
)
64 struct registry_context
*rctx
= (struct registry_context
*)_data
;
65 struct registry_key
*root
;
68 error
= reg_get_predefined_key_by_name(rctx
, "HKEY_CLASSES_ROOT",
70 torture_assert_werr_ok(tctx
, error
,
71 "getting predefined key failed");
73 error
= reg_get_predefined_key_by_name(rctx
, "HKEY_classes_ROOT",
75 torture_assert_werr_ok(tctx
, error
,
76 "getting predefined key case insensitively failed");
81 static bool test_predef_key_by_name_invalid(struct torture_context
*tctx
,
84 struct registry_context
*rctx
= (struct registry_context
*)_data
;
85 struct registry_key
*root
;
88 error
= reg_get_predefined_key_by_name(rctx
, "BLA", &root
);
89 torture_assert_werr_equal(tctx
, error
, WERR_FILE_NOT_FOUND
,
90 "getting predefined key failed");
95 * Test creating a new subkey
97 static bool test_create_subkey(struct torture_context
*tctx
, void *_data
)
99 struct registry_context
*rctx
= (struct registry_context
*)_data
;
100 struct registry_key
*root
, *newkey
;
103 error
= reg_get_predefined_key(rctx
, HKEY_CLASSES_ROOT
, &root
);
104 torture_assert_werr_ok(tctx
, error
,
105 "getting predefined key failed");
107 error
= reg_key_add_name(rctx
, root
, "Bad Bentheim", NULL
, NULL
,
109 torture_assert_werr_ok(tctx
, error
, "Creating key return code");
110 torture_assert(tctx
, newkey
!= NULL
, "Creating new key");
116 * Test creating a new nested subkey
118 static bool test_create_nested_subkey(struct torture_context
*tctx
, void *_data
)
120 struct registry_context
*rctx
= (struct registry_context
*)_data
;
121 struct registry_key
*root
, *newkey
;
124 error
= reg_get_predefined_key(rctx
, HKEY_CLASSES_ROOT
, &root
);
125 torture_assert_werr_ok(tctx
, error
,
126 "getting predefined key failed");
128 error
= reg_key_add_name(rctx
, root
, "Hamburg\\Hamburg", NULL
, NULL
,
130 torture_assert_werr_ok(tctx
, error
, "Creating key return code");
131 torture_assert(tctx
, newkey
!= NULL
, "Creating new key");
137 * Test creating a new subkey
139 static bool test_key_add_abs_top(struct torture_context
*tctx
, void *_data
)
141 struct registry_context
*rctx
= (struct registry_context
*)_data
;
142 struct registry_key
*root
;
145 error
= reg_key_add_abs(tctx
, rctx
, "HKEY_CLASSES_ROOT", 0, NULL
,
147 torture_assert_werr_equal(tctx
, error
, WERR_ALREADY_EXISTS
,
154 * Test creating a new subkey
156 static bool test_key_add_abs(struct torture_context
*tctx
, void *_data
)
159 struct registry_context
*rctx
= (struct registry_context
*)_data
;
160 struct registry_key
*root
, *result1
, *result2
;
162 error
= reg_key_add_abs(tctx
, rctx
, "HKEY_CLASSES_ROOT\\bloe", 0, NULL
,
164 torture_assert_werr_ok(tctx
, error
, "create lowest");
166 error
= reg_key_add_abs(tctx
, rctx
, "HKEY_CLASSES_ROOT\\bloe\\bla", 0,
168 torture_assert_werr_ok(tctx
, error
, "create nested");
170 error
= reg_get_predefined_key(rctx
, HKEY_CLASSES_ROOT
, &root
);
171 torture_assert_werr_ok(tctx
, error
,
172 "getting predefined key failed");
174 error
= reg_open_key(tctx
, root
, "bloe", &result2
);
175 torture_assert_werr_ok(tctx
, error
, "opening key");
177 error
= reg_open_key(tctx
, root
, "bloe\\bla", &result2
);
178 torture_assert_werr_ok(tctx
, error
, "opening key");
184 static bool test_del_key(struct torture_context
*tctx
, void *_data
)
186 struct registry_context
*rctx
= (struct registry_context
*)_data
;
187 struct registry_key
*root
, *newkey
;
190 error
= reg_get_predefined_key(rctx
, HKEY_CLASSES_ROOT
, &root
);
191 torture_assert_werr_ok(tctx
, error
,
192 "getting predefined key failed");
194 error
= reg_key_add_name(rctx
, root
, "Polen", NULL
, NULL
, &newkey
);
196 torture_assert_werr_ok(tctx
, error
, "Creating key return code");
197 torture_assert(tctx
, newkey
!= NULL
, "Creating new key");
199 error
= reg_key_del(tctx
, root
, "Polen");
200 torture_assert_werr_ok(tctx
, error
, "Delete key");
202 error
= reg_key_del(tctx
, root
, "Polen");
203 torture_assert_werr_equal(tctx
, error
, WERR_FILE_NOT_FOUND
,
204 "Delete missing key");
210 * Convenience function for opening the HKEY_CLASSES_ROOT hive and
211 * creating a single key for testing purposes.
213 static bool create_test_key(struct torture_context
*tctx
,
214 struct registry_context
*rctx
,
216 struct registry_key
**root
,
217 struct registry_key
**subkey
)
221 error
= reg_get_predefined_key(rctx
, HKEY_CLASSES_ROOT
, root
);
222 torture_assert_werr_ok(tctx
, error
,
223 "getting predefined key failed");
225 error
= reg_key_add_name(rctx
, *root
, name
, NULL
, NULL
, subkey
);
226 torture_assert_werr_ok(tctx
, error
, "Creating key return code");
232 static bool test_flush_key(struct torture_context
*tctx
, void *_data
)
234 struct registry_context
*rctx
= (struct registry_context
*)_data
;
235 struct registry_key
*root
, *subkey
;
238 if (!create_test_key(tctx
, rctx
, "Bremen", &root
, &subkey
))
241 error
= reg_key_flush(subkey
);
242 torture_assert_werr_ok(tctx
, error
, "flush key");
244 torture_assert_werr_equal(tctx
, reg_key_flush(NULL
),
245 WERR_INVALID_PARAMETER
, "flush key");
250 static bool test_query_key(struct torture_context
*tctx
, void *_data
)
252 struct registry_context
*rctx
= (struct registry_context
*)_data
;
253 struct registry_key
*root
, *subkey
;
255 NTTIME last_changed_time
;
256 uint32_t num_subkeys
, num_values
;
257 const char *classname
;
258 const char *data
= "temp";
260 if (!create_test_key(tctx
, rctx
, "Muenchen", &root
, &subkey
))
263 error
= reg_key_get_info(tctx
, subkey
, &classname
,
264 &num_subkeys
, &num_values
,
265 &last_changed_time
, NULL
, NULL
, NULL
);
267 torture_assert_werr_ok(tctx
, error
, "get info key");
268 torture_assert(tctx
, classname
== NULL
, "classname");
269 torture_assert_int_equal(tctx
, num_subkeys
, 0, "num subkeys");
270 torture_assert_int_equal(tctx
, num_values
, 0, "num values");
272 error
= reg_val_set(subkey
, "", REG_SZ
,
273 data_blob_string_const(data
));
274 torture_assert_werr_ok(tctx
, error
, "set default value");
276 error
= reg_key_get_info(tctx
, subkey
, &classname
,
277 &num_subkeys
, &num_values
,
278 &last_changed_time
, NULL
, NULL
, NULL
);
280 torture_assert_werr_ok(tctx
, error
, "get info key");
281 torture_assert(tctx
, classname
== NULL
, "classname");
282 torture_assert_int_equal(tctx
, num_subkeys
, 0, "num subkeys");
283 torture_assert_int_equal(tctx
, num_values
, 1, "num values");
288 static bool test_query_key_nums(struct torture_context
*tctx
, void *_data
)
290 struct registry_context
*rctx
= (struct registry_context
*)_data
;
291 struct registry_key
*root
, *subkey1
, *subkey2
;
293 uint32_t num_subkeys
, num_values
;
297 if (!create_test_key(tctx
, rctx
, "Berlin", &root
, &subkey1
))
300 error
= reg_key_add_name(rctx
, subkey1
, "Bentheim", NULL
, NULL
,
302 torture_assert_werr_ok(tctx
, error
, "Creating key return code");
304 error
= reg_val_set(subkey1
, "Answer", REG_DWORD
,
305 data_blob_talloc(tctx
, &data
, sizeof(data
)));
306 torture_assert_werr_ok(tctx
, error
, "set value");
308 error
= reg_key_get_info(tctx
, subkey1
, NULL
, &num_subkeys
,
309 &num_values
, NULL
, NULL
, NULL
, NULL
);
311 torture_assert_werr_ok(tctx
, error
, "get info key");
312 torture_assert_int_equal(tctx
, num_subkeys
, 1, "num subkeys");
313 torture_assert_int_equal(tctx
, num_values
, 1, "num values");
319 * Test that the subkeys of a key can be enumerated, that
320 * the returned parameters for get_subkey_by_index are optional and
321 * that enumerating the parents of a non-top-level node works.
323 static bool test_list_subkeys(struct torture_context
*tctx
, void *_data
)
325 struct registry_context
*rctx
= (struct registry_context
*)_data
;
326 struct registry_key
*subkey
= NULL
, *root
;
328 NTTIME last_mod_time
;
329 const char *classname
, *name
;
331 if (!create_test_key(tctx
, rctx
, "Goettingen", &root
, &subkey
))
334 error
= reg_key_get_subkey_by_index(tctx
, root
, 0, &name
, &classname
,
337 torture_assert_werr_ok(tctx
, error
, "Enum keys return code");
338 torture_assert_str_equal(tctx
, name
, "Goettingen", "Enum keys data");
341 error
= reg_key_get_subkey_by_index(tctx
, root
, 0, NULL
, NULL
, NULL
);
343 torture_assert_werr_ok(tctx
, error
,
344 "Enum keys with NULL arguments return code");
346 error
= reg_key_get_subkey_by_index(tctx
, root
, 1, NULL
, NULL
, NULL
);
348 torture_assert_werr_equal(tctx
, error
, WERR_NO_MORE_ITEMS
,
349 "Invalid error for no more items");
351 error
= reg_key_get_subkey_by_index(tctx
, subkey
, 0, NULL
, NULL
, NULL
);
353 torture_assert_werr_equal(tctx
, error
, WERR_NO_MORE_ITEMS
,
354 "Invalid error for no more items");
360 * Test setting a value
362 static bool test_set_value(struct torture_context
*tctx
, void *_data
)
364 struct registry_context
*rctx
= (struct registry_context
*)_data
;
365 struct registry_key
*subkey
= NULL
, *root
;
371 if (!create_test_key(tctx
, rctx
, "Dusseldorf", &root
, &subkey
))
374 error
= reg_val_set(subkey
, "Answer", REG_DWORD
,
375 data_blob_talloc(tctx
, data
, sizeof(data
)));
376 torture_assert_werr_ok (tctx
, error
, "setting value");
382 * Test getting/setting security descriptors
384 static bool test_security(struct torture_context
*tctx
, void *_data
)
386 struct registry_context
*rctx
= (struct registry_context
*)_data
;
387 struct registry_key
*subkey
= NULL
, *root
;
389 struct security_descriptor
*osd
, *nsd
;
391 if (!create_test_key(tctx
, rctx
, "Düsseldorf", &root
, &subkey
))
394 osd
= security_descriptor_dacl_create(tctx
,
397 SID_NT_AUTHENTICATED_USERS
,
398 SEC_ACE_TYPE_ACCESS_ALLOWED
,
400 SEC_ACE_FLAG_OBJECT_INHERIT
,
403 error
= reg_set_sec_desc(subkey
, osd
);
404 torture_assert_werr_ok(tctx
, error
, "setting security descriptor");
406 error
= reg_get_sec_desc(tctx
, subkey
, &nsd
);
407 torture_assert_werr_ok (tctx
, error
, "getting security descriptor");
409 torture_assert(tctx
, security_descriptor_equal(osd
, nsd
),
410 "security descriptor changed!");
416 * Test getting a value
418 static bool test_get_value(struct torture_context
*tctx
, void *_data
)
420 struct registry_context
*rctx
= (struct registry_context
*)_data
;
421 struct registry_key
*subkey
= NULL
, *root
;
426 const char *data_val
= "temp";
430 if (!create_test_key(tctx
, rctx
, "Duisburg", &root
, &subkey
))
433 error
= reg_key_get_value_by_name(tctx
, subkey
, __FUNCTION__
, &type
,
435 torture_assert_werr_equal(tctx
, error
, WERR_FILE_NOT_FOUND
,
436 "getting missing value");
438 error
= reg_val_set(subkey
, __FUNCTION__
, REG_DWORD
,
439 data_blob_talloc(tctx
, value
, sizeof(value
)));
440 torture_assert_werr_ok(tctx
, error
, "setting value");
442 error
= reg_key_get_value_by_name(tctx
, subkey
, __FUNCTION__
, &type
,
444 torture_assert_werr_ok(tctx
, error
, "getting value");
446 torture_assert_int_equal(tctx
, sizeof(value
), data
.length
, "value length ok");
447 torture_assert_mem_equal(tctx
, data
.data
, value
, sizeof(value
),
449 torture_assert_int_equal(tctx
, REG_DWORD
, type
, "value type");
451 error
= reg_val_set(subkey
, "", REG_SZ
,
452 data_blob_talloc(tctx
, data_val
,
454 torture_assert_werr_ok(tctx
, error
, "set default value");
456 error
= reg_key_get_value_by_name(tctx
, subkey
, "", &type
,
458 torture_assert_werr_ok(tctx
, error
, "getting default value");
459 torture_assert_int_equal(tctx
, REG_SZ
, type
, "value type ok");
460 torture_assert_int_equal(tctx
, strlen(data_val
), data
.length
, "value length ok");
461 torture_assert_str_equal(tctx
, data_val
, (char *)data
.data
, "value ok");
467 * Test unsetting a value
469 static bool test_del_value(struct torture_context
*tctx
, void *_data
)
471 struct registry_context
*rctx
=(struct registry_context
*)_data
;
472 struct registry_key
*subkey
= NULL
, *root
;
477 const char *data_val
= "temp";
481 if (!create_test_key(tctx
, rctx
, "Warschau", &root
, &subkey
))
484 error
= reg_key_get_value_by_name(tctx
, subkey
, __FUNCTION__
, &type
,
486 torture_assert_werr_equal(tctx
, error
, WERR_FILE_NOT_FOUND
,
487 "getting missing value");
489 error
= reg_val_set(subkey
, __FUNCTION__
, REG_DWORD
,
490 data_blob_talloc(tctx
, value
, sizeof(value
)));
491 torture_assert_werr_ok (tctx
, error
, "setting value");
493 error
= reg_del_value(tctx
, subkey
, __FUNCTION__
);
494 torture_assert_werr_ok (tctx
, error
, "unsetting value");
496 error
= reg_key_get_value_by_name(tctx
, subkey
, __FUNCTION__
,
498 torture_assert_werr_equal(tctx
, error
, WERR_FILE_NOT_FOUND
,
499 "getting missing value");
501 error
= reg_del_value(tctx
, subkey
, "");
502 torture_assert_werr_equal(tctx
, error
, WERR_FILE_NOT_FOUND
,
503 "unsetting missing default value");
505 error
= reg_val_set(subkey
, "", REG_SZ
,
506 data_blob_talloc(tctx
, data_val
,
508 torture_assert_werr_ok(tctx
, error
, "set default value");
510 error
= reg_del_value(tctx
, subkey
, "");
511 torture_assert_werr_ok (tctx
, error
, "unsetting default value");
517 * Test listing values
519 static bool test_list_values(struct torture_context
*tctx
, void *_data
)
521 struct registry_context
*rctx
= (struct registry_context
*)_data
;
522 struct registry_key
*subkey
= NULL
, *root
;
528 const char *data_val
= "temp";
532 if (!create_test_key(tctx
, rctx
, "Bonn", &root
, &subkey
))
535 error
= reg_val_set(subkey
, "bar", REG_DWORD
,
536 data_blob_talloc(tctx
, value
, sizeof(value
)));
537 torture_assert_werr_ok (tctx
, error
, "setting value");
539 error
= reg_key_get_value_by_index(tctx
, subkey
, 0, &name
,
541 torture_assert_werr_ok(tctx
, error
, "getting value");
543 torture_assert_str_equal(tctx
, name
, "bar", "value name");
544 torture_assert_int_equal(tctx
, sizeof(value
), data
.length
, "value length");
545 torture_assert_mem_equal(tctx
, data
.data
, value
, sizeof(value
),
547 torture_assert_int_equal(tctx
, REG_DWORD
, type
, "value type");
549 error
= reg_key_get_value_by_index(tctx
, subkey
, 1, &name
,
551 torture_assert_werr_equal(tctx
, error
, WERR_NO_MORE_ITEMS
,
552 "getting missing value");
554 error
= reg_val_set(subkey
, "", REG_SZ
,
555 data_blob_talloc(tctx
, data_val
, strlen(data_val
)));
556 torture_assert_werr_ok(tctx
, error
, "set default value");
558 error
= reg_key_get_value_by_index(tctx
, subkey
, 0, &name
,
560 torture_assert_werr_ok(tctx
, error
, "getting default value");
561 torture_assert_int_equal(tctx
, REG_SZ
, type
, "value type ok");
562 torture_assert_int_equal(tctx
, strlen(data_val
), data
.length
, "value length ok");
563 torture_assert_str_equal(tctx
, data_val
, (char *)data
.data
, "value ok");
568 static bool setup_local_registry(struct torture_context
*tctx
, void **data
)
570 struct registry_context
*rctx
;
574 struct hive_key
*hive_key
;
575 const char *filename
;
577 error
= reg_open_local(tctx
, &rctx
);
578 torture_assert_werr_ok(tctx
, error
, "Opening local registry failed");
580 status
= torture_temp_dir(tctx
, "registry-local", &tempdir
);
581 torture_assert_ntstatus_ok(tctx
, status
, "Creating temp dir failed");
583 filename
= talloc_asprintf(tctx
, "%s/classes_root.ldb", tempdir
);
584 error
= reg_open_ldb_file(tctx
, filename
, NULL
, NULL
, tctx
->ev
, tctx
->lp_ctx
, &hive_key
);
585 torture_assert_werr_ok(tctx
, error
, "Opening classes_root file failed");
587 error
= reg_mount_hive(rctx
, hive_key
, HKEY_CLASSES_ROOT
, NULL
);
588 torture_assert_werr_ok(tctx
, error
, "Mounting hive failed");
595 static void tcase_add_tests(struct torture_tcase
*tcase
)
597 torture_tcase_add_simple_test(tcase
, "list_subkeys",
599 torture_tcase_add_simple_test(tcase
, "get_predefined_key",
600 test_get_predefined
);
601 torture_tcase_add_simple_test(tcase
, "get_predefined_key",
602 test_get_predefined_unknown
);
603 torture_tcase_add_simple_test(tcase
, "create_key",
605 torture_tcase_add_simple_test(tcase
, "create_key",
606 test_create_nested_subkey
);
607 torture_tcase_add_simple_test(tcase
, "key_add_abs",
609 torture_tcase_add_simple_test(tcase
, "key_add_abs_top",
610 test_key_add_abs_top
);
611 torture_tcase_add_simple_test(tcase
, "set_value",
613 torture_tcase_add_simple_test(tcase
, "get_value",
615 torture_tcase_add_simple_test(tcase
, "list_values",
617 torture_tcase_add_simple_test(tcase
, "del_key",
619 torture_tcase_add_simple_test(tcase
, "del_value",
621 torture_tcase_add_simple_test(tcase
, "flush_key",
623 torture_tcase_add_simple_test(tcase
, "query_key",
625 torture_tcase_add_simple_test(tcase
, "query_key_nums",
626 test_query_key_nums
);
627 torture_tcase_add_simple_test(tcase
, "test_predef_key_by_name",
628 test_predef_key_by_name
);
629 torture_tcase_add_simple_test(tcase
, "security",
631 torture_tcase_add_simple_test(tcase
,"test_predef_key_by_name_invalid",
632 test_predef_key_by_name_invalid
);
635 struct torture_suite
*torture_registry_registry(TALLOC_CTX
*mem_ctx
)
637 struct torture_tcase
*tcase
;
638 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "registry");
640 tcase
= torture_suite_add_tcase(suite
, "local");
641 torture_tcase_set_fixture(tcase
, setup_local_registry
, NULL
);
642 tcase_add_tests(tcase
);