1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd
5 Copyright 2014 Ronny Chevalier
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.
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.
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/>.
22 #include <sys/types.h>
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"
37 #include "selinux-util.h"
38 #include "smack-util.h"
42 #include "user-util.h"
44 static void test_condition_test_path(void) {
47 condition
= condition_new(CONDITION_PATH_EXISTS
, "/bin/sh", false, false);
49 assert_se(condition_test(condition
));
50 condition_free(condition
);
52 condition
= condition_new(CONDITION_PATH_EXISTS
, "/bin/s?", false, false);
54 assert_se(!condition_test(condition
));
55 condition_free(condition
);
57 condition
= condition_new(CONDITION_PATH_EXISTS_GLOB
, "/bin/s?", false, false);
59 assert_se(condition_test(condition
));
60 condition_free(condition
);
62 condition
= condition_new(CONDITION_PATH_EXISTS_GLOB
, "/bin/s?", false, true);
64 assert_se(!condition_test(condition
));
65 condition_free(condition
);
67 condition
= condition_new(CONDITION_PATH_EXISTS
, "/thiscertainlywontexist", false, false);
69 assert_se(!condition_test(condition
));
70 condition_free(condition
);
72 condition
= condition_new(CONDITION_PATH_EXISTS
, "/thiscertainlywontexist", false, true);
74 assert_se(condition_test(condition
));
75 condition_free(condition
);
77 condition
= condition_new(CONDITION_PATH_IS_DIRECTORY
, "/bin", false, false);
79 assert_se(condition_test(condition
));
80 condition_free(condition
);
82 condition
= condition_new(CONDITION_DIRECTORY_NOT_EMPTY
, "/bin", false, false);
84 assert_se(condition_test(condition
));
85 condition_free(condition
);
87 condition
= condition_new(CONDITION_FILE_NOT_EMPTY
, "/bin/sh", false, false);
89 assert_se(condition_test(condition
));
90 condition_free(condition
);
92 condition
= condition_new(CONDITION_FILE_IS_EXECUTABLE
, "/bin/sh", false, false);
94 assert_se(condition_test(condition
));
95 condition_free(condition
);
97 condition
= condition_new(CONDITION_FILE_IS_EXECUTABLE
, "/etc/passwd", false, false);
99 assert_se(!condition_test(condition
));
100 condition_free(condition
);
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
);
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
);
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
);
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
);
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
);
128 static void test_condition_test_ac_power(void) {
129 Condition
*condition
;
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
);
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
);
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
);
147 static void test_condition_test_host(void) {
148 _cleanup_free_
char *hostname
= NULL
;
149 char sid
[SD_ID128_STRING_MAX
];
150 Condition
*condition
;
154 r
= sd_id128_get_machine(&id
);
156 assert_se(sd_id128_to_string(id
, sid
));
158 condition
= condition_new(CONDITION_HOST
, sid
, false, false);
159 assert_se(condition
);
160 assert_se(condition_test(condition
));
161 condition_free(condition
);
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
);
168 condition
= condition_new(CONDITION_HOST
, sid
, false, true);
169 assert_se(condition
);
170 assert_se(!condition_test(condition
));
171 condition_free(condition
);
173 hostname
= gethostname_malloc();
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");
180 condition
= condition_new(CONDITION_HOST
, hostname
, false, false);
181 assert_se(condition
);
182 assert_se(condition_test(condition
));
183 condition_free(condition
);
187 static void test_condition_test_architecture(void) {
188 Condition
*condition
;
192 a
= uname_architecture();
195 sa
= architecture_to_string(a
);
198 condition
= condition_new(CONDITION_ARCHITECTURE
, sa
, false, false);
199 assert_se(condition
);
200 assert_se(condition_test(condition
) > 0);
201 condition_free(condition
);
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
);
208 condition
= condition_new(CONDITION_ARCHITECTURE
, sa
, false, true);
209 assert_se(condition
);
210 assert_se(condition_test(condition
) == 0);
211 condition_free(condition
);
214 static void test_condition_test_kernel_command_line(void) {
215 Condition
*condition
;
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
);
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
);
228 static void test_condition_test_null(void) {
229 Condition
*condition
;
231 condition
= condition_new(CONDITION_NULL
, NULL
, false, false);
232 assert_se(condition
);
233 assert_se(condition_test(condition
));
234 condition_free(condition
);
236 condition
= condition_new(CONDITION_NULL
, NULL
, false, true);
237 assert_se(condition
);
238 assert_se(!condition_test(condition
));
239 condition_free(condition
);
242 static void test_condition_test_security(void) {
243 Condition
*condition
;
245 condition
= condition_new(CONDITION_SECURITY
, "garbage oifdsjfoidsjoj", false, false);
246 assert_se(condition
);
247 assert_se(!condition_test(condition
));
248 condition_free(condition
);
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
);
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
);
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
);
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
);
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
);
276 static void test_condition_test_virtualization(void) {
277 Condition
*condition
;
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
);
286 condition_free(condition
);
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
);
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
);
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
);
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
);
328 condition_free(condition
);
332 static void test_condition_test_user(void) {
333 Condition
*condition
;
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
);
343 condition_free(condition
);
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
);
351 condition_free(condition
);
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
);
360 condition_free(condition
);
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
);
369 condition_free(condition
);
372 username
= getusername_malloc();
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
);
379 condition_free(condition
);
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
);
388 condition_free(condition
);
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()))
398 condition_free(condition
);
401 static void test_condition_test_group(void) {
402 Condition
*condition
;
405 gid_t
*gids
, max_gid
;
406 int ngroups_max
, ngroups
, r
, i
;
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
);
414 condition_free(condition
);
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
);
423 condition_free(condition
);
426 ngroups_max
= sysconf(_SC_NGROUPS_MAX
);
427 assert(ngroups_max
> 0);
429 gids
= alloca(sizeof(gid_t
) * ngroups_max
);
431 ngroups
= getgroups(ngroups_max
, gids
);
432 assert(ngroups
>= 0);
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
);
442 condition_free(condition
);
444 max_gid
= gids
[i
] > max_gid
? gids
[i
] : max_gid
;
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
);
453 condition_free(condition
);
455 max_gid
= gids
[i
] > max_gid
? gids
[i
] : max_gid
;
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
);
464 condition_free(condition
);
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
);
473 condition_free(condition
);
476 int main(int argc
, char *argv
[]) {
477 log_set_max_level(LOG_DEBUG
);
478 log_parse_environment();
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();