diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/condition.c | 34 | ||||
-rw-r--r-- | src/condition.h | 1 | ||||
-rw-r--r-- | src/load-fragment-gperf.gperf.m4 | 1 |
3 files changed, 36 insertions, 0 deletions
diff --git a/src/condition.c b/src/condition.c index 07624c841d..f18c45421a 100644 --- a/src/condition.c +++ b/src/condition.c @@ -23,6 +23,7 @@ #include <errno.h> #include <string.h> #include <unistd.h> +#include <sys/capability.h> #ifdef HAVE_SELINUX #include <selinux/selinux.h> @@ -159,6 +160,36 @@ static bool test_security(const char *parameter) { return false; } +static bool test_capability(const char *parameter) { + cap_value_t value; + FILE *f; + char line[LINE_MAX]; + unsigned long long capabilities = (unsigned long long) -1; + + /* If it's an invalid capability, we don't have it */ + + if (cap_from_name(parameter, &value) < 0) + return false; + + /* If it's a valid capability we default to assume + * that we have it */ + + f = fopen("/proc/self/status", "re"); + if (!f) + return true; + + while (fgets(line, sizeof(line), f)) { + truncate_nl(line); + + if (startswith(line, "CapBnd:")) { + (void) sscanf(line+7, "%llx", &capabilities); + break; + } + } + + return !!(capabilities & (1ULL << value)); +} + bool condition_test(Condition *c) { assert(c); @@ -214,6 +245,9 @@ bool condition_test(Condition *c) { case CONDITION_SECURITY: return test_security(c->parameter) == !c->negate; + case CONDITION_CAPABILITY: + return test_capability(c->parameter) == !c->negate; + case CONDITION_NULL: return !c->negate; diff --git a/src/condition.h b/src/condition.h index dd65aa6054..71b1c6761e 100644 --- a/src/condition.h +++ b/src/condition.h @@ -37,6 +37,7 @@ typedef enum ConditionType { CONDITION_KERNEL_COMMAND_LINE, CONDITION_VIRTUALIZATION, CONDITION_SECURITY, + CONDITION_CAPABILITY, CONDITION_NULL, _CONDITION_TYPE_MAX, _CONDITION_TYPE_INVALID = -1 diff --git a/src/load-fragment-gperf.gperf.m4 b/src/load-fragment-gperf.gperf.m4 index 7749b88dfb..41797d20c0 100644 --- a/src/load-fragment-gperf.gperf.m4 +++ b/src/load-fragment-gperf.gperf.m4 @@ -119,6 +119,7 @@ Unit.ConditionFileIsExecutable, config_parse_unit_condition_path, CONDITION_F Unit.ConditionKernelCommandLine, config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, 0 Unit.ConditionVirtualization, config_parse_unit_condition_string, CONDITION_VIRTUALIZATION, 0 Unit.ConditionSecurity, config_parse_unit_condition_string, CONDITION_SECURITY, 0 +Unit.ConditionCapability, config_parse_unit_condition_string, CONDITION_CAPABILITY, 0 Unit.ConditionNull, config_parse_unit_condition_null, 0, 0 m4_dnl Service.PIDFile, config_parse_unit_path_printf, 0, offsetof(Service, pid_file) |