unit: introduce ConditionCapability

This commit is contained in:
Lennart Poettering 2011-10-11 15:16:52 +02:00
parent 822b18599d
commit 62590f23c1
5 changed files with 56 additions and 6 deletions

2
TODO
View File

@ -19,7 +19,7 @@ Bugfixes:
Features:
* ConditionCapability=
* unset container= in PID1?
* if we can not get user quota for tmpfs, mount a separate tmpfs instance
for every user in /run/user/$USER with a configured maximum size

View File

@ -673,6 +673,7 @@
<term><varname>ConditionKernelCommandLine=</varname></term>
<term><varname>ConditionVirtualization=</varname></term>
<term><varname>ConditionSecurity=</varname></term>
<term><varname>ConditionCapability=</varname></term>
<term><varname>ConditionNull=</varname></term>
<listitem><para>Before starting a unit
@ -749,9 +750,9 @@
value to check if being executed in
any virtualized environment, or one of
<varname>vm</varname> and
<varname>container</varname> to test against
a specific type of virtualization
solution, or one of
<varname>container</varname> to test
against a specific type of
virtualization solution, or one of
<varname>qemu</varname>,
<varname>kvm</varname>,
<varname>vmware</varname>,
@ -775,7 +776,19 @@
system. Currently the only recognized
value is <varname>selinux</varname>.
The test may be negated by prepending
an exclamation mark. Finally,
an exclamation
mark. <varname>ConditionCapability=</varname>
may be used to check whether the given
capability exists in the capability
bounding set of the service manager
(i.e. this does not check whether
capability is actually available in
the permitted or effective sets, see
<citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
for details). Pass a capability name
such as <literal>CAP_MKNOD</literal>,
possibly prefixed with an exclamation
mark to negate the check. Finally,
<varname>ConditionNull=</varname> may
be used to add a constant condition
check value to the unit. It takes a
@ -932,7 +945,8 @@
<citerefentry><refentrytitle>systemd.target</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.path</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.snapshot</refentrytitle><manvolnum>5</manvolnum></citerefentry>
<citerefentry><refentrytitle>systemd.snapshot</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
</para>
</refsect1>

View File

@ -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;

View File

@ -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

View File

@ -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)