summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd.service.xml40
-rw-r--r--src/core/load-fragment-gperf.gperf.m43
-rw-r--r--src/core/load-fragment.c56
-rw-r--r--src/core/load-fragment.h1
4 files changed, 100 insertions, 0 deletions
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index c84a5254b3..a82dfb2c86 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -308,6 +308,46 @@
</varlistentry>
<varlistentry>
+ <term><varname>BusPolicy=</varname></term>
+
+ <listitem><para>If specfied, a custom kdbus
+ endpoint will be created and installed as the
+ default bus node for the service. Such a custom
+ endpoint can hold an own set of policy rules
+ that are enforced on top of the bus-wide ones.
+ The custom endpoint is named after the service
+ it was created for, and its node will be
+ bind-mounted over the default bus node
+ location, so the service can only access the
+ bus through its own endpoint. Note that custom
+ bus endpoints default to a 'deny all' policy.
+ Hence, if at least one
+ <varname>BusPolicy=</varname> directive is
+ given, you have to make sure to add explicit
+ rules for everything the service should be able
+ to do.</para>
+ <para>The value of this directive is comprised
+ of two parts; the bus name, and a verb to
+ specify to granted access, which is one of
+ <option>see</option>,
+ <option>talk</option> or
+ <option>own</option>.
+ <option>talk</option> implies
+ <option>see</option>, and <option>own</option>
+ implies both <option>talk</option> and
+ <option>see</option>.
+ If multiple access levels are specified for the
+ same bus name, the most powerful one takes
+ effect.
+ </para>
+ <para>Examples:</para>
+ <programlisting>BusPolicy=org.freedesktop.systemd1 talk</programlisting>
+ <programlisting>BusPolicy=org.foo.bar see</programlisting>
+ <para>This option is only available on kdbus enabled systems.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>ExecStart=</varname></term>
<listitem><para>Commands with their
arguments that are executed when this
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index 24aa80d9ea..e764d68ce4 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -205,6 +205,9 @@ Service.NonBlocking, config_parse_bool, 0,
Service.BusName, config_parse_unit_string_printf, 0, offsetof(Service, bus_name)
Service.NotifyAccess, config_parse_notify_access, 0, offsetof(Service, notify_access)
Service.Sockets, config_parse_service_sockets, 0, 0
+m4_ifdef(`ENABLE_KDBUS',
+`Service.BusPolicy, config_parse_bus_endpoint_policy, 0, offsetof(Service, exec_context)',
+`Service.BusPolicy, config_parse_warn_compat, 0, 0')
EXEC_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
CGROUP_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
KILL_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index b4da6a550e..2f3acd7cbe 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -1752,6 +1752,62 @@ int config_parse_bus_policy(
return 0;
}
+int config_parse_bus_endpoint_policy(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ _cleanup_free_ char *name = NULL;
+ BusPolicyAccess access;
+ ExecContext *c = data;
+ char *access_str;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ name = strdup(rvalue);
+ if (!name)
+ return log_oom();
+
+ access_str = strpbrk(name, WHITESPACE);
+ if (!access_str) {
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+ "Invalid endpoint policy value '%s'", rvalue);
+ return 0;
+ }
+
+ *access_str = '\0';
+ access_str++;
+ access_str += strspn(access_str, WHITESPACE);
+
+ access = bus_policy_access_from_string(access_str);
+ if (access <= _BUS_POLICY_ACCESS_INVALID ||
+ access >= _BUS_POLICY_ACCESS_MAX) {
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+ "Invalid endpoint policy access type '%s'", access_str);
+ return 0;
+ }
+
+ if (!c->bus_endpoint) {
+ r = bus_endpoint_new(&c->bus_endpoint);
+
+ if (r < 0)
+ return r;
+ }
+
+ return bus_endpoint_add_policy(c->bus_endpoint, name, access);
+}
+
int config_parse_unit_env_file(const char *unit,
const char *filename,
unsigned line,
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
index 9a1d7c5aac..65100c9bd7 100644
--- a/src/core/load-fragment.h
+++ b/src/core/load-fragment.h
@@ -67,6 +67,7 @@ int config_parse_service_sockets(const char *unit, const char *filename, unsigne
int config_parse_busname_service(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_bus_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_bus_policy_world(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_bus_endpoint_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_unit_env_file(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_ip_tos(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_unit_condition_path(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);