Zbigniew Jędrzejewski-Szmek 62fe94
From 501996231293506a85bf4d610938a655ddc8cb92 Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek 62fe94
From: Daniel Mack <zonque@gmail.com>
Zbigniew Jędrzejewski-Szmek 62fe94
Date: Mon, 18 Aug 2014 22:42:28 +0200
Zbigniew Jędrzejewski-Szmek 62fe94
Subject: [PATCH] bus: parse BusPolicy directive in service files
Zbigniew Jędrzejewski-Szmek 62fe94
Zbigniew Jędrzejewski-Szmek 62fe94
Add a new directive called BusPolicy to define custom endpoint policies. If
Zbigniew Jędrzejewski-Szmek 62fe94
one such directive is given, an endpoint object in the service's ExecContext is
Zbigniew Jędrzejewski-Szmek 62fe94
created and the given policy is added to it.
Zbigniew Jędrzejewski-Szmek 62fe94
---
Zbigniew Jędrzejewski-Szmek 62fe94
 man/systemd.service.xml               | 40 +++++++++++++++++++++++++
Zbigniew Jędrzejewski-Szmek 62fe94
 src/core/load-fragment-gperf.gperf.m4 |  3 ++
Zbigniew Jędrzejewski-Szmek 62fe94
 src/core/load-fragment.c              | 56 +++++++++++++++++++++++++++++++++++
Zbigniew Jędrzejewski-Szmek 62fe94
 src/core/load-fragment.h              |  1 +
Zbigniew Jędrzejewski-Szmek 62fe94
 4 files changed, 100 insertions(+)
Zbigniew Jędrzejewski-Szmek 62fe94
Zbigniew Jędrzejewski-Szmek 62fe94
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
Zbigniew Jędrzejewski-Szmek 62fe94
index c84a5254b3..a82dfb2c86 100644
Zbigniew Jędrzejewski-Szmek 62fe94
--- a/man/systemd.service.xml
Zbigniew Jędrzejewski-Szmek 62fe94
+++ b/man/systemd.service.xml
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -308,6 +308,46 @@
Zbigniew Jędrzejewski-Szmek 62fe94
                         </varlistentry>
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
                         <varlistentry>
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <term><varname>BusPolicy=</varname></term>
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <listitem><para>If specfied, a custom kdbus
Zbigniew Jędrzejewski-Szmek 62fe94
+                                endpoint will be created and installed as the
Zbigniew Jędrzejewski-Szmek 62fe94
+                                default bus node for the service. Such a custom
Zbigniew Jędrzejewski-Szmek 62fe94
+                                endpoint can hold an own set of policy rules
Zbigniew Jędrzejewski-Szmek 62fe94
+                                that are enforced on top of the bus-wide ones.
Zbigniew Jędrzejewski-Szmek 62fe94
+                                The custom endpoint is named after the service
Zbigniew Jędrzejewski-Szmek 62fe94
+                                it was created for, and its node will be
Zbigniew Jędrzejewski-Szmek 62fe94
+                                bind-mounted over the default bus node
Zbigniew Jędrzejewski-Szmek 62fe94
+                                location, so the service can only access the
Zbigniew Jędrzejewski-Szmek 62fe94
+                                bus through its own endpoint. Note that custom
Zbigniew Jędrzejewski-Szmek 62fe94
+                                bus endpoints default to a 'deny all' policy.
Zbigniew Jędrzejewski-Szmek 62fe94
+                                Hence, if at least one
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <varname>BusPolicy=</varname> directive is
Zbigniew Jędrzejewski-Szmek 62fe94
+                                given, you have to make sure to add explicit
Zbigniew Jędrzejewski-Szmek 62fe94
+                                rules for everything the service should be able
Zbigniew Jędrzejewski-Szmek 62fe94
+                                to do.</para>
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <para>The value of this directive is comprised
Zbigniew Jędrzejewski-Szmek 62fe94
+                                of two parts; the bus name, and a verb to
Zbigniew Jędrzejewski-Szmek 62fe94
+                                specify to granted access, which is one of
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <option>see</option>,
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <option>talk</option> or
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <option>own</option>.
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <option>talk</option> implies
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <option>see</option>, and <option>own</option>
Zbigniew Jędrzejewski-Szmek 62fe94
+                                implies both <option>talk</option> and
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <option>see</option>.
Zbigniew Jędrzejewski-Szmek 62fe94
+                                If multiple access levels are specified for the
Zbigniew Jędrzejewski-Szmek 62fe94
+                                same bus name, the most powerful one takes
Zbigniew Jędrzejewski-Szmek 62fe94
+                                effect.
Zbigniew Jędrzejewski-Szmek 62fe94
+                                </para>
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <para>Examples:</para>
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <programlisting>BusPolicy=org.freedesktop.systemd1 talk</programlisting>
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <programlisting>BusPolicy=org.foo.bar see</programlisting>
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <para>This option is only available on kdbus enabled systems.</para>
Zbigniew Jędrzejewski-Szmek 62fe94
+                                </listitem>
Zbigniew Jędrzejewski-Szmek 62fe94
+                        </varlistentry>
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+                        <varlistentry>
Zbigniew Jędrzejewski-Szmek 62fe94
                                 <term><varname>ExecStart=</varname></term>
