$OpenBSD: patch-daemon_gdm-manager_c,v 1.10 2016/04/26 08:25:04 ajacoutot Exp $

XXX fix+push upstream

REVERT - OpenBSD does not have a systemd implementation (we need ConsoleKit)
From 1ac67f522f5690c27023d98096ca817f12f7eb88 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 12 Jun 2015 13:28:01 -0400
Subject: drop consolekit support

REVERT - OpenBSD does not have a systemd implementation (we need ConsoleKit)
From 9be58c9ec9a3a411492a5182ac4b0d51fdc3a323 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 12 Jun 2015 13:48:52 -0400
Subject: require logind support

--- daemon/gdm-manager.c.orig	Tue Apr 19 07:00:04 2016
+++ daemon/gdm-manager.c	Tue Apr 26 10:02:48 2016
@@ -34,7 +34,9 @@
 #include <glib/gstdio.h>
 #include <glib-object.h>
 
+#ifdef WITH_SYSTEMD
 #include <systemd/sd-login.h>
+#endif
 
 #include "gdm-common.h"
 
@@ -57,8 +59,17 @@
 #define GDM_MANAGER_PATH          GDM_DBUS_PATH "/Manager"
 #define GDM_MANAGER_DISPLAYS_PATH GDM_DBUS_PATH "/Displays"
 
-#define INITIAL_SETUP_USERNAME "gnome-initial-setup"
+#define INITIAL_SETUP_USERNAME "_gnome-initial-setup"
 
+#define CK_NAME      "org.freedesktop.ConsoleKit"
+#define CK_PATH      "/org/freedesktop/ConsoleKit"
+#define CK_INTERFACE "org.freedesktop.ConsoleKit"
+
+#define CK_MANAGER_PATH      "/org/freedesktop/ConsoleKit/Manager"
+#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
+#define CK_SEAT_INTERFACE    "org.freedesktop.ConsoleKit.Seat"
+#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
+
 typedef struct
 {
         GdmManager *manager;
@@ -202,9 +213,10 @@ plymouth_quit_without_transition (void)
 }
 #endif
 
+#ifdef WITH_SYSTEMD
 static char *
-get_session_id_for_pid (pid_t    pid,
-                        GError **error)
+get_session_id_for_pid_systemd (pid_t    pid,
+                                GError **error)
 {
         char *session, *gsession;
         int ret;
@@ -229,11 +241,61 @@ get_session_id_for_pid (pid_t    pid,
                 return NULL;
         }
 }
+#endif
 
+#ifdef WITH_CONSOLE_KIT
+static char *
+get_session_id_for_pid_consolekit (GDBusConnection  *connection,
+                                   pid_t             pid,
+                                   GError          **error)
+{
+        GVariant *reply;
+        char *retval;
+
+        reply = g_dbus_connection_call_sync (connection,
+                                             "org.freedesktop.ConsoleKit",
+                                             "/org/freedesktop/ConsoleKit/Manager",
+                                             "org.freedesktop.ConsoleKit.Manager",
+                                             "GetSessionForUnixProcess",
+                                             g_variant_new ("(u)", pid),
+                                             G_VARIANT_TYPE ("(o)"),
+                                             G_DBUS_CALL_FLAGS_NONE,
+                                             -1,
+                                             NULL, error);
+        if (reply == NULL) {
+                return NULL;
+        }
+
+        g_variant_get (reply, "(o)", &retval);
+        g_variant_unref (reply);
+
+        return retval;
+}
+#endif
+
+static char *
+get_session_id_for_pid (GDBusConnection  *connection,
+                        pid_t             pid,
+                        GError          **error)
+{
+#ifdef WITH_SYSTEMD
+        if (LOGIND_RUNNING()) {
+                return get_session_id_for_pid_systemd (pid, error);
+        }
+#endif
+
+#ifdef WITH_CONSOLE_KIT
+        return get_session_id_for_pid_consolekit (connection, pid, error);
+#endif
+
+        return NULL;
+}
+
+#ifdef WITH_SYSTEMD
 static gboolean
