~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/lib/registry/tests/hive.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

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