Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : *
4 : * Copyright (C) 2019 Michael Hanselmann <public@hansmi.ch>
5 : *
6 : * This program is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU General Public License as published by
8 : * the Free Software Foundation; either version 3 of the License, or
9 : * (at your option) any later version.
10 : *
11 : * This program is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : * GNU General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public License
17 : * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include <stdarg.h>
21 : #include <stddef.h>
22 : #include <setjmp.h>
23 : #include <stdint.h>
24 : #include <cmocka.h>
25 :
26 : #include <errno.h>
27 : #include <stdlib.h>
28 : #include <sys/types.h>
29 : #include <sys/stat.h>
30 : #include <fcntl.h>
31 :
32 : #include "includes.h"
33 : #include "lib/replace/replace.h"
34 : #include "system/filesys.h"
35 : #include "lib/util/samba_util.h"
36 : #include "registry/regfio.h"
37 :
38 : struct test_ctx {
39 : char *tmp_regfile;
40 : int tmp_regfile_fd;
41 : REGF_FILE *rb;
42 : };
43 :
44 3 : static int setup_context(void **state)
45 : {
46 3 : struct test_ctx *test_ctx;
47 :
48 3 : test_ctx = talloc_zero(NULL, struct test_ctx);
49 3 : assert_non_null(test_ctx);
50 :
51 3 : test_ctx->tmp_regfile_fd = -1;
52 :
53 3 : *state = test_ctx;
54 :
55 3 : return 0;
56 : }
57 :
58 1 : static int setup_context_tempfile(void **state)
59 : {
60 1 : struct test_ctx *test_ctx;
61 1 : int ret;
62 :
63 1 : ret = setup_context(state);
64 :
65 1 : if (ret == 0) {
66 1 : test_ctx = talloc_get_type_abort(*state, struct test_ctx);
67 :
68 1 : test_ctx->tmp_regfile = talloc_strdup(test_ctx, "/tmp/regfio.XXXXXX");
69 1 : assert_non_null(test_ctx->tmp_regfile);
70 :
71 1 : test_ctx->tmp_regfile_fd = mkstemp(test_ctx->tmp_regfile);
72 1 : assert_return_code(test_ctx->tmp_regfile_fd, errno);
73 : }
74 :
75 1 : return ret;
76 : }
77 :
78 3 : static int teardown_context(void **state)
79 : {
80 3 : struct test_ctx *test_ctx =
81 3 : talloc_get_type_abort(*state, struct test_ctx);
82 :
83 3 : if (test_ctx->rb) {
84 3 : regfio_close(test_ctx->rb);
85 : }
86 :
87 3 : if (test_ctx->tmp_regfile) {
88 1 : unlink(test_ctx->tmp_regfile);
89 : }
90 :
91 3 : if (test_ctx->tmp_regfile_fd != -1) {
92 1 : close(test_ctx->tmp_regfile_fd);
93 : }
94 :
95 3 : talloc_free(test_ctx);
96 :
97 3 : return 0;
98 : }
99 :
100 2 : static void open_testfile(struct test_ctx *test_ctx, const char *filename)
101 : {
102 2 : char *path;
103 :
104 2 : path = talloc_asprintf(test_ctx, "%s/testdata/samba3/%s", SRCDIR, filename);
105 2 : assert_non_null(path);
106 :
107 2 : test_ctx->rb = regfio_open(path, O_RDONLY, 0600);
108 2 : assert_non_null(test_ctx->rb);
109 2 : }
110 :
111 1 : static void test_regfio_open_new_file(void **state)
112 : {
113 1 : struct test_ctx *test_ctx =
114 1 : talloc_get_type_abort(*state, struct test_ctx);
115 1 : REGF_NK_REC *root;
116 1 : struct regval_ctr *values;
117 1 : struct regsubkey_ctr *subkeys;
118 1 : WERROR werr;
119 :
120 1 : test_ctx->rb = regfio_open(test_ctx->tmp_regfile,
121 : O_RDWR | O_CREAT | O_TRUNC, 0600);
122 1 : assert_non_null(test_ctx->rb);
123 :
124 1 : root = regfio_rootkey(test_ctx->rb);
125 1 : assert_null(root);
126 :
127 1 : werr = regsubkey_ctr_init(NULL, &subkeys);
128 1 : assert_true(W_ERROR_IS_OK(werr));
129 :
130 1 : werr = regval_ctr_init(subkeys, &values);
131 1 : assert_true(W_ERROR_IS_OK(werr));
132 :
133 : /* Write root key */
134 1 : regfio_write_key(test_ctx->rb, "", values, subkeys, NULL, NULL);
135 :
136 1 : root = regfio_rootkey(test_ctx->rb);
137 1 : assert_non_null(root);
138 1 : assert_memory_equal(root->header, "nk", sizeof(root->header));
139 1 : assert_int_equal(root->key_type, NK_TYPE_ROOTKEY);
140 1 : }
141 :
142 1 : static void test_regfio_corrupt_hbin(void **state)
143 : {
144 1 : struct test_ctx *test_ctx =
145 1 : talloc_get_type_abort(*state, struct test_ctx);
146 1 : REGF_NK_REC *root;
147 :
148 1 : open_testfile(test_ctx, "regfio_corrupt_hbin1.dat");
149 :
150 1 : root = regfio_rootkey(test_ctx->rb);
151 1 : assert_null(root);
152 1 : }
153 :
154 1 : static void test_regfio_corrupt_lf_subkeys(void **state)
155 : {
156 1 : struct test_ctx *test_ctx =
157 1 : talloc_get_type_abort(*state, struct test_ctx);
158 1 : REGF_NK_REC *root, *subkey;
159 :
160 1 : open_testfile(test_ctx, "regfio_corrupt_lf_subkeys.dat");
161 :
162 1 : root = regfio_rootkey(test_ctx->rb);
163 1 : assert_non_null(root);
164 :
165 1 : root->subkey_index = 0;
166 2 : while ((subkey = regfio_fetch_subkey(test_ctx->rb, root))) {
167 1 : }
168 1 : }
169 :
170 1 : int main(void) {
171 1 : const struct CMUnitTest tests[] = {
172 : cmocka_unit_test_setup_teardown(test_regfio_open_new_file,
173 : setup_context_tempfile,
174 : teardown_context),
175 : cmocka_unit_test_setup_teardown(test_regfio_corrupt_hbin,
176 : setup_context,
177 : teardown_context),
178 : cmocka_unit_test_setup_teardown(test_regfio_corrupt_lf_subkeys,
179 : setup_context,
180 : teardown_context),
181 : };
182 :
183 1 : cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
184 :
185 1 : return cmocka_run_group_tests(tests, NULL, NULL);
186 : }
|