diff options
| -rw-r--r-- | src/core/busname.c | 8 | ||||
| -rw-r--r-- | src/core/busname.h | 34 | ||||
| -rw-r--r-- | src/core/load-fragment-gperf.gperf.m4 | 4 | ||||
| -rw-r--r-- | src/core/load-fragment.c | 85 | ||||
| -rw-r--r-- | src/core/load-fragment.h | 1 | 
5 files changed, 132 insertions, 0 deletions
| diff --git a/src/core/busname.c b/src/core/busname.c index bca2145021..4806e741ca 100644 --- a/src/core/busname.c +++ b/src/core/busname.c @@ -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), diff --git a/src/core/busname.h b/src/core/busname.h index 6debd48551..f79f510ea2 100644 --- a/src/core/busname.h +++ b/src/core/busname.h @@ -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_; diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 5604ee975d..f85d868043 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -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) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 18dab02cd7..06e3031d65 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -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, diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index fabbda212d..35138514f3 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -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); | 
