WHATSNEW: SMB3 Directory Leases
[Samba.git] / source4 / lib / registry / tests / registry.c
blob4d94b5ace743b3c0119a478a957326bd129c62dc
1 /*
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.
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 #include "lib/registry/tests/proto.h"
31 /**
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;
38 WERROR error;
40 error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
41 torture_assert_werr_ok(tctx, error,
42 "getting predefined key failed");
43 return true;
46 /**
47 * Test obtaining a predefined key.
49 static bool test_get_predefined_unknown(struct torture_context *tctx,
50 void *_data)
52 struct registry_context *rctx = _data;
53 struct registry_key *root;
54 WERROR error;
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");
59 return true;
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;
66 WERROR error;
68 error = reg_get_predefined_key_by_name(rctx, "HKEY_CLASSES_ROOT",
69 &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",
74 &root);
75 torture_assert_werr_ok(tctx, error,
76 "getting predefined key case insensitively failed");
78 return true;
81 static bool test_predef_key_by_name_invalid(struct torture_context *tctx,
82 void *_data)
84 struct registry_context *rctx = (struct registry_context *)_data;
85 struct registry_key *root;
86 WERROR error;
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");
91 return true;
94 /**
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;
101 WERROR error;
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,
108 &newkey);
109 torture_assert_werr_ok(tctx, error, "Creating key return code");
110 torture_assert(tctx, newkey != NULL, "Creating new key");
112 return true;
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;
122 WERROR error;
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,
129 &newkey);
130 torture_assert_werr_ok(tctx, error, "Creating key return code");
131 torture_assert(tctx, newkey != NULL, "Creating new key");
133 return true;
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;
143 WERROR error;
145 error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT", 0, NULL,
146 &root);
147 torture_assert_werr_equal(tctx, error, WERR_ALREADY_EXISTS,
148 "create top level");
150 return true;
154 * Test creating a new subkey
156 static bool test_key_add_abs(struct torture_context *tctx, void *_data)
158 WERROR error;
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,
163 &result1);
164 torture_assert_werr_ok(tctx, error, "create lowest");
166 error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT\\bloe\\bla", 0,
167 NULL, &result1);
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");
180 return true;
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;
188 WERROR error;
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");
206 return true;
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,
215 const char *name,
216 struct registry_key **root,
217 struct registry_key **subkey)
219 WERROR error;
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");
228 return true;
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;
236 WERROR error;
238 if (!create_test_key(tctx, rctx, "Bremen", &root, &subkey))
239 return false;
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");
247 return true;
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;
254 WERROR error;
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))
261 return false;
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");
285 return true;
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;
292 WERROR error;
293 uint32_t num_subkeys, num_values;
294 char data[4];
295 SIVAL(data, 0, 42);
297 if (!create_test_key(tctx, rctx, "Berlin", &root, &subkey1))
298 return false;
300 error = reg_key_add_name(rctx, subkey1, "Bentheim", NULL, NULL,
301 &subkey2);
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");
315 return true;
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;
327 WERROR error;
328 NTTIME last_mod_time;
329 const char *classname, *name;
331 if (!create_test_key(tctx, rctx, "Goettingen", &root, &subkey))
332 return false;
334 error = reg_key_get_subkey_by_index(tctx, root, 0, &name, &classname,
335 &last_mod_time);
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");
356 return true;
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;
366 WERROR error;
367 char data[4];
369 SIVAL(data, 0, 42);
371 if (!create_test_key(tctx, rctx, "Dusseldorf", &root, &subkey))
372 return false;
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");
378 return true;
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;
388 WERROR error;
389 struct security_descriptor *osd, *nsd;
391 if (!create_test_key(tctx, rctx, "Düsseldorf", &root, &subkey))
392 return false;
394 osd = security_descriptor_dacl_create(tctx,
396 NULL, NULL,
397 SID_NT_AUTHENTICATED_USERS,
398 SEC_ACE_TYPE_ACCESS_ALLOWED,
399 SEC_GENERIC_ALL,
400 SEC_ACE_FLAG_OBJECT_INHERIT,
401 NULL);
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!");
412 return true;
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;
422 WERROR error;
423 DATA_BLOB data;
424 char value[4];
425 uint32_t type;
426 const char *data_val = "temp";
428 SIVAL(value, 0, 42);
430 if (!create_test_key(tctx, rctx, "Duisburg", &root, &subkey))
431 return false;
433 error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type,
434 &data);
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,
443 &data);
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),
448 "value content ok");
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,
453 strlen(data_val)));
454 torture_assert_werr_ok(tctx, error, "set default value");
456 error = reg_key_get_value_by_name(tctx, subkey, "", &type,
457 &data);
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");
463 return true;
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;
473 WERROR error;
474 DATA_BLOB data;
475 uint32_t type;
476 char value[4];
477 const char *data_val = "temp";
479 SIVAL(value, 0, 42);
481 if (!create_test_key(tctx, rctx, "Warschau", &root, &subkey))
482 return false;
484 error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type,
485 &data);
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__,
497 &type, &data);
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,
507 strlen(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");
513 return true;
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;
523 WERROR error;
524 DATA_BLOB data;
525 uint32_t type;
526 const char *name;
527 char value[4];
528 const char *data_val = "temp";
530 SIVAL(value, 0, 42);
532 if (!create_test_key(tctx, rctx, "Bonn", &root, &subkey))
533 return false;
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,
540 &type, &data);
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),
546 "value content");
547 torture_assert_int_equal(tctx, REG_DWORD, type, "value type");
549 error = reg_key_get_value_by_index(tctx, subkey, 1, &name,
550 &type, &data);
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,
559 &type, &data);
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");
565 return true;
568 static bool setup_local_registry(struct torture_context *tctx, void **data)
570 struct registry_context *rctx;
571 WERROR error;
572 char *tempdir;
573 NTSTATUS status;
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");
590 *data = rctx;
592 return true;
595 static void tcase_add_tests(struct torture_tcase *tcase)
597 torture_tcase_add_simple_test(tcase, "list_subkeys",
598 test_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",
604 test_create_subkey);
605 torture_tcase_add_simple_test(tcase, "create_key",
606 test_create_nested_subkey);
607 torture_tcase_add_simple_test(tcase, "key_add_abs",
608 test_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",
612 test_set_value);
613 torture_tcase_add_simple_test(tcase, "get_value",
614 test_get_value);
615 torture_tcase_add_simple_test(tcase, "list_values",
616 test_list_values);
617 torture_tcase_add_simple_test(tcase, "del_key",
618 test_del_key);
619 torture_tcase_add_simple_test(tcase, "del_value",
620 test_del_value);
621 torture_tcase_add_simple_test(tcase, "flush_key",
622 test_flush_key);
623 torture_tcase_add_simple_test(tcase, "query_key",
624 test_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",
630 test_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);
644 return suite;