Zbigniew Jędrzejewski-Szmek 62fe94
                                 <listitem><para>Commands with their
Zbigniew Jędrzejewski-Szmek 62fe94
                                 arguments that are executed when this
Zbigniew Jędrzejewski-Szmek 62fe94
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
Zbigniew Jędrzejewski-Szmek 62fe94
index 24aa80d9ea..e764d68ce4 100644
Zbigniew Jędrzejewski-Szmek 62fe94
--- a/src/core/load-fragment-gperf.gperf.m4
Zbigniew Jędrzejewski-Szmek 62fe94
+++ b/src/core/load-fragment-gperf.gperf.m4
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -205,6 +205,9 @@ Service.NonBlocking,             config_parse_bool,                  0,
Zbigniew Jędrzejewski-Szmek 62fe94
 Service.BusName,                 config_parse_unit_string_printf,    0,                             offsetof(Service, bus_name)
Zbigniew Jędrzejewski-Szmek 62fe94
 Service.NotifyAccess,            config_parse_notify_access,         0,                             offsetof(Service, notify_access)
Zbigniew Jędrzejewski-Szmek 62fe94
 Service.Sockets,                 config_parse_service_sockets,       0,                             0
Zbigniew Jędrzejewski-Szmek 62fe94
+m4_ifdef(`ENABLE_KDBUS',
Zbigniew Jędrzejewski-Szmek 62fe94
+`Service.BusPolicy,              config_parse_bus_endpoint_policy,   0,                             offsetof(Service, exec_context)',
Zbigniew Jędrzejewski-Szmek 62fe94
+`Service.BusPolicy,              config_parse_warn_compat,           0,                             0')
Zbigniew Jędrzejewski-Szmek 62fe94
 EXEC_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
Zbigniew Jędrzejewski-Szmek 62fe94
 CGROUP_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
Zbigniew Jędrzejewski-Szmek 62fe94
 KILL_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
Zbigniew Jędrzejewski-Szmek 62fe94
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
Zbigniew Jędrzejewski-Szmek 62fe94
index b4da6a550e..2f3acd7cbe 100644
Zbigniew Jędrzejewski-Szmek 62fe94
--- a/src/core/load-fragment.c
Zbigniew Jędrzejewski-Szmek 62fe94
+++ b/src/core/load-fragment.c
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -1752,6 +1752,62 @@ int config_parse_bus_policy(
Zbigniew Jędrzejewski-Szmek 62fe94
         return 0;
Zbigniew Jędrzejewski-Szmek 62fe94
 }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
+int config_parse_bus_endpoint_policy(
Zbigniew Jędrzejewski-Szmek 62fe94
+                const char *unit,
Zbigniew Jędrzejewski-Szmek 62fe94
+                const char *filename,
Zbigniew Jędrzejewski-Szmek 62fe94
+                unsigned line,
Zbigniew Jędrzejewski-Szmek 62fe94
+                const char *section,
Zbigniew Jędrzejewski-Szmek 62fe94
+                unsigned section_line,
Zbigniew Jędrzejewski-Szmek 62fe94
+                const char *lvalue,
Zbigniew Jędrzejewski-Szmek 62fe94
+                int ltype,
Zbigniew Jędrzejewski-Szmek 62fe94
+                const char *rvalue,
Zbigniew Jędrzejewski-Szmek 62fe94
+                void *data,
Zbigniew Jędrzejewski-Szmek 62fe94
+                void *userdata) {
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        _cleanup_free_ char *name = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
+        BusPolicyAccess access;
Zbigniew Jędrzejewski-Szmek 62fe94
+        ExecContext *c = data;
Zbigniew Jędrzejewski-Szmek 62fe94
+        char *access_str;
Zbigniew Jędrzejewski-Szmek 62fe94
+        int r;
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        assert(filename);
Zbigniew Jędrzejewski-Szmek 62fe94
+        assert(lvalue);
Zbigniew Jędrzejewski-Szmek 62fe94
+        assert(rvalue);
Zbigniew Jędrzejewski-Szmek 62fe94
+        assert(data);
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        name = strdup(rvalue);
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (!name)
Zbigniew Jędrzejewski-Szmek 62fe94
+                return log_oom();
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        access_str = strpbrk(name, WHITESPACE);
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (!access_str) {
Zbigniew Jędrzejewski-Szmek 62fe94
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
Zbigniew Jędrzejewski-Szmek 62fe94
+                           "Invalid endpoint policy value '%s'", rvalue);
Zbigniew Jędrzejewski-Szmek 62fe94
+                return 0;
Zbigniew Jędrzejewski-Szmek 62fe94
+        }
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        *access_str = '\0';
Zbigniew Jędrzejewski-Szmek 62fe94
+        access_str++;
Zbigniew Jędrzejewski-Szmek 62fe94
+        access_str += strspn(access_str, WHITESPACE);
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        access = bus_policy_access_from_string(access_str);
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (access <= _BUS_POLICY_ACCESS_INVALID ||
Zbigniew Jędrzejewski-Szmek 62fe94
+            access >= _BUS_POLICY_ACCESS_MAX) {
Zbigniew Jędrzejewski-Szmek 62fe94
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
Zbigniew Jędrzejewski-Szmek 62fe94
+                           "Invalid endpoint policy access type '%s'", access_str);
Zbigniew Jędrzejewski-Szmek 62fe94
+                return 0;
Zbigniew Jędrzejewski-Szmek 62fe94
+        }
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (!c->bus_endpoint) {
Zbigniew Jędrzejewski-Szmek 62fe94
+                r = bus_endpoint_new(&c->bus_endpoint);
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+                if (r < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
+                        return r;
Zbigniew Jędrzejewski-Szmek 62fe94
+        }
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        return bus_endpoint_add_policy(c->bus_endpoint, name, access);
Zbigniew Jędrzejewski-Szmek 62fe94
+}
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
 int config_parse_unit_env_file(const char *unit,
Zbigniew Jędrzejewski-Szmek 62fe94
                                const char *filename,
Zbigniew Jędrzejewski-Szmek 62fe94
                                unsigned line,
Zbigniew Jędrzejewski-Szmek 62fe94
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
Zbigniew Jędrzejewski-Szmek 62fe94
index 9a1d7c5aac..65100c9bd7 100644
Zbigniew Jędrzejewski-Szmek 62fe94
--- a/src/core/load-fragment.h
Zbigniew Jędrzejewski-Szmek 62fe94
+++ b/src/core/load-fragment.h
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -67,6 +67,7 @@ int config_parse_service_sockets(const char *unit, const char *filename, unsigne
Zbigniew Jędrzejewski-Szmek 62fe94
 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);
Zbigniew Jędrzejewski-Szmek 62fe94
 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);
Zbigniew Jędrzejewski-Szmek 62fe94
 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);
Zbigniew Jędrzejewski-Szmek 62fe94
+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);
Zbigniew Jędrzejewski-Szmek 62fe94
 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);
Zbigniew Jędrzejewski-Szmek 62fe94
 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);
Zbigniew Jędrzejewski-Szmek 62fe94
 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);