s4-smbtorture: Make test names lowercase and dot-separated.
[metze/samba/wip.git] / source4 / lib / registry / tests / hive.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    local testing of registry library - hives
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 "system/filesys.h"
28 #include "param/param.h"
29 #include "libcli/security/security.h"
30
31 static bool test_del_nonexistant_key(struct torture_context *tctx,
32                                      const void *test_data)
33 {
34         const struct hive_key *root = (const struct hive_key *)test_data;
35         WERROR error = hive_key_del(tctx, root, "bla");
36         torture_assert_werr_equal(tctx, error, WERR_BADFILE,
37                                   "invalid return code");
38
39         return true;
40 }
41
42 static bool test_keyinfo_root(struct torture_context *tctx,
43                               const void *test_data)
44 {
45         uint32_t num_subkeys, num_values;
46         const struct hive_key *root = (const struct hive_key *)test_data;
47         WERROR error;
48
49         /* This is a new backend. There should be no subkeys and no
50          * values */
51         error = hive_key_get_info(tctx, root, NULL, &num_subkeys, &num_values,
52                                   NULL, NULL, NULL, NULL);
53         torture_assert_werr_ok(tctx, error, "reg_key_num_subkeys()");
54
55         torture_assert_int_equal(tctx, num_subkeys, 0,
56                                  "New key has non-zero subkey count");
57
58         torture_assert_werr_ok(tctx, error, "reg_key_num_values");
59
60         torture_assert_int_equal(tctx, num_values, 0,
61                                  "New key has non-zero value count");
62
63         return true;
64 }
65
66 static bool test_keyinfo_nums(struct torture_context *tctx, void *test_data)
67 {
68         uint32_t num_subkeys, num_values;
69         struct hive_key *root = (struct hive_key *)test_data;
70         WERROR error;
71         struct hive_key *subkey;
72         uint8_t d[] = { 0x42, 0x00, 0x00, 0x00 };
73         DATA_BLOB db = { d, 4 };
74
75         error = hive_key_add_name(tctx, root, "Nested Keyll", NULL,
76                                   NULL, &subkey);
77         torture_assert_werr_ok(tctx, error, "hive_key_add_name");
78
79         error = hive_key_set_value(root, "Answer", REG_DWORD, db);
80         torture_assert_werr_ok(tctx, error, "hive_key_set_value");
81
82         /* This is a new backend. There should be no subkeys and no
83          * values */
84         error = hive_key_get_info(tctx, root, NULL, &num_subkeys, &num_values,
85                                   NULL, NULL, NULL, NULL);
86         torture_assert_werr_ok(tctx, error, "reg_key_num_subkeys()");
87
88         torture_assert_int_equal(tctx, num_subkeys, 1, "subkey count");
89
90         torture_assert_werr_ok(tctx, error, "reg_key_num_values");
91
92         torture_assert_int_equal(tctx, num_values, 1, "value count");
93
94         return true;
95 }
96
97 static bool test_add_subkey(struct torture_context *tctx,
98                             const void *test_data)
99 {
100         WERROR error;
101         struct hive_key *subkey;
102         const struct hive_key *root = (const struct hive_key *)test_data;
103         TALLOC_CTX *mem_ctx = tctx;
104
105         error = hive_key_add_name(mem_ctx, root, "Nested Key", NULL,
106                                   NULL, &subkey);
107         torture_assert_werr_ok(tctx, error, "hive_key_add_name");
108
109         error = hive_key_del(mem_ctx, root, "Nested Key");
110         torture_assert_werr_ok(tctx, error, "reg_key_del");
111
112         return true;
113 }
114
115 static bool test_del_recursive(struct torture_context *tctx,
116                                const void *test_data)
117 {
118         WERROR error;
119         struct hive_key *subkey;
120         struct hive_key *subkey2;
121         const struct hive_key *root = (const struct hive_key *)test_data;
122         TALLOC_CTX *mem_ctx = tctx;
123         uint8_t d[] = { 0x42, 0x00, 0x00, 0x00 };
124         DATA_BLOB db = { d, 4 };
125
126         /* Create a new key under the root */
127         error = hive_key_add_name(mem_ctx, root, "Parent Key", NULL,
128                                   NULL, &subkey);
129         torture_assert_werr_ok(tctx, error, "hive_key_add_name");
130
131         /* Create a new key under "Parent Key" */
132         error = hive_key_add_name(mem_ctx, subkey, "Child Key", NULL,
133                                   NULL, &subkey2);
134         torture_assert_werr_ok(tctx, error, "hive_key_add_name");
135
136         /* Create a new value under "Child Key" */
137         error = hive_key_set_value(subkey2, "Answer Recursive", REG_DWORD, db);
138         torture_assert_werr_ok(tctx, error, "hive_key_set_value");
139
140         /* Deleting "Parent Key" will also delete "Child Key" and the value. */
141         error = hive_key_del(mem_ctx, root, "Parent Key");
142         torture_assert_werr_ok(tctx, error, "hive_key_del");
143
144         return true;
145 }
146
147 static bool test_flush_key(struct torture_context *tctx, void *test_data)
148 {
149         struct hive_key *root = (struct hive_key *)test_data;
150
151         torture_assert_werr_ok(tctx, hive_key_flush(root), "flush key");
152
153         return true;
154 }
155
156 static bool test_del_key(struct torture_context *tctx, const void *test_data)
157 {
158         WERROR error;
159         struct hive_key *subkey;
160         const struct hive_key *root = (const struct hive_key *)test_data;
161         TALLOC_CTX *mem_ctx = tctx;
162
163         error = hive_key_add_name(mem_ctx, root, "Nested Key", NULL,
164                                   NULL, &subkey);
165         torture_assert_werr_ok(tctx, error, "hive_key_add_name");
166
167         error = hive_key_del(mem_ctx, root, "Nested Key");
168         torture_assert_werr_ok(tctx, error, "reg_key_del");
169
170         error = hive_key_del(mem_ctx, root, "Nested Key");
171         torture_assert_werr_equal(tctx, error, WERR_BADFILE, "reg_key_del");
172
173         return true;
174 }
175
176 static bool test_set_value(struct torture_context *tctx,
177                            const void *test_data)
178 {
179         WERROR error;
180         struct hive_key *subkey;
181         const struct hive_key *root = (const struct hive_key *)test_data;
182         TALLOC_CTX *mem_ctx = tctx;
183         uint8_t d[] = { 0x42, 0x00, 0x00, 0x00 };
184         DATA_BLOB db = { d, 4 };
185
186         error = hive_key_add_name(mem_ctx, root, "YA Nested Key", NULL,
187                                   NULL, &subkey);
188         torture_assert_werr_ok(tctx, error, "hive_key_add_name");
189
190         error = hive_key_set_value(subkey, "Answer", REG_DWORD, db);
191         torture_assert_werr_ok(tctx, error, "hive_key_set_value");
192
193         return true;
194 }
195
196 static bool test_get_value(struct torture_context *tctx, const void *test_data)
197 {
198         WERROR error;
199         struct hive_key *subkey;
200         const struct hive_key *root = (const struct hive_key *)test_data;
201         TALLOC_CTX *mem_ctx = tctx;
202         uint32_t type;
203         uint8_t d[] = { 0x42, 0x00, 0x00, 0x00 };
204         DATA_BLOB db = { d, 4 }, data;
205
206         error = hive_key_add_name(mem_ctx, root, "EYA Nested Key", NULL,
207                                   NULL, &subkey);
208         torture_assert_werr_ok(tctx, error, "hive_key_add_name");
209
210         error = hive_get_value(mem_ctx, subkey, "Answer", &type, &data);
211         torture_assert_werr_equal(tctx, error, WERR_BADFILE,
212                                   "getting missing value");
213
214         error = hive_key_set_value(subkey, "Answer", REG_DWORD, db);
215         torture_assert_werr_ok(tctx, error, "hive_key_set_value");
216
217         error = hive_get_value(mem_ctx, subkey, "Answer", &type, &data);
218         torture_assert_werr_ok(tctx, error, "getting value");
219
220         torture_assert_int_equal(tctx, data.length, 4, "value length");
221         torture_assert_int_equal(tctx, type, REG_DWORD, "value type");
222
223         torture_assert_mem_equal(tctx, data.data, db.data, 4, "value data");
224
225         return true;
226 }
227
228 static bool test_del_value(struct torture_context *tctx, const void *test_data)
229 {
230         WERROR error;
231         struct hive_key *subkey;
232         const struct hive_key *root = (const struct hive_key *)test_data;
233         TALLOC_CTX *mem_ctx = tctx;
234         uint32_t type;
235         uint8_t d[] = { 0x42, 0x00, 0x00, 0x00 };
236         DATA_BLOB db = { d, 4 };
237
238         error = hive_key_add_name(mem_ctx, root, "EEYA Nested Key", NULL,
239                                                          NULL, &subkey);
240         torture_assert_werr_ok(tctx, error, "hive_key_add_name");
241
242         error = hive_key_set_value(subkey, "Answer", REG_DWORD, db);
243         torture_assert_werr_ok(tctx, error, "hive_key_set_value");
244
245         error = hive_key_del_value(mem_ctx, subkey, "Answer");
246         torture_assert_werr_ok(tctx, error, "deleting value");
247
248         error = hive_get_value(mem_ctx, subkey, "Answer", &type, &db);
249         torture_assert_werr_equal(tctx, error, WERR_BADFILE, "getting value");
250
251         error = hive_key_del_value(mem_ctx, subkey, "Answer");
252         torture_assert_werr_equal(tctx, error, WERR_BADFILE,
253                                   "deleting value");
254
255         return true;
256 }
257
258 static bool test_list_values(struct torture_context *tctx,
259                              const void *test_data)
260 {
261         WERROR error;
262         struct hive_key *subkey;
263         const struct hive_key *root = (const struct hive_key *)test_data;
264         TALLOC_CTX *mem_ctx = tctx;
265         uint32_t type;
266         uint8_t d[] = { 0x42, 0x00, 0x00, 0x00 };
267         DATA_BLOB db = { d, 4 }, data;
268         const char *name;
269
270         error = hive_key_add_name(mem_ctx, root, "AYAYA Nested Key", NULL,
271                                   NULL, &subkey);
272         torture_assert_werr_ok(tctx, error, "hive_key_add_name");
273
274         error = hive_key_set_value(subkey, "Answer", REG_DWORD, db);
275         torture_assert_werr_ok(tctx, error, "hive_key_set_value");
276
277         error = hive_get_value_by_index(mem_ctx, subkey, 0, &name,
278                                         &type, &data);
279         torture_assert_werr_ok(tctx, error, "getting value");
280
281         torture_assert_str_equal(tctx, name, "Answer", "value name");
282
283         torture_assert_int_equal(tctx, data.length, 4, "value length");
284         torture_assert_int_equal(tctx, type, REG_DWORD, "value type");
285         
286         torture_assert_mem_equal(tctx, data.data, db.data, 4, "value data");
287         
288         error = hive_get_value_by_index(mem_ctx, subkey, 1, &name,
289                                         &type, &data);
290         torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS,
291                                   "getting missing value");
292
293         return true;
294 }
295
296 static bool test_hive_security(struct torture_context *tctx, const void *_data)
297 {
298         struct hive_key *subkey = NULL;
299         const struct hive_key *root = _data;
300         WERROR error;
301         struct security_descriptor *osd, *nsd;
302         
303         osd = security_descriptor_dacl_create(tctx,
304                                          0,
305                                          NULL, NULL,
306                                          SID_NT_AUTHENTICATED_USERS,
307                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
308                                          SEC_GENERIC_ALL,
309                                          SEC_ACE_FLAG_OBJECT_INHERIT,
310                                          NULL);
311
312
313         error = hive_key_add_name(tctx, root, "SecurityKey", NULL,
314                                   osd, &subkey);
315         torture_assert_werr_ok(tctx, error, "hive_key_add_name");
316
317         error = hive_get_sec_desc(tctx, subkey, &nsd);
318         torture_assert_werr_ok (tctx, error, "getting security descriptor");
319
320         torture_assert(tctx, security_descriptor_equal(osd, nsd),
321                        "security descriptor changed!");
322
323         /* Create a fresh security descriptor */        
324         talloc_free(osd);
325         osd = security_descriptor_dacl_create(tctx,
326                                          0,
327                                          NULL, NULL,
328                                          SID_NT_AUTHENTICATED_USERS,
329                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
330                                          SEC_GENERIC_ALL,
331                                          SEC_ACE_FLAG_OBJECT_INHERIT,
332                                          NULL);
333
334         error = hive_set_sec_desc(subkey, osd);
335         torture_assert_werr_ok(tctx, error, "setting security descriptor");
336         
337         error = hive_get_sec_desc(tctx, subkey, &nsd);
338         torture_assert_werr_ok (tctx, error, "getting security descriptor");
339         
340         torture_assert(tctx, security_descriptor_equal(osd, nsd),
341                        "security descriptor changed!");
342
343         return true;
344 }
345
346 static void tcase_add_tests(struct torture_tcase *tcase)
347 {
348         torture_tcase_add_simple_test_const(tcase, "del_nonexistant_key",
349                                                 test_del_nonexistant_key);
350         torture_tcase_add_simple_test_const(tcase, "add_subkey",
351                                                 test_add_subkey);
352         torture_tcase_add_simple_test(tcase, "flush_key",
353                                                 test_flush_key);
354         /* test_del_recursive() test must run before test_keyinfo_root().
355            test_keyinfo_root() checks the number of subkeys, which verifies
356            the recursive delete worked properly. */
357         torture_tcase_add_simple_test_const(tcase, "del_recursive",
358                                                 test_del_recursive);
359         torture_tcase_add_simple_test_const(tcase, "get_info",
360                                                 test_keyinfo_root);
361         torture_tcase_add_simple_test(tcase, "get_info_nums",
362                                                 test_keyinfo_nums);
363         torture_tcase_add_simple_test_const(tcase, "set_value",
364                                                 test_set_value);
365         torture_tcase_add_simple_test_const(tcase, "get_value",
366                                                 test_get_value);
367         torture_tcase_add_simple_test_const(tcase, "list_values",
368                                                 test_list_values);
369         torture_tcase_add_simple_test_const(tcase, "del_key",
370                                                 test_del_key);
371         torture_tcase_add_simple_test_const(tcase, "del_value",
372                                                 test_del_value);
373         torture_tcase_add_simple_test_const(tcase, "check hive security",
374                                                 test_hive_security);
375 }
376
377 static bool hive_setup_dir(struct torture_context *tctx, void **data)
378 {
379         struct hive_key *key;
380         WERROR error;
381         char *dirname;
382         NTSTATUS status;
383
384         status = torture_temp_dir(tctx, "hive-dir", &dirname);
385         if (!NT_STATUS_IS_OK(status))
386                 return false;
387
388         rmdir(dirname);
389
390         error = reg_create_directory(tctx, dirname, &key);
391         if (!W_ERROR_IS_OK(error)) {
392                 fprintf(stderr, "Unable to initialize dir hive\n");
393                 return false;
394         }
395
396         *data = key;
397
398         return true;
399 }
400
401 static bool hive_setup_ldb(struct torture_context *tctx, void **data)
402 {
403         struct hive_key *key;
404         WERROR error;
405         char *dirname;
406         NTSTATUS status;
407
408         status = torture_temp_dir(tctx, "hive-ldb", &dirname);
409         if (!NT_STATUS_IS_OK(status))
410                 return false;
411
412         rmdir(dirname);
413
414         error = reg_open_ldb_file(tctx, dirname, NULL, NULL, tctx->ev, tctx->lp_ctx, &key);
415         if (!W_ERROR_IS_OK(error)) {
416                 fprintf(stderr, "Unable to initialize ldb hive\n");
417                 return false;
418         }
419
420         *data = key;
421
422         return true;
423 }
424
425 static bool hive_setup_regf(struct torture_context *tctx, void **data)
426 {
427         struct hive_key *key;
428         WERROR error;
429         char *dirname;
430         NTSTATUS status;
431
432         status = torture_temp_dir(tctx, "hive-regf", &dirname);
433         if (!NT_STATUS_IS_OK(status))
434                 return false;
435
436         rmdir(dirname);
437
438         error = reg_create_regf_file(tctx, dirname, 5, &key);
439         if (!W_ERROR_IS_OK(error)) {
440                 fprintf(stderr, "Unable to create new regf file\n");
441                 return false;
442         }
443
444         *data = key;
445
446         return true;
447 }
448
449 static bool test_dir_refuses_null_location(struct torture_context *tctx)
450 {
451         torture_assert_werr_equal(tctx, WERR_INVALID_PARAM,
452                                   reg_open_directory(NULL, NULL, NULL),
453                                   "reg_open_directory accepts NULL location");
454         return true;
455 }
456
457 struct torture_suite *torture_registry_hive(TALLOC_CTX *mem_ctx)
458 {
459         struct torture_tcase *tcase;
460         struct torture_suite *suite = torture_suite_create(mem_ctx, "hive");
461
462         torture_suite_add_simple_test(suite, "dir-refuses-null-location",
463                                       test_dir_refuses_null_location);
464
465         tcase = torture_suite_add_tcase(suite, "dir");
466         torture_tcase_set_fixture(tcase, hive_setup_dir, NULL);
467         tcase_add_tests(tcase);
468
469         tcase = torture_suite_add_tcase(suite, "ldb");
470         torture_tcase_set_fixture(tcase, hive_setup_ldb, NULL);
471         tcase_add_tests(tcase);
472
473         tcase = torture_suite_add_tcase(suite, "regf");
474         torture_tcase_set_fixture(tcase, hive_setup_regf, NULL);
475         tcase_add_tests(tcase);
476
477         return suite;
478 }