]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/condition.c
condition: Create AssertControlGroupController (#7630)
[thirdparty/systemd.git] / src / shared / condition.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
b77c08e0
TG
2/***
3 This file is part of systemd.
4
5 Copyright 2010 Lennart Poettering
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
b77c08e0 21#include <errno.h>
a8fbdf54 22#include <fcntl.h>
84ac7bea 23#include <fnmatch.h>
a8fbdf54 24#include <limits.h>
84ac7bea 25#include <stdlib.h>
b77c08e0 26#include <string.h>
a8fbdf54 27#include <sys/stat.h>
c465a29f 28#include <sys/types.h>
a8fbdf54 29#include <time.h>
b77c08e0 30#include <unistd.h>
b77c08e0 31
d1bddcec 32#include "sd-id128.h"
84ac7bea 33
b5efdb8a 34#include "alloc-util.h"
d1bddcec 35#include "apparmor-util.h"
84ac7bea 36#include "architecture.h"
430f0182 37#include "audit-util.h"
2822da4f 38#include "cap-list.h"
e16647c3 39#include "cgroup-util.h"
3ffd4af2 40#include "condition.h"
84ac7bea 41#include "extract-word.h"
3ffd4af2 42#include "fd-util.h"
fb8b0869 43#include "fileio.h"
7d50b32a 44#include "glob-util.h"
958b66ea 45#include "hostname-util.h"
84ac7bea 46#include "ima-util.h"
a8fbdf54
TA
47#include "list.h"
48#include "macro.h"
4349cd7c 49#include "mount-util.h"
6bedfcbb 50#include "parse-util.h"
84ac7bea 51#include "path-util.h"
4e731273 52#include "proc-cmdline.h"
df0ff127 53#include "process-util.h"
84ac7bea
LP
54#include "selinux-util.h"
55#include "smack-util.h"
8fcde012 56#include "stat-util.h"
8b43440b 57#include "string-table.h"
07630cea 58#include "string-util.h"
ed440f6b 59#include "tomoyo-util.h"
c465a29f 60#include "user-util.h"
84ac7bea
LP
61#include "util.h"
62#include "virt.h"
b77c08e0
TG
63
64Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) {
65 Condition *c;
d1bddcec 66 int r;
b77c08e0 67
b80ba1da 68 assert(type >= 0);
b77c08e0 69 assert(type < _CONDITION_TYPE_MAX);
8a9c6071 70 assert((!parameter) == (type == CONDITION_NULL));
b77c08e0
TG
71
72 c = new0(Condition, 1);
73 if (!c)
74 return NULL;
75
76 c->type = type;
77 c->trigger = trigger;
78 c->negate = negate;
79
d1bddcec
LP
80 r = free_and_strdup(&c->parameter, parameter);
81 if (r < 0) {
5fecf46d 82 return mfree(c);
b77c08e0
TG
83 }
84
85 return c;
86}
87
88void condition_free(Condition *c) {
89 assert(c);
90
91 free(c->parameter);
92 free(c);
93}
94
447021aa 95Condition* condition_free_list(Condition *first) {
b77c08e0
TG
96 Condition *c, *n;
97
98 LIST_FOREACH_SAFE(conditions, c, n, first)
99 condition_free(c);
447021aa
ZJS
100
101 return NULL;
b77c08e0
TG
102}
103
a4705396 104static int condition_test_kernel_command_line(Condition *c) {
07318c29
LP
105 _cleanup_free_ char *line = NULL;
106 const char *p;
b77c08e0
TG
107 bool equal;
108 int r;
b77c08e0
TG
109
110 assert(c);
111 assert(c->parameter);
112 assert(c->type == CONDITION_KERNEL_COMMAND_LINE);
113
114 r = proc_cmdline(&line);
115 if (r < 0)
592fd144 116 return r;
b77c08e0
TG
117
118 equal = !!strchr(c->parameter, '=');
07318c29 119
c58bd76a 120 for (p = line;;) {
07318c29
LP
121 _cleanup_free_ char *word = NULL;
122 bool found;
123
12ba2c44 124 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
592fd144
LP
125 if (r < 0)
126 return r;
127 if (r == 0)
a4705396 128 break;
07318c29
LP
129
130 if (equal)
131 found = streq(word, c->parameter);
132 else {
133 const char *f;
134
135 f = startswith(word, c->parameter);
4c701096 136 found = f && IN_SET(*f, 0, '=');
b77c08e0
TG
137 }
138
07318c29 139 if (found)
a4705396 140 return true;
b77c08e0 141 }
b77c08e0 142
a4705396 143 return false;
b77c08e0
TG
144}
145
c465a29f
FS
146static int condition_test_user(Condition *c) {
147 uid_t id;
148 int r;
149 _cleanup_free_ char *username = NULL;
150 const char *u;
151
152 assert(c);
153 assert(c->parameter);
154 assert(c->type == CONDITION_USER);
155
156 r = parse_uid(c->parameter, &id);
157 if (r >= 0)
158 return id == getuid() || id == geteuid();
159
534bab66 160 if (streq("@system", c->parameter))
ece877d4 161 return uid_is_system(getuid()) || uid_is_system(geteuid());
534bab66 162
c465a29f
FS
163 username = getusername_malloc();
164 if (!username)
165 return -ENOMEM;
166
167 if (streq(username, c->parameter))
168 return 1;
169
df0ff127 170 if (getpid_cached() == 1)
c465a29f
FS
171 return streq(c->parameter, "root");
172
173 u = c->parameter;
174 r = get_user_creds(&u, &id, NULL, NULL, NULL);
175 if (r < 0)
176 return 0;
177
178 return id == getuid() || id == geteuid();
179}
180
e16647c3
CD
181static int condition_test_control_group_controller(Condition *c) {
182 int r;
183 CGroupMask system_mask, wanted_mask = 0;
184
185 assert(c);
186 assert(c->parameter);
187 assert(c->type == CONDITION_CONTROL_GROUP_CONTROLLER);
188
189 r = cg_mask_supported(&system_mask);
190 if (r < 0)
191 return log_debug_errno(r, "Failed to determine supported controllers: %m");
192
193 r = cg_mask_from_string(c->parameter, &wanted_mask);
194 if (r < 0 || wanted_mask <= 0) {
195 /* This won't catch the case that we have an unknown controller
196 * mixed in with valid ones -- these are only assessed on the
197 * validity of the valid controllers found. */
198 log_debug("Failed to parse cgroup string: %s", c->parameter);
199 return 1;
200 }
201
202 return (system_mask & wanted_mask) == wanted_mask;
203}
204
c465a29f
FS
205static int condition_test_group(Condition *c) {
206 gid_t id;
207 int r;
208
209 assert(c);
210 assert(c->parameter);
211 assert(c->type == CONDITION_GROUP);
212
213 r = parse_gid(c->parameter, &id);
214 if (r >= 0)
215 return in_gid(id);
216
217 /* Avoid any NSS lookups if we are PID1 */
df0ff127 218 if (getpid_cached() == 1)
c465a29f
FS
219 return streq(c->parameter, "root");
220
221 return in_group(c->parameter) > 0;
222}
223
a4705396 224static int condition_test_virtualization(Condition *c) {
248fab74 225 int b, v;
b77c08e0
TG
226
227 assert(c);
228 assert(c->parameter);
229 assert(c->type == CONDITION_VIRTUALIZATION);
230
239a5707
ZJS
231 if (streq(c->parameter, "private-users"))
232 return running_in_userns();
233
75f86906 234 v = detect_virtualization();
592fd144
LP
235 if (v < 0)
236 return v;
b77c08e0
TG
237
238 /* First, compare with yes/no */
239 b = parse_boolean(c->parameter);
0809d774
ZJS
240 if (b >= 0)
241 return b == !!v;
b77c08e0
TG
242
243 /* Then, compare categorization */
0809d774
ZJS
244 if (streq(c->parameter, "vm"))
245 return VIRTUALIZATION_IS_VM(v);
b77c08e0 246
0809d774
ZJS
247 if (streq(c->parameter, "container"))
248 return VIRTUALIZATION_IS_CONTAINER(v);
b77c08e0
TG
249
250 /* Finally compare id */
75f86906 251 return v != VIRTUALIZATION_NONE && streq(c->parameter, virtualization_to_string(v));
b77c08e0
TG
252}
253
a4705396 254static int condition_test_architecture(Condition *c) {
592fd144 255 int a, b;
099524d7
LP
256
257 assert(c);
258 assert(c->parameter);
259 assert(c->type == CONDITION_ARCHITECTURE);
260
261 a = uname_architecture();
262 if (a < 0)
592fd144 263 return a;
099524d7
LP
264
265 if (streq(c->parameter, "native"))
266 b = native_architecture();
2cb62395 267 else {
099524d7 268 b = architecture_from_string(c->parameter);
2cb62395
LP
269 if (b < 0) /* unknown architecture? Then it's definitely not ours */
270 return false;
271 }
099524d7 272
a4705396 273 return a == b;
099524d7
LP
274}
275
a4705396 276static int condition_test_host(Condition *c) {
dc92e62c 277 _cleanup_free_ char *h = NULL;
b77c08e0 278 sd_id128_t x, y;
b77c08e0 279 int r;
b77c08e0
TG
280
281 assert(c);
282 assert(c->parameter);
283 assert(c->type == CONDITION_HOST);
284
285 if (sd_id128_from_string(c->parameter, &x) >= 0) {
286
287 r = sd_id128_get_machine(&y);
288 if (r < 0)
592fd144 289 return r;
b77c08e0 290
a4705396 291 return sd_id128_equal(x, y);
b77c08e0
TG
292 }
293
294 h = gethostname_malloc();
295 if (!h)
592fd144 296 return -ENOMEM;
b77c08e0 297
a4705396 298 return fnmatch(c->parameter, h, FNM_CASEFOLD) == 0;
b77c08e0
TG
299}
300
a4705396 301static int condition_test_ac_power(Condition *c) {
b77c08e0
TG
302 int r;
303
304 assert(c);
305 assert(c->parameter);
306 assert(c->type == CONDITION_AC_POWER);
307
308 r = parse_boolean(c->parameter);
309 if (r < 0)
592fd144 310 return r;
b77c08e0 311
a4705396 312 return (on_ac_power() != 0) == !!r;
b77c08e0
TG
313}
314
d1bddcec
LP
315static int condition_test_security(Condition *c) {
316 assert(c);
317 assert(c->parameter);
318 assert(c->type == CONDITION_SECURITY);
319
320 if (streq(c->parameter, "selinux"))
6d395665 321 return mac_selinux_use();
d1bddcec 322 if (streq(c->parameter, "smack"))
a4705396 323 return mac_smack_use();
d1bddcec 324 if (streq(c->parameter, "apparmor"))
a4705396 325 return mac_apparmor_use();
d1bddcec 326 if (streq(c->parameter, "audit"))
a4705396 327 return use_audit();
d1bddcec 328 if (streq(c->parameter, "ima"))
a4705396 329 return use_ima();
ed440f6b
SL
330 if (streq(c->parameter, "tomoyo"))
331 return mac_tomoyo_use();
d1bddcec 332
a4705396 333 return false;
d1bddcec
LP
334}
335
336static int condition_test_capability(Condition *c) {
337 _cleanup_fclose_ FILE *f = NULL;
2822da4f 338 int value;
d1bddcec
LP
339 char line[LINE_MAX];
340 unsigned long long capabilities = -1;
341
342 assert(c);
343 assert(c->parameter);
344 assert(c->type == CONDITION_CAPABILITY);
345
346 /* If it's an invalid capability, we don't have it */
2822da4f
LP
347 value = capability_from_name(c->parameter);
348 if (value < 0)
d1bddcec
LP
349 return -EINVAL;
350
351 /* If it's a valid capability we default to assume
352 * that we have it */
353
354 f = fopen("/proc/self/status", "re");
355 if (!f)
356 return -errno;
357
358 while (fgets(line, sizeof(line), f)) {
359 truncate_nl(line);
360
361 if (startswith(line, "CapBnd:")) {
362 (void) sscanf(line+7, "%llx", &capabilities);
363 break;
364 }
365 }
366
a4705396 367 return !!(capabilities & (1ULL << value));
d1bddcec
LP
368}
369
370static int condition_test_needs_update(Condition *c) {
371 const char *p;
372 struct stat usr, other;
373
374 assert(c);
375 assert(c->parameter);
376 assert(c->type == CONDITION_NEEDS_UPDATE);
377
378 /* If the file system is read-only we shouldn't suggest an update */
379 if (path_is_read_only_fs(c->parameter) > 0)
a4705396 380 return false;
d1bddcec
LP
381
382 /* Any other failure means we should allow the condition to be true,
96d49011 383 * so that we rather invoke too many update tools than too
d1bddcec
LP
384 * few. */
385
386 if (!path_is_absolute(c->parameter))
a4705396 387 return true;
d1bddcec 388
63c372cb 389 p = strjoina(c->parameter, "/.updated");
d1bddcec 390 if (lstat(p, &other) < 0)
a4705396 391 return true;
d1bddcec
LP
392
393 if (lstat("/usr/", &usr) < 0)
a4705396 394 return true;
d1bddcec 395
fb8b0869
IS
396 /*
397 * First, compare seconds as they are always accurate...
398 */
399 if (usr.st_mtim.tv_sec != other.st_mtim.tv_sec)
400 return usr.st_mtim.tv_sec > other.st_mtim.tv_sec;
401
402 /*
403 * ...then compare nanoseconds.
404 *
405 * A false positive is only possible when /usr's nanoseconds > 0
406 * (otherwise /usr cannot be strictly newer than the target file)
407 * AND the target file's nanoseconds == 0
408 * (otherwise the filesystem supports nsec timestamps, see stat(2)).
409 */
410 if (usr.st_mtim.tv_nsec > 0 && other.st_mtim.tv_nsec == 0) {
411 _cleanup_free_ char *timestamp_str = NULL;
412 uint64_t timestamp;
413 int r;
414
ec2ebfd5 415 r = parse_env_file(p, NULL, "TIMESTAMP_NSEC", &timestamp_str, NULL);
fb8b0869 416 if (r < 0) {
ec2ebfd5 417 log_error_errno(r, "Failed to parse timestamp file '%s', using mtime: %m", p);
fb8b0869
IS
418 return true;
419 } else if (r == 0) {
420 log_debug("No data in timestamp file '%s', using mtime", p);
421 return true;
422 }
423
424 r = safe_atou64(timestamp_str, &timestamp);
425 if (r < 0) {
ec2ebfd5 426 log_error_errno(r, "Failed to parse timestamp value '%s' in file '%s', using mtime: %m", timestamp_str, p);
fb8b0869
IS
427 return true;
428 }
429
ec2ebfd5 430 timespec_store(&other.st_mtim, timestamp);
fb8b0869
IS
431 }
432
433 return usr.st_mtim.tv_nsec > other.st_mtim.tv_nsec;
d1bddcec
LP
434}
435
436static int condition_test_first_boot(Condition *c) {
437 int r;
438
439 assert(c);
440 assert(c->parameter);
441 assert(c->type == CONDITION_FIRST_BOOT);
442
443 r = parse_boolean(c->parameter);
444 if (r < 0)
445 return r;
446
a4705396 447 return (access("/run/systemd/first-boot", F_OK) >= 0) == !!r;
d1bddcec
LP
448}
449
450static int condition_test_path_exists(Condition *c) {
451 assert(c);
452 assert(c->parameter);
453 assert(c->type == CONDITION_PATH_EXISTS);
454
a4705396 455 return access(c->parameter, F_OK) >= 0;
d1bddcec
LP
456}
457
458static int condition_test_path_exists_glob(Condition *c) {
459 assert(c);
460 assert(c->parameter);
461 assert(c->type == CONDITION_PATH_EXISTS_GLOB);
462
a4705396 463 return glob_exists(c->parameter) > 0;
d1bddcec
LP
464}
465
466static int condition_test_path_is_directory(Condition *c) {
467 assert(c);
468 assert(c->parameter);
469 assert(c->type == CONDITION_PATH_IS_DIRECTORY);
470
a4705396 471 return is_dir(c->parameter, true) > 0;
d1bddcec
LP
472}
473
474static int condition_test_path_is_symbolic_link(Condition *c) {
475 assert(c);
476 assert(c->parameter);
477 assert(c->type == CONDITION_PATH_IS_SYMBOLIC_LINK);
478
a4705396 479 return is_symlink(c->parameter) > 0;
d1bddcec
LP
480}
481
482static int condition_test_path_is_mount_point(Condition *c) {
483 assert(c);
484 assert(c->parameter);
485 assert(c->type == CONDITION_PATH_IS_MOUNT_POINT);
486
e1873695 487 return path_is_mount_point(c->parameter, NULL, AT_SYMLINK_FOLLOW) > 0;
d1bddcec
LP
488}
489
490static int condition_test_path_is_read_write(Condition *c) {
491 assert(c);
492 assert(c->parameter);
493 assert(c->type == CONDITION_PATH_IS_READ_WRITE);
494
a4705396 495 return path_is_read_only_fs(c->parameter) <= 0;
d1bddcec
LP
496}
497
498static int condition_test_directory_not_empty(Condition *c) {
499 int r;
500
501 assert(c);
502 assert(c->parameter);
503 assert(c->type == CONDITION_DIRECTORY_NOT_EMPTY);
504
505 r = dir_is_empty(c->parameter);
a4705396 506 return r <= 0 && r != -ENOENT;
d1bddcec
LP
507}
508
509static int condition_test_file_not_empty(Condition *c) {
510 struct stat st;
511
512 assert(c);
513 assert(c->parameter);
514 assert(c->type == CONDITION_FILE_NOT_EMPTY);
515
516 return (stat(c->parameter, &st) >= 0 &&
517 S_ISREG(st.st_mode) &&
a4705396 518 st.st_size > 0);
d1bddcec
LP
519}
520
521static int condition_test_file_is_executable(Condition *c) {
522 struct stat st;
523
524 assert(c);
525 assert(c->parameter);
526 assert(c->type == CONDITION_FILE_IS_EXECUTABLE);
527
528 return (stat(c->parameter, &st) >= 0 &&
529 S_ISREG(st.st_mode) &&
a4705396 530 (st.st_mode & 0111));
d1bddcec
LP
531}
532
533static int condition_test_null(Condition *c) {
534 assert(c);
d1bddcec
LP
535 assert(c->type == CONDITION_NULL);
536
537 /* Note that during parsing we already evaluate the string and
538 * store it in c->negate */
a4705396 539 return true;
d1bddcec
LP
540}
541
542int condition_test(Condition *c) {
543
544 static int (*const condition_tests[_CONDITION_TYPE_MAX])(Condition *c) = {
545 [CONDITION_PATH_EXISTS] = condition_test_path_exists,
546 [CONDITION_PATH_EXISTS_GLOB] = condition_test_path_exists_glob,
547 [CONDITION_PATH_IS_DIRECTORY] = condition_test_path_is_directory,
548 [CONDITION_PATH_IS_SYMBOLIC_LINK] = condition_test_path_is_symbolic_link,
549 [CONDITION_PATH_IS_MOUNT_POINT] = condition_test_path_is_mount_point,
550 [CONDITION_PATH_IS_READ_WRITE] = condition_test_path_is_read_write,
551 [CONDITION_DIRECTORY_NOT_EMPTY] = condition_test_directory_not_empty,
552 [CONDITION_FILE_NOT_EMPTY] = condition_test_file_not_empty,
553 [CONDITION_FILE_IS_EXECUTABLE] = condition_test_file_is_executable,
554 [CONDITION_KERNEL_COMMAND_LINE] = condition_test_kernel_command_line,
555 [CONDITION_VIRTUALIZATION] = condition_test_virtualization,
556 [CONDITION_SECURITY] = condition_test_security,
557 [CONDITION_CAPABILITY] = condition_test_capability,
558 [CONDITION_HOST] = condition_test_host,
559 [CONDITION_AC_POWER] = condition_test_ac_power,
560 [CONDITION_ARCHITECTURE] = condition_test_architecture,
561 [CONDITION_NEEDS_UPDATE] = condition_test_needs_update,
562 [CONDITION_FIRST_BOOT] = condition_test_first_boot,
c465a29f
FS
563 [CONDITION_USER] = condition_test_user,
564 [CONDITION_GROUP] = condition_test_group,
e16647c3 565 [CONDITION_CONTROL_GROUP_CONTROLLER] = condition_test_control_group_controller,
d1bddcec
LP
566 [CONDITION_NULL] = condition_test_null,
567 };
cc50ef13
LP
568
569 int r, b;
d1bddcec
LP
570
571 assert(c);
572 assert(c->type >= 0);
573 assert(c->type < _CONDITION_TYPE_MAX);
574
a4705396 575 r = condition_tests[c->type](c);
cc50ef13
LP
576 if (r < 0) {
577 c->result = CONDITION_ERROR;
a4705396 578 return r;
cc50ef13 579 }
a4705396 580
cc50ef13
LP
581 b = (r > 0) == !c->negate;
582 c->result = b ? CONDITION_SUCCEEDED : CONDITION_FAILED;
583 return b;
d1bddcec
LP
584}
585
59fccdc5 586void condition_dump(Condition *c, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t)) {
b77c08e0
TG
587 assert(c);
588 assert(f);
589
590 if (!prefix)
591 prefix = "";
592
593 fprintf(f,
594 "%s\t%s: %s%s%s %s\n",
595 prefix,
59fccdc5 596 to_string(c->type),
b77c08e0
TG
597 c->trigger ? "|" : "",
598 c->negate ? "!" : "",
599 c->parameter,
cc50ef13 600 condition_result_to_string(c->result));
b77c08e0
TG
601}
602
59fccdc5 603void condition_dump_list(Condition *first, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t)) {
b77c08e0
TG
604 Condition *c;
605
606 LIST_FOREACH(conditions, c, first)
59fccdc5 607 condition_dump(c, f, prefix, to_string);
b77c08e0
TG
608}
609
610static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
651c3318
LP
611 [CONDITION_ARCHITECTURE] = "ConditionArchitecture",
612 [CONDITION_VIRTUALIZATION] = "ConditionVirtualization",
613 [CONDITION_HOST] = "ConditionHost",
614 [CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine",
615 [CONDITION_SECURITY] = "ConditionSecurity",
616 [CONDITION_CAPABILITY] = "ConditionCapability",
617 [CONDITION_AC_POWER] = "ConditionACPower",
618 [CONDITION_NEEDS_UPDATE] = "ConditionNeedsUpdate",
619 [CONDITION_FIRST_BOOT] = "ConditionFirstBoot",
b77c08e0
TG
620 [CONDITION_PATH_EXISTS] = "ConditionPathExists",
621 [CONDITION_PATH_EXISTS_GLOB] = "ConditionPathExistsGlob",
622 [CONDITION_PATH_IS_DIRECTORY] = "ConditionPathIsDirectory",
623 [CONDITION_PATH_IS_SYMBOLIC_LINK] = "ConditionPathIsSymbolicLink",
624 [CONDITION_PATH_IS_MOUNT_POINT] = "ConditionPathIsMountPoint",
625 [CONDITION_PATH_IS_READ_WRITE] = "ConditionPathIsReadWrite",
626 [CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty",
627 [CONDITION_FILE_NOT_EMPTY] = "ConditionFileNotEmpty",
628 [CONDITION_FILE_IS_EXECUTABLE] = "ConditionFileIsExecutable",
c465a29f
FS
629 [CONDITION_USER] = "ConditionUser",
630 [CONDITION_GROUP] = "ConditionGroup",
e16647c3 631 [CONDITION_CONTROL_GROUP_CONTROLLER] = "ConditionControlGroupController",
b77c08e0
TG
632 [CONDITION_NULL] = "ConditionNull"
633};
634
635DEFINE_STRING_TABLE_LOOKUP(condition_type, ConditionType);
cc50ef13 636
59fccdc5 637static const char* const assert_type_table[_CONDITION_TYPE_MAX] = {
651c3318
LP
638 [CONDITION_ARCHITECTURE] = "AssertArchitecture",
639 [CONDITION_VIRTUALIZATION] = "AssertVirtualization",
640 [CONDITION_HOST] = "AssertHost",
641 [CONDITION_KERNEL_COMMAND_LINE] = "AssertKernelCommandLine",
642 [CONDITION_SECURITY] = "AssertSecurity",
643 [CONDITION_CAPABILITY] = "AssertCapability",
644 [CONDITION_AC_POWER] = "AssertACPower",
645 [CONDITION_NEEDS_UPDATE] = "AssertNeedsUpdate",
646 [CONDITION_FIRST_BOOT] = "AssertFirstBoot",
59fccdc5
LP
647 [CONDITION_PATH_EXISTS] = "AssertPathExists",
648 [CONDITION_PATH_EXISTS_GLOB] = "AssertPathExistsGlob",
649 [CONDITION_PATH_IS_DIRECTORY] = "AssertPathIsDirectory",
650 [CONDITION_PATH_IS_SYMBOLIC_LINK] = "AssertPathIsSymbolicLink",
651 [CONDITION_PATH_IS_MOUNT_POINT] = "AssertPathIsMountPoint",
652 [CONDITION_PATH_IS_READ_WRITE] = "AssertPathIsReadWrite",
653 [CONDITION_DIRECTORY_NOT_EMPTY] = "AssertDirectoryNotEmpty",
654 [CONDITION_FILE_NOT_EMPTY] = "AssertFileNotEmpty",
655 [CONDITION_FILE_IS_EXECUTABLE] = "AssertFileIsExecutable",
c465a29f
FS
656 [CONDITION_USER] = "AssertUser",
657 [CONDITION_GROUP] = "AssertGroup",
e16647c3 658 [CONDITION_CONTROL_GROUP_CONTROLLER] = "AssertControlGroupController",
59fccdc5
LP
659 [CONDITION_NULL] = "AssertNull"
660};
661
662DEFINE_STRING_TABLE_LOOKUP(assert_type, ConditionType);
663
cc50ef13
LP
664static const char* const condition_result_table[_CONDITION_RESULT_MAX] = {
665 [CONDITION_UNTESTED] = "untested",
666 [CONDITION_SUCCEEDED] = "succeeded",
667 [CONDITION_FAILED] = "failed",
668 [CONDITION_ERROR] = "error",
669};
670
671DEFINE_STRING_TABLE_LOOKUP(condition_result, ConditionResult);