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"
31 * Test obtaining a predefined key.
33 static bool test_get_predefined(struct torture_context
*tctx
, void *_data
)
35 struct registry_context
*rctx
= (struct registry_context
*)_data
;
36 struct registry_key
*root
;
39 error
= reg_get_predefined_key(rctx
, HKEY_CLASSES_ROOT
, &root
);
40 torture_assert_werr_ok(tctx
, error
,
41 "getting predefined key failed");
46 * Test obtaining a predefined key.
48 static bool test_get_predefined_unknown(struct torture_context
*tctx
,
51 struct registry_context
*rctx
= _data
;
52 struct registry_key
*root
;
55 error
= reg_get_predefined_key(rctx
, 1337, &root
);
56 torture_assert_werr_equal(tctx
, error
, WERR_BADFILE
,
57 "getting predefined key failed");
61 static bool test_predef_key_by_name(struct torture_context
*tctx
, void *_data
)
63 struct registry_context
*rctx
= (struct registry_context
*)_data
;
64 struct registry_key
*root
;
67 error
= reg_get_predefined_key_by_name(rctx
, "HKEY_CLASSES_ROOT",
69 torture_assert_werr_ok(tctx
, error
,
70 "getting predefined key failed");
72 error
= reg_get_predefined_key_by_name(rctx
, "HKEY_classes_ROOT",
74 torture_assert_werr_ok(tctx
, error
,
75 "getting predefined key case insensitively failed");
80 static bool test_predef_key_by_name_invalid(struct torture_context
*tctx
,
83 struct registry_context
*rctx
= (struct registry_context
*)_data
;
84 struct registry_key
*root
;
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");
94 * Test creating a new subkey
96 static bool test_create_subkey(struct torture_context
*tctx
, void *_data
)
98 struct registry_context
*rctx
= (struct registry_context
*)_data
;
99 struct registry_key
*root
, *newkey
;
102 error
= reg_get_predefined_key(rctx
, HKEY_CLASSES_ROOT
, &root
);
103 torture_assert_werr_ok(tctx
, error
,
104 "getting predefined key failed");
106 error
= reg_key_add_name(rctx
, root
, "Bad Bentheim", NULL
, NULL
,
108 torture_assert_werr_ok(tctx
, error
, "Creating key return code");
109 torture_assert(tctx
, newkey
!= NULL
, "Creating new key");
115 * Test creating a new nested subkey
117 static bool test_create_nested_subkey(struct torture_context
*tctx
, void *_data
)
119 struct registry_context
*rctx
= (struct registry_context
*)_data
;
120 struct registry_key
*root
, *newkey1
, *newkey2
;
123 error
= reg_get_predefined_key(rctx
, HKEY_CLASSES_ROOT
, &root
);
124 torture_assert_werr_ok(tctx
, error
,
125 "getting predefined key failed");
127 error
= reg_key_add_name(rctx
, root
, "Hamburg", NULL
, NULL
,
129 torture_assert_werr_ok(tctx
, error
, "Creating key return code");
130 torture_assert(tctx
, newkey1
!= NULL
, "Creating new key");
132 error
= reg_key_add_name(rctx
, root
, "Hamburg\\Hamburg", NULL
, NULL
,
134 torture_assert_werr_ok(tctx
, error
, "Creating key return code");
135 torture_assert(tctx
, newkey2
!= NULL
, "Creating new key");
141 * Test creating a new subkey
143 static bool test_key_add_abs_top(struct torture_context
*tctx
, void *_data
)
145 struct registry_context
*rctx
= (struct registry_context
*)_data
;
146 struct registry_key
*root
;
149 error
= reg_key_add_abs(tctx
, rctx
, "HKEY_CLASSES_ROOT", 0, NULL
,
151 torture_assert_werr_equal(tctx
, error
, WERR_ALREADY_EXISTS
,
158 * Test creating a new subkey
160 static bool test_key_add_abs(struct torture_context
*tctx
, void *_data
)
163 struct registry_context
*rctx
= (struct registry_context
*)_data
;
164 struct registry_key
*root
, *result1
, *result2
;
166 error
= reg_key_add_abs(tctx
, rctx
, "HKEY_CLASSES_ROOT\\bloe", 0, NULL
,
168 torture_assert_werr_ok(tctx
, error
, "create lowest");
170 error
= reg_key_add_abs(tctx
, rctx
, "HKEY_CLASSES_ROOT\\bloe\\bla", 0,
172 torture_assert_werr_ok(tctx
, error
, "create nested");
174 error
= reg_get_predefined_key(rctx
, HKEY_CLASSES_ROOT
, &root
);
175 torture_assert_werr_ok(tctx
, error
,
176 "getting predefined key failed");
178 error
= reg_open_key(tctx
, root
, "bloe", &result2
);
179 torture_assert_werr_ok(tctx
, error
, "opening key");
181 error
= reg_open_key(tctx
, root
, "bloe\\bla", &result2
);
182 torture_assert_werr_ok(tctx
, error
, "opening key");
188 static bool test_del_key(struct torture_context
*tctx
, void *_data
)
190 struct registry_context
*rctx
= (struct registry_context
*)_data
;
191 struct registry_key
*root
, *newkey
;
194 error
= reg_get_predefined_key(rctx
, HKEY_CLASSES_ROOT
, &root
);
195 torture_assert_werr_ok(tctx
, error
,
196 "getting predefined key failed");
198 error
= reg_key_add_name(rctx
, root
, "Polen", NULL
, NULL
, &newkey
);
200 torture_assert_werr_ok(tctx
, error
, "Creating key return code");
201 torture_assert(tctx
, newkey
!= NULL
, "Creating new key");
203 error
= reg_key_del(root
, "Polen");
204 torture_assert_werr_ok(tctx
, error
, "Delete key");
206 error
= reg_key_del(root
, "Polen");
207 torture_assert_werr_equal(tctx
, error
, WERR_BADFILE
,
208 "Delete missing key");
214 * Convenience function for opening the HKEY_CLASSES_ROOT hive and
215 * creating a single key for testing purposes.
217 static bool create_test_key(struct torture_context
*tctx
,
218 struct registry_context
*rctx
,
220 struct registry_key
**root
,
221 struct registry_key
**subkey
)
225 error
= reg_get_predefined_key(rctx
, HKEY_CLASSES_ROOT
, root
);
226 torture_assert_werr_ok(tctx
, error
,
227 "getting predefined key failed");
229 error
= reg_key_add_name(rctx
, *root
, name
, NULL
, NULL
, subkey
);
230 torture_assert_werr_ok(tctx
, error
, "Creating key return code");
236 static bool test_flush_key(struct torture_context
*tctx
, void *_data
)
238 struct registry_context
*rctx
= (struct registry_context
*)_data
;
239 struct registry_key
*root
, *subkey
;
242 if (!create_test_key(tctx
, rctx
, "Bremen", &root
, &subkey
))
245 error
= reg_key_flush(subkey
);
246 torture_assert_werr_ok(tctx
, error
, "flush key");
248 torture_assert_werr_equal(tctx
, reg_key_flush(NULL
),
249 WERR_INVALID_PARAM
, "flush key");
254 static bool test_query_key(struct torture_context
*tctx
, void *_data
)
256 struct registry_context
*rctx
= (struct registry_context
*)_data
;
257 struct registry_key
*root
, *subkey
;
259 NTTIME last_changed_time
;
260 uint32_t num_subkeys
, num_values
;
261 const char *classname
;
263 if (!create_test_key(tctx
, rctx
, "Munchen", &root
, &subkey
))
266 error
= reg_key_get_info(tctx
, subkey
, &classname
,
267 &num_subkeys
, &num_values
,
268 &last_changed_time
, NULL
, NULL
, NULL
);
270 torture_assert_werr_ok(tctx
, error
, "get info key");
271 torture_assert(tctx
, classname
== NULL
, "classname");
272 torture_assert_int_equal(tctx
, num_subkeys
, 0, "num subkeys");
273 torture_assert_int_equal(tctx
, num_values
, 0, "num values");
278 static bool test_query_key_nums(struct torture_context
*tctx
, void *_data
)
280 struct registry_context
*rctx
= (struct registry_context
*)_data
;
281 struct registry_key
*root
, *subkey1
, *subkey2
;
283 uint32_t num_subkeys
, num_values
;
286 if (!create_test_key(tctx
, rctx
, "Berlin", &root
, &subkey1
))
289 error
= reg_key_add_name(rctx
, subkey1
, "Bentheim", NULL
, NULL
,
291 torture_assert_werr_ok(tctx
, error
, "Creating key return code");
293 error
= reg_val_set(subkey1
, "Answer", REG_DWORD
,
294 data_blob_talloc(tctx
, &data
, sizeof(data
)));
295 torture_assert_werr_ok(tctx
, error
, "set value");
297 error
= reg_key_get_info(tctx
, subkey1
, NULL
, &num_subkeys
,
298 &num_values
, NULL
, NULL
, NULL
, NULL
);
300 torture_assert_werr_ok(tctx
, error
, "get info key");
301 torture_assert_int_equal(tctx
, num_subkeys
, 1, "num subkeys");
302 torture_assert_int_equal(tctx
, num_values
, 1, "num values");
308 * Test that the subkeys of a key can be enumerated, that
309 * the returned parameters for get_subkey_by_index are optional and
310 * that enumerating the parents of a non-top-level node works.
312 static bool test_list_subkeys(struct torture_context
*tctx
, void *_data
)
314 struct registry_context
*rctx
= (struct registry_context
*)_data
;
315 struct registry_key
*subkey
= NULL
, *root
;
317 NTTIME last_mod_time
;
318 const char *classname
, *name
;
320 if (!create_test_key(tctx
, rctx
, "Goettingen", &root
, &subkey
))
323 error
= reg_key_get_subkey_by_index(tctx
, root
, 0, &name
, &classname
,
326 torture_assert_werr_ok(tctx
, error
, "Enum keys return code");
327 torture_assert_str_equal(tctx
, name
, "Goettingen", "Enum keys data");
330 error
= reg_key_get_subkey_by_index(tctx
, root
, 0, NULL
, NULL
, NULL
);
332 torture_assert_werr_ok(tctx
, error
,
333 "Enum keys with NULL arguments return code");
335 error
= reg_key_get_subkey_by_index(tctx
, root
, 1, NULL
, NULL
, NULL
);
337 torture_assert_werr_equal(tctx
, error
, WERR_NO_MORE_ITEMS
,
338 "Invalid error for no more items");
340 error
= reg_key_get_subkey_by_index(tctx
, subkey
, 0, NULL
, NULL
, NULL
);
342 torture_assert_werr_equal(tctx
, error
, WERR_NO_MORE_ITEMS
,
343 "Invalid error for no more items");
349 * Test setting a value
351 static bool test_set_value(struct torture_context
*tctx
, void *_data
)
353 struct registry_context
*rctx
= (struct registry_context
*)_data
;
354 struct registry_key
*subkey
= NULL
, *root
;
358 if (!create_test_key(tctx
, rctx
, "Dusseldorf", &root
, &subkey
))
361 error
= reg_val_set(subkey
, "Answer", REG_DWORD
,
362 data_blob_talloc(tctx
, &data
, sizeof(data
)));
363 torture_assert_werr_ok (tctx
, error
, "setting value");
369 * Test getting/setting security descriptors
371 static bool test_security(struct torture_context
*tctx
, void *_data
)
373 struct registry_context
*rctx
= (struct registry_context
*)_data
;
374 struct registry_key
*subkey
= NULL
, *root
;
376 struct security_descriptor
*osd
, *nsd
;
378 if (!create_test_key(tctx
, rctx
, "Düsseldorf", &root
, &subkey
))
381 osd
= security_descriptor_dacl_create(tctx
,
384 SID_NT_AUTHENTICATED_USERS
,
385 SEC_ACE_TYPE_ACCESS_ALLOWED
,
387 SEC_ACE_FLAG_OBJECT_INHERIT
,
390 error
= reg_set_sec_desc(subkey
, osd
);
391 torture_assert_werr_ok(tctx
, error
, "setting security descriptor");
393 error
= reg_get_sec_desc(tctx
, subkey
, &nsd
);
394 torture_assert_werr_ok (tctx
, error
, "getting security descriptor");
396 torture_assert(tctx
, security_descriptor_equal(osd
, nsd
),
397 "security descriptor changed!");
403 * Test getting a value
405 static bool test_get_value(struct torture_context
*tctx
, void *_data
)
407 struct registry_context
*rctx
= (struct registry_context
*)_data
;
408 struct registry_key
*subkey
= NULL
, *root
;
414 if (!create_test_key(tctx
, rctx
, "Duisburg", &root
, &subkey
))
417 error
= reg_key_get_value_by_name(tctx
, subkey
, __FUNCTION__
, &type
,
419 torture_assert_werr_equal(tctx
, error
, WERR_BADFILE
,
420 "getting missing value");
422 error
= reg_val_set(subkey
, __FUNCTION__
, REG_DWORD
,
423 data_blob_talloc(tctx
, &value
, 4));
424 torture_assert_werr_ok(tctx
, error
, "setting value");
426 error
= reg_key_get_value_by_name(tctx
, subkey
, __FUNCTION__
, &type
,
428 torture_assert_werr_ok(tctx
, error
, "getting value");
430 torture_assert_int_equal(tctx
, 4, data
.length
, "value length ok");
431 torture_assert_mem_equal(tctx
, data
.data
, &value
, 4,
433 torture_assert_int_equal(tctx
, REG_DWORD
, type
, "value type");
439 * Test unsetting a value
441 static bool test_del_value(struct torture_context
*tctx
, void *_data
)
443 struct registry_context
*rctx
=(struct registry_context
*)_data
;
444 struct registry_key
*subkey
= NULL
, *root
;
450 if (!create_test_key(tctx
, rctx
, "Warschau", &root
, &subkey
))
453 error
= reg_key_get_value_by_name(tctx
, subkey
, __FUNCTION__
, &type
,
455 torture_assert_werr_equal(tctx
, error
, WERR_BADFILE
,
456 "getting missing value");
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");
462 error
= reg_del_value(subkey
, __FUNCTION__
);
463 torture_assert_werr_ok (tctx
, error
, "unsetting value");
465 error
= reg_key_get_value_by_name(tctx
, subkey
, __FUNCTION__
,
467 torture_assert_werr_equal(tctx
, error
, WERR_BADFILE
,
468 "getting missing value");
474 * Test listing values
476 static bool test_list_values(struct torture_context
*tctx
, void *_data
)
478 struct registry_context
*rctx
= (struct registry_context
*)_data
;
479 struct registry_key
*subkey
= NULL
, *root
;
486 if (!create_test_key(tctx
, rctx
, "Bonn", &root
, &subkey
))
489 error
= reg_val_set(subkey
, "bar", REG_DWORD
,
490 data_blob_talloc(tctx
, &value
, 4));
491 torture_assert_werr_ok (tctx
, error
, "setting value");
493 error
= reg_key_get_value_by_index(tctx
, subkey
, 0, &name
,
495 torture_assert_werr_ok(tctx
, error
, "getting value");
497 torture_assert_str_equal(tctx
, name
, "bar", "value name");
498 torture_assert_int_equal(tctx
, 4, data
.length
, "value length");
499 torture_assert_mem_equal(tctx
, data
.data
, &value
, 4,
501 torture_assert_int_equal(tctx
, REG_DWORD
, type
, "value type");
503 error
= reg_key_get_value_by_index(tctx
, subkey
, 1, &name
,
505 torture_assert_werr_equal(tctx
, error
, WERR_NO_MORE_ITEMS
,
506 "getting missing value");
511 static bool setup_local_registry(struct torture_context
*tctx
, void **data
)
513 struct registry_context
*rctx
;
517 struct hive_key
*hive_key
;
518 const char *filename
;
520 error
= reg_open_local(tctx
, &rctx
, NULL
, NULL
);
521 torture_assert_werr_ok(tctx
, error
, "Opening local registry failed");
523 status
= torture_temp_dir(tctx
, "registry-local", &tempdir
);
524 torture_assert_ntstatus_ok(tctx
, status
, "Creating temp dir failed");
526 filename
= talloc_asprintf(tctx
, "%s/classes_root.ldb", tempdir
);
527 error
= reg_open_ldb_file(tctx
, filename
, NULL
, NULL
, tctx
->lp_ctx
, &hive_key
);
528 torture_assert_werr_ok(tctx
, error
, "Opening classes_root file failed");
530 error
= reg_mount_hive(rctx
, hive_key
, HKEY_CLASSES_ROOT
, NULL
);
531 torture_assert_werr_ok(tctx
, error
, "Mounting hive failed");
538 static void tcase_add_tests(struct torture_tcase
*tcase
)
540 torture_tcase_add_simple_test(tcase
, "list_subkeys",
542 torture_tcase_add_simple_test(tcase
, "get_predefined_key",
543 test_get_predefined
);
544 torture_tcase_add_simple_test(tcase
, "get_predefined_key",
545 test_get_predefined_unknown
);
546 torture_tcase_add_simple_test(tcase
, "create_key",
548 torture_tcase_add_simple_test(tcase
, "create_key",
549 test_create_nested_subkey
);
550 torture_tcase_add_simple_test(tcase
, "key_add_abs",
552 torture_tcase_add_simple_test(tcase
, "key_add_abs_top",
553 test_key_add_abs_top
);
554 torture_tcase_add_simple_test(tcase
, "set_value",
556 torture_tcase_add_simple_test(tcase
, "get_value",
558 torture_tcase_add_simple_test(tcase
, "list_values",
560 torture_tcase_add_simple_test(tcase
, "del_key",
562 torture_tcase_add_simple_test(tcase
, "del_value",
564 torture_tcase_add_simple_test(tcase
, "flush_key",
566 torture_tcase_add_simple_test(tcase
, "query_key",
568 torture_tcase_add_simple_test(tcase
, "query_key_nums",
569 test_query_key_nums
);
570 torture_tcase_add_simple_test(tcase
, "test_predef_key_by_name",
571 test_predef_key_by_name
);
572 torture_tcase_add_simple_test(tcase
, "security",
574 torture_tcase_add_simple_test(tcase
,"test_predef_key_by_name_invalid",
575 test_predef_key_by_name_invalid
);
578 struct torture_suite
*torture_registry_registry(TALLOC_CTX
*mem_ctx
)
580 struct torture_tcase
*tcase
;
581 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "REGISTRY");
583 tcase
= torture_suite_add_tcase(suite
, "local");
584 torture_tcase_set_fixture(tcase
, setup_local_registry
, NULL
);
585 tcase_add_tests(tcase
);