chiark / gitweb /
busname: add parser for bus name policies
authorDaniel Mack <zonque@gmail.com>
Thu, 6 Mar 2014 21:42:42 +0000 (22:42 +0100)
committerDaniel Mack <zonque@gmail.com>
Fri, 7 Mar 2014 18:14:05 +0000 (19:14 +0100)
There are three directives to specify bus name polices in .busname
files:

 * AllowUser [username] [access]
 * AllowGroup [groupname] [access]
 * AllowWorld [access]

Where [access] is one of

 * 'see': The user/group/world is allowed to see a name on the bus
 * 'talk': The user/group/world is allowed to talk to a name
 * 'own': The user/group/world is allowed to own a name

There is no user added yet in this commit.

src/core/busname.c
src/core/busname.h
src/core/load-fragment-gperf.gperf.m4
src/core/load-fragment.c
src/core/load-fragment.h

index bca2145..4806e74 100644 (file)
@@ -553,6 +553,14 @@ static const char* const busname_result_table[_BUSNAME_RESULT_MAX] = {
 
 DEFINE_STRING_TABLE_LOOKUP(busname_result, BusNameResult);
 
+static const char* const busname_policy_access_table[_BUSNAME_POLICY_ACCESS_MAX] = {
+        [BUSNAME_POLICY_ACCESS_SEE] = "see",
+        [BUSNAME_POLICY_ACCESS_TALK] = "talk",
+        [BUSNAME_POLICY_ACCESS_OWN] = "own",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(busname_policy_access, BusNamePolicyAccess);
+
 const UnitVTable busname_vtable = {
         .object_size = sizeof(BusName),
 
index 6debd48..f79f510 100644 (file)
@@ -22,6 +22,7 @@
 ***/
 
 typedef struct BusName BusName;
+typedef struct BusNamePolicy BusNamePolicy;
 
 #include "unit.h"
 
@@ -54,6 +55,36 @@ struct BusName {
         BusNameResult result;
 
         sd_event_source *event_source;
+
+        LIST_HEAD(BusNamePolicy, policy);
+};
+
+typedef enum BusNamePolicyType {
+        BUSNAME_POLICY_TYPE_USER,
+        BUSNAME_POLICY_TYPE_GROUP,
+        BUSNAME_POLICY_TYPE_WORLD,
+        _BUSNAME_POLICY_TYPE_MAX,
+        _BUSNAME_POLICY_TYPE_INVALID = -1
+} BusNamePolicyType;
+
+typedef enum BusNamePolicyAccess {
+        BUSNAME_POLICY_ACCESS_SEE,
+        BUSNAME_POLICY_ACCESS_TALK,
+        BUSNAME_POLICY_ACCESS_OWN,
+        _BUSNAME_POLICY_ACCESS_MAX,
+        _BUSNAME_POLICY_ACCESS_INVALID = -1
+} BusNamePolicyAccess;
+
+struct BusNamePolicy {
+        BusNamePolicyType type;
+        BusNamePolicyAccess access;
+
+        union {
+                uid_t uid;
+                gid_t gid;
+        };
+
+        LIST_FIELDS(BusNamePolicy, policy);
 };
 
 extern const UnitVTable busname_vtable;
@@ -63,3 +94,6 @@ BusNameState busname_state_from_string(const char *s) _pure_;
 
 const char* busname_result_to_string(BusNameResult i) _const_;
 BusNameResult busname_result_from_string(const char *s) _pure_;
+
+const char* busname_policy_access_to_string(BusNamePolicyAccess i) _const_;
+BusNamePolicyAccess busname_policy_access_from_string(const char *s) _pure_;
index 5604ee9..f85d868 100644 (file)
@@ -252,6 +252,10 @@ KILL_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl
 m4_dnl
 BusName.Name,                    config_parse_string,                0,                             offsetof(BusName, name)
 BusName.Service,                 config_parse_busname_service,       0,                             0
+BusName.AllowUser,               config_parse_bus_policy,            0,                             0
+BusName.AllowGroup,              config_parse_bus_policy,            0,                             0
+BusName.AllowWorld,              config_parse_bus_policy,            0,                             0
+BusName.SELinuxContext,          config_parse_exec_selinux_context,  0,                             0
 m4_dnl
 Mount.What,                      config_parse_string,                0,                             offsetof(Mount, parameters_fragment.what)
 Mount.Where,                     config_parse_path,                  0,                             offsetof(Mount, where)
index 18dab02..06e3031 100644 (file)
@@ -33,6 +33,8 @@
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/resource.h>
+#include <sys/types.h>
+#include <grp.h>
 
 #ifdef HAVE_SECCOMP
 #include <seccomp.h>
@@ -1606,6 +1608,89 @@ int config_parse_busname_service(
         return 0;
 }
 
+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) {
+
+        _cleanup_free_ BusNamePolicy *p = NULL;
+        _cleanup_free_ char *id_str = NULL;
+        BusName *busname = data;
+        char *access_str;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        p = new0(BusNamePolicy, 1);
+        if (!p)
+                return log_oom();
+
+        if (streq(lvalue, "AllowUser"))
+                p->type = BUSNAME_POLICY_TYPE_USER;
+        else if (streq(lvalue, "AllowGroup"))
+                p->type = BUSNAME_POLICY_TYPE_GROUP;
+        else if (streq(lvalue, "AllowWorld"))
+                p->type = BUSNAME_POLICY_TYPE_WORLD;
+        else
+                assert_not_reached("Unknown lvalue");
+
+        id_str = strdup(rvalue);
+        if (!id_str)
+                return log_oom();
+
+        if (p->type != BUSNAME_POLICY_TYPE_WORLD) {
+                access_str = strchr(id_str, ' ');
+                if (!access_str) {
+                        log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Invalid busname policy value '%s'", rvalue);
+                        return 0;
+                }
+
+                *access_str = '\0';
+                access_str++;
+
+                if (p->type == BUSNAME_POLICY_TYPE_USER) {
+                        const char *user = id_str;
+
+                        r = get_user_creds(&user, &p->uid, NULL, NULL, NULL);
+                        if (r < 0) {
+                                log_syntax(unit, LOG_ERR, filename, line, r, "Unable to parse uid from '%s'", id_str);
+                                return 0;
+                        }
+                } else {
+                        const char *group = id_str;
+
+                        r = get_group_creds(&group, &p->gid);
+                        if (r < 0) {
+                                log_syntax(unit, LOG_ERR, filename, line, -errno, "Unable to parse gid from '%s'", id_str);
+                                return 0;
+                        }
+                }
+        } else {
+                access_str = id_str;
+        }
+
+        p->access = busname_policy_access_from_string(access_str);
+        if (p->access < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Invalid busname policy access type '%s'", access_str);
+                return 0;
+        }
+
+        LIST_PREPEND(policy, busname->policy, p);
+        p = NULL;
+
+        return 0;
+}
+
 int config_parse_unit_env_file(const char *unit,
                                const char *filename,
                                unsigned line,
index fabbda2..3513851 100644 (file)
@@ -64,6 +64,7 @@ int config_parse_path_spec(const char *unit, const char *filename, unsigned line
 int config_parse_socket_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_service_sockets(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_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_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);