]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-condition.c
Merge pull request #7551 from poettering/resolved-unknown-scope
[thirdparty/systemd.git] / src / test / test-condition.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd
4
5 Copyright 2014 Ronny Chevalier
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24
25 #include "sd-id128.h"
26
27 #include "alloc-util.h"
28 #include "apparmor-util.h"
29 #include "architecture.h"
30 #include "audit-util.h"
31 #include "condition.h"
32 #include "hostname-util.h"
33 #include "id128-util.h"
34 #include "ima-util.h"
35 #include "log.h"
36 #include "macro.h"
37 #include "selinux-util.h"
38 #include "smack-util.h"
39 #include "strv.h"
40 #include "virt.h"
41 #include "util.h"
42 #include "user-util.h"
43
44 static void test_condition_test_path(void) {
45 Condition *condition;
46
47 condition = condition_new(CONDITION_PATH_EXISTS, "/bin/sh", false, false);
48 assert_se(condition);
49 assert_se(condition_test(condition));
50 condition_free(condition);
51
52 condition = condition_new(CONDITION_PATH_EXISTS, "/bin/s?", false, false);
53 assert_se(condition);
54 assert_se(!condition_test(condition));
55 condition_free(condition);
56
57 condition = condition_new(CONDITION_PATH_EXISTS_GLOB, "/bin/s?", false, false);
58 assert_se(condition);
59 assert_se(condition_test(condition));
60 condition_free(condition);
61
62 condition = condition_new(CONDITION_PATH_EXISTS_GLOB, "/bin/s?", false, true);
63 assert_se(condition);
64 assert_se(!condition_test(condition));
65 condition_free(condition);
66
67 condition = condition_new(CONDITION_PATH_EXISTS, "/thiscertainlywontexist", false, false);
68 assert_se(condition);
69 assert_se(!condition_test(condition));
70 condition_free(condition);
71
72 condition = condition_new(CONDITION_PATH_EXISTS, "/thiscertainlywontexist", false, true);
73 assert_se(condition);
74 assert_se(condition_test(condition));
75 condition_free(condition);
76
77 condition = condition_new(CONDITION_PATH_IS_DIRECTORY, "/bin", false, false);
78 assert_se(condition);
79 assert_se(condition_test(condition));
80 condition_free(condition);
81
82 condition = condition_new(CONDITION_DIRECTORY_NOT_EMPTY, "/bin", false, false);
83 assert_se(condition);
84 assert_se(condition_test(condition));
85 condition_free(condition);
86
87 condition = condition_new(CONDITION_FILE_NOT_EMPTY, "/bin/sh", false, false);
88 assert_se(condition);
89 assert_se(condition_test(condition));
90 condition_free(condition);
91
92 condition = condition_new(CONDITION_FILE_IS_EXECUTABLE, "/bin/sh", false, false);
93 assert_se(condition);
94 assert_se(condition_test(condition));
95 condition_free(condition);
96
97 condition = condition_new(CONDITION_FILE_IS_EXECUTABLE, "/etc/passwd", false, false);
98 assert_se(condition);
99 assert_se(!condition_test(condition));
100 condition_free(condition);
101
102 condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/proc", false, false);
103 assert_se(condition);
104 assert_se(condition_test(condition));
105 condition_free(condition);
106
107 condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/", false, false);
108 assert_se(condition);
109 assert_se(condition_test(condition));
110 condition_free(condition);
111
112 condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/bin", false, false);
113 assert_se(condition);
114 assert_se(!condition_test(condition));
115 condition_free(condition);
116
117 condition = condition_new(CONDITION_PATH_IS_READ_WRITE, "/tmp", false, false);
118 assert_se(condition);
119 assert_se(condition_test(condition));
120 condition_free(condition);
121
122 condition = condition_new(CONDITION_PATH_IS_SYMBOLIC_LINK, "/dev/stdout", false, false);
123 assert_se(condition);
124 assert_se(condition_test(condition));
125 condition_free(condition);
126 }
127
128 static void test_condition_test_ac_power(void) {
129 Condition *condition;
130
131 condition = condition_new(CONDITION_AC_POWER, "true", false, false);
132 assert_se(condition);
133 assert_se(condition_test(condition) == on_ac_power());
134 condition_free(condition);
135
136 condition = condition_new(CONDITION_AC_POWER, "false", false, false);
137 assert_se(condition);
138 assert_se(condition_test(condition) != on_ac_power());
139 condition_free(condition);
140
141 condition = condition_new(CONDITION_AC_POWER, "false", false, true);
142 assert_se(condition);
143 assert_se(condition_test(condition) == on_ac_power());
144 condition_free(condition);
145 }
146
147 static void test_condition_test_host(void) {
148 _cleanup_free_ char *hostname = NULL;
149 char sid[SD_ID128_STRING_MAX];
150 Condition *condition;
151 sd_id128_t id;
152 int r;
153
154 r = sd_id128_get_machine(&id);
155 assert_se(r >= 0);
156 assert_se(sd_id128_to_string(id, sid));
157
158 condition = condition_new(CONDITION_HOST, sid, false, false);
159 assert_se(condition);
160 assert_se(condition_test(condition));
161 condition_free(condition);
162
163 condition = condition_new(CONDITION_HOST, "garbage value jjjjjjjjjjjjjj", false, false);
164 assert_se(condition);
165 assert_se(!condition_test(condition));
166 condition_free(condition);
167
168 condition = condition_new(CONDITION_HOST, sid, false, true);
169 assert_se(condition);
170 assert_se(!condition_test(condition));
171 condition_free(condition);
172
173 hostname = gethostname_malloc();
174 assert_se(hostname);
175
176 /* if hostname looks like an id128 then skip testing it */
177 if (id128_is_valid(hostname))
178 log_notice("hostname is an id128, skipping test");
179 else {
180 condition = condition_new(CONDITION_HOST, hostname, false, false);
181 assert_se(condition);
182 assert_se(condition_test(condition));
183 condition_free(condition);
184 }
185 }
186
187 static void test_condition_test_architecture(void) {
188 Condition *condition;
189 const char *sa;
190 int a;
191
192 a = uname_architecture();
193 assert_se(a >= 0);
194
195 sa = architecture_to_string(a);
196 assert_se(sa);
197
198 condition = condition_new(CONDITION_ARCHITECTURE, sa, false, false);
199 assert_se(condition);
200 assert_se(condition_test(condition) > 0);
201 condition_free(condition);
202
203 condition = condition_new(CONDITION_ARCHITECTURE, "garbage value", false, false);
204 assert_se(condition);
205 assert_se(condition_test(condition) == 0);
206 condition_free(condition);
207
208 condition = condition_new(CONDITION_ARCHITECTURE, sa, false, true);
209 assert_se(condition);
210 assert_se(condition_test(condition) == 0);
211 condition_free(condition);
212 }
213
214 static void test_condition_test_kernel_command_line(void) {
215 Condition *condition;
216
217 condition = condition_new(CONDITION_KERNEL_COMMAND_LINE, "thisreallyshouldntbeonthekernelcommandline", false, false);
218 assert_se(condition);
219 assert_se(!condition_test(condition));
220 condition_free(condition);
221
222 condition = condition_new(CONDITION_KERNEL_COMMAND_LINE, "andthis=neither", false, false);
223 assert_se(condition);
224 assert_se(!condition_test(condition));
225 condition_free(condition);
226 }
227
228 static void test_condition_test_null(void) {
229 Condition *condition;
230
231 condition = condition_new(CONDITION_NULL, NULL, false, false);
232 assert_se(condition);
233 assert_se(condition_test(condition));
234 condition_free(condition);
235
236 condition = condition_new(CONDITION_NULL, NULL, false, true);
237 assert_se(condition);
238 assert_se(!condition_test(condition));
239 condition_free(condition);
240 }
241
242 static void test_condition_test_security(void) {
243 Condition *condition;
244
245 condition = condition_new(CONDITION_SECURITY, "garbage oifdsjfoidsjoj", false, false);
246 assert_se(condition);
247 assert_se(!condition_test(condition));
248 condition_free(condition);
249
250 condition = condition_new(CONDITION_SECURITY, "selinux", false, true);
251 assert_se(condition);
252 assert_se(condition_test(condition) != mac_selinux_use());
253 condition_free(condition);
254
255 condition = condition_new(CONDITION_SECURITY, "ima", false, false);
256 assert_se(condition);
257 assert_se(condition_test(condition) == use_ima());
258 condition_free(condition);
259
260 condition = condition_new(CONDITION_SECURITY, "apparmor", false, false);
261 assert_se(condition);
262 assert_se(condition_test(condition) == mac_apparmor_use());
263 condition_free(condition);
264
265 condition = condition_new(CONDITION_SECURITY, "smack", false, false);
266 assert_se(condition);
267 assert_se(condition_test(condition) == mac_smack_use());
268 condition_free(condition);
269
270 condition = condition_new(CONDITION_SECURITY, "audit", false, false);
271 assert_se(condition);
272 assert_se(condition_test(condition) == use_audit());
273 condition_free(condition);
274 }
275
276 static void test_condition_test_virtualization(void) {
277 Condition *condition;
278 const char *virt;
279 int r;
280
281 condition = condition_new(CONDITION_VIRTUALIZATION, "garbage oifdsjfoidsjoj", false, false);
282 assert_se(condition);
283 r = condition_test(condition);
284 log_info("ConditionVirtualization=garbage → %i", r);
285 assert_se(r == 0);
286 condition_free(condition);
287
288 condition = condition_new(CONDITION_VIRTUALIZATION, "container", false, false);
289 assert_se(condition);
290 r = condition_test(condition);
291 log_info("ConditionVirtualization=container → %i", r);
292 assert_se(r == !!detect_container());
293 condition_free(condition);
294
295 condition = condition_new(CONDITION_VIRTUALIZATION, "vm", false, false);
296 assert_se(condition);
297 r = condition_test(condition);
298 log_info("ConditionVirtualization=vm → %i", r);
299 assert_se(r == (detect_vm() && !detect_container()));
300 condition_free(condition);
301
302 condition = condition_new(CONDITION_VIRTUALIZATION, "private-users", false, false);
303 assert_se(condition);
304 r = condition_test(condition);
305 log_info("ConditionVirtualization=private-users → %i", r);
306 assert_se(r == !!running_in_userns());
307 condition_free(condition);
308
309 NULSTR_FOREACH(virt,
310 "kvm\0"
311 "qemu\0"
312 "bochs\0"
313 "xen\0"
314 "uml\0"
315 "vmware\0"
316 "oracle\0"
317 "microsoft\0"
318 "zvm\0"
319 "parallels\0"
320 "bhyve\0"
321 "vm_other\0") {
322
323 condition = condition_new(CONDITION_VIRTUALIZATION, virt, false, false);
324 assert_se(condition);
325 r = condition_test(condition);
326 log_info("ConditionVirtualization=%s → %i", virt, r);
327 assert_se(r >= 0);
328 condition_free(condition);
329 }
330 }
331
332 static void test_condition_test_user(void) {
333 Condition *condition;
334 char* uid;
335 char* username;
336 int r;
337
338 condition = condition_new(CONDITION_USER, "garbage oifdsjfoidsjoj", false, false);
339 assert_se(condition);
340 r = condition_test(condition);
341 log_info("ConditionUser=garbage → %i", r);
342 assert_se(r == 0);
343 condition_free(condition);
344
345 assert_se(asprintf(&uid, "%"PRIu32, UINT32_C(0xFFFF)) > 0);
346 condition = condition_new(CONDITION_USER, uid, false, false);
347 assert_se(condition);
348 r = condition_test(condition);
349 log_info("ConditionUser=%s → %i", uid, r);
350 assert_se(r == 0);
351 condition_free(condition);
352 free(uid);
353
354 assert_se(asprintf(&uid, "%u", (unsigned)getuid()) > 0);
355 condition = condition_new(CONDITION_USER, uid, false, false);
356 assert_se(condition);
357 r = condition_test(condition);
358 log_info("ConditionUser=%s → %i", uid, r);
359 assert_se(r > 0);
360 condition_free(condition);
361 free(uid);
362
363 assert_se(asprintf(&uid, "%u", (unsigned)getuid()+1) > 0);
364 condition = condition_new(CONDITION_USER, uid, false, false);
365 assert_se(condition);
366 r = condition_test(condition);
367 log_info("ConditionUser=%s → %i", uid, r);
368 assert_se(r == 0);
369 condition_free(condition);
370 free(uid);
371
372 username = getusername_malloc();
373 assert_se(username);
374 condition = condition_new(CONDITION_USER, username, false, false);
375 assert_se(condition);
376 r = condition_test(condition);
377 log_info("ConditionUser=%s → %i", username, r);
378 assert_se(r > 0);
379 condition_free(condition);
380 free(username);
381
382 username = (char*)(geteuid() == 0 ? NOBODY_USER_NAME : "root");
383 condition = condition_new(CONDITION_USER, username, false, false);
384 assert_se(condition);
385 r = condition_test(condition);
386 log_info("ConditionUser=%s → %i", username, r);
387 assert_se(r == 0);
388 condition_free(condition);
389
390 condition = condition_new(CONDITION_USER, "@system", false, false);
391 assert_se(condition);
392 r = condition_test(condition);
393 log_info("ConditionUser=@system → %i", r);
394 if (uid_is_system(getuid()) || uid_is_system(geteuid()))
395 assert_se(r > 0);
396 else
397 assert_se(r == 0);
398 condition_free(condition);
399 }
400
401 static void test_condition_test_group(void) {
402 Condition *condition;
403 char* gid;
404 char* groupname;
405 gid_t *gids, max_gid;
406 int ngroups_max, ngroups, r, i;
407
408 assert_se(0 < asprintf(&gid, "%u", UINT32_C(0xFFFF)));
409 condition = condition_new(CONDITION_GROUP, gid, false, false);
410 assert_se(condition);
411 r = condition_test(condition);
412 log_info("ConditionGroup=%s → %i", gid, r);
413 assert_se(r == 0);
414 condition_free(condition);
415 free(gid);
416
417 assert_se(0 < asprintf(&gid, "%u", getgid()));
418 condition = condition_new(CONDITION_GROUP, gid, false, false);
419 assert_se(condition);
420 r = condition_test(condition);
421 log_info("ConditionGroup=%s → %i", gid, r);
422 assert_se(r > 0);
423 condition_free(condition);
424 free(gid);
425
426 ngroups_max = sysconf(_SC_NGROUPS_MAX);
427 assert(ngroups_max > 0);
428
429 gids = alloca(sizeof(gid_t) * ngroups_max);
430
431 ngroups = getgroups(ngroups_max, gids);
432 assert(ngroups >= 0);
433
434 max_gid = getgid();
435 for (i = 0; i < ngroups; i++) {
436 assert_se(0 < asprintf(&gid, "%u", gids[i]));
437 condition = condition_new(CONDITION_GROUP, gid, false, false);
438 assert_se(condition);
439 r = condition_test(condition);
440 log_info("ConditionGroup=%s → %i", gid, r);
441 assert_se(r > 0);
442 condition_free(condition);
443 free(gid);
444 max_gid = gids[i] > max_gid ? gids[i] : max_gid;
445
446 groupname = gid_to_name(gids[i]);
447 assert_se(groupname);
448 condition = condition_new(CONDITION_GROUP, groupname, false, false);
449 assert_se(condition);
450 r = condition_test(condition);
451 log_info("ConditionGroup=%s → %i", groupname, r);
452 assert_se(r > 0);
453 condition_free(condition);
454 free(groupname);
455 max_gid = gids[i] > max_gid ? gids[i] : max_gid;
456 }
457
458 assert_se(0 < asprintf(&gid, "%u", max_gid+1));
459 condition = condition_new(CONDITION_GROUP, gid, false, false);
460 assert_se(condition);
461 r = condition_test(condition);
462 log_info("ConditionGroup=%s → %i", gid, r);
463 assert_se(r == 0);
464 condition_free(condition);
465 free(gid);
466
467 groupname = (char*)(geteuid() == 0 ? NOBODY_GROUP_NAME : "root");
468 condition = condition_new(CONDITION_GROUP, groupname, false, false);
469 assert_se(condition);
470 r = condition_test(condition);
471 log_info("ConditionGroup=%s → %i", groupname, r);
472 assert_se(r == 0);
473 condition_free(condition);
474 }
475
476 int main(int argc, char *argv[]) {
477 log_set_max_level(LOG_DEBUG);
478 log_parse_environment();
479 log_open();
480
481 test_condition_test_path();
482 test_condition_test_ac_power();
483 test_condition_test_host();
484 test_condition_test_architecture();
485 test_condition_test_kernel_command_line();
486 test_condition_test_null();
487 test_condition_test_security();
488 test_condition_test_virtualization();
489 test_condition_test_user();
490 test_condition_test_group();
491
492 return 0;
493 }