Merge pull request #15817 from poettering/more-conditions
Add ConditionEnvironment= and ConditionIsEncrypted=
This commit is contained in:
+91
-34
@@ -25,6 +25,7 @@
|
||||
#include "extract-word.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "glob-util.h"
|
||||
#include "hostname-util.h"
|
||||
#include "ima-util.h"
|
||||
@@ -72,11 +73,11 @@ Condition* condition_new(ConditionType type, const char *parameter, bool trigger
|
||||
return c;
|
||||
}
|
||||
|
||||
void condition_free(Condition *c) {
|
||||
Condition* condition_free(Condition *c) {
|
||||
assert(c);
|
||||
|
||||
free(c->parameter);
|
||||
free(c);
|
||||
return mfree(c);
|
||||
}
|
||||
|
||||
Condition* condition_free_list_type(Condition *head, ConditionType type) {
|
||||
@@ -92,7 +93,7 @@ Condition* condition_free_list_type(Condition *head, ConditionType type) {
|
||||
return head;
|
||||
}
|
||||
|
||||
static int condition_test_kernel_command_line(Condition *c) {
|
||||
static int condition_test_kernel_command_line(Condition *c, char **env) {
|
||||
_cleanup_free_ char *line = NULL;
|
||||
const char *p;
|
||||
bool equal;
|
||||
@@ -201,7 +202,7 @@ static bool test_order(int k, OrderOperator p) {
|
||||
}
|
||||
}
|
||||
|
||||
static int condition_test_kernel_version(Condition *c) {
|
||||
static int condition_test_kernel_version(Condition *c, char **env) {
|
||||
OrderOperator order;
|
||||
struct utsname u;
|
||||
const char *p;
|
||||
@@ -259,7 +260,7 @@ static int condition_test_kernel_version(Condition *c) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int condition_test_memory(Condition *c) {
|
||||
static int condition_test_memory(Condition *c, char **env) {
|
||||
OrderOperator order;
|
||||
uint64_t m, k;
|
||||
const char *p;
|
||||
@@ -283,7 +284,7 @@ static int condition_test_memory(Condition *c) {
|
||||
return test_order(CMP(m, k), order);
|
||||
}
|
||||
|
||||
static int condition_test_cpus(Condition *c) {
|
||||
static int condition_test_cpus(Condition *c, char **env) {
|
||||
OrderOperator order;
|
||||
const char *p;
|
||||
unsigned k;
|
||||
@@ -309,7 +310,7 @@ static int condition_test_cpus(Condition *c) {
|
||||
return test_order(CMP((unsigned) n, k), order);
|
||||
}
|
||||
|
||||
static int condition_test_user(Condition *c) {
|
||||
static int condition_test_user(Condition *c, char **env) {
|
||||
uid_t id;
|
||||
int r;
|
||||
_cleanup_free_ char *username = NULL;
|
||||
@@ -344,7 +345,7 @@ static int condition_test_user(Condition *c) {
|
||||
return id == getuid() || id == geteuid();
|
||||
}
|
||||
|
||||
static int condition_test_control_group_controller(Condition *c) {
|
||||
static int condition_test_control_group_controller(Condition *c, char **env) {
|
||||
int r;
|
||||
CGroupMask system_mask, wanted_mask = 0;
|
||||
|
||||
@@ -368,7 +369,7 @@ static int condition_test_control_group_controller(Condition *c) {
|
||||
return FLAGS_SET(system_mask, wanted_mask);
|
||||
}
|
||||
|
||||
static int condition_test_group(Condition *c) {
|
||||
static int condition_test_group(Condition *c, char **env) {
|
||||
gid_t id;
|
||||
int r;
|
||||
|
||||
@@ -387,7 +388,7 @@ static int condition_test_group(Condition *c) {
|
||||
return in_group(c->parameter) > 0;
|
||||
}
|
||||
|
||||
static int condition_test_virtualization(Condition *c) {
|
||||
static int condition_test_virtualization(Condition *c, char **env) {
|
||||
int b, v;
|
||||
|
||||
assert(c);
|
||||
@@ -417,7 +418,7 @@ static int condition_test_virtualization(Condition *c) {
|
||||
return v != VIRTUALIZATION_NONE && streq(c->parameter, virtualization_to_string(v));
|
||||
}
|
||||
|
||||
static int condition_test_architecture(Condition *c) {
|
||||
static int condition_test_architecture(Condition *c, char **env) {
|
||||
int a, b;
|
||||
|
||||
assert(c);
|
||||
@@ -439,7 +440,7 @@ static int condition_test_architecture(Condition *c) {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
static int condition_test_host(Condition *c) {
|
||||
static int condition_test_host(Condition *c, char **env) {
|
||||
_cleanup_free_ char *h = NULL;
|
||||
sd_id128_t x, y;
|
||||
int r;
|
||||
@@ -464,7 +465,7 @@ static int condition_test_host(Condition *c) {
|
||||
return fnmatch(c->parameter, h, FNM_CASEFOLD) == 0;
|
||||
}
|
||||
|
||||
static int condition_test_ac_power(Condition *c) {
|
||||
static int condition_test_ac_power(Condition *c, char **env) {
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
@@ -478,7 +479,7 @@ static int condition_test_ac_power(Condition *c) {
|
||||
return (on_ac_power() != 0) == !!r;
|
||||
}
|
||||
|
||||
static int condition_test_security(Condition *c) {
|
||||
static int condition_test_security(Condition *c, char **env) {
|
||||
assert(c);
|
||||
assert(c->parameter);
|
||||
assert(c->type == CONDITION_SECURITY);
|
||||
@@ -501,7 +502,7 @@ static int condition_test_security(Condition *c) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static int condition_test_capability(Condition *c) {
|
||||
static int condition_test_capability(Condition *c, char **env) {
|
||||
unsigned long long capabilities = (unsigned long long) -1;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int value, r;
|
||||
@@ -544,7 +545,7 @@ static int condition_test_capability(Condition *c) {
|
||||
return !!(capabilities & (1ULL << value));
|
||||
}
|
||||
|
||||
static int condition_test_needs_update(Condition *c) {
|
||||
static int condition_test_needs_update(Condition *c, char **env) {
|
||||
const char *p;
|
||||
struct stat usr, other;
|
||||
|
||||
@@ -610,7 +611,7 @@ static int condition_test_needs_update(Condition *c) {
|
||||
return usr.st_mtim.tv_nsec > other.st_mtim.tv_nsec;
|
||||
}
|
||||
|
||||
static int condition_test_first_boot(Condition *c) {
|
||||
static int condition_test_first_boot(Condition *c, char **env) {
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
@@ -624,7 +625,36 @@ static int condition_test_first_boot(Condition *c) {
|
||||
return (access("/run/systemd/first-boot", F_OK) >= 0) == !!r;
|
||||
}
|
||||
|
||||
static int condition_test_path_exists(Condition *c) {
|
||||
static int condition_test_environment(Condition *c, char **env) {
|
||||
bool equal;
|
||||
char **i;
|
||||
|
||||
assert(c);
|
||||
assert(c->parameter);
|
||||
assert(c->type == CONDITION_ENVIRONMENT);
|
||||
|
||||
equal = strchr(c->parameter, '=');
|
||||
|
||||
STRV_FOREACH(i, env) {
|
||||
bool found;
|
||||
|
||||
if (equal)
|
||||
found = streq(c->parameter, *i);
|
||||
else {
|
||||
const char *f;
|
||||
|
||||
f = startswith(*i, c->parameter);
|
||||
found = f && IN_SET(*f, 0, '=');
|
||||
}
|
||||
|
||||
if (found)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int condition_test_path_exists(Condition *c, char **env) {
|
||||
assert(c);
|
||||
assert(c->parameter);
|
||||
assert(c->type == CONDITION_PATH_EXISTS);
|
||||
@@ -632,7 +662,7 @@ static int condition_test_path_exists(Condition *c) {
|
||||
return access(c->parameter, F_OK) >= 0;
|
||||
}
|
||||
|
||||
static int condition_test_path_exists_glob(Condition *c) {
|
||||
static int condition_test_path_exists_glob(Condition *c, char **env) {
|
||||
assert(c);
|
||||
assert(c->parameter);
|
||||
assert(c->type == CONDITION_PATH_EXISTS_GLOB);
|
||||
@@ -640,7 +670,7 @@ static int condition_test_path_exists_glob(Condition *c) {
|
||||
return glob_exists(c->parameter) > 0;
|
||||
}
|
||||
|
||||
static int condition_test_path_is_directory(Condition *c) {
|
||||
static int condition_test_path_is_directory(Condition *c, char **env) {
|
||||
assert(c);
|
||||
assert(c->parameter);
|
||||
assert(c->type == CONDITION_PATH_IS_DIRECTORY);
|
||||
@@ -648,7 +678,7 @@ static int condition_test_path_is_directory(Condition *c) {
|
||||
return is_dir(c->parameter, true) > 0;
|
||||
}
|
||||
|
||||
static int condition_test_path_is_symbolic_link(Condition *c) {
|
||||
static int condition_test_path_is_symbolic_link(Condition *c, char **env) {
|
||||
assert(c);
|
||||
assert(c->parameter);
|
||||
assert(c->type == CONDITION_PATH_IS_SYMBOLIC_LINK);
|
||||
@@ -656,7 +686,7 @@ static int condition_test_path_is_symbolic_link(Condition *c) {
|
||||
return is_symlink(c->parameter) > 0;
|
||||
}
|
||||
|
||||
static int condition_test_path_is_mount_point(Condition *c) {
|
||||
static int condition_test_path_is_mount_point(Condition *c, char **env) {
|
||||
assert(c);
|
||||
assert(c->parameter);
|
||||
assert(c->type == CONDITION_PATH_IS_MOUNT_POINT);
|
||||
@@ -664,7 +694,7 @@ static int condition_test_path_is_mount_point(Condition *c) {
|
||||
return path_is_mount_point(c->parameter, NULL, AT_SYMLINK_FOLLOW) > 0;
|
||||
}
|
||||
|
||||
static int condition_test_path_is_read_write(Condition *c) {
|
||||
static int condition_test_path_is_read_write(Condition *c, char **env) {
|
||||
assert(c);
|
||||
assert(c->parameter);
|
||||
assert(c->type == CONDITION_PATH_IS_READ_WRITE);
|
||||
@@ -672,7 +702,21 @@ static int condition_test_path_is_read_write(Condition *c) {
|
||||
return path_is_read_only_fs(c->parameter) <= 0;
|
||||
}
|
||||
|
||||
static int condition_test_directory_not_empty(Condition *c) {
|
||||
static int condition_test_path_is_encrypted(Condition *c, char **env) {
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
assert(c->parameter);
|
||||
assert(c->type == CONDITION_PATH_IS_ENCRYPTED);
|
||||
|
||||
r = path_is_encrypted(c->parameter);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
log_debug_errno(r, "Failed to determine if '%s' is encrypted: %m", c->parameter);
|
||||
|
||||
return r > 0;
|
||||
}
|
||||
|
||||
static int condition_test_directory_not_empty(Condition *c, char **env) {
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
@@ -683,7 +727,7 @@ static int condition_test_directory_not_empty(Condition *c) {
|
||||
return r <= 0 && r != -ENOENT;
|
||||
}
|
||||
|
||||
static int condition_test_file_not_empty(Condition *c) {
|
||||
static int condition_test_file_not_empty(Condition *c, char **env) {
|
||||
struct stat st;
|
||||
|
||||
assert(c);
|
||||
@@ -695,7 +739,7 @@ static int condition_test_file_not_empty(Condition *c) {
|
||||
st.st_size > 0);
|
||||
}
|
||||
|
||||
static int condition_test_file_is_executable(Condition *c) {
|
||||
static int condition_test_file_is_executable(Condition *c, char **env) {
|
||||
struct stat st;
|
||||
|
||||
assert(c);
|
||||
@@ -707,7 +751,7 @@ static int condition_test_file_is_executable(Condition *c) {
|
||||
(st.st_mode & 0111));
|
||||
}
|
||||
|
||||
static int condition_test_null(Condition *c) {
|
||||
static int condition_test_null(Condition *c, char **env) {
|
||||
assert(c);
|
||||
assert(c->type == CONDITION_NULL);
|
||||
|
||||
@@ -716,15 +760,16 @@ static int condition_test_null(Condition *c) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int condition_test(Condition *c) {
|
||||
int condition_test(Condition *c, char **env) {
|
||||
|
||||
static int (*const condition_tests[_CONDITION_TYPE_MAX])(Condition *c) = {
|
||||
static int (*const condition_tests[_CONDITION_TYPE_MAX])(Condition *c, char **env) = {
|
||||
[CONDITION_PATH_EXISTS] = condition_test_path_exists,
|
||||
[CONDITION_PATH_EXISTS_GLOB] = condition_test_path_exists_glob,
|
||||
[CONDITION_PATH_IS_DIRECTORY] = condition_test_path_is_directory,
|
||||
[CONDITION_PATH_IS_SYMBOLIC_LINK] = condition_test_path_is_symbolic_link,
|
||||
[CONDITION_PATH_IS_MOUNT_POINT] = condition_test_path_is_mount_point,
|
||||
[CONDITION_PATH_IS_READ_WRITE] = condition_test_path_is_read_write,
|
||||
[CONDITION_PATH_IS_ENCRYPTED] = condition_test_path_is_encrypted,
|
||||
[CONDITION_DIRECTORY_NOT_EMPTY] = condition_test_directory_not_empty,
|
||||
[CONDITION_FILE_NOT_EMPTY] = condition_test_file_not_empty,
|
||||
[CONDITION_FILE_IS_EXECUTABLE] = condition_test_file_is_executable,
|
||||
@@ -744,6 +789,7 @@ int condition_test(Condition *c) {
|
||||
[CONDITION_NULL] = condition_test_null,
|
||||
[CONDITION_CPUS] = condition_test_cpus,
|
||||
[CONDITION_MEMORY] = condition_test_memory,
|
||||
[CONDITION_ENVIRONMENT] = condition_test_environment,
|
||||
};
|
||||
|
||||
int r, b;
|
||||
@@ -752,7 +798,7 @@ int condition_test(Condition *c) {
|
||||
assert(c->type >= 0);
|
||||
assert(c->type < _CONDITION_TYPE_MAX);
|
||||
|
||||
r = condition_tests[c->type](c);
|
||||
r = condition_tests[c->type](c, env);
|
||||
if (r < 0) {
|
||||
c->result = CONDITION_ERROR;
|
||||
return r;
|
||||
@@ -763,7 +809,13 @@ int condition_test(Condition *c) {
|
||||
return b;
|
||||
}
|
||||
|
||||
bool condition_test_list(Condition *first, const char *(*to_string)(ConditionType t), condition_test_logger_t logger, void *userdata) {
|
||||
bool condition_test_list(
|
||||
Condition *first,
|
||||
char **env,
|
||||
condition_to_string_t to_string,
|
||||
condition_test_logger_t logger,
|
||||
void *userdata) {
|
||||
|
||||
Condition *c;
|
||||
int triggered = -1;
|
||||
|
||||
@@ -779,7 +831,7 @@ bool condition_test_list(Condition *first, const char *(*to_string)(ConditionTyp
|
||||
LIST_FOREACH(conditions, c, first) {
|
||||
int r;
|
||||
|
||||
r = condition_test(c);
|
||||
r = condition_test(c, env);
|
||||
|
||||
if (logger) {
|
||||
const char *p = c->type == CONDITION_NULL ? "true" : c->parameter;
|
||||
@@ -812,9 +864,10 @@ bool condition_test_list(Condition *first, const char *(*to_string)(ConditionTyp
|
||||
return triggered != 0;
|
||||
}
|
||||
|
||||
void condition_dump(Condition *c, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t)) {
|
||||
void condition_dump(Condition *c, FILE *f, const char *prefix, condition_to_string_t to_string) {
|
||||
assert(c);
|
||||
assert(f);
|
||||
assert(to_string);
|
||||
|
||||
prefix = strempty(prefix);
|
||||
|
||||
@@ -828,7 +881,7 @@ void condition_dump(Condition *c, FILE *f, const char *prefix, const char *(*to_
|
||||
condition_result_to_string(c->result));
|
||||
}
|
||||
|
||||
void condition_dump_list(Condition *first, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t)) {
|
||||
void condition_dump_list(Condition *first, FILE *f, const char *prefix, condition_to_string_t to_string) {
|
||||
Condition *c;
|
||||
|
||||
LIST_FOREACH(conditions, c, first)
|
||||
@@ -852,6 +905,7 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
|
||||
[CONDITION_PATH_IS_SYMBOLIC_LINK] = "ConditionPathIsSymbolicLink",
|
||||
[CONDITION_PATH_IS_MOUNT_POINT] = "ConditionPathIsMountPoint",
|
||||
[CONDITION_PATH_IS_READ_WRITE] = "ConditionPathIsReadWrite",
|
||||
[CONDITION_PATH_IS_ENCRYPTED] = "ConditionPathIsEncrypted",
|
||||
[CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty",
|
||||
[CONDITION_FILE_NOT_EMPTY] = "ConditionFileNotEmpty",
|
||||
[CONDITION_FILE_IS_EXECUTABLE] = "ConditionFileIsExecutable",
|
||||
@@ -861,6 +915,7 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
|
||||
[CONDITION_NULL] = "ConditionNull",
|
||||
[CONDITION_CPUS] = "ConditionCPUs",
|
||||
[CONDITION_MEMORY] = "ConditionMemory",
|
||||
[CONDITION_ENVIRONMENT] = "ConditionEnvironment",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(condition_type, ConditionType);
|
||||
@@ -882,6 +937,7 @@ static const char* const assert_type_table[_CONDITION_TYPE_MAX] = {
|
||||
[CONDITION_PATH_IS_SYMBOLIC_LINK] = "AssertPathIsSymbolicLink",
|
||||
[CONDITION_PATH_IS_MOUNT_POINT] = "AssertPathIsMountPoint",
|
||||
[CONDITION_PATH_IS_READ_WRITE] = "AssertPathIsReadWrite",
|
||||
[CONDITION_PATH_IS_ENCRYPTED] = "AssertPathIsEncrypted",
|
||||
[CONDITION_DIRECTORY_NOT_EMPTY] = "AssertDirectoryNotEmpty",
|
||||
[CONDITION_FILE_NOT_EMPTY] = "AssertFileNotEmpty",
|
||||
[CONDITION_FILE_IS_EXECUTABLE] = "AssertFileIsExecutable",
|
||||
@@ -891,6 +947,7 @@ static const char* const assert_type_table[_CONDITION_TYPE_MAX] = {
|
||||
[CONDITION_NULL] = "AssertNull",
|
||||
[CONDITION_CPUS] = "AssertCPUs",
|
||||
[CONDITION_MEMORY] = "AssertMemory",
|
||||
[CONDITION_ENVIRONMENT] = "AssertEnvironment",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(assert_type, ConditionType);
|
||||
|
||||
+11
-6
@@ -18,6 +18,7 @@ typedef enum ConditionType {
|
||||
CONDITION_AC_POWER,
|
||||
CONDITION_MEMORY,
|
||||
CONDITION_CPUS,
|
||||
CONDITION_ENVIRONMENT,
|
||||
|
||||
CONDITION_NEEDS_UPDATE,
|
||||
CONDITION_FIRST_BOOT,
|
||||
@@ -28,6 +29,7 @@ typedef enum ConditionType {
|
||||
CONDITION_PATH_IS_SYMBOLIC_LINK,
|
||||
CONDITION_PATH_IS_MOUNT_POINT,
|
||||
CONDITION_PATH_IS_READ_WRITE,
|
||||
CONDITION_PATH_IS_ENCRYPTED,
|
||||
CONDITION_DIRECTORY_NOT_EMPTY,
|
||||
CONDITION_FILE_NOT_EMPTY,
|
||||
CONDITION_FILE_IS_EXECUTABLE,
|
||||
@@ -66,18 +68,20 @@ typedef struct Condition {
|
||||
} Condition;
|
||||
|
||||
Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate);
|
||||
void condition_free(Condition *c);
|
||||
Condition* condition_free(Condition *c);
|
||||
Condition* condition_free_list_type(Condition *first, ConditionType type);
|
||||
static inline Condition* condition_free_list(Condition *first) {
|
||||
return condition_free_list_type(first, _CONDITION_TYPE_INVALID);
|
||||
}
|
||||
|
||||
int condition_test(Condition *c);
|
||||
typedef int (*condition_test_logger_t)(void *userdata, int level, int error, const char *file, int line, const char *func, const char *format, ...) _printf_(7, 8);
|
||||
bool condition_test_list(Condition *first, const char *(*to_string)(ConditionType t), condition_test_logger_t logger, void *userdata);
|
||||
int condition_test(Condition *c, char **env);
|
||||
|
||||
void condition_dump(Condition *c, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t));
|
||||
void condition_dump_list(Condition *c, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t));
|
||||
typedef int (*condition_test_logger_t)(void *userdata, int level, int error, const char *file, int line, const char *func, const char *format, ...) _printf_(7, 8);
|
||||
typedef const char* (*condition_to_string_t)(ConditionType t) _const_;
|
||||
bool condition_test_list(Condition *first, char **env, condition_to_string_t to_string, condition_test_logger_t logger, void *userdata);
|
||||
|
||||
void condition_dump(Condition *c, FILE *f, const char *prefix, condition_to_string_t to_string);
|
||||
void condition_dump_list(Condition *c, FILE *f, const char *prefix, condition_to_string_t to_string);
|
||||
|
||||
const char* condition_type_to_string(ConditionType t) _const_;
|
||||
ConditionType condition_type_from_string(const char *s) _pure_;
|
||||
@@ -96,6 +100,7 @@ static inline bool condition_takes_path(ConditionType t) {
|
||||
CONDITION_PATH_IS_SYMBOLIC_LINK,
|
||||
CONDITION_PATH_IS_MOUNT_POINT,
|
||||
CONDITION_PATH_IS_READ_WRITE,
|
||||
CONDITION_PATH_IS_ENCRYPTED,
|
||||
CONDITION_DIRECTORY_NOT_EMPTY,
|
||||
CONDITION_FILE_NOT_EMPTY,
|
||||
CONDITION_FILE_IS_EXECUTABLE,
|
||||
|
||||
Reference in New Issue
Block a user