chiark / gitweb /
Prep v225: Applying various fixes and changes to src/basic that got lost during git...
[elogind.git] / src / login / logind-dbus.c
index ca435dfcbbbd905f57eec4ad5c01f24ef15b1655..1f5cf865b1440824cd5680053ca4a9c99efe487f 100644 (file)
@@ -158,7 +158,7 @@ static int property_get_idle_since_hint(
                 sd_bus_error *error) {
 
         Manager *m = userdata;
-        dual_timestamp t = DUAL_TIMESTAMP_NULL;
+        dual_timestamp t;
 
         assert(bus);
         assert(reply);
@@ -243,24 +243,6 @@ static int property_get_scheduled_shutdown(
 
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
 
-static int property_get_docked(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Manager *m = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(m);
-
-        return sd_bus_message_append(reply, "b", manager_is_docked_or_external_displays(m));
-}
-
 static int method_get_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
         _cleanup_free_ char *p = NULL;
         Manager *m = userdata;
@@ -689,26 +671,45 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus
                         return r;
         }
 
-        r = manager_get_session_by_pid(m, leader, NULL);
-        if (r > 0)
-                return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already running in a session");
-
-        /*
-         * Old gdm and lightdm start the user-session on the same VT as
-         * the greeter session. But they destroy the greeter session
-         * after the user-session and want the user-session to take
-         * over the VT. We need to support this for
-         * backwards-compatibility, so make sure we allow new sessions
-         * on a VT that a greeter is running on. Furthermore, to allow
-         * re-logins, we have to allow a greeter to take over a used VT for
-         * the exact same reasons.
-         */
-        if (c != SESSION_GREETER &&
-            vtnr > 0 &&
-            vtnr < m->seat0->position_count &&
-            m->seat0->positions[vtnr] &&
-            m->seat0->positions[vtnr]->class != SESSION_GREETER)
-                return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already occupied by a session");
+        manager_get_session_by_pid(m, leader, &session);
+        if (session) {
+                _cleanup_free_ char *path = NULL;
+                _cleanup_close_ int fifo_fd = -1;
+
+                /* Session already exists, client is probably
+                 * something like "su" which changes uid but is still
+                 * the same session */
+
+                fifo_fd = session_create_fifo(session);
+                if (fifo_fd < 0)
+                        return fifo_fd;
+
+                path = session_bus_path(session);
+                if (!path)
+                        return -ENOMEM;
+
+                log_debug("Sending reply about an existing session: "
+                          "id=%s object_path=%s uid=%u runtime_path=%s "
+                          "session_fd=%d seat=%s vtnr=%u",
+                          session->id,
+                          path,
+                          (uint32_t) session->user->uid,
+                          session->user->runtime_path,
+                          fifo_fd,
+                          session->seat ? session->seat->id : "",
+                          (uint32_t) session->vtnr);
+
+                return sd_bus_reply_method_return(
+                                message, "soshusub",
+                                session->id,
+                                path,
+                                session->user->runtime_path,
+                                fifo_fd,
+                                (uint32_t) session->user->uid,
+                                session->seat ? session->seat->id : "",
+                                (uint32_t) session->vtnr,
+                                true);
+        }
 
         audit_session_from_pid(leader, &audit_id);
         if (audit_id > 0) {
@@ -1175,7 +1176,7 @@ static int trigger_device(Manager *m, struct udev_device *d) {
                 if (!t)
                         return -ENOMEM;
 
-                write_string_file(t, "change", WRITE_STRING_FILE_CREATE);
+                write_string_file(t, "change");
         }
 
         return 0;
@@ -1467,13 +1468,18 @@ static int execute_shutdown_or_sleep(
         return 0;
 }
 
-int manager_dispatch_delayed(Manager *manager, bool timeout) {
+static int manager_inhibit_timeout_handler(
+                        sd_event_source *s,
+                        uint64_t usec,
+                        void *userdata) {
 
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
         Inhibitor *offending = NULL;
+        Manager *manager = userdata;
         int r;
 
         assert(manager);
+        assert(manager->inhibit_timeout_source == s);
 
         if (manager->action_what == 0 || manager->action_job)
                 return 0;
@@ -1481,9 +1487,6 @@ int manager_dispatch_delayed(Manager *manager, bool timeout) {
         if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
                 _cleanup_free_ char *comm = NULL, *u = NULL;
 
-                if (!timeout)
-                        return 0;
-
                 (void) get_process_comm(offending->pid, &comm);
                 u = uid_to_name(offending->uid);
 
@@ -1499,25 +1502,9 @@ int manager_dispatch_delayed(Manager *manager, bool timeout) {
 
                 manager->action_unit = NULL;
                 manager->action_what = 0;
-                return r;
         }
 
-        return 1;
-}
-
-static int manager_inhibit_timeout_handler(
-                        sd_event_source *s,
-                        uint64_t usec,
-                        void *userdata) {
-
-        Manager *manager = userdata;
-        int r;
-
-        assert(manager);
-        assert(manager->inhibit_timeout_source == s);
-
-        r = manager_dispatch_delayed(manager, true);
-        return (r < 0) ? r : 0;
+        return 0;
 }
 
 static int delay_shutdown_or_sleep(
@@ -1774,7 +1761,7 @@ static int nologin_timeout_handler(
 
         log_info("Creating /run/nologin, blocking further logins...");
 
-        r = write_string_file("/run/nologin", "System is going down.", WRITE_STRING_FILE_ATOMIC);
+        r = write_string_file_atomic("/run/nologin", "System is going down.");
         if (r < 0)
                 log_error_errno(r, "Failed to create /run/nologin: %m");
         else
@@ -1977,11 +1964,6 @@ static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userd
         m->scheduled_shutdown_type = NULL;
         m->scheduled_shutdown_timeout = 0;
 
-        if (m->unlink_nologin) {
-                (void) unlink("/run/nologin");
-                m->unlink_nologin = false;
-        }
-
         if (cancelled) {
                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
                 const char *tty = NULL;
@@ -2419,7 +2401,6 @@ const sd_bus_vtable manager_vtable[] = {
         SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
         SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
         SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
-        SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0),
 
         SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
@@ -2536,7 +2517,6 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err
                 session_jobs_reply(session, unit, result);
 
                 session_save(session);
-                user_save(session->user);
                 session_add_to_gc_queue(session);
         }