mirror of
https://github.com/systemd/systemd.git
synced 2024-11-23 18:23:32 +08:00
unit: introduce ConditionCapability
This commit is contained in:
parent
822b18599d
commit
62590f23c1
2
TODO
2
TODO
@ -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
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user