summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Mack <zonque@gmail.com>2014-03-06 22:42:42 +0100
committerDaniel Mack <zonque@gmail.com>2014-03-07 19:14:05 +0100
commit54d76c92868838e17d6aad0a3bb0cc7a5b11e35f (patch)
treec094188e6eb2ac57b19bc64acc295654c160185d
parentfb255b31c5f4eca821d60a2c9b1235a513f15732 (diff)
busname: add parser for bus name policies
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.
-rw-r--r--src/core/busname.c8
-rw-r--r--src/core/busname.h34
-rw-r--r--src/core/load-fragment-gperf.gperf.m44
-rw-r--r--src/core/load-fragment.c85
-rw-r--r--src/core/load-fragment.h1
5 files changed, 132 insertions, 0 deletions
diff --git a/src/core/busname.c b/src/core/busname.c
index bca214502..4806e741c 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 6debd4855..f79f510ea 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 5604ee975..f85d86804 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 18dab02cd..06e3031d6 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 fabbda212..35138514f 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);