mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
dbus: make DeviceAllow=/DevicePolicy= writable
This commit is contained in:
parent
b42defe3b8
commit
7041efe960
4
TODO
4
TODO
@ -28,6 +28,10 @@ Fedora 19:
|
||||
|
||||
Features:
|
||||
|
||||
* split up BlockIOWeight= and BlockIODeviceWeight=
|
||||
|
||||
* how to reset dynamically changed attributes sanely?
|
||||
|
||||
* when reloading configuration, apply new cgroup configuration
|
||||
|
||||
* implement system-wide DefaultCPUAccounting=1 switch (and similar for blockio, memory, fair scheduling?)
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
#include "path-util.h"
|
||||
#include "dbus-cgroup.h"
|
||||
|
||||
static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_cgroup_append_device_policy, cgroup_device_policy, CGroupDevicePolicy);
|
||||
@ -264,6 +265,110 @@ int bus_cgroup_set_property(
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "DevicePolicy")) {
|
||||
const char *policy;
|
||||
CGroupDevicePolicy p;
|
||||
|
||||
if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING)
|
||||
return -EINVAL;
|
||||
|
||||
dbus_message_iter_get_basic(i, &policy);
|
||||
p = cgroup_device_policy_from_string(policy);
|
||||
if (p < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (mode != UNIT_CHECK) {
|
||||
char *buf;
|
||||
|
||||
c->device_policy = p;
|
||||
|
||||
buf = strappenda("DevicePolicy=", policy);
|
||||
unit_write_drop_in_private_section(u, mode, "device-policy", buf);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "DeviceAllow")) {
|
||||
DBusMessageIter sub;
|
||||
unsigned n = 0;
|
||||
|
||||
if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_ARRAY ||
|
||||
dbus_message_iter_get_element_type(i) != DBUS_TYPE_STRUCT)
|
||||
return -EINVAL;
|
||||
|
||||
dbus_message_iter_recurse(i, &sub);
|
||||
while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
|
||||
DBusMessageIter sub2;
|
||||
const char *path, *rwm;
|
||||
CGroupDeviceAllow *a;
|
||||
|
||||
dbus_message_iter_recurse(&sub, &sub2);
|
||||
|
||||
if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) < 0 ||
|
||||
bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &rwm, false) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!path_startswith(path, "/dev")) {
|
||||
dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "DeviceAllow= requires device node");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (isempty(rwm))
|
||||
rwm = "rwm";
|
||||
|
||||
if (!in_charset(rwm, "rwm")) {
|
||||
dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "DeviceAllow= requires combination of rwm flags");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
n++;
|
||||
|
||||
if (mode != UNIT_CHECK) {
|
||||
a = new0(CGroupDeviceAllow, 1);
|
||||
if (!a)
|
||||
return -ENOMEM;
|
||||
|
||||
a->path = strdup(path);
|
||||
if (!a->path) {
|
||||
free(a);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
a->r = !!strchr(rwm, 'r');
|
||||
a->w = !!strchr(rwm, 'w');
|
||||
a->m = !!strchr(rwm, 'm');
|
||||
|
||||
LIST_PREPEND(CGroupDeviceAllow, device_allow, c->device_allow, a);
|
||||
}
|
||||
|
||||
dbus_message_iter_next(&sub);
|
||||
}
|
||||
|
||||
if (mode != UNIT_CHECK) {
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
CGroupDeviceAllow *a;
|
||||
size_t size = 0;
|
||||
|
||||
if (n == 0) {
|
||||
while (c->device_allow)
|
||||
cgroup_context_free_device_allow(c, c->device_allow);
|
||||
}
|
||||
|
||||
f = open_memstream(&buf, &size);
|
||||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
fputs("DeviceAllow=\n", f);
|
||||
LIST_FOREACH(device_allow, a, c->device_allow)
|
||||
fprintf(f, "DeviceAllow=%s %s%s%s\n", a->path, a->r ? "r" : "", a->w ? "w" : "", a->m ? "m" : "");
|
||||
|
||||
fflush(f);
|
||||
unit_write_drop_in_private_section(u, mode, "device-allow", buf);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -3661,6 +3661,43 @@ static int append_assignment(DBusMessageIter *iter, const char *assignment) {
|
||||
!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT64, &u))
|
||||
return log_oom();
|
||||
|
||||
} else if (streq(field, "DevicePolicy")) {
|
||||
|
||||
if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "s", &sub) ||
|
||||
!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &eq))
|
||||
return log_oom();
|
||||
|
||||
} else if (streq(field, "DeviceAllow")) {
|
||||
DBusMessageIter sub2;
|
||||
|
||||
if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a(ss)", &sub) ||
|
||||
!dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "(ss)", &sub2))
|
||||
return log_oom();
|
||||
|
||||
if (!isempty(eq)) {
|
||||
const char *path, *rwm;
|
||||
DBusMessageIter sub3;
|
||||
char *e;
|
||||
|
||||
e = strchr(eq, ' ');
|
||||
if (e) {
|
||||
path = strndupa(eq, e - eq);
|
||||
rwm = e+1;
|
||||
} else {
|
||||
path = eq;
|
||||
rwm = "";
|
||||
}
|
||||
|
||||
if (!dbus_message_iter_open_container(&sub2, DBUS_TYPE_STRUCT, NULL, &sub3) ||
|
||||
!dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &path) ||
|
||||
!dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, &rwm) ||
|
||||
!dbus_message_iter_close_container(&sub2, &sub3))
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
if (!dbus_message_iter_close_container(&sub, &sub2))
|
||||
return log_oom();
|
||||
|
||||
} else {
|
||||
log_error("Unknown assignment %s.", assignment);
|
||||
return -EINVAL;
|
||||
|
Loading…
Reference in New Issue
Block a user