auth/credentials: don't ignore "client use kerberos" and --use-kerberos for machine...
[Samba.git] / lib / util / tests / test_util.c
blob62f10edeca4c4240e90188d74dc57259282991fd
1 /*
2 * Unix SMB/CIFS implementation.
4 * Unit test for util.c
6 * Copyright (C) Christof Schmitt 2020
7 * Copyright (C) Andreas Schneider 2020
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 #include <stdarg.h>
24 #include <stddef.h>
25 #include <stdint.h>
26 #include <setjmp.h>
27 #include <cmocka.h>
29 #include "lib/replace/replace.h"
30 #include "system/dir.h"
32 #include "lib/util/util.c"
34 struct test_paths {
35 char testdir[PATH_MAX];
36 char none[PATH_MAX];
37 char dir[PATH_MAX];
38 char dir_recursive[PATH_MAX];
39 mode_t dir_mode;
40 char file[PATH_MAX];
41 mode_t file_mode;
42 char symlink_none[PATH_MAX];
43 char symlink_dir[PATH_MAX];
44 char symlink_file[PATH_MAX];
47 static int group_setup(void **state)
49 struct test_paths *paths = NULL;
50 char *testdir = NULL;
51 int ret, fd;
53 umask(0);
55 paths = malloc(sizeof(struct test_paths));
56 assert_non_null(paths);
58 strlcpy(paths->testdir, tmpdir(), sizeof(paths->testdir));
59 strlcat(paths->testdir, "/test_util_XXXXXX", sizeof(paths->testdir));
60 testdir = mkdtemp(paths->testdir);
61 assert_non_null(testdir);
63 strlcpy(paths->none, testdir, sizeof(paths->none));
64 strlcat(paths->none, "/none", sizeof(paths->none));
66 strlcpy(paths->dir, testdir, sizeof(paths->dir));
67 strlcat(paths->dir, "/dir", sizeof(paths->dir));
68 paths->dir_mode = 0750;
69 ret = mkdir(paths->dir, paths->dir_mode);
70 assert_return_code(ret, errno);
72 strlcpy(paths->dir_recursive, testdir, sizeof(paths->dir));
73 strlcat(paths->dir_recursive, "/dir_recursive", sizeof(paths->dir));
74 paths->dir_mode = 0750;
75 ret = mkdir(paths->dir_recursive, paths->dir_mode);
76 assert_return_code(ret, errno);
78 strlcpy(paths->file, testdir, sizeof(paths->file));
79 strlcat(paths->file, "/file", sizeof(paths->file));
80 paths->file_mode = 0640;
81 fd = creat(paths->file, paths->file_mode);
82 assert_return_code(fd, errno);
83 ret = close(fd);
84 assert_return_code(ret, errno);
86 strlcpy(paths->symlink_none, testdir, sizeof(paths->symlink_none));
87 strlcat(paths->symlink_none, "/symlink_none",
88 sizeof(paths->symlink_none));
89 ret = symlink("/none", paths->symlink_none);
90 assert_return_code(ret, errno);
92 strlcpy(paths->symlink_dir, testdir, sizeof(paths->symlink_dir));
93 strlcat(paths->symlink_dir, "/symlink_dir", sizeof(paths->symlink_dir));
94 ret = symlink(paths->dir, paths->symlink_dir);
95 assert_return_code(ret, errno);
97 strlcpy(paths->symlink_file, testdir, sizeof(paths->symlink_file));
98 strlcat(paths->symlink_file, "/symlink_file",
99 sizeof(paths->symlink_file));
100 ret = symlink(paths->file, paths->symlink_file);
101 assert_return_code(ret, errno);
103 *state = paths;
105 return 0;
108 static int torture_rmdirs(const char *path)
110 DIR *d;
111 struct dirent *dp;
112 struct stat sb;
113 char *fname;
115 if ((d = opendir(path)) != NULL) {
116 while(stat(path, &sb) == 0) {
117 /* if we can remove the directory we're done */
118 if (rmdir(path) == 0) {
119 break;
121 switch (errno) {
122 case ENOTEMPTY:
123 case EEXIST:
124 case EBADF:
125 break; /* continue */
126 default:
127 closedir(d);
128 return 0;
131 while ((dp = readdir(d)) != NULL) {
132 size_t len;
133 /* skip '.' and '..' */
134 if (dp->d_name[0] == '.' &&
135 (dp->d_name[1] == '\0' ||
136 (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) {
137 continue;
140 len = strlen(path) + strlen(dp->d_name) + 2;
141 fname = malloc(len);
142 if (fname == NULL) {
143 closedir(d);
144 return -1;
146 snprintf(fname, len, "%s/%s", path, dp->d_name);
148 /* stat the file */
149 if (lstat(fname, &sb) != -1) {
150 if (S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode)) {
151 if (rmdir(fname) < 0) { /* can't be deleted */
152 if (errno == EACCES) {
153 closedir(d);
154 SAFE_FREE(fname);
155 return -1;
157 torture_rmdirs(fname);
159 } else {
160 unlink(fname);
162 } /* lstat */
163 SAFE_FREE(fname);
164 } /* readdir */
166 rewinddir(d);
168 } else {
169 return -1;
172 closedir(d);
173 return 0;
176 static int group_teardown(void **state)
178 struct test_paths *paths = *state;
179 int ret;
181 ret = unlink(paths->file);
182 assert_return_code(ret, errno);
184 ret = unlink(paths->symlink_none);
185 assert_return_code(ret, errno);
187 ret = unlink(paths->symlink_dir);
188 assert_return_code(ret, errno);
190 ret = unlink(paths->symlink_file);
191 assert_return_code(ret, errno);
193 ret = torture_rmdirs(paths->testdir);
194 assert_return_code(ret, errno);
196 free(paths);
197 return 0;
200 static void test_directory_create_or_exists_none(void **state)
202 struct test_paths *paths = *state;
203 bool b;
204 struct stat sbuf;
205 int ret;
207 b = directory_create_or_exist(paths->none, 0775);
208 assert_true(b);
210 ret = lstat(paths->none, &sbuf);
211 assert_return_code(ret, errno);
212 assert_int_equal(sbuf.st_mode & 0777, 0775);
213 assert_true(S_ISDIR(sbuf.st_mode));
216 static int teardown_none_directory(void **state)
218 struct test_paths *paths = *state;
220 rmdir(paths->none);
221 return 0;
224 static void test_directory_create_or_exists_dir(void **state)
226 struct test_paths *paths = *state;
227 bool b;
228 struct stat sbuf;
229 int ret;
231 b = directory_create_or_exist(paths->dir, 770);
232 assert_true(b);
234 ret = lstat(paths->dir, &sbuf);
235 assert_return_code(ret, errno);
236 assert_int_equal(sbuf.st_mode & 0777, paths->dir_mode);
237 assert_true(S_ISDIR(sbuf.st_mode));
240 static void test_directory_create_or_exists_file(void **state)
242 struct test_paths *paths = *state;
243 bool b;
244 struct stat sbuf;
245 int ret;
247 b = directory_create_or_exist(paths->file, 770);
248 assert_false(b);
250 ret = lstat(paths->file, &sbuf);
251 assert_return_code(ret, errno);
252 assert_int_equal(sbuf.st_mode & 0777, paths->file_mode);
253 assert_true(S_ISREG(sbuf.st_mode));
256 static void test_directory_create_or_exists_symlink_none(void **state)
258 struct test_paths *paths = *state;
259 bool b;
260 struct stat sbuf;
261 int ret;
263 b = directory_create_or_exist(paths->symlink_none, 770);
264 assert_false(b);
266 ret = lstat(paths->symlink_none, &sbuf);
267 assert_return_code(ret, errno);
268 assert_int_equal(sbuf.st_mode & 0777, 0777);
269 assert_true(S_ISLNK(sbuf.st_mode));
272 static void test_directory_create_or_exists_symlink_dir(void **state)
274 struct test_paths *paths = *state;
275 bool b;
276 struct stat sbuf;
277 int ret;
279 b = directory_create_or_exist(paths->symlink_dir, 770);
280 assert_true(b);
282 ret = lstat(paths->symlink_dir, &sbuf);
283 assert_return_code(ret, errno);
284 assert_int_equal(sbuf.st_mode & 0777, 0777);
285 assert_true(S_ISLNK(sbuf.st_mode));
288 static void test_directory_create_or_exists_symlink_file(void **state)
290 struct test_paths *paths = *state;
291 bool b;
292 struct stat sbuf;
293 int ret;
295 b = directory_create_or_exist(paths->symlink_file, 770);
296 assert_false(b);
298 ret = lstat(paths->symlink_file, &sbuf);
299 assert_return_code(ret, errno);
300 assert_int_equal(sbuf.st_mode & 0777, 0777);
301 assert_true(S_ISLNK(sbuf.st_mode));
304 static void test_directory_create_or_exists_recursive(void **state)
306 struct test_paths *paths = *state;
307 char recursive_testdir[PATH_MAX] = {0};
308 struct stat sbuf = {0};
309 bool ok;
310 int ret;
312 ret = snprintf(recursive_testdir,
313 sizeof(recursive_testdir),
314 "%s/wurst/brot",
315 paths->dir_recursive);
316 assert_int_not_equal(ret, -1);
318 ok = directory_create_or_exists_recursive(recursive_testdir,
319 0700);
320 assert_true(ok);
322 ret = lstat(recursive_testdir, &sbuf);
323 assert_return_code(ret, errno);
324 assert_int_equal(sbuf.st_mode & 0777, 0700);
325 assert_true(S_ISDIR(sbuf.st_mode));
328 int main(int argc, char **argv)
330 const struct CMUnitTest tests[] = {
331 cmocka_unit_test_teardown(test_directory_create_or_exists_none,
332 teardown_none_directory),
333 cmocka_unit_test(test_directory_create_or_exists_dir),
334 cmocka_unit_test(test_directory_create_or_exists_file),
335 cmocka_unit_test(test_directory_create_or_exists_symlink_none),
336 cmocka_unit_test(test_directory_create_or_exists_symlink_dir),
337 cmocka_unit_test(test_directory_create_or_exists_symlink_file),
338 cmocka_unit_test(test_directory_create_or_exists_recursive),
341 cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
343 return cmocka_run_group_tests(tests, group_setup, group_teardown);