summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-12-23 21:28:22 +0100
committerLennart Poettering <lennart@poettering.net>2014-12-23 21:28:48 +0100
commitd04c1fb8e215600b4950c6778c6c16ddafc14024 (patch)
tree796dc9260b6f0419c747a5b115f7307751d354d2
parent18d703816300790b041c4fd6991e3561aa2704cb (diff)
downloadsystemd-d04c1fb8e215600b4950c6778c6c16ddafc14024.tar.gz
machined: introduce polkit for OpenLogin() call
This way "machinectl login" can be opened up to run without privileges.
-rw-r--r--Makefile.am6
-rw-r--r--src/machine/.gitignore1
-rw-r--r--src/machine/machine-dbus.c13
-rw-r--r--src/machine/machinectl.c28
-rw-r--r--src/machine/machined-dbus.c2
-rw-r--r--src/machine/machined.c2
-rw-r--r--src/machine/machined.h2
-rw-r--r--src/machine/org.freedesktop.machine1.conf8
-rw-r--r--src/machine/org.freedesktop.machine1.policy.in29
9 files changed, 81 insertions, 10 deletions
diff --git a/Makefile.am b/Makefile.am
index f55e6ca0d1..4173147ee5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5090,6 +5090,12 @@ dist_dbussystemservice_DATA += \
dist_dbuspolicy_DATA += \
src/machine/org.freedesktop.machine1.conf
+polkitpolicy_files += \
+ src/machine/org.freedesktop.machine1.policy
+
+polkitpolicy_in_files += \
+ src/machine/org.freedesktop.machine1.policy.in
+
dist_zshcompletion_DATA += \
shell-completion/zsh/_machinectl \
shell-completion/zsh/_sd_machines
diff --git a/src/machine/.gitignore b/src/machine/.gitignore
new file mode 100644
index 0000000000..e1065b5894
--- /dev/null
+++ b/src/machine/.gitignore
@@ -0,0 +1 @@
+/org.freedesktop.machine1.policy
diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c
index 600d42f195..e63b7ad129 100644
--- a/src/machine/machine-dbus.c
+++ b/src/machine/machine-dbus.c
@@ -431,6 +431,18 @@ int bus_machine_method_open_login(sd_bus *bus, sd_bus_message *message, void *us
const char *p;
int r;
+ r = bus_verify_polkit_async(
+ message,
+ CAP_SYS_ADMIN,
+ "org.freedesktop.machine1.login",
+ false,
+ &m->manager->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+
master = openpt_in_namespace(m->leader, O_RDWR|O_NOCTTY|O_CLOEXEC);
if (master < 0)
return master;
@@ -512,6 +524,7 @@ const sd_bus_vtable machine_vtable[] = {
SD_BUS_METHOD("GetAddresses", NULL, "a(iay)", bus_machine_method_get_addresses, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_machine_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("OpenPTY", NULL, "hs", bus_machine_method_open_pty, 0),
+ SD_BUS_METHOD("OpenLogin", NULL, "hs", bus_machine_method_open_login, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
};
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index f558c8495f..472fab6e49 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -1012,7 +1012,7 @@ finish:
static int login_machine(int argc, char *argv[], void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+ _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
_cleanup_(pty_forward_freep) PTYForward *forward = NULL;
_cleanup_event_unref_ sd_event *event = NULL;
int master = -1, r, ret = 0;
@@ -1037,14 +1037,24 @@ static int login_machine(int argc, char *argv[], void *userdata) {
if (r < 0)
return log_error_errno(r, "Failed to attach bus to event loop: %m");
- r = sd_bus_call_method(bus,
- "org.freedesktop.machine1",
- "/org/freedesktop/machine1",
- "org.freedesktop.machine1.Manager",
- "OpenMachineLogin",
- &error,
- &reply,
- "s", argv[1]);
+ r = sd_bus_message_new_method_call(bus,
+ &m,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "OpenMachineLogin");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_set_allow_interactive_authorization(m, true);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(m, "s", argv[1]);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0) {
log_error("Failed to get machine PTY: %s", bus_error_message(&error, -r));
return r;
diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c
index 5ce091bf29..0bf97e1ebb 100644
--- a/src/machine/machined-dbus.c
+++ b/src/machine/machined-dbus.c
@@ -573,7 +573,7 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_METHOD("GetMachineAddresses", "s", "a(iay)", method_get_machine_addresses, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetMachineOSRelease", "s", "a{ss}", method_get_machine_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("OpenMachinePTY", "s", "hs", method_open_machine_pty, 0),
- SD_BUS_METHOD("OpenMachineLogin", "s", "hs", method_open_machine_login, 0),
+ SD_BUS_METHOD("OpenMachineLogin", "s", "hs", method_open_machine_login, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_SIGNAL("MachineNew", "so", 0),
SD_BUS_SIGNAL("MachineRemoved", "so", 0),
SD_BUS_VTABLE_END
diff --git a/src/machine/machined.c b/src/machine/machined.c
index 82cfcf0fd9..c5c20abf0c 100644
--- a/src/machine/machined.c
+++ b/src/machine/machined.c
@@ -76,6 +76,8 @@ void manager_free(Manager *m) {
hashmap_free(m->machine_units);
hashmap_free(m->machine_leaders);
+ bus_verify_polkit_async_registry_free(m->polkit_registry);
+
sd_bus_unref(m->bus);
sd_event_unref(m->event);
diff --git a/src/machine/machined.h b/src/machine/machined.h
index ed0bd7020a..5fc1bd17b3 100644
--- a/src/machine/machined.h
+++ b/src/machine/machined.h
@@ -43,6 +43,8 @@ struct Manager {
Hashmap *machine_units;
Hashmap *machine_leaders;
+ Hashmap *polkit_registry;
+
LIST_HEAD(Machine, machine_gc_queue);
};
diff --git a/src/machine/org.freedesktop.machine1.conf b/src/machine/org.freedesktop.machine1.conf
index bd8fbeff4f..37f84bd6f3 100644
--- a/src/machine/org.freedesktop.machine1.conf
+++ b/src/machine/org.freedesktop.machine1.conf
@@ -65,6 +65,10 @@
send_member="GetMachineOSRelease"/>
<allow send_destination="org.freedesktop.machine1"
+ send_interface="org.freedesktop.machine1.Manager"
+ send_member="OpenMachineLogin"/>
+
+ <allow send_destination="org.freedesktop.machine1"
send_interface="org.freedesktop.machine1.Machine"
send_member="GetAddresses"/>
@@ -72,6 +76,10 @@
send_interface="org.freedesktop.machine1.Machine"
send_member="GetOSRelease"/>
+ <allow send_destination="org.freedesktop.machine1"
+ send_interface="org.freedesktop.machine1.Machine"
+ send_member="OpenLogin"/>
+
<allow receive_sender="org.freedesktop.machine1"/>
</policy>
diff --git a/src/machine/org.freedesktop.machine1.policy.in b/src/machine/org.freedesktop.machine1.policy.in
new file mode 100644
index 0000000000..4dbceab6f5
--- /dev/null
+++ b/src/machine/org.freedesktop.machine1.policy.in
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?> <!--*-nxml-*-->
+<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
+
+<!--
+ This file is part of systemd.
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+-->
+
+<policyconfig>
+
+ <vendor>The systemd Project</vendor>
+ <vendor_url>http://www.freedesktop.org/wiki/Software/systemd</vendor_url>
+
+ <action id="org.freedesktop.machine1.login">
+ <_description>Login into a local container</_description>
+ <_message>Authentication is required to allow login into a local container.</_message>
+ <defaults>
+ <allow_any>auth_admin</allow_any>
+ <allow_inactive>auth_admin</allow_inactive>
+ <allow_active>auth_admin_keep</allow_active>
+ </defaults>
+ </action>
+
+</policyconfig>