chiark / gitweb /
Make test-login and test-sleep output debugging
[elogind.git] / src / login / logind-session-dbus.c
index 62b9ffd52a7f150cd63e276640f8fa622b9b2157..35bf4480cbf6490d46bd44757f5ba6bb2d3bed8e 100644 (file)
         "   <arg name=\"who\" type=\"s\"/>\n"                           \
         "   <arg name=\"signal\" type=\"s\"/>\n"                        \
         "  </method>\n"                                                 \
+        "  <method name=\"TakeControl\"/>\n"                            \
+        "   <arg name=\"force\" type=\"b\"/>\n"                         \
+        "  </method>\n"                                                 \
+        "  <method name=\"ReleaseControl\"/>\n"                         \
         "  <signal name=\"Lock\"/>\n"                                   \
         "  <signal name=\"Unlock\"/>\n"                                 \
         "  <property name=\"Id\" type=\"s\" access=\"read\"/>\n"        \
@@ -366,6 +370,44 @@ static DBusHandlerResult session_message_dispatch(
                 if (!reply)
                         goto oom;
 
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "TakeControl")) {
+                dbus_bool_t force;
+                unsigned long ul;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_BOOLEAN, &force,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), &error);
+                if (ul == (unsigned long) -1)
+                        return bus_send_error_reply(connection, message, &error, -EIO);
+
+                if (ul != 0 && (force || ul != s->user->uid))
+                        return bus_send_error_reply(connection, message, NULL, -EPERM);
+
+                r = session_set_controller(s, bus_message_get_sender_with_fallback(message), force);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, NULL, r);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "ReleaseControl")) {
+                const char *sender = bus_message_get_sender_with_fallback(message);
+
+                if (!session_is_controller(s, sender))
+                        return bus_send_error_reply(connection, message, NULL, -EPERM);
+
+                session_drop_controller(s);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
         } else {
                 const BusBoundProperties bps[] = {
                         { "org.freedesktop.login1.Session", bus_login_session_properties,      s       },
@@ -535,6 +577,10 @@ int session_send_create_reply(Session *s, DBusError *error) {
         if (!s->create_message)
                 return 0;
 
+        /* This is called after the session scope was successfully
+         * created, and finishes where bus_manager_create_session()
+         * left off. */
+
         if (error) {
                 DBusError buffer;
 
@@ -588,6 +634,10 @@ int session_send_create_reply(Session *s, DBusError *error) {
                         return log_oom();
         }
 
+        /* Update the state file before we notify the client about the
+         * result */
+        session_save(s);
+
         if (!dbus_connection_send(s->manager->bus, reply, NULL))
                 return log_oom();