Use correct size for test string, sizeof() was of the pointer
[obnox/samba/samba-obnox.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 3 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 "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"
30
31 /**
32  * Test obtaining a predefined key.
33  */
34 static bool test_get_predefined(struct torture_context *tctx, void *_data)
35 {
36         struct registry_context *rctx = (struct registry_context *)_data;
37         struct registry_key *root;
38         WERROR error;
39
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;
44 }
45
46 /**
47  * Test obtaining a predefined key.
48  */
49 static bool test_get_predefined_unknown(struct torture_context *tctx,
50                 void *_data)
51 {
52         struct registry_context *rctx = _data;
53         struct registry_key *root;
54         WERROR error;
55
56         error = reg_get_predefined_key(rctx, 1337, &root);
57         torture_assert_werr_equal(tctx, error, WERR_BADFILE,
58                                   "getting predefined key failed");
59         return true;
60 }
61
62 static bool test_predef_key_by_name(struct torture_context *tctx, void *_data)
63 {
64         struct registry_context *rctx = (struct registry_context *)_data;
65         struct registry_key *root;
66         WERROR error;
67
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");
72
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");
77
78         return true;
79 }
80
81 static bool test_predef_key_by_name_invalid(struct torture_context *tctx,
82                 void *_data)
83 {
84         struct registry_context *rctx = (struct registry_context *)_data;
85         struct registry_key *root;
86         WERROR error;
87
88         error = reg_get_predefined_key_by_name(rctx, "BLA", &root);
89         torture_assert_werr_equal(tctx, error, WERR_BADFILE,
90                                   "getting predefined key failed");
91         return true;
92 }
93
94 /**
95  * Test creating a new subkey
96  */
97 static bool test_create_subkey(struct torture_context *tctx, void *_data)
98 {
99         struct registry_context *rctx = (struct registry_context *)_data;
100         struct registry_key *root, *newkey;
101         WERROR error;
102
103         error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
104         torture_assert_werr_ok(tctx, error,
105                                "getting predefined key failed");
106
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");
111
112         return true;
113 }
114
115 /**
116  * Test creating a new nested subkey
117  */
118 static bool test_create_nested_subkey(struct torture_context *tctx, void *_data)
119 {
120         struct registry_context *rctx = (struct registry_context *)_data;
121         struct registry_key *root, *newkey;
122         WERROR error;
123
124         error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
125         torture_assert_werr_ok(tctx, error,
126                                "getting predefined key failed");
127
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");
132
133         return true;
134 }
135
136 /**
137  * Test creating a new subkey
138  */
139 static bool test_key_add_abs_top(struct torture_context *tctx, void *_data)
140 {
141         struct registry_context *rctx = (struct registry_context *)_data;
142         struct registry_key *root;
143         WERROR error;
144
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");
149
150         return true;
151 }
152
153 /**
154  * Test creating a new subkey
155  */
156 static bool test_key_add_abs(struct torture_context *tctx, void *_data)
157 {
158         WERROR error;
159         struct registry_context *rctx = (struct registry_context *)_data;
160         struct registry_key *root, *result1, *result2;
161
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");
165
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");
169
170         error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
171         torture_assert_werr_ok(tctx, error,
172                                "getting predefined key failed");
173
174         error = reg_open_key(tctx, root, "bloe", &result2);
175         torture_assert_werr_ok(tctx, error, "opening key");
176
177         error = reg_open_key(tctx, root, "bloe\\bla", &result2);
178         torture_assert_werr_ok(tctx, error, "opening key");
179
180         return true;
181 }
182
183
184 static bool test_del_key(struct torture_context *tctx, void *_data)
185 {
186         struct registry_context *rctx = (struct registry_context *)_data;
187         struct registry_key *root, *newkey;
188         WERROR error;
189
190         error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root);
191         torture_assert_werr_ok(tctx, error,
192                                "getting predefined key failed");
193
194         error = reg_key_add_name(rctx, root, "Polen", NULL, NULL, &newkey);
195
196         torture_assert_werr_ok(tctx, error, "Creating key return code");
197         torture_assert(tctx, newkey != NULL, "Creating new key");
198
199         error = reg_key_del(tctx, root, "Polen");
200         torture_assert_werr_ok(tctx, error, "Delete key");
201
202         error = reg_key_del(tctx, root, "Polen");
203         torture_assert_werr_equal(tctx, error, WERR_BADFILE,
204                                   "Delete missing key");
205
206         return true;
207 }
208
209 /**
210  * Convenience function for opening the HKEY_CLASSES_ROOT hive and
211  * creating a single key for testing purposes.
212  */
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)
218 {
219         WERROR error;
220
221         error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, root);
222         torture_assert_werr_ok(tctx, error,
223                                "getting predefined key failed");
224
225         error = reg_key_add_name(rctx, *root, name, NULL, NULL, subkey);
226         torture_assert_werr_ok(tctx, error, "Creating key return code");
227
228         return true;
229 }
230
231
232 static bool test_flush_key(struct torture_context *tctx, void *_data)
233 {
234         struct registry_context *rctx = (struct registry_context *)_data;
235         struct registry_key *root, *subkey;
236         WERROR error;
237
238         if (!create_test_key(tctx, rctx, "Bremen", &root, &subkey))
239                 return false;
240
241         error = reg_key_flush(subkey);
242         torture_assert_werr_ok(tctx, error, "flush key");
243
244         torture_assert_werr_equal(tctx, reg_key_flush(NULL),
245                                   WERR_INVALID_PARAM, "flush key");
246
247         return true;
248 }
249
250 static bool test_query_key(struct torture_context *tctx, void *_data)
251 {
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";
259
260         if (!create_test_key(tctx, rctx, "Muenchen", &root, &subkey))
261                 return false;
262
263         error = reg_key_get_info(tctx, subkey, &classname,
264                                  &num_subkeys, &num_values,
265                                  &last_changed_time, NULL, NULL, NULL);
266
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");
271
272         error = reg_val_set(subkey, "", REG_SZ,
273                             data_blob_string_const(data));
274         torture_assert_werr_ok(tctx, error, "set default value");
275
276         error = reg_key_get_info(tctx, subkey, &classname,
277                                  &num_subkeys, &num_values,
278                                  &last_changed_time, NULL, NULL, NULL);
279
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");
284
285         return true;
286 }
287
288 static bool test_query_key_nums(struct torture_context *tctx, void *_data)
289 {
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);
296
297         if (!create_test_key(tctx, rctx, "Berlin", &root, &subkey1))
298                 return false;
299
300         error = reg_key_add_name(rctx, subkey1, "Bentheim", NULL, NULL,
301                                  &subkey2);
302         torture_assert_werr_ok(tctx, error, "Creating key return code");
303
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");
307
308         error = reg_key_get_info(tctx, subkey1, NULL, &num_subkeys,
309                                  &num_values, NULL, NULL, NULL, NULL);
310
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");
314
315         return true;
316 }
317
318 /**
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.
322  */
323 static bool test_list_subkeys(struct torture_context *tctx, void *_data)
324 {
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;
330
331         if (!create_test_key(tctx, rctx, "Goettingen", &root, &subkey))
332                 return false;
333
334         error = reg_key_get_subkey_by_index(tctx, root, 0, &name, &classname,
335                                             &last_mod_time);
336
337         torture_assert_werr_ok(tctx, error, "Enum keys return code");
338         torture_assert_str_equal(tctx, name, "Goettingen", "Enum keys data");
339
340
341         error = reg_key_get_subkey_by_index(tctx, root, 0, NULL, NULL, NULL);
342
343         torture_assert_werr_ok(tctx, error,
344                                "Enum keys with NULL arguments return code");
345
346         error = reg_key_get_subkey_by_index(tctx, root, 1, NULL, NULL, NULL);
347
348         torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS,
349                                   "Invalid error for no more items");
350
351         error = reg_key_get_subkey_by_index(tctx, subkey, 0, NULL, NULL, NULL);
352
353         torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS,
354                                   "Invalid error for no more items");
355
356         return true;
357 }
358
359 /**
360  * Test setting a value
361  */
362 static bool test_set_value(struct torture_context *tctx, void *_data)
363 {
364         struct registry_context *rctx = (struct registry_context *)_data;
365         struct registry_key *subkey = NULL, *root;
366         WERROR error;
367         char data[4];
368
369         SIVAL(data, 0, 42);
370
371         if (!create_test_key(tctx, rctx, "Dusseldorf", &root, &subkey))
372                 return false;
373
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");
377
378         return true;
379 }
380
381 /**
382  * Test getting/setting security descriptors
383  */
384 static bool test_security(struct torture_context *tctx, void *_data)
385 {
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;
390
391         if (!create_test_key(tctx, rctx, "Düsseldorf", &root, &subkey))
392                 return false;
393
394         osd = security_descriptor_dacl_create(tctx,
395                                          0,
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);
402
403         error = reg_set_sec_desc(subkey, osd);
404         torture_assert_werr_ok(tctx, error, "setting security descriptor");
405
406         error = reg_get_sec_desc(tctx, subkey, &nsd);
407         torture_assert_werr_ok (tctx, error, "getting security descriptor");
408
409         torture_assert(tctx, security_descriptor_equal(osd, nsd),
410                        "security descriptor changed!");
411
412         return true;
413 }
414
415 /**
416  * Test getting a value
417  */
418 static bool test_get_value(struct torture_context *tctx, void *_data)
419 {
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";
427
428         SIVAL(value, 0, 42);
429
430         if (!create_test_key(tctx, rctx, "Duisburg", &root, &subkey))
431                 return false;
432
433         error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type,
434                                           &data);
435         torture_assert_werr_equal(tctx, error, WERR_BADFILE,
436                                   "getting missing value");
437
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");
441
442         error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type,
443                                           &data);
444         torture_assert_werr_ok(tctx, error, "getting value");
445
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");
450
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");
455
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");
462
463         return true;
464 }
465
466 /**
467  * Test unsetting a value
468  */
469 static bool test_del_value(struct torture_context *tctx, void *_data)
470 {
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";
478
479         SIVAL(value, 0, 42);
480
481         if (!create_test_key(tctx, rctx, "Warschau", &root, &subkey))
482                 return false;
483
484         error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type,
485                                           &data);
486         torture_assert_werr_equal(tctx, error, WERR_BADFILE,
487                                   "getting missing value");
488
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");
492
493         error = reg_del_value(tctx, subkey, __FUNCTION__);
494         torture_assert_werr_ok (tctx, error, "unsetting value");
495
496         error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__,
497                                           &type, &data);
498         torture_assert_werr_equal(tctx, error, WERR_BADFILE,
499                                   "getting missing value");
500
501         error = reg_del_value(tctx, subkey, "");
502         torture_assert_werr_equal(tctx, error, WERR_BADFILE,
503                                   "unsetting missing default value");
504
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");
509
510         error = reg_del_value(tctx, subkey, "");
511         torture_assert_werr_ok (tctx, error, "unsetting default value");
512
513         return true;
514 }
515
516 /**
517  * Test listing values
518  */
519 static bool test_list_values(struct torture_context *tctx, void *_data)
520 {
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";
529
530         SIVAL(value, 0, 42);
531
532         if (!create_test_key(tctx, rctx, "Bonn", &root, &subkey))
533                 return false;
534
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");
538
539         error = reg_key_get_value_by_index(tctx, subkey, 0, &name,
540                                            &type, &data);
541         torture_assert_werr_ok(tctx, error, "getting value");
542
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");
548
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");
553
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");
557
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");
564
565         return true;
566 }
567
568 static bool setup_local_registry(struct torture_context *tctx, void **data)
569 {
570         struct registry_context *rctx;
571         WERROR error;
572         char *tempdir;
573         NTSTATUS status;
574         struct hive_key *hive_key;
575         const char *filename;
576
577         error = reg_open_local(tctx, &rctx);
578         torture_assert_werr_ok(tctx, error, "Opening local registry failed");
579
580         status = torture_temp_dir(tctx, "registry-local", &tempdir);
581         torture_assert_ntstatus_ok(tctx, status, "Creating temp dir failed");
582
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");
586
587         error = reg_mount_hive(rctx, hive_key, HKEY_CLASSES_ROOT, NULL);
588         torture_assert_werr_ok(tctx, error, "Mounting hive failed");
589
590         *data = rctx;
591
592         return true;
593 }
594
595 static void tcase_add_tests(struct torture_tcase *tcase)
596 {
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);
633 }
634
635 struct torture_suite *torture_registry_registry(TALLOC_CTX *mem_ctx)
636 {
637         struct torture_tcase *tcase;
638         struct torture_suite *suite = torture_suite_create(mem_ctx, "registry");
639
640         tcase = torture_suite_add_tcase(suite, "local");
641         torture_tcase_set_fixture(tcase, setup_local_registry, NULL);
642         tcase_add_tests(tcase);
643
644         return suite;
645 }