-get_uid_for_session_id (const char  *session_id,
-                        uid_t       *uid,
-                        GError     **error)
+get_uid_for_systemd_session_id (const char  *session_id,
+                                uid_t       *uid,
+                                GError     **error)
 {
         int ret;
 
@@ -250,8 +312,62 @@ get_uid_for_session_id (const char  *session_id,
 
         return TRUE;
 }
+#endif
 
+#ifdef WITH_CONSOLE_KIT
 static gboolean
+get_uid_for_consolekit_session_id (GDBusConnection  *connection,
+                                   const char       *session_id,
+                                   uid_t            *out_uid,
+                                   GError          **error)
+{
+        GVariant *reply;
+        guint32 uid;
+
+        reply = g_dbus_connection_call_sync (connection,
+                                             "org.freedesktop.ConsoleKit",
+                                             session_id,
+                                             "org.freedesktop.ConsoleKit.Session",
+                                             "GetUnixUser",
+                                             NULL,
+                                             G_VARIANT_TYPE ("(u)"),
+                                             G_DBUS_CALL_FLAGS_NONE,
+                                             -1,
+                                             NULL,
+                                             error);
+        if (reply == NULL) {
+                return FALSE;
+        }
+
+        g_variant_get (reply, "(u)", &uid);
+        g_variant_unref (reply);
+
+        *out_uid = (uid_t) uid;
+
+        return TRUE;
+}
+#endif
+
+static gboolean
+get_uid_for_session_id (GDBusConnection  *connection,
+                        const char       *session_id,
+                        uid_t            *uid,
+                        GError          **error)
+{
+#ifdef WITH_SYSTEMD
+        if (LOGIND_RUNNING()) {
+                return get_uid_for_systemd_session_id (session_id, uid, error);
+        }
+#endif
+
+#ifdef WITH_CONSOLE_KIT
+        return get_uid_for_consolekit_session_id (connection, session_id, uid, error);
+#endif
+
+        return FALSE;
+}
+
+static gboolean
 lookup_by_session_id (const char *id,
                       GdmDisplay *display,
                       gpointer    user_data)
@@ -263,11 +379,51 @@ lookup_by_session_id (const char *id,
         return g_strcmp0 (current, looking_for) == 0;
 }
 
+#ifdef WITH_CONSOLE_KIT
 static gboolean
-is_login_session (GdmManager  *self,
-                  const char  *session_id,
-                  GError     **error)
+is_consolekit_login_session (GdmManager       *self,
+                             GDBusConnection  *connection,
+                             const char       *session_id,
+                             GError          **error)
 {
+        GVariant *reply;
+        char *session_type = NULL;
+
+        reply = g_dbus_connection_call_sync (connection,
+                                             "org.freedesktop.ConsoleKit",
+                                             session_id,
+                                             "org.freedesktop.ConsoleKit.Session",
+                                             "GetSessionType",
+                                             NULL,
+                                             G_VARIANT_TYPE ("(s)"),
+                                             G_DBUS_CALL_FLAGS_NONE,
+                                             -1,
+                                             NULL,
+                                             error);
+        if (reply == NULL) {
+                return FALSE;
+        }
+
+        g_variant_get (reply, "(s)", &session_type);
+        g_variant_unref (reply);
+
+        if (g_strcmp0 (session_type, "LoginWindow") != 0) {
+                g_free (session_type);
+
+                return FALSE;
+        }
+
+        g_free (session_type);
+        return TRUE;
+}
+#endif
+
+#ifdef WITH_SYSTEMD
+static gboolean
+is_systemd_login_session (GdmManager  *self,
+                          const char  *session_id,
+                          GError     **error)
+{
         char *session_class = NULL;
         int ret;
 
@@ -291,12 +447,33 @@ is_login_session (GdmManager  *self,
         g_free (session_class);
         return TRUE;
 }
+#endif
 
 static gboolean
-activate_session_id (GdmManager *manager,
-                     const char *seat_id,
-                     const char *session_id)
+is_login_session (GdmManager       *self,
+                  GDBusConnection  *connection,
+                  const char       *session_id,
+                  GError          **error)
 {
+#ifdef WITH_SYSTEMD
+        if (LOGIND_RUNNING()) {
+                return is_systemd_login_session (self, session_id, error);
+        }
+#endif
+
+#ifdef WITH_CONSOLE_KIT
+        return is_consolekit_login_session (self, connection, session_id, error);
+#endif
+
+        return FALSE;
+}
+
+#ifdef WITH_SYSTEMD
+static gboolean
+activate_session_id_for_systemd (GdmManager   *manager,
+                                 const char *seat_id,
+                                 const char *session_id)
+{
         GError *error = NULL;
         GVariant *reply;
 
@@ -322,16 +499,75 @@ activate_session_id (GdmManager *manager,
 
         return TRUE;
 }
+#endif
 
+#ifdef WITH_CONSOLE_KIT
 static gboolean
-session_unlock (GdmManager *manager,
-                const char *ssid)
+activate_session_id_for_ck (GdmManager *manager,
+                            const char *seat_id,
+                            const char *session_id)
 {
         GError *error = NULL;
         GVariant *reply;
 
-        g_debug ("Unlocking session %s", ssid);
+        reply = g_dbus_connection_call_sync (manager->priv->connection,
+                                             CK_NAME,
+                                             seat_id,
+                                             "org.freedesktop.ConsoleKit.Seat",
+                                             "ActivateSession",
+                                             g_variant_new ("(o)", session_id),
+                                             NULL, /* expected reply */
+                                             G_DBUS_CALL_FLAGS_NONE,
+                                             -1,
+                                             NULL,
+                                             &error);
+        if (reply == NULL) {
+                g_debug ("GdmManager: ConsoleKit %s raised:\n %s\n\n",
+                         g_dbus_error_get_remote_error (error), error->message);
+                g_error_free (error);
 
+                /* It is very likely that the "error" just reported is
+                 * that the session is already active.  Unfortunately,
+                 * ConsoleKit doesn't use proper error codes and it
+                 * translates the error message, so we have no real way
+                 * to detect this case...
+                 */
+                return TRUE;
+        }
+
+        g_variant_unref (reply);
+
+        return TRUE;
+}
+#endif
+
+static gboolean
+activate_session_id (GdmManager *manager,
+                     const char *seat_id,
+                     const char *session_id)
+{
+
+#ifdef WITH_SYSTEMD
+        if (LOGIND_RUNNING()) {
+                return activate_session_id_for_systemd (manager, seat_id, session_id);
+        }
+#endif
+
+#ifdef WITH_CONSOLE_KIT
+        return activate_session_id_for_ck (manager, seat_id, session_id);
+#else
+        return FALSE;
+#endif
+}
+
+#ifdef WITH_SYSTEMD
+static gboolean
+session_unlock_for_systemd (GdmManager *manager,
+                            const char *ssid)
+{
+        GError *error = NULL;
+        GVariant *reply;
+
         reply = g_dbus_connection_call_sync (manager->priv->connection,
                                              "org.freedesktop.login1",
                                              "/org/freedesktop/login1",
@@ -354,7 +590,60 @@ session_unlock (GdmManager *manager,
 
         return TRUE;
 }
+#endif
 
+#ifdef WITH_CONSOLE_KIT
+static gboolean
+session_unlock_for_ck (GdmManager *manager,
+                       const char *ssid)
+{
+        GError *error = NULL;
+        GVariant *reply;
+
+        reply = g_dbus_connection_call_sync (manager->priv->connection,
+                                             CK_NAME,
+                                             ssid,
+                                             CK_SESSION_INTERFACE,
+                                             "Unlock",
+                                             NULL, /* parameters */
+                                             NULL, /* expected reply */
+                                             G_DBUS_CALL_FLAGS_NONE,
+                                             -1,
+                                             NULL,
+                                             &error);
+        if (reply == NULL) {
+                g_debug ("GdmManager: ConsoleKit %s raised:\n %s\n\n",
+                         g_dbus_error_get_remote_error (error), error->message);
+                g_error_free (error);
+                return FALSE;
+        }
+
+        g_variant_unref (reply);
+
+        return TRUE;
+}
+#endif
+
+static gboolean
+session_unlock (GdmManager *manager,
+                const char *ssid)
+{
+
+        g_debug ("Unlocking session %s", ssid);
+
+#ifdef WITH_SYSTEMD
+        if (LOGIND_RUNNING()) {
+                return session_unlock_for_systemd (manager, ssid);
+        }
+#endif
+
+#ifdef WITH_CONSOLE_KIT
+        return session_unlock_for_ck (manager, ssid);
+#else
+        return TRUE;
+#endif
+}
+
 static GdmSession *
 find_session_for_user_on_seat (GdmManager *manager,
                                const char *username,
@@ -385,11 +674,44 @@ find_session_for_user_on_seat (GdmManager *manager,
         return NULL;
 }
 
+#ifdef WITH_CONSOLE_KIT
 static gboolean
-is_remote_session (GdmManager  *self,
-                   const char  *session_id,
-                   GError     **error)
+is_consolekit_remote_session (GdmManager       *self,
+                             GDBusConnection  *connection,
+                             const char       *session_id,
+                             GError          **error)
 {
+        GVariant *reply;
+        gboolean is_remote;
+
+        reply = g_dbus_connection_call_sync (connection,
+                                             "org.freedesktop.ConsoleKit",
+                                             session_id,
+                                             "org.freedesktop.ConsoleKit.Session",
+                                             "IsLocal",
+                                             NULL,
+                                             G_VARIANT_TYPE ("(b)"),
+                                             G_DBUS_CALL_FLAGS_NONE,
+                                             -1,
+                                             NULL,
+                                             error);
+        if (reply == NULL) {
+                return FALSE;
+        }
+
+        g_variant_get (reply, "(b)", &is_remote);
+        g_variant_unref (reply);
+
+        return is_remote;
+}
+#endif
+
+#ifdef WITH_SYSTEMD
+static gboolean
+is_systemd_remote_session (GdmManager  *self,
+                           const char  *session_id,
+                           GError     **error)
+{
         char *seat;
         int ret;
         gboolean is_remote;
@@ -414,10 +736,31 @@ is_remote_session (GdmManager  *self,
 
         return is_remote;
 }
+#endif
 
+static gboolean
+is_remote_session (GdmManager       *self,
+                  GDBusConnection  *connection,
+                  const char       *session_id,
+                  GError          **error)
+{
+#ifdef WITH_SYSTEMD
+        if (LOGIND_RUNNING()) {
+                return is_systemd_remote_session (self, session_id, error);
+        }
+#endif
+
+#ifdef WITH_CONSOLE_KIT
+        return is_consolekit_remote_session (self, connection, session_id, error);
+#endif
+
+        return FALSE;
+}
+
+#ifdef WITH_SYSTEMD
 static char *
-get_seat_id_for_session_id (const char  *session_id,
-                            GError     **error)
+get_seat_id_for_systemd_session_id (const char  *session_id,
+                                    GError     **error)
 {
         int ret;
         char *seat, *out_seat;
@@ -442,11 +785,62 @@ get_seat_id_for_session_id (const char  *session_id,
 
         return out_seat;
 }
+#endif
 
+#ifdef WITH_CONSOLE_KIT
 static char *
-get_tty_for_session_id (const char  *session_id,
-                        GError     **error)
+get_seat_id_for_consolekit_session_id (GDBusConnection  *connection,
+                                       const char       *session_id,
+                                       GError          **error)
 {
+        GVariant *reply;
+        char *retval;
+
+        reply = g_dbus_connection_call_sync (connection,
+                                             "org.freedesktop.ConsoleKit",
+                                             session_id,
+                                             "org.freedesktop.ConsoleKit.Session",
+                                             "GetSeatId",
+                                             NULL,
+                                             G_VARIANT_TYPE ("(o)"),
+                                             G_DBUS_CALL_FLAGS_NONE,
+                                             -1,
+                                             NULL,
+                                             error);
+        if (reply == NULL) {
+                return NULL;
+        }
+
+        g_variant_get (reply, "(o)", &retval);
+        g_variant_unref (reply);
+
+        return retval;
+}
+#endif
+
+static char *
+get_seat_id_for_session_id (GDBusConnection  *connection,
+                            const char       *session_id,
+                            GError          **error)
+{
+#ifdef WITH_SYSTEMD
+        if (LOGIND_RUNNING()) {
+                return get_seat_id_for_systemd_session_id (session_id, error);
+        }
+#endif
+
+#ifdef WITH_CONSOLE_KIT
+        return get_seat_id_for_consolekit_session_id (connection, session_id, error);
+#endif
+
+        return NULL;
+}
+
+#ifdef WITH_SYSTEMD
+static char *
+get_tty_for_systemd_session_id (const char  *session_id,
+                                GError     **error)
+{
         int ret;
         char *tty, *out_tty;
 
@@ -469,7 +863,21 @@ get_tty_for_session_id (const char  *session_id,
 
         return out_tty;
 }
+#endif
 
+static char *
+get_tty_for_session_id (const char  *session_id,
+                        GError     **error)
+{
+#ifdef WITH_SYSTEMD
+        if (LOGIND_RUNNING()) {
+                return get_tty_for_systemd_session_id (session_id, error);
+        }
+#endif
+
+        return NULL;
+}
+
 static void
 get_display_and_details_for_bus_sender (GdmManager       *self,
                                         GDBusConnection  *connection,
@@ -512,7 +920,7 @@ get_display_and_details_for_bus_sender (GdmManager    
                 goto out;
         }
 
-        session_id = get_session_id_for_pid (pid, &error);
+        session_id = get_session_id_for_pid (connection, pid, &error);
 
         if (session_id == NULL) {
                 g_debug ("GdmManager: Error while retrieving session id for sender: %s",
@@ -526,7 +934,7 @@ get_display_and_details_for_bus_sender (GdmManager    
         }
 
         if (out_is_login_screen != NULL) {
-                *out_is_login_screen = is_login_session (self, session_id, &error);
+                *out_is_login_screen = is_login_session (self, connection, session_id, &error);
 
                 if (error != NULL) {
                         g_debug ("GdmManager: Error while checking if sender is login screen: %s",
@@ -536,7 +944,7 @@ get_display_and_details_for_bus_sender (GdmManager    
                 }
         }
 
-        if (!get_uid_for_session_id (session_id, &session_uid, &error)) {
+        if (!get_uid_for_session_id (connection, session_id, &session_uid, &error)) {
                 g_debug ("GdmManager: Error while retrieving uid for session: %s",
                          error->message);
                 g_error_free (error);
@@ -553,7 +961,7 @@ get_display_and_details_for_bus_sender (GdmManager    
         }
 
         if (out_seat_id != NULL) {
-                *out_seat_id = get_seat_id_for_session_id (session_id, &error);
+                *out_seat_id = get_seat_id_for_session_id (connection, session_id, &error);
 
                 if (error != NULL) {
                         g_debug ("GdmManager: Error while retrieving seat id for session: %s",
@@ -563,7 +971,7 @@ get_display_and_details_for_bus_sender (GdmManager    
         }
 
         if (out_is_remote != NULL) {
-                *out_is_remote = is_remote_session (self, session_id, &error);
+                *out_is_remote = is_remote_session (self, connection, session_id, &error);
 
                 if (error != NULL) {
                         g_debug ("GdmManager: Error while retrieving remoteness for session: %s",
@@ -927,7 +1335,8 @@ on_reauthentication_client_rejected (GdmSession       
                  * same audit session, ignore it since it doesn't "own" the
                  * reauthentication session
                  */
-                client_session_id = get_session_id_for_pid (pid_of_client,
+                client_session_id = get_session_id_for_pid (self->priv->connection,
+                                                            pid_of_client,
                                                             NULL);
                 session_id = g_object_get_data (G_OBJECT (session), "caller-session-id");
 
@@ -1139,16 +1548,20 @@ static gboolean
 display_is_on_seat0 (GdmDisplay *display)
 {
         gboolean is_on_seat0 = TRUE;
-        char *seat_id = NULL;
 
-        g_object_get (G_OBJECT (display), "seat-id", &seat_id, NULL);
+#ifdef WITH_SYSTEMD
+        if (LOGIND_RUNNING()) {
+                char *seat_id = NULL;
 
-        if (g_strcmp0 (seat_id, "seat0") != 0) {
-            is_on_seat0 = FALSE;
-        }
+                g_object_get (G_OBJECT (display), "seat-id", &seat_id, NULL);
 
-        g_free (seat_id);
+                if (g_strcmp0 (seat_id, "seat0") != 0) {
+                        is_on_seat0 = FALSE;
+                }
 
+                g_free (seat_id);
+        }
+#endif
         return is_on_seat0;
 }
 
@@ -1785,11 +2198,57 @@ on_user_session_died (GdmSession *session,
 }
 
 static char *
+query_ck_for_display_device (GdmManager *manager,
+                             GdmDisplay *display)
+{
+        char    *out;
+        char    *command;
+        char    *display_name = NULL;
+        int      status;
+        gboolean res;
+        GError  *error;
+
+        g_object_get (G_OBJECT (display),
+                      "x11-display-name", &display_name,
+                      NULL);
+
+        error = NULL;
+        command = g_strdup_printf (CONSOLEKIT_DIR "/ck-get-x11-display-device --display %s",
+                                   display_name);
+        g_free (display_name);
+
+        g_debug ("GdmManager: Running helper %s", command);
+        out = NULL;
+        res = g_spawn_command_line_sync (command,
+                                         &out,
+                                         NULL,
+                                         &status,
+                                         &error);
+        if (! res) {
+                g_warning ("GdmManager: Could not run helper %s: %s", command, error->message);
+                g_error_free (error);
+        } else {
+                out = g_strstrip (out);
+                g_debug ("GdmManager: Got tty: '%s'", out);
+        }
+
+        g_free (command);
+
+        return out;
+}
+
+static char *
 get_display_device (GdmManager *manager,
                     GdmDisplay *display)
 {
-        /* systemd finds the display device out on its own based on the display */
-        return NULL;
+#ifdef WITH_SYSTEMD
+        if (LOGIND_RUNNING()) {
+                /* systemd finds the display device out on its own based on the display */
+                return NULL;
+        }
+#endif
+
+        return query_ck_for_display_device (manager, display);
 }
 
 static void
