chiark / gitweb /
machined: introduce polkit for OpenLogin() call
authorLennart Poettering <lennart@poettering.net>
Tue, 23 Dec 2014 20:28:22 +0000 (21:28 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 23 Dec 2014 20:28:48 +0000 (21:28 +0100)
This way "machinectl login" can be opened up to run without privileges.

Makefile.am
src/machine/.gitignore [new file with mode: 0644]
src/machine/machine-dbus.c
src/machine/machinectl.c
src/machine/machined-dbus.c
src/machine/machined.c
src/machine/machined.h
src/machine/org.freedesktop.machine1.conf
src/machine/org.freedesktop.machine1.policy.in [new file with mode: 0644]

index f55e6ca..4173147 100644 (file)
@@ -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 (file)
index 0000000..e1065b5
--- /dev/null
@@ -0,0 +1 @@
+/org.freedesktop.machine1.policy
index 600d42f..e63b7ad 100644 (file)
@@ -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
 };
 
index f558c84..472fab6 100644 (file)
@@ -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;
index 5ce091b..0bf97e1 100644 (file)
@@ -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
index 82cfcf0..c5c20ab 100644 (file)
@@ -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);
 
index ed0bd70..5fc1bd1 100644 (file)
@@ -43,6 +43,8 @@ struct Manager {
         Hashmap *machine_units;
         Hashmap *machine_leaders;
 
+        Hashmap *polkit_registry;
+
         LIST_HEAD(Machine, machine_gc_queue);
 };
 
index bd8fbef..37f84bd 100644 (file)
                        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"/>
 
                        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 (file)
index 0000000..4dbceab
--- /dev/null
@@ -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>