Merge pull request #15817 from poettering/more-conditions

Add ConditionEnvironment= and ConditionIsEncrypted=
This commit is contained in:
Lennart Poettering 2020-05-15 20:25:34 +02:00 committed by GitHub
commit 18fbb567a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 302 additions and 142 deletions

2
TODO
View File

@ -68,8 +68,6 @@ Features:
* homed: add a way to "adopt" a home directory, i.e. strip foreign signatures * homed: add a way to "adopt" a home directory, i.e. strip foreign signatures
and insert a local signature instead. and insert a local signature instead.
* Maybe expose path_is_encrypted() as a new ConditionPathIsEncrypted=?
* homed: as an extension to the directory+subvolume backend: if located on * homed: as an extension to the directory+subvolume backend: if located on
especially marked fs, then sync down password into LUKS header of that fs, especially marked fs, then sync down password into LUKS header of that fs,
and always verify passwords against it too. Bootstrapping is a problem and always verify passwords against it too. Bootstrapping is a problem

View File

@ -1226,6 +1226,24 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>ConditionEnvironment=</varname></term>
<listitem><para><varname>ConditionEnvironment=</varname> may be used to check whether a specific
environment variable is set (or if prefixed with the exclamation mark — unset) in the service
manager's environment block.
The argument may be a single word, to check if the variable with this name is defined in the
environment block, or an assignment
(<literal><replaceable>name</replaceable>=<replaceable>value</replaceable></literal>), to check if
the variable with this exact value is defined. Note that the environment block of the service
manager itself is checked, i.e. not any variables defined with <varname>Environment=</varname> or
<varname>EnvironmentFile=</varname>, as described above. This is particularly useful when the
service manager runs inside a containerized environment or as per-user service manager, in order to
check for variables passed in by the enclosing container manager or PAM.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><varname>ConditionSecurity=</varname></term> <term><varname>ConditionSecurity=</varname></term>
@ -1346,6 +1364,18 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>ConditionPathIsEncrypted=</varname></term>
<listitem><para><varname>ConditionPathIsEncrypted=</varname> is similar to
<varname>ConditionPathExists=</varname> but verifies that the underlying file system's backing
block device is encrypted using dm-crypt/LUKS. Note that this check does not cover ext4
per-directory encryption, and only detects block level encryption. Moreover, if the specified path
resides on a file system on top of a loopback block device, only encryption above the loopback device is
detected. It is not detected whether the file system backing the loopback block device is encrypted.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><varname>ConditionDirectoryNotEmpty=</varname></term> <term><varname>ConditionDirectoryNotEmpty=</varname></term>

View File

@ -21,6 +21,7 @@ static const condition_definition condition_definitions[] = {
{ "ConditionPathIsSymbolicLink", config_parse_unit_condition_path, CONDITION_PATH_IS_SYMBOLIC_LINK }, { "ConditionPathIsSymbolicLink", config_parse_unit_condition_path, CONDITION_PATH_IS_SYMBOLIC_LINK },
{ "ConditionPathIsMountPoint", config_parse_unit_condition_path, CONDITION_PATH_IS_MOUNT_POINT }, { "ConditionPathIsMountPoint", config_parse_unit_condition_path, CONDITION_PATH_IS_MOUNT_POINT },
{ "ConditionPathIsReadWrite", config_parse_unit_condition_path, CONDITION_PATH_IS_READ_WRITE }, { "ConditionPathIsReadWrite", config_parse_unit_condition_path, CONDITION_PATH_IS_READ_WRITE },
{ "ConditionPathIsEncrypted", config_parse_unit_condition_path, CONDITION_PATH_IS_ENCRYPTED },
{ "ConditionDirectoryNotEmpty", config_parse_unit_condition_path, CONDITION_DIRECTORY_NOT_EMPTY }, { "ConditionDirectoryNotEmpty", config_parse_unit_condition_path, CONDITION_DIRECTORY_NOT_EMPTY },
{ "ConditionFileNotEmpty", config_parse_unit_condition_path, CONDITION_FILE_NOT_EMPTY }, { "ConditionFileNotEmpty", config_parse_unit_condition_path, CONDITION_FILE_NOT_EMPTY },
{ "ConditionFileIsExecutable", config_parse_unit_condition_path, CONDITION_FILE_IS_EXECUTABLE }, { "ConditionFileIsExecutable", config_parse_unit_condition_path, CONDITION_FILE_IS_EXECUTABLE },
@ -44,6 +45,7 @@ static const condition_definition condition_definitions[] = {
{ "AssertPathIsSymbolicLink", config_parse_unit_condition_path, CONDITION_PATH_IS_SYMBOLIC_LINK }, { "AssertPathIsSymbolicLink", config_parse_unit_condition_path, CONDITION_PATH_IS_SYMBOLIC_LINK },
{ "AssertPathIsMountPoint", config_parse_unit_condition_path, CONDITION_PATH_IS_MOUNT_POINT }, { "AssertPathIsMountPoint", config_parse_unit_condition_path, CONDITION_PATH_IS_MOUNT_POINT },
{ "AssertPathIsReadWrite", config_parse_unit_condition_path, CONDITION_PATH_IS_READ_WRITE }, { "AssertPathIsReadWrite", config_parse_unit_condition_path, CONDITION_PATH_IS_READ_WRITE },
{ "AssertPathIsEncrypted", config_parse_unit_condition_path, CONDITION_PATH_IS_ENCRYPTED },
{ "AssertDirectoryNotEmpty", config_parse_unit_condition_path, CONDITION_DIRECTORY_NOT_EMPTY }, { "AssertDirectoryNotEmpty", config_parse_unit_condition_path, CONDITION_DIRECTORY_NOT_EMPTY },
{ "AssertFileNotEmpty", config_parse_unit_condition_path, CONDITION_FILE_NOT_EMPTY }, { "AssertFileNotEmpty", config_parse_unit_condition_path, CONDITION_FILE_NOT_EMPTY },
{ "AssertFileIsExecutable", config_parse_unit_condition_path, CONDITION_FILE_IS_EXECUTABLE }, { "AssertFileIsExecutable", config_parse_unit_condition_path, CONDITION_FILE_IS_EXECUTABLE },
@ -143,11 +145,11 @@ int verify_conditions(char **lines, UnitFileScope scope) {
return r; return r;
} }
r = condition_test_list(u->asserts, assert_type_to_string, log_helper, u); r = condition_test_list(u->asserts, environ, assert_type_to_string, log_helper, u);
if (u->asserts) if (u->asserts)
log_notice("Asserts %s.", r > 0 ? "succeeded" : "failed"); log_notice("Asserts %s.", r > 0 ? "succeeded" : "failed");
q = condition_test_list(u->conditions, condition_type_to_string, log_helper, u); q = condition_test_list(u->conditions, environ, condition_type_to_string, log_helper, u);
if (u->conditions) if (u->conditions)
log_notice("Conditions %s.", q > 0 ? "succeeded" : "failed"); log_notice("Conditions %s.", q > 0 ? "succeeded" : "failed");

View File

@ -41,6 +41,11 @@ uint64_t physical_memory(void) {
} }
if (r > 0) { if (r > 0) {
r = cg_get_attribute("memory", root, "memory.max", &value); r = cg_get_attribute("memory", root, "memory.max", &value);
if (r == -ENOENT) /* Field does not exist on the system's top-level cgroup, hence don't
* complain. (Note that it might exist on our own root though, if we live
* in a cgroup namespace, hence check anyway instead of not even
* trying.) */
return mem;
if (r < 0) { if (r < 0) {
log_debug_errno(r, "Failed to read memory.max cgroup attribute, ignoring cgroup memory limit: %m"); log_debug_errno(r, "Failed to read memory.max cgroup attribute, ignoring cgroup memory limit: %m");
return mem; return mem;

View File

@ -1705,24 +1705,50 @@ static int log_unit_internal(void *userdata, int level, int error, const char *f
} }
static bool unit_test_condition(Unit *u) { static bool unit_test_condition(Unit *u) {
_cleanup_strv_free_ char **env = NULL;
int r;
assert(u); assert(u);
dual_timestamp_get(&u->condition_timestamp); dual_timestamp_get(&u->condition_timestamp);
u->condition_result = condition_test_list(u->conditions, condition_type_to_string, log_unit_internal, u);
r = manager_get_effective_environment(u->manager, &env);
if (r < 0) {
log_unit_error_errno(u, r, "Failed to determine effective environment: %m");
u->condition_result = CONDITION_ERROR;
} else
u->condition_result = condition_test_list(
u->conditions,
env,
condition_type_to_string,
log_unit_internal,
u);
unit_add_to_dbus_queue(u); unit_add_to_dbus_queue(u);
return u->condition_result; return u->condition_result;
} }
static bool unit_test_assert(Unit *u) { static bool unit_test_assert(Unit *u) {
_cleanup_strv_free_ char **env = NULL;
int r;
assert(u); assert(u);
dual_timestamp_get(&u->assert_timestamp); dual_timestamp_get(&u->assert_timestamp);
u->assert_result = condition_test_list(u->asserts, assert_type_to_string, log_unit_internal, u);
r = manager_get_effective_environment(u->manager, &env);
if (r < 0) {
log_unit_error_errno(u, r, "Failed to determine effective environment: %m");
u->assert_result = CONDITION_ERROR;
} else
u->assert_result = condition_test_list(
u->asserts,
env,
assert_type_to_string,
log_unit_internal,
u);
unit_add_to_dbus_queue(u); unit_add_to_dbus_queue(u);
return u->assert_result; return u->assert_result;
} }

View File

@ -2,6 +2,7 @@
#include <net/if.h> #include <net/if.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <unistd.h>
#include "alloc-util.h" #include "alloc-util.h"
#include "bond.h" #include "bond.h"
@ -693,7 +694,7 @@ int netdev_load_one(Manager *manager, const char *filename) {
return r; return r;
/* skip out early if configuration does not match the environment */ /* skip out early if configuration does not match the environment */
if (!condition_test_list(netdev_raw->conditions, NULL, NULL, NULL)) { if (!condition_test_list(netdev_raw->conditions, environ, NULL, NULL, NULL)) {
log_debug("%s: Conditions in the file do not match the system environment, skipping.", filename); log_debug("%s: Conditions in the file do not match the system environment, skipping.", filename);
return 0; return 0;
} }

View File

@ -3,6 +3,7 @@
#include <net/if.h> #include <net/if.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <unistd.h>
#include "alloc-util.h" #include "alloc-util.h"
#include "conf-files.h" #include "conf-files.h"
@ -172,7 +173,7 @@ int network_verify(Network *network) {
network->filename); network->filename);
/* skip out early if configuration does not match the environment */ /* skip out early if configuration does not match the environment */
if (!condition_test_list(network->conditions, NULL, NULL, NULL)) if (!condition_test_list(network->conditions, environ, NULL, NULL, NULL))
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: Conditions in the file do not match the system environment, skipping.", "%s: Conditions in the file do not match the system environment, skipping.",
network->filename); network->filename);

View File

@ -107,7 +107,7 @@ int kernel_route_expiration_supported(void) {
.type = CONDITION_KERNEL_VERSION, .type = CONDITION_KERNEL_VERSION,
.parameter = (char *) ">= 4.5" .parameter = (char *) ">= 4.5"
}; };
r = condition_test(&c); r = condition_test(&c, NULL);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -25,6 +25,7 @@
#include "extract-word.h" #include "extract-word.h"
#include "fd-util.h" #include "fd-util.h"
#include "fileio.h" #include "fileio.h"
#include "fs-util.h"
#include "glob-util.h" #include "glob-util.h"
#include "hostname-util.h" #include "hostname-util.h"
#include "ima-util.h" #include "ima-util.h"
@ -72,11 +73,11 @@ Condition* condition_new(ConditionType type, const char *parameter, bool trigger
return c; return c;
} }
void condition_free(Condition *c) { Condition* condition_free(Condition *c) {
assert(c); assert(c);
free(c->parameter); free(c->parameter);
free(c); return mfree(c);
} }
Condition* condition_free_list_type(Condition *head, ConditionType type) { Condition* condition_free_list_type(Condition *head, ConditionType type) {
@ -92,7 +93,7 @@ Condition* condition_free_list_type(Condition *head, ConditionType type) {
return head; 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; _cleanup_free_ char *line = NULL;
const char *p; const char *p;
bool equal; 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; OrderOperator order;
struct utsname u; struct utsname u;
const char *p; const char *p;
@ -259,7 +260,7 @@ static int condition_test_kernel_version(Condition *c) {
return true; return true;
} }
static int condition_test_memory(Condition *c) { static int condition_test_memory(Condition *c, char **env) {
OrderOperator order; OrderOperator order;
uint64_t m, k; uint64_t m, k;
const char *p; const char *p;
@ -283,7 +284,7 @@ static int condition_test_memory(Condition *c) {
return test_order(CMP(m, k), order); 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; OrderOperator order;
const char *p; const char *p;
unsigned k; unsigned k;
@ -309,7 +310,7 @@ static int condition_test_cpus(Condition *c) {
return test_order(CMP((unsigned) n, k), order); 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; uid_t id;
int r; int r;
_cleanup_free_ char *username = NULL; _cleanup_free_ char *username = NULL;
@ -344,7 +345,7 @@ static int condition_test_user(Condition *c) {
return id == getuid() || id == geteuid(); 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; int r;
CGroupMask system_mask, wanted_mask = 0; 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); 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; gid_t id;
int r; int r;
@ -387,7 +388,7 @@ static int condition_test_group(Condition *c) {
return in_group(c->parameter) > 0; 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; int b, v;
assert(c); assert(c);
@ -417,7 +418,7 @@ static int condition_test_virtualization(Condition *c) {
return v != VIRTUALIZATION_NONE && streq(c->parameter, virtualization_to_string(v)); 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; int a, b;
assert(c); assert(c);
@ -439,7 +440,7 @@ static int condition_test_architecture(Condition *c) {
return a == b; return a == b;
} }
static int condition_test_host(Condition *c) { static int condition_test_host(Condition *c, char **env) {
_cleanup_free_ char *h = NULL; _cleanup_free_ char *h = NULL;
sd_id128_t x, y; sd_id128_t x, y;
int r; int r;
@ -464,7 +465,7 @@ static int condition_test_host(Condition *c) {
return fnmatch(c->parameter, h, FNM_CASEFOLD) == 0; 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; int r;
assert(c); assert(c);
@ -478,7 +479,7 @@ static int condition_test_ac_power(Condition *c) {
return (on_ac_power() != 0) == !!r; 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);
assert(c->parameter); assert(c->parameter);
assert(c->type == CONDITION_SECURITY); assert(c->type == CONDITION_SECURITY);
@ -501,7 +502,7 @@ static int condition_test_security(Condition *c) {
return false; 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; unsigned long long capabilities = (unsigned long long) -1;
_cleanup_fclose_ FILE *f = NULL; _cleanup_fclose_ FILE *f = NULL;
int value, r; int value, r;
@ -544,7 +545,7 @@ static int condition_test_capability(Condition *c) {
return !!(capabilities & (1ULL << value)); 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; const char *p;
struct stat usr, other; 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; 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; int r;
assert(c); assert(c);
@ -624,7 +625,36 @@ static int condition_test_first_boot(Condition *c) {
return (access("/run/systemd/first-boot", F_OK) >= 0) == !!r; 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);
assert(c->parameter); assert(c->parameter);
assert(c->type == CONDITION_PATH_EXISTS); 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; 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);
assert(c->parameter); assert(c->parameter);
assert(c->type == CONDITION_PATH_EXISTS_GLOB); 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; 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);
assert(c->parameter); assert(c->parameter);
assert(c->type == CONDITION_PATH_IS_DIRECTORY); 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; 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);
assert(c->parameter); assert(c->parameter);
assert(c->type == CONDITION_PATH_IS_SYMBOLIC_LINK); 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; 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);
assert(c->parameter); assert(c->parameter);
assert(c->type == CONDITION_PATH_IS_MOUNT_POINT); 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; 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);
assert(c->parameter); assert(c->parameter);
assert(c->type == CONDITION_PATH_IS_READ_WRITE); 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; 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; int r;
assert(c); assert(c);
@ -683,7 +727,7 @@ static int condition_test_directory_not_empty(Condition *c) {
return r <= 0 && r != -ENOENT; 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; struct stat st;
assert(c); assert(c);
@ -695,7 +739,7 @@ static int condition_test_file_not_empty(Condition *c) {
st.st_size > 0); 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; struct stat st;
assert(c); assert(c);
@ -707,7 +751,7 @@ static int condition_test_file_is_executable(Condition *c) {
(st.st_mode & 0111)); (st.st_mode & 0111));
} }
static int condition_test_null(Condition *c) { static int condition_test_null(Condition *c, char **env) {
assert(c); assert(c);
assert(c->type == CONDITION_NULL); assert(c->type == CONDITION_NULL);
@ -716,15 +760,16 @@ static int condition_test_null(Condition *c) {
return true; 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] = condition_test_path_exists,
[CONDITION_PATH_EXISTS_GLOB] = condition_test_path_exists_glob, [CONDITION_PATH_EXISTS_GLOB] = condition_test_path_exists_glob,
[CONDITION_PATH_IS_DIRECTORY] = condition_test_path_is_directory, [CONDITION_PATH_IS_DIRECTORY] = condition_test_path_is_directory,
[CONDITION_PATH_IS_SYMBOLIC_LINK] = condition_test_path_is_symbolic_link, [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_MOUNT_POINT] = condition_test_path_is_mount_point,
[CONDITION_PATH_IS_READ_WRITE] = condition_test_path_is_read_write, [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_DIRECTORY_NOT_EMPTY] = condition_test_directory_not_empty,
[CONDITION_FILE_NOT_EMPTY] = condition_test_file_not_empty, [CONDITION_FILE_NOT_EMPTY] = condition_test_file_not_empty,
[CONDITION_FILE_IS_EXECUTABLE] = condition_test_file_is_executable, [CONDITION_FILE_IS_EXECUTABLE] = condition_test_file_is_executable,
@ -744,6 +789,7 @@ int condition_test(Condition *c) {
[CONDITION_NULL] = condition_test_null, [CONDITION_NULL] = condition_test_null,
[CONDITION_CPUS] = condition_test_cpus, [CONDITION_CPUS] = condition_test_cpus,
[CONDITION_MEMORY] = condition_test_memory, [CONDITION_MEMORY] = condition_test_memory,
[CONDITION_ENVIRONMENT] = condition_test_environment,
}; };
int r, b; int r, b;
@ -752,7 +798,7 @@ int condition_test(Condition *c) {
assert(c->type >= 0); assert(c->type >= 0);
assert(c->type < _CONDITION_TYPE_MAX); assert(c->type < _CONDITION_TYPE_MAX);
r = condition_tests[c->type](c); r = condition_tests[c->type](c, env);
if (r < 0) { if (r < 0) {
c->result = CONDITION_ERROR; c->result = CONDITION_ERROR;
return r; return r;
@ -763,7 +809,13 @@ int condition_test(Condition *c) {
return b; 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; Condition *c;
int triggered = -1; int triggered = -1;
@ -779,7 +831,7 @@ bool condition_test_list(Condition *first, const char *(*to_string)(ConditionTyp
LIST_FOREACH(conditions, c, first) { LIST_FOREACH(conditions, c, first) {
int r; int r;
r = condition_test(c); r = condition_test(c, env);
if (logger) { if (logger) {
const char *p = c->type == CONDITION_NULL ? "true" : c->parameter; 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; 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(c);
assert(f); assert(f);
assert(to_string);
prefix = strempty(prefix); 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)); 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; Condition *c;
LIST_FOREACH(conditions, c, first) 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_SYMBOLIC_LINK] = "ConditionPathIsSymbolicLink",
[CONDITION_PATH_IS_MOUNT_POINT] = "ConditionPathIsMountPoint", [CONDITION_PATH_IS_MOUNT_POINT] = "ConditionPathIsMountPoint",
[CONDITION_PATH_IS_READ_WRITE] = "ConditionPathIsReadWrite", [CONDITION_PATH_IS_READ_WRITE] = "ConditionPathIsReadWrite",
[CONDITION_PATH_IS_ENCRYPTED] = "ConditionPathIsEncrypted",
[CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty", [CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty",
[CONDITION_FILE_NOT_EMPTY] = "ConditionFileNotEmpty", [CONDITION_FILE_NOT_EMPTY] = "ConditionFileNotEmpty",
[CONDITION_FILE_IS_EXECUTABLE] = "ConditionFileIsExecutable", [CONDITION_FILE_IS_EXECUTABLE] = "ConditionFileIsExecutable",
@ -861,6 +915,7 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
[CONDITION_NULL] = "ConditionNull", [CONDITION_NULL] = "ConditionNull",
[CONDITION_CPUS] = "ConditionCPUs", [CONDITION_CPUS] = "ConditionCPUs",
[CONDITION_MEMORY] = "ConditionMemory", [CONDITION_MEMORY] = "ConditionMemory",
[CONDITION_ENVIRONMENT] = "ConditionEnvironment",
}; };
DEFINE_STRING_TABLE_LOOKUP(condition_type, ConditionType); 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_SYMBOLIC_LINK] = "AssertPathIsSymbolicLink",
[CONDITION_PATH_IS_MOUNT_POINT] = "AssertPathIsMountPoint", [CONDITION_PATH_IS_MOUNT_POINT] = "AssertPathIsMountPoint",
[CONDITION_PATH_IS_READ_WRITE] = "AssertPathIsReadWrite", [CONDITION_PATH_IS_READ_WRITE] = "AssertPathIsReadWrite",
[CONDITION_PATH_IS_ENCRYPTED] = "AssertPathIsEncrypted",
[CONDITION_DIRECTORY_NOT_EMPTY] = "AssertDirectoryNotEmpty", [CONDITION_DIRECTORY_NOT_EMPTY] = "AssertDirectoryNotEmpty",
[CONDITION_FILE_NOT_EMPTY] = "AssertFileNotEmpty", [CONDITION_FILE_NOT_EMPTY] = "AssertFileNotEmpty",
[CONDITION_FILE_IS_EXECUTABLE] = "AssertFileIsExecutable", [CONDITION_FILE_IS_EXECUTABLE] = "AssertFileIsExecutable",
@ -891,6 +947,7 @@ static const char* const assert_type_table[_CONDITION_TYPE_MAX] = {
[CONDITION_NULL] = "AssertNull", [CONDITION_NULL] = "AssertNull",
[CONDITION_CPUS] = "AssertCPUs", [CONDITION_CPUS] = "AssertCPUs",
[CONDITION_MEMORY] = "AssertMemory", [CONDITION_MEMORY] = "AssertMemory",
[CONDITION_ENVIRONMENT] = "AssertEnvironment",
}; };
DEFINE_STRING_TABLE_LOOKUP(assert_type, ConditionType); DEFINE_STRING_TABLE_LOOKUP(assert_type, ConditionType);

View File

@ -18,6 +18,7 @@ typedef enum ConditionType {
CONDITION_AC_POWER, CONDITION_AC_POWER,
CONDITION_MEMORY, CONDITION_MEMORY,
CONDITION_CPUS, CONDITION_CPUS,
CONDITION_ENVIRONMENT,
CONDITION_NEEDS_UPDATE, CONDITION_NEEDS_UPDATE,
CONDITION_FIRST_BOOT, CONDITION_FIRST_BOOT,
@ -28,6 +29,7 @@ typedef enum ConditionType {
CONDITION_PATH_IS_SYMBOLIC_LINK, CONDITION_PATH_IS_SYMBOLIC_LINK,
CONDITION_PATH_IS_MOUNT_POINT, CONDITION_PATH_IS_MOUNT_POINT,
CONDITION_PATH_IS_READ_WRITE, CONDITION_PATH_IS_READ_WRITE,
CONDITION_PATH_IS_ENCRYPTED,
CONDITION_DIRECTORY_NOT_EMPTY, CONDITION_DIRECTORY_NOT_EMPTY,
CONDITION_FILE_NOT_EMPTY, CONDITION_FILE_NOT_EMPTY,
CONDITION_FILE_IS_EXECUTABLE, CONDITION_FILE_IS_EXECUTABLE,
@ -66,18 +68,20 @@ typedef struct Condition {
} Condition; } Condition;
Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate); 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); Condition* condition_free_list_type(Condition *first, ConditionType type);
static inline Condition* condition_free_list(Condition *first) { static inline Condition* condition_free_list(Condition *first) {
return condition_free_list_type(first, _CONDITION_TYPE_INVALID); return condition_free_list_type(first, _CONDITION_TYPE_INVALID);
} }
int condition_test(Condition *c); int condition_test(Condition *c, char **env);
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);
void condition_dump(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);
void condition_dump_list(Condition *c, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t)); 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_; const char* condition_type_to_string(ConditionType t) _const_;
ConditionType condition_type_from_string(const char *s) _pure_; 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_SYMBOLIC_LINK,
CONDITION_PATH_IS_MOUNT_POINT, CONDITION_PATH_IS_MOUNT_POINT,
CONDITION_PATH_IS_READ_WRITE, CONDITION_PATH_IS_READ_WRITE,
CONDITION_PATH_IS_ENCRYPTED,
CONDITION_DIRECTORY_NOT_EMPTY, CONDITION_DIRECTORY_NOT_EMPTY,
CONDITION_FILE_NOT_EMPTY, CONDITION_FILE_NOT_EMPTY,
CONDITION_FILE_IS_EXECUTABLE, CONDITION_FILE_IS_EXECUTABLE,

View File

@ -39,82 +39,87 @@ static void test_condition_test_path(void) {
condition = condition_new(CONDITION_PATH_EXISTS, "/bin/sh", false, false); condition = condition_new(CONDITION_PATH_EXISTS, "/bin/sh", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition)); assert_se(condition_test(condition, environ));
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_PATH_EXISTS, "/bin/s?", false, false); condition = condition_new(CONDITION_PATH_EXISTS, "/bin/s?", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_PATH_EXISTS_GLOB, "/bin/s?", false, false); condition = condition_new(CONDITION_PATH_EXISTS_GLOB, "/bin/s?", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_PATH_EXISTS_GLOB, "/bin/s?", false, true); condition = condition_new(CONDITION_PATH_EXISTS_GLOB, "/bin/s?", false, true);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_PATH_EXISTS, "/thiscertainlywontexist", false, false); condition = condition_new(CONDITION_PATH_EXISTS, "/thiscertainlywontexist", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_PATH_EXISTS, "/thiscertainlywontexist", false, true); condition = condition_new(CONDITION_PATH_EXISTS, "/thiscertainlywontexist", false, true);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_PATH_IS_DIRECTORY, "/bin", false, false); condition = condition_new(CONDITION_PATH_IS_DIRECTORY, "/bin", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_DIRECTORY_NOT_EMPTY, "/bin", false, false); condition = condition_new(CONDITION_DIRECTORY_NOT_EMPTY, "/bin", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_FILE_NOT_EMPTY, "/bin/sh", false, false); condition = condition_new(CONDITION_FILE_NOT_EMPTY, "/bin/sh", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_FILE_IS_EXECUTABLE, "/bin/sh", false, false); condition = condition_new(CONDITION_FILE_IS_EXECUTABLE, "/bin/sh", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_FILE_IS_EXECUTABLE, "/etc/passwd", false, false); condition = condition_new(CONDITION_FILE_IS_EXECUTABLE, "/etc/passwd", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/proc", false, false); condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/proc", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/", false, false); condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/bin", false, false); condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/bin", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_PATH_IS_READ_WRITE, "/tmp", false, false); condition = condition_new(CONDITION_PATH_IS_READ_WRITE, "/tmp", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition);
condition = condition_new(CONDITION_PATH_IS_ENCRYPTED, "/sys", false, false);
assert_se(condition);
assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_PATH_IS_SYMBOLIC_LINK, "/dev/stdout", false, false); condition = condition_new(CONDITION_PATH_IS_SYMBOLIC_LINK, "/dev/stdout", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
} }
@ -134,12 +139,12 @@ static void test_condition_test_control_group_controller(void) {
/* Invalid controllers are ignored */ /* Invalid controllers are ignored */
condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "thisisnotarealcontroller", false, false); condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "thisisnotarealcontroller", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "thisisnotarealcontroller", false, true); condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "thisisnotarealcontroller", false, true);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
assert_se(cg_mask_supported(&system_mask) >= 0); assert_se(cg_mask_supported(&system_mask) >= 0);
@ -152,23 +157,23 @@ static void test_condition_test_control_group_controller(void) {
log_info("this controller is available"); log_info("this controller is available");
condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, false); condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, true); condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, true);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
} else { } else {
log_info("this controller is unavailable"); log_info("this controller is unavailable");
condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, false); condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, true); condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, true);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
} }
} }
@ -178,12 +183,12 @@ static void test_condition_test_control_group_controller(void) {
condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, strempty(controller_name), false, false); condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, strempty(controller_name), false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, strempty(controller_name), false, true); condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, strempty(controller_name), false, true);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
} }
@ -192,17 +197,17 @@ static void test_condition_test_ac_power(void) {
condition = condition_new(CONDITION_AC_POWER, "true", false, false); condition = condition_new(CONDITION_AC_POWER, "true", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == on_ac_power()); assert_se(condition_test(condition, environ) == on_ac_power());
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_AC_POWER, "false", false, false); condition = condition_new(CONDITION_AC_POWER, "false", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) != on_ac_power()); assert_se(condition_test(condition, environ) != on_ac_power());
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_AC_POWER, "false", false, true); condition = condition_new(CONDITION_AC_POWER, "false", false, true);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == on_ac_power()); assert_se(condition_test(condition, environ) == on_ac_power());
condition_free(condition); condition_free(condition);
} }
@ -219,17 +224,17 @@ static void test_condition_test_host(void) {
condition = condition_new(CONDITION_HOST, sid, false, false); condition = condition_new(CONDITION_HOST, sid, false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_HOST, "garbage value jjjjjjjjjjjjjj", false, false); condition = condition_new(CONDITION_HOST, "garbage value jjjjjjjjjjjjjj", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_HOST, sid, false, true); condition = condition_new(CONDITION_HOST, sid, false, true);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
hostname = gethostname_malloc(); hostname = gethostname_malloc();
@ -241,7 +246,7 @@ static void test_condition_test_host(void) {
else { else {
condition = condition_new(CONDITION_HOST, hostname, false, false); condition = condition_new(CONDITION_HOST, hostname, false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
} }
} }
@ -259,17 +264,17 @@ static void test_condition_test_architecture(void) {
condition = condition_new(CONDITION_ARCHITECTURE, sa, false, false); condition = condition_new(CONDITION_ARCHITECTURE, sa, false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_ARCHITECTURE, "garbage value", false, false); condition = condition_new(CONDITION_ARCHITECTURE, "garbage value", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_ARCHITECTURE, sa, false, true); condition = condition_new(CONDITION_ARCHITECTURE, sa, false, true);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
} }
@ -279,7 +284,7 @@ static void test_condition_test_kernel_command_line(void) {
condition = condition_new(CONDITION_KERNEL_COMMAND_LINE, "thisreallyshouldntbeonthekernelcommandline", false, false); condition = condition_new(CONDITION_KERNEL_COMMAND_LINE, "thisreallyshouldntbeonthekernelcommandline", false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
if (ERRNO_IS_PRIVILEGE(r)) if (ERRNO_IS_PRIVILEGE(r))
return; return;
assert_se(r == 0); assert_se(r == 0);
@ -287,7 +292,7 @@ static void test_condition_test_kernel_command_line(void) {
condition = condition_new(CONDITION_KERNEL_COMMAND_LINE, "andthis=neither", false, false); condition = condition_new(CONDITION_KERNEL_COMMAND_LINE, "andthis=neither", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
} }
@ -298,26 +303,26 @@ static void test_condition_test_kernel_version(void) {
condition = condition_new(CONDITION_KERNEL_VERSION, "*thisreallyshouldntbeinthekernelversion*", false, false); condition = condition_new(CONDITION_KERNEL_VERSION, "*thisreallyshouldntbeinthekernelversion*", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, "*", false, false); condition = condition_new(CONDITION_KERNEL_VERSION, "*", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
/* An artificially empty condition. It evaluates to true, but normally /* An artificially empty condition. It evaluates to true, but normally
* such condition cannot be created, because the condition list is reset instead. */ * such condition cannot be created, because the condition list is reset instead. */
condition = condition_new(CONDITION_KERNEL_VERSION, "", false, false); condition = condition_new(CONDITION_KERNEL_VERSION, "", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
assert_se(uname(&u) >= 0); assert_se(uname(&u) >= 0);
condition = condition_new(CONDITION_KERNEL_VERSION, u.release, false, false); condition = condition_new(CONDITION_KERNEL_VERSION, u.release, false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
strshorten(u.release, 4); strshorten(u.release, 4);
@ -325,79 +330,79 @@ static void test_condition_test_kernel_version(void) {
condition = condition_new(CONDITION_KERNEL_VERSION, u.release, false, false); condition = condition_new(CONDITION_KERNEL_VERSION, u.release, false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
/* 0.1.2 would be a very very very old kernel */ /* 0.1.2 would be a very very very old kernel */
condition = condition_new(CONDITION_KERNEL_VERSION, "> 0.1.2", false, false); condition = condition_new(CONDITION_KERNEL_VERSION, "> 0.1.2", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, ">0.1.2", false, false); condition = condition_new(CONDITION_KERNEL_VERSION, ">0.1.2", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, "'>0.1.2' '<9.0.0'", false, false); condition = condition_new(CONDITION_KERNEL_VERSION, "'>0.1.2' '<9.0.0'", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, "> 0.1.2 < 9.0.0", false, false); condition = condition_new(CONDITION_KERNEL_VERSION, "> 0.1.2 < 9.0.0", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == -EINVAL); assert_se(condition_test(condition, environ) == -EINVAL);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, ">", false, false); condition = condition_new(CONDITION_KERNEL_VERSION, ">", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == -EINVAL); assert_se(condition_test(condition, environ) == -EINVAL);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, ">= 0.1.2", false, false); condition = condition_new(CONDITION_KERNEL_VERSION, ">= 0.1.2", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, "< 0.1.2", false, false); condition = condition_new(CONDITION_KERNEL_VERSION, "< 0.1.2", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, "<= 0.1.2", false, false); condition = condition_new(CONDITION_KERNEL_VERSION, "<= 0.1.2", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, "= 0.1.2", false, false); condition = condition_new(CONDITION_KERNEL_VERSION, "= 0.1.2", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
/* 4711.8.15 is a very very very future kernel */ /* 4711.8.15 is a very very very future kernel */
condition = condition_new(CONDITION_KERNEL_VERSION, "< 4711.8.15", false, false); condition = condition_new(CONDITION_KERNEL_VERSION, "< 4711.8.15", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, "<= 4711.8.15", false, false); condition = condition_new(CONDITION_KERNEL_VERSION, "<= 4711.8.15", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, "= 4711.8.15", false, false); condition = condition_new(CONDITION_KERNEL_VERSION, "= 4711.8.15", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, "> 4711.8.15", false, false); condition = condition_new(CONDITION_KERNEL_VERSION, "> 4711.8.15", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, ">= 4711.8.15", false, false); condition = condition_new(CONDITION_KERNEL_VERSION, ">= 4711.8.15", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
assert_se(uname(&u) >= 0); assert_se(uname(&u) >= 0);
@ -405,31 +410,31 @@ static void test_condition_test_kernel_version(void) {
v = strjoina(">=", u.release); v = strjoina(">=", u.release);
condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false); condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
v = strjoina("= ", u.release); v = strjoina("= ", u.release);
condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false); condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
v = strjoina("<=", u.release); v = strjoina("<=", u.release);
condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false); condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
v = strjoina("> ", u.release); v = strjoina("> ", u.release);
condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false); condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
v = strjoina("< ", u.release); v = strjoina("< ", u.release);
condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false); condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
} }
@ -438,12 +443,12 @@ static void test_condition_test_null(void) {
condition = condition_new(CONDITION_NULL, NULL, false, false); condition = condition_new(CONDITION_NULL, NULL, false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) > 0); assert_se(condition_test(condition, environ) > 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_NULL, NULL, false, true); condition = condition_new(CONDITION_NULL, NULL, false, true);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
} }
@ -452,42 +457,42 @@ static void test_condition_test_security(void) {
condition = condition_new(CONDITION_SECURITY, "garbage oifdsjfoidsjoj", false, false); condition = condition_new(CONDITION_SECURITY, "garbage oifdsjfoidsjoj", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == 0); assert_se(condition_test(condition, environ) == 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_SECURITY, "selinux", false, true); condition = condition_new(CONDITION_SECURITY, "selinux", false, true);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) != mac_selinux_use()); assert_se(condition_test(condition, environ) != mac_selinux_use());
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_SECURITY, "apparmor", false, false); condition = condition_new(CONDITION_SECURITY, "apparmor", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == mac_apparmor_use()); assert_se(condition_test(condition, environ) == mac_apparmor_use());
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_SECURITY, "tomoyo", false, false); condition = condition_new(CONDITION_SECURITY, "tomoyo", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == mac_tomoyo_use()); assert_se(condition_test(condition, environ) == mac_tomoyo_use());
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_SECURITY, "ima", false, false); condition = condition_new(CONDITION_SECURITY, "ima", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == use_ima()); assert_se(condition_test(condition, environ) == use_ima());
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_SECURITY, "smack", false, false); condition = condition_new(CONDITION_SECURITY, "smack", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == mac_smack_use()); assert_se(condition_test(condition, environ) == mac_smack_use());
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_SECURITY, "audit", false, false); condition = condition_new(CONDITION_SECURITY, "audit", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == use_audit()); assert_se(condition_test(condition, environ) == use_audit());
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_SECURITY, "uefi-secureboot", false, false); condition = condition_new(CONDITION_SECURITY, "uefi-secureboot", false, false);
assert_se(condition); assert_se(condition);
assert_se(condition_test(condition) == is_efi_secure_boot()); assert_se(condition_test(condition, environ) == is_efi_secure_boot());
condition_free(condition); condition_free(condition);
} }
@ -510,7 +515,7 @@ static void test_condition_test_virtualization(void) {
condition = condition_new(CONDITION_VIRTUALIZATION, "garbage oifdsjfoidsjoj", false, false); condition = condition_new(CONDITION_VIRTUALIZATION, "garbage oifdsjfoidsjoj", false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
if (ERRNO_IS_PRIVILEGE(r)) if (ERRNO_IS_PRIVILEGE(r))
return; return;
log_info("ConditionVirtualization=garbage → %i", r); log_info("ConditionVirtualization=garbage → %i", r);
@ -519,21 +524,21 @@ static void test_condition_test_virtualization(void) {
condition = condition_new(CONDITION_VIRTUALIZATION, "container", false, false); condition = condition_new(CONDITION_VIRTUALIZATION, "container", false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
log_info("ConditionVirtualization=container → %i", r); log_info("ConditionVirtualization=container → %i", r);
assert_se(r == !!detect_container()); assert_se(r == !!detect_container());
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_VIRTUALIZATION, "vm", false, false); condition = condition_new(CONDITION_VIRTUALIZATION, "vm", false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
log_info("ConditionVirtualization=vm → %i", r); log_info("ConditionVirtualization=vm → %i", r);
assert_se(r == (detect_vm() && !detect_container())); assert_se(r == (detect_vm() && !detect_container()));
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_VIRTUALIZATION, "private-users", false, false); condition = condition_new(CONDITION_VIRTUALIZATION, "private-users", false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
log_info("ConditionVirtualization=private-users → %i", r); log_info("ConditionVirtualization=private-users → %i", r);
assert_se(r == !!running_in_userns()); assert_se(r == !!running_in_userns());
condition_free(condition); condition_free(condition);
@ -554,7 +559,7 @@ static void test_condition_test_virtualization(void) {
condition = condition_new(CONDITION_VIRTUALIZATION, virt, false, false); condition = condition_new(CONDITION_VIRTUALIZATION, virt, false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
log_info("ConditionVirtualization=%s → %i", virt, r); log_info("ConditionVirtualization=%s → %i", virt, r);
assert_se(r >= 0); assert_se(r >= 0);
condition_free(condition); condition_free(condition);
@ -569,7 +574,7 @@ static void test_condition_test_user(void) {
condition = condition_new(CONDITION_USER, "garbage oifdsjfoidsjoj", false, false); condition = condition_new(CONDITION_USER, "garbage oifdsjfoidsjoj", false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
log_info("ConditionUser=garbage → %i", r); log_info("ConditionUser=garbage → %i", r);
assert_se(r == 0); assert_se(r == 0);
condition_free(condition); condition_free(condition);
@ -577,7 +582,7 @@ static void test_condition_test_user(void) {
assert_se(asprintf(&uid, "%"PRIu32, UINT32_C(0xFFFF)) > 0); assert_se(asprintf(&uid, "%"PRIu32, UINT32_C(0xFFFF)) > 0);
condition = condition_new(CONDITION_USER, uid, false, false); condition = condition_new(CONDITION_USER, uid, false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
log_info("ConditionUser=%s → %i", uid, r); log_info("ConditionUser=%s → %i", uid, r);
assert_se(r == 0); assert_se(r == 0);
condition_free(condition); condition_free(condition);
@ -586,7 +591,7 @@ static void test_condition_test_user(void) {
assert_se(asprintf(&uid, "%u", (unsigned)getuid()) > 0); assert_se(asprintf(&uid, "%u", (unsigned)getuid()) > 0);
condition = condition_new(CONDITION_USER, uid, false, false); condition = condition_new(CONDITION_USER, uid, false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
log_info("ConditionUser=%s → %i", uid, r); log_info("ConditionUser=%s → %i", uid, r);
assert_se(r > 0); assert_se(r > 0);
condition_free(condition); condition_free(condition);
@ -595,7 +600,7 @@ static void test_condition_test_user(void) {
assert_se(asprintf(&uid, "%u", (unsigned)getuid()+1) > 0); assert_se(asprintf(&uid, "%u", (unsigned)getuid()+1) > 0);
condition = condition_new(CONDITION_USER, uid, false, false); condition = condition_new(CONDITION_USER, uid, false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
log_info("ConditionUser=%s → %i", uid, r); log_info("ConditionUser=%s → %i", uid, r);
assert_se(r == 0); assert_se(r == 0);
condition_free(condition); condition_free(condition);
@ -605,7 +610,7 @@ static void test_condition_test_user(void) {
assert_se(username); assert_se(username);
condition = condition_new(CONDITION_USER, username, false, false); condition = condition_new(CONDITION_USER, username, false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
log_info("ConditionUser=%s → %i", username, r); log_info("ConditionUser=%s → %i", username, r);
assert_se(r > 0); assert_se(r > 0);
condition_free(condition); condition_free(condition);
@ -614,14 +619,14 @@ static void test_condition_test_user(void) {
username = (char*)(geteuid() == 0 ? NOBODY_USER_NAME : "root"); username = (char*)(geteuid() == 0 ? NOBODY_USER_NAME : "root");
condition = condition_new(CONDITION_USER, username, false, false); condition = condition_new(CONDITION_USER, username, false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
log_info("ConditionUser=%s → %i", username, r); log_info("ConditionUser=%s → %i", username, r);
assert_se(r == 0); assert_se(r == 0);
condition_free(condition); condition_free(condition);
condition = condition_new(CONDITION_USER, "@system", false, false); condition = condition_new(CONDITION_USER, "@system", false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
log_info("ConditionUser=@system → %i", r); log_info("ConditionUser=@system → %i", r);
if (uid_is_system(getuid()) || uid_is_system(geteuid())) if (uid_is_system(getuid()) || uid_is_system(geteuid()))
assert_se(r > 0); assert_se(r > 0);
@ -640,7 +645,7 @@ static void test_condition_test_group(void) {
assert_se(0 < asprintf(&gid, "%u", UINT32_C(0xFFFF))); assert_se(0 < asprintf(&gid, "%u", UINT32_C(0xFFFF)));
condition = condition_new(CONDITION_GROUP, gid, false, false); condition = condition_new(CONDITION_GROUP, gid, false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
log_info("ConditionGroup=%s → %i", gid, r); log_info("ConditionGroup=%s → %i", gid, r);
assert_se(r == 0); assert_se(r == 0);
condition_free(condition); condition_free(condition);
@ -649,7 +654,7 @@ static void test_condition_test_group(void) {
assert_se(0 < asprintf(&gid, "%u", getgid())); assert_se(0 < asprintf(&gid, "%u", getgid()));
condition = condition_new(CONDITION_GROUP, gid, false, false); condition = condition_new(CONDITION_GROUP, gid, false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
log_info("ConditionGroup=%s → %i", gid, r); log_info("ConditionGroup=%s → %i", gid, r);
assert_se(r > 0); assert_se(r > 0);
condition_free(condition); condition_free(condition);
@ -668,7 +673,7 @@ static void test_condition_test_group(void) {
assert_se(0 < asprintf(&gid, "%u", gids[i])); assert_se(0 < asprintf(&gid, "%u", gids[i]));
condition = condition_new(CONDITION_GROUP, gid, false, false); condition = condition_new(CONDITION_GROUP, gid, false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
log_info("ConditionGroup=%s → %i", gid, r); log_info("ConditionGroup=%s → %i", gid, r);
assert_se(r > 0); assert_se(r > 0);
condition_free(condition); condition_free(condition);
@ -679,7 +684,7 @@ static void test_condition_test_group(void) {
assert_se(groupname); assert_se(groupname);
condition = condition_new(CONDITION_GROUP, groupname, false, false); condition = condition_new(CONDITION_GROUP, groupname, false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
log_info("ConditionGroup=%s → %i", groupname, r); log_info("ConditionGroup=%s → %i", groupname, r);
assert_se(r > 0); assert_se(r > 0);
condition_free(condition); condition_free(condition);
@ -690,7 +695,7 @@ static void test_condition_test_group(void) {
assert_se(0 < asprintf(&gid, "%u", max_gid+1)); assert_se(0 < asprintf(&gid, "%u", max_gid+1));
condition = condition_new(CONDITION_GROUP, gid, false, false); condition = condition_new(CONDITION_GROUP, gid, false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
log_info("ConditionGroup=%s → %i", gid, r); log_info("ConditionGroup=%s → %i", gid, r);
assert_se(r == 0); assert_se(r == 0);
condition_free(condition); condition_free(condition);
@ -699,7 +704,7 @@ static void test_condition_test_group(void) {
groupname = (char*)(getegid() == 0 ? NOBODY_GROUP_NAME : "root"); groupname = (char*)(getegid() == 0 ? NOBODY_GROUP_NAME : "root");
condition = condition_new(CONDITION_GROUP, groupname, false, false); condition = condition_new(CONDITION_GROUP, groupname, false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
log_info("ConditionGroup=%s → %i", groupname, r); log_info("ConditionGroup=%s → %i", groupname, r);
assert_se(r == 0); assert_se(r == 0);
condition_free(condition); condition_free(condition);
@ -714,7 +719,7 @@ static void test_condition_test_cpus_one(const char *s, bool result) {
condition = condition_new(CONDITION_CPUS, s, false, false); condition = condition_new(CONDITION_CPUS, s, false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
assert_se(r >= 0); assert_se(r >= 0);
assert_se(r == result); assert_se(r == result);
condition_free(condition); condition_free(condition);
@ -775,7 +780,7 @@ static void test_condition_test_memory_one(const char *s, bool result) {
condition = condition_new(CONDITION_MEMORY, s, false, false); condition = condition_new(CONDITION_MEMORY, s, false, false);
assert_se(condition); assert_se(condition);
r = condition_test(condition); r = condition_test(condition, environ);
assert_se(r >= 0); assert_se(r >= 0);
assert_se(r == result); assert_se(r == result);
condition_free(condition); condition_free(condition);
@ -826,6 +831,34 @@ static void test_condition_test_memory(void) {
t = mfree(t); t = mfree(t);
} }
static void test_condition_test_environment_one(const char *s, bool result) {
Condition *condition;
int r;
log_debug("%s=%s", condition_type_to_string(CONDITION_ENVIRONMENT), s);
condition = condition_new(CONDITION_ENVIRONMENT, s, false, false);
assert_se(condition);
r = condition_test(condition, environ);
assert_se(r >= 0);
assert_se(r == result);
condition_free(condition);
}
static void test_condition_test_environment(void) {
assert_se(setenv("EXISTINGENVVAR", "foo", false) >= 0);
test_condition_test_environment_one("MISSINGENVVAR", false);
test_condition_test_environment_one("MISSINGENVVAR=foo", false);
test_condition_test_environment_one("MISSINGENVVAR=", false);
test_condition_test_environment_one("EXISTINGENVVAR", true);
test_condition_test_environment_one("EXISTINGENVVAR=foo", true);
test_condition_test_environment_one("EXISTINGENVVAR=bar", false);
test_condition_test_environment_one("EXISTINGENVVAR=", false);
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
test_setup_logging(LOG_DEBUG); test_setup_logging(LOG_DEBUG);
@ -844,6 +877,7 @@ int main(int argc, char *argv[]) {
test_condition_test_control_group_controller(); test_condition_test_control_group_controller();
test_condition_test_cpus(); test_condition_test_cpus();
test_condition_test_memory(); test_condition_test_memory();
test_condition_test_environment();
return 0; return 0;
} }

View File

@ -2,6 +2,7 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <netinet/ether.h> #include <netinet/ether.h>
#include <unistd.h>
#include "sd-device.h" #include "sd-device.h"
#include "sd-netlink.h" #include "sd-netlink.h"
@ -173,7 +174,7 @@ int link_load_one(link_config_ctx *ctx, const char *filename) {
return 0; return 0;
} }
if (!condition_test_list(link->conditions, NULL, NULL, NULL)) { if (!condition_test_list(link->conditions, environ, NULL, NULL, NULL)) {
log_debug("%s: Conditions do not match the system environment, skipping.", filename); log_debug("%s: Conditions do not match the system environment, skipping.", filename);
return 0; return 0;
} }