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