|
|
01018b |
From 16adbf262b641ec722794a30a91097767d13fc16 Mon Sep 17 00:00:00 2001
|
|
|
01018b |
From: Ray Strode <rstrode@redhat.com>
|
|
|
01018b |
Date: Wed, 12 Feb 2014 14:22:31 -0500
|
|
|
01018b |
Subject: [PATCH 1/4] manager: explicitly disallow login screen from opening
|
|
|
01018b |
reauth channel
|
|
|
01018b |
|
|
|
01018b |
It doesn't make sense for it to do, and right now the shell does it
|
|
|
01018b |
up front, waits for the failure, and then does the "right" thing
|
|
|
01018b |
(opens a new auth session) after.
|
|
|
01018b |
|
|
|
01018b |
This commit makes the failure explicit, so we can subsequently make
|
|
|
01018b |
other cases where a reauth channel is requested work even if there is
|
|
|
01018b |
no session to channel to by implicitly creating a transient one just
|
|
|
01018b |
in time. That will come later.
|
|
|
01018b |
---
|
|
|
01018b |
daemon/gdm-manager.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++---
|
|
|
01018b |
1 file changed, 116 insertions(+), 6 deletions(-)
|
|
|
01018b |
|
|
|
01018b |
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
|
|
01018b |
index 6c0fe1d..6ce37e8 100644
|
|
|
01018b |
--- a/daemon/gdm-manager.c
|
|
|
01018b |
+++ b/daemon/gdm-manager.c
|
|
|
01018b |
@@ -244,192 +244,302 @@ get_uid_for_session_id (GDBusConnection *connection,
|
|
|
01018b |
if (LOGIND_RUNNING()) {
|
|
|
01018b |
return get_uid_for_systemd_session_id (session_id, uid, error);
|
|
|
01018b |
}
|
|
|
01018b |
#endif
|
|
|
01018b |
|
|
|
01018b |
#ifdef WITH_CONSOLE_KIT
|
|
|
01018b |
return get_uid_for_consolekit_session_id (connection, session_id, uid, error);
|
|
|
01018b |
#endif
|
|
|
01018b |
|
|
|
01018b |
return FALSE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
static gboolean
|
|
|
01018b |
lookup_by_session_id (const char *id,
|
|
|
01018b |
GdmDisplay *display,
|
|
|
01018b |
gpointer user_data)
|
|
|
01018b |
{
|
|
|
01018b |
const char *looking_for = user_data;
|
|
|
01018b |
char *current;
|
|
|
01018b |
gboolean res;
|
|
|
01018b |
|
|
|
01018b |
current = gdm_display_get_session_id (display);
|
|
|
01018b |
|
|
|
01018b |
res = g_strcmp0 (current, looking_for) == 0;
|
|
|
01018b |
|
|
|
01018b |
g_free (current);
|
|
|
01018b |
|
|
|
01018b |
return res;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
+#ifdef WITH_CONSOLE_KIT
|
|
|
01018b |
+static gboolean
|
|
|
01018b |
+is_consolekit_login_session (GdmManager *self,
|
|
|
01018b |
+ GDBusConnection *connection,
|
|
|
01018b |
+ const char *session_id,
|
|
|
01018b |
+ GError **error)
|
|
|
01018b |
+{
|
|
|
01018b |
+ GVariant *reply;
|
|
|
01018b |
+ char *session_type = NULL;
|
|
|
01018b |
+
|
|
|
01018b |
+ reply = g_dbus_connection_call_sync (connection,
|
|
|
01018b |
+ "org.freedesktop.ConsoleKit",
|
|
|
01018b |
+ session_id,
|
|
|
01018b |
+ "org.freedesktop.ConsoleKit.Session",
|
|
|
01018b |
+ "GetSessionType",
|
|
|
01018b |
+ NULL,
|
|
|
01018b |
+ G_VARIANT_TYPE ("(s)"),
|
|
|
01018b |
+ G_DBUS_CALL_FLAGS_NONE,
|
|
|
01018b |
+ -1,
|
|
|
01018b |
+ NULL,
|
|
|
01018b |
+ error);
|
|
|
01018b |
+ if (reply == NULL) {
|
|
|
01018b |
+ return FALSE;
|
|
|
01018b |
+ }
|
|
|
01018b |
+
|
|
|
01018b |
+ g_variant_get (reply, "(s)", &session_type);
|
|
|
01018b |
+ g_variant_unref (reply);
|
|
|
01018b |
+
|
|
|
01018b |
+ if (g_strcmp0 (session_type, "LoginWindow") != 0) {
|
|
|
01018b |
+ g_free (session_type);
|
|
|
01018b |
+
|
|
|
01018b |
+ return FALSE;
|
|
|
01018b |
+ }
|
|
|
01018b |
+
|
|
|
01018b |
+ g_free (session_type);
|
|
|
01018b |
+ return TRUE;
|
|
|
01018b |
+}
|
|
|
01018b |
+#endif
|
|
|
01018b |
+
|
|
|
01018b |
+#ifdef WITH_SYSTEMD
|
|
|
01018b |
+static gboolean
|
|
|
01018b |
+is_systemd_login_session (GdmManager *self,
|
|
|
01018b |
+ const char *session_id,
|
|
|
01018b |
+ GError **error)
|
|
|
01018b |
+{
|
|
|
01018b |
+ char *session_class = NULL;
|
|
|
01018b |
+ int ret;
|
|
|
01018b |
+
|
|
|
01018b |
+ ret = sd_session_get_class (session_id, &session_class);
|
|
|
01018b |
+
|
|
|
01018b |
+ if (ret < 0) {
|
|
|
01018b |
+ g_set_error (error,
|
|
|
01018b |
+ GDM_DISPLAY_ERROR,
|
|
|
01018b |
+ GDM_DISPLAY_ERROR_GETTING_SESSION_INFO,
|
|
|
01018b |
+ "Error getting class for session id %s from systemd: %s",
|
|
|
01018b |
+ session_id,
|
|
|
01018b |
+ g_strerror (-ret));
|
|
|
01018b |
+ return FALSE;
|
|
|
01018b |
+ }
|
|
|
01018b |
+
|
|
|
01018b |
+ if (g_strcmp0 (session_class, "greeter") != 0) {
|
|
|
01018b |
+ g_free (session_class);
|
|
|
01018b |
+ return FALSE;
|
|
|
01018b |
+ }
|
|
|
01018b |
+
|
|
|
01018b |
+ g_free (session_class);
|
|
|
01018b |
+ return TRUE;
|
|
|
01018b |
+}
|
|
|
01018b |
+#endif
|
|
|
01018b |
+
|
|
|
01018b |
+static gboolean
|
|
|
01018b |
+is_login_session (GdmManager *self,
|
|
|
01018b |
+ GDBusConnection *connection,
|
|
|
01018b |
+ const char *session_id,
|
|
|
01018b |
+ GError **error)
|
|
|
01018b |
+{
|
|
|
01018b |
+#ifdef WITH_SYSTEMD
|
|
|
01018b |
+ if (LOGIND_RUNNING()) {
|
|
|
01018b |
+ return is_systemd_login_session (self, session_id, error);
|
|
|
01018b |
+ }
|
|
|
01018b |
+#endif
|
|
|
01018b |
+
|
|
|
01018b |
+#ifdef WITH_CONSOLE_KIT
|
|
|
01018b |
+ return is_consolekit_login_session (self, connection, session_id, error);
|
|
|
01018b |
+#endif
|
|
|
01018b |
+
|
|
|
01018b |
+ return FALSE;
|
|
|
01018b |
+}
|
|
|
01018b |
+
|
|
|
01018b |
static GdmDisplay *
|
|
|
01018b |
get_display_and_details_for_bus_sender (GdmManager *self,
|
|
|
01018b |
- GDBusConnection *connection,
|
|
|
01018b |
- const char *sender,
|
|
|
01018b |
- GPid *out_pid,
|
|
|
01018b |
- uid_t *out_uid)
|
|
|
01018b |
+ GDBusConnection *connection,
|
|
|
01018b |
+ const char *sender,
|
|
|
01018b |
+ GPid *out_pid,
|
|
|
01018b |
+ uid_t *out_uid,
|
|
|
01018b |
+ gboolean *out_is_login_screen)
|
|
|
01018b |
{
|
|
|
01018b |
GdmDisplay *display = NULL;
|
|
|
01018b |
char *session_id = NULL;
|
|
|
01018b |
GError *error = NULL;
|
|
|
01018b |
int ret;
|
|
|
01018b |
GPid pid;
|
|
|
01018b |
uid_t caller_uid, session_uid;
|
|
|
01018b |
|
|
|
01018b |
ret = gdm_dbus_get_pid_for_name (sender, &pid, &error);
|
|
|
01018b |
|
|
|
01018b |
if (!ret) {
|
|
|
01018b |
g_debug ("GdmManager: Error while retrieving pid for sender: %s",
|
|
|
01018b |
error->message);
|
|
|
01018b |
g_error_free (error);
|
|
|
01018b |
goto out;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
ret = gdm_dbus_get_uid_for_name (sender, &caller_uid, &error);
|
|
|
01018b |
|
|
|
01018b |
if (!ret) {
|
|
|
01018b |
g_debug ("GdmManager: Error while retrieving uid for sender: %s",
|
|
|
01018b |
error->message);
|
|
|
01018b |
g_error_free (error);
|
|
|
01018b |
goto out;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
session_id = get_session_id_for_pid (connection, pid, &error);
|
|
|
01018b |
|
|
|
01018b |
if (session_id == NULL) {
|
|
|
01018b |
g_debug ("GdmManager: Error while retrieving session id for sender: %s",
|
|
|
01018b |
error->message);
|
|
|
01018b |
g_error_free (error);
|
|
|
01018b |
goto out;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
+ if (out_is_login_screen != NULL) {
|
|
|
01018b |
+ *out_is_login_screen = is_login_session (self, connection, session_id, &error);
|
|
|
01018b |
+
|
|
|
01018b |
+ if (error != NULL) {
|
|
|
01018b |
+ g_debug ("GdmManager: Error while checking if sender is login screen: %s",
|
|
|
01018b |
+ error->message);
|
|
|
01018b |
+ g_error_free (error);
|
|
|
01018b |
+ goto out;
|
|
|
01018b |
+ }
|
|
|
01018b |
+ }
|
|
|
01018b |
+
|
|
|
01018b |
if (!get_uid_for_session_id (connection, session_id, &session_uid, &error)) {
|
|
|
01018b |
g_debug ("GdmManager: Error while retrieving uid for session: %s",
|
|
|
01018b |
error->message);
|
|
|
01018b |
g_error_free (error);
|
|
|
01018b |
goto out;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
if (caller_uid != session_uid) {
|
|
|
01018b |
g_debug ("GdmManager: uid for sender and uid for session don't match");
|
|
|
01018b |
goto out;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
display = gdm_display_store_find (self->priv->display_store,
|
|
|
01018b |
lookup_by_session_id,
|
|
|
01018b |
(gpointer) session_id);
|
|
|
01018b |
out:
|
|
|
01018b |
g_free (session_id);
|
|
|
01018b |
|
|
|
01018b |
if (display != NULL) {
|
|
|
01018b |
if (out_pid != NULL)
|
|
|
01018b |
*out_pid = pid;
|
|
|
01018b |
|
|
|
01018b |
if (out_uid != NULL)
|
|
|
01018b |
*out_uid = session_uid;
|
|
|
01018b |
}
|
|
|
01018b |
return display;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
static gboolean
|
|
|
01018b |
gdm_manager_handle_open_session (GdmDBusManager *manager,
|
|
|
01018b |
GDBusMethodInvocation *invocation)
|
|
|
01018b |
{
|
|
|
01018b |
GdmManager *self = GDM_MANAGER (manager);
|
|
|
01018b |
const char *sender = NULL;
|
|
|
01018b |
GError *error = NULL;
|
|
|
01018b |
GDBusConnection *connection;
|
|
|
01018b |
GdmDisplay *display;
|
|
|
01018b |
char *address;
|
|
|
01018b |
GPid pid;
|
|
|
01018b |
uid_t uid;
|
|
|
01018b |
|
|
|
01018b |
g_debug ("GdmManager: trying to open new session");
|
|
|
01018b |
|
|
|
01018b |
sender = g_dbus_method_invocation_get_sender (invocation);
|
|
|
01018b |
connection = g_dbus_method_invocation_get_connection (invocation);
|
|
|
01018b |
- display = get_display_and_details_for_bus_sender (self, connection, sender, &pid, &uid);
|
|
|
01018b |
+ display = get_display_and_details_for_bus_sender (self, connection, sender, &pid, &uid, NULL);
|
|
|
01018b |
|
|
|
01018b |
if (display == NULL) {
|
|
|
01018b |
g_dbus_method_invocation_return_error_literal (invocation,
|
|
|
01018b |
G_DBUS_ERROR,
|
|
|
01018b |
G_DBUS_ERROR_ACCESS_DENIED,
|
|
|
01018b |
_("No session available"));
|
|
|
01018b |
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
address = gdm_display_open_session_sync (display, pid, uid, NULL, &error);
|
|
|
01018b |
|
|
|
01018b |
if (address == NULL) {
|
|
|
01018b |
g_dbus_method_invocation_return_gerror (invocation, error);
|
|
|
01018b |
g_error_free (error);
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
gdm_dbus_manager_complete_open_session (GDM_DBUS_MANAGER (manager),
|
|
|
01018b |
invocation,
|
|
|
01018b |
address);
|
|
|
01018b |
g_free (address);
|
|
|
01018b |
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
static gboolean
|
|
|
01018b |
gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager,
|
|
|
01018b |
GDBusMethodInvocation *invocation,
|
|
|
01018b |
const char *username)
|
|
|
01018b |
{
|
|
|
01018b |
GdmManager *self = GDM_MANAGER (manager);
|
|
|
01018b |
const char *sender = NULL;
|
|
|
01018b |
GError *error = NULL;
|
|
|
01018b |
GDBusConnection *connection;
|
|
|
01018b |
GdmDisplay *display;
|
|
|
01018b |
char *address;
|
|
|
01018b |
GPid pid;
|
|
|
01018b |
uid_t uid;
|
|
|
01018b |
+ gboolean is_login_screen = FALSE;
|
|
|
01018b |
|
|
|
01018b |
g_debug ("GdmManager: trying to open reauthentication channel for user %s", username);
|
|
|
01018b |
|
|
|
01018b |
sender = g_dbus_method_invocation_get_sender (invocation);
|
|
|
01018b |
connection = g_dbus_method_invocation_get_connection (invocation);
|
|
|
01018b |
- display = get_display_and_details_for_bus_sender (self, connection, sender, &pid, &uid);
|
|
|
01018b |
+ display = get_display_and_details_for_bus_sender (self, connection, sender, &pid, &uid, &is_login_screen);
|
|
|
01018b |
+
|
|
|
01018b |
+ if (is_login_screen) {
|
|
|
01018b |
+ g_dbus_method_invocation_return_error_literal (invocation,
|
|
|
01018b |
+ G_DBUS_ERROR,
|
|
|
01018b |
+ G_DBUS_ERROR_ACCESS_DENIED,
|
|
|
01018b |
+ _("Login screen not allow to open reauthentication channel"));
|
|
|
01018b |
+ return TRUE;
|
|
|
01018b |
+ }
|
|
|
01018b |
|
|
|
01018b |
if (display == NULL) {
|
|
|
01018b |
g_dbus_method_invocation_return_error_literal (invocation,
|
|
|
01018b |
G_DBUS_ERROR,
|
|
|
01018b |
G_DBUS_ERROR_ACCESS_DENIED,
|
|
|
01018b |
_("No session available"));
|
|
|
01018b |
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
address = gdm_display_open_reauthentication_channel_sync (display,
|
|
|
01018b |
username,
|
|
|
01018b |
pid,
|
|
|
01018b |
uid,
|
|
|
01018b |
NULL,
|
|
|
01018b |
&error);
|
|
|
01018b |
|
|
|
01018b |
if (address == NULL) {
|
|
|
01018b |
g_dbus_method_invocation_return_gerror (invocation, error);
|
|
|
01018b |
g_error_free (error);
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
gdm_dbus_manager_complete_open_reauthentication_channel (GDM_DBUS_MANAGER (manager),
|
|
|
01018b |
invocation,
|
|
|
01018b |
address);
|
|
|
01018b |
g_free (address);
|
|
|
01018b |
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
--
|
|
|
01018b |
1.8.4.2
|
|
|
01018b |
|
|
|
01018b |
|
|
|
01018b |
From 3a1330c93213a060c51b2d3021360e80a779814c Mon Sep 17 00:00:00 2001
|
|
|
01018b |
From: Ray Strode <rstrode@redhat.com>
|
|
|
01018b |
Date: Tue, 11 Mar 2014 23:46:35 -0400
|
|
|
01018b |
Subject: [PATCH 2/4] worker: support authentication without X11 display
|
|
|
01018b |
|
|
|
01018b |
At the moment we unconditionally set PAM_XDISPLAY
|
|
|
01018b |
and PAM_XAUTHDATA based on values passed to the worker.
|
|
|
01018b |
|
|
|
01018b |
In a future commit, those values are going to become
|
|
|
01018b |
stubs, so as a first step, this commit makes PAM_XDISPLAY
|
|
|
01018b |
and PAM_XAUTHDATA optional.
|
|
|
01018b |
---
|
|
|
01018b |
daemon/gdm-session-worker.c | 11 ++++++++---
|
|
|
01018b |
1 file changed, 8 insertions(+), 3 deletions(-)
|
|
|
01018b |
|
|
|
01018b |
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
|
|
|
01018b |
index 79cf202..eb81450 100644
|
|
|
01018b |
--- a/daemon/gdm-session-worker.c
|
|
|
01018b |
+++ b/daemon/gdm-session-worker.c
|
|
|
01018b |
@@ -1073,76 +1073,81 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker,
|
|
|
01018b |
|
|
|
01018b |
/* set TTY */
|
|
|
01018b |
pam_tty = _get_tty_for_pam (x11_display_name, display_device);
|
|
|
01018b |
if (pam_tty != NULL && pam_tty[0] != '\0') {
|
|
|
01018b |
error_code = pam_set_item (worker->priv->pam_handle, PAM_TTY, pam_tty);
|
|
|
01018b |
}
|
|
|
01018b |
g_free (pam_tty);
|
|
|
01018b |
|
|
|
01018b |
if (error_code != PAM_SUCCESS) {
|
|
|
01018b |
g_set_error (error,
|
|
|
01018b |
GDM_SESSION_WORKER_ERROR,
|
|
|
01018b |
GDM_SESSION_WORKER_ERROR_AUTHENTICATING,
|
|
|
01018b |
_("error informing authentication system of user's console: %s"),
|
|
|
01018b |
pam_strerror (worker->priv->pam_handle, error_code));
|
|
|
01018b |
goto out;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
#ifdef WITH_SYSTEMD
|
|
|
01018b |
/* set seat ID */
|
|
|
01018b |
if (seat_id != NULL && seat_id[0] != '\0' && LOGIND_RUNNING()) {
|
|
|
01018b |
gdm_session_worker_set_environment_variable (worker, "XDG_SEAT", seat_id);
|
|
|
01018b |
}
|
|
|
01018b |
#endif
|
|
|
01018b |
|
|
|
01018b |
if (strcmp (service, "gdm-launch-environment") == 0) {
|
|
|
01018b |
gdm_session_worker_set_environment_variable (worker, "XDG_SESSION_CLASS", "greeter");
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
#ifdef PAM_XDISPLAY
|
|
|
01018b |
/* set XDISPLAY */
|
|
|
01018b |
- error_code = pam_set_item (worker->priv->pam_handle, PAM_XDISPLAY, x11_display_name);
|
|
|
01018b |
+ if (x11_display_name != NULL && x11_display_name[0] != '\0') {
|
|
|
01018b |
+ error_code = pam_set_item (worker->priv->pam_handle, PAM_XDISPLAY, x11_display_name);
|
|
|
01018b |
+ }
|
|
|
01018b |
|
|
|
01018b |
if (error_code != PAM_SUCCESS) {
|
|
|
01018b |
g_set_error (error,
|
|
|
01018b |
GDM_SESSION_WORKER_ERROR,
|
|
|
01018b |
GDM_SESSION_WORKER_ERROR_AUTHENTICATING,
|
|
|
01018b |
_("error informing authentication system of display string: %s"),
|
|
|
01018b |
pam_strerror (worker->priv->pam_handle, error_code));
|
|
|
01018b |
goto out;
|
|
|
01018b |
}
|
|
|
01018b |
#endif
|
|
|
01018b |
#ifdef PAM_XAUTHDATA
|
|
|
01018b |
/* set XAUTHDATA */
|
|
|
01018b |
pam_xauth = _get_xauth_for_pam (x11_authority_file);
|
|
|
01018b |
- error_code = pam_set_item (worker->priv->pam_handle, PAM_XAUTHDATA, pam_xauth);
|
|
|
01018b |
- g_free (pam_xauth);
|
|
|
01018b |
+
|
|
|
01018b |
+ if (pam_xauth != NULL) {
|
|
|
01018b |
+ error_code = pam_set_item (worker->priv->pam_handle, PAM_XAUTHDATA, pam_xauth);
|
|
|
01018b |
+ g_free (pam_xauth);
|
|
|
01018b |
+ }
|
|
|
01018b |
|
|
|
01018b |
if (error_code != PAM_SUCCESS) {
|
|
|
01018b |
g_set_error (error,
|
|
|
01018b |
GDM_SESSION_WORKER_ERROR,
|
|
|
01018b |
GDM_SESSION_WORKER_ERROR_AUTHENTICATING,
|
|
|
01018b |
_("error informing authentication system of display xauth credentials: %s"),
|
|
|
01018b |
pam_strerror (worker->priv->pam_handle, error_code));
|
|
|
01018b |
goto out;
|
|
|
01018b |
}
|
|
|
01018b |
#endif
|
|
|
01018b |
|
|
|
01018b |
g_debug ("GdmSessionWorker: state SETUP_COMPLETE");
|
|
|
01018b |
worker->priv->state = GDM_SESSION_WORKER_STATE_SETUP_COMPLETE;
|
|
|
01018b |
|
|
|
01018b |
out:
|
|
|
01018b |
if (error_code != PAM_SUCCESS) {
|
|
|
01018b |
gdm_session_worker_uninitialize_pam (worker, error_code);
|
|
|
01018b |
return FALSE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
static gboolean
|
|
|
01018b |
gdm_session_worker_authenticate_user (GdmSessionWorker *worker,
|
|
|
01018b |
gboolean password_is_required,
|
|
|
01018b |
GError **error)
|
|
|
01018b |
{
|
|
|
01018b |
int error_code;
|
|
|
01018b |
int authentication_flags;
|
|
|
01018b |
--
|
|
|
01018b |
1.8.4.2
|
|
|
01018b |
|
|
|
01018b |
|
|
|
01018b |
From e8c249d57b744d61c3c119f55e26f1ff1c14a598 Mon Sep 17 00:00:00 2001
|
|
|
01018b |
From: Ray Strode <rstrode@redhat.com>
|
|
|
01018b |
Date: Wed, 19 Feb 2014 10:54:56 -0500
|
|
|
01018b |
Subject: [PATCH 3/4] manager: collect more details about bus sender
|
|
|
01018b |
|
|
|
01018b |
In the future we're going to need to know more details about the
|
|
|
01018b |
sender to know how to move forward (such as seat id, session id,
|
|
|
01018b |
if it's remote, etc) in order to create a transient session soley
|
|
|
01018b |
for reauthentication.
|
|
|
01018b |
|
|
|
01018b |
To prepare for that future, this commit adds the necessary
|
|
|
01018b |
functionality to get_display_and_details_for_bus_sender.
|
|
|
01018b |
---
|
|
|
01018b |
daemon/gdm-manager.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++-----
|
|
|
01018b |
1 file changed, 209 insertions(+), 19 deletions(-)
|
|
|
01018b |
|
|
|
01018b |
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
|
|
01018b |
index 6ce37e8..4c47045 100644
|
|
|
01018b |
--- a/daemon/gdm-manager.c
|
|
|
01018b |
+++ b/daemon/gdm-manager.c
|
|
|
01018b |
@@ -333,205 +333,395 @@ is_systemd_login_session (GdmManager *self,
|
|
|
01018b |
|
|
|
01018b |
if (g_strcmp0 (session_class, "greeter") != 0) {
|
|
|
01018b |
g_free (session_class);
|
|
|
01018b |
return FALSE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
g_free (session_class);
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
#endif
|
|
|
01018b |
|
|
|
01018b |
static gboolean
|
|
|
01018b |
is_login_session (GdmManager *self,
|
|
|
01018b |
GDBusConnection *connection,
|
|
|
01018b |
const char *session_id,
|
|
|
01018b |
GError **error)
|
|
|
01018b |
{
|
|
|
01018b |
#ifdef WITH_SYSTEMD
|
|
|
01018b |
if (LOGIND_RUNNING()) {
|
|
|
01018b |
return is_systemd_login_session (self, session_id, error);
|
|
|
01018b |
}
|
|
|
01018b |
#endif
|
|
|
01018b |
|
|
|
01018b |
#ifdef WITH_CONSOLE_KIT
|
|
|
01018b |
return is_consolekit_login_session (self, connection, session_id, error);
|
|
|
01018b |
#endif
|
|
|
01018b |
|
|
|
01018b |
return FALSE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
-static GdmDisplay *
|
|
|
01018b |
+#ifdef WITH_CONSOLE_KIT
|
|
|
01018b |
+static gboolean
|
|
|
01018b |
+is_consolekit_remote_session (GdmManager *self,
|
|
|
01018b |
+ GDBusConnection *connection,
|
|
|
01018b |
+ const char *session_id,
|
|
|
01018b |
+ GError **error)
|
|
|
01018b |
+{
|
|
|
01018b |
+ GVariant *reply;
|
|
|
01018b |
+ gboolean is_remote;
|
|
|
01018b |
+
|
|
|
01018b |
+ reply = g_dbus_connection_call_sync (connection,
|
|
|
01018b |
+ "org.freedesktop.ConsoleKit",
|
|
|
01018b |
+ session_id,
|
|
|
01018b |
+ "org.freedesktop.ConsoleKit.Session",
|
|
|
01018b |
+ "IsLocal",
|
|
|
01018b |
+ NULL,
|
|
|
01018b |
+ G_VARIANT_TYPE ("(b)"),
|
|
|
01018b |
+ G_DBUS_CALL_FLAGS_NONE,
|
|
|
01018b |
+ -1,
|
|
|
01018b |
+ NULL,
|
|
|
01018b |
+ error);
|
|
|
01018b |
+ if (reply == NULL) {
|
|
|
01018b |
+ return FALSE;
|
|
|
01018b |
+ }
|
|
|
01018b |
+
|
|
|
01018b |
+ g_variant_get (reply, "(b)", &is_remote);
|
|
|
01018b |
+ g_variant_unref (reply);
|
|
|
01018b |
+
|
|
|
01018b |
+ return is_remote;
|
|
|
01018b |
+}
|
|
|
01018b |
+#endif
|
|
|
01018b |
+
|
|
|
01018b |
+#ifdef WITH_SYSTEMD
|
|
|
01018b |
+static gboolean
|
|
|
01018b |
+is_systemd_remote_session (GdmManager *self,
|
|
|
01018b |
+ const char *session_id,
|
|
|
01018b |
+ GError **error)
|
|
|
01018b |
+{
|
|
|
01018b |
+ char *seat;
|
|
|
01018b |
+ int ret;
|
|
|
01018b |
+ gboolean is_remote;
|
|
|
01018b |
+
|
|
|
01018b |
+ /* FIXME: The next release of logind is going to have explicit api for
|
|
|
01018b |
+ * checking remoteness.
|
|
|
01018b |
+ */
|
|
|
01018b |
+ seat = NULL;
|
|
|
01018b |
+ ret = sd_session_get_seat (session_id, &seat;;
|
|
|
01018b |
+
|
|
|
01018b |
+ if (ret < 0 && ret != -ENOENT) {
|
|
|
01018b |
+ g_debug ("GdmManager: Error while retrieving seat for session %s: %s",
|
|
|
01018b |
+ session_id, strerror (-ret));
|
|
|
01018b |
+ }
|
|
|
01018b |
+
|
|
|
01018b |
+ if (seat != NULL) {
|
|
|
01018b |
+ is_remote = FALSE;
|
|
|
01018b |
+ free (seat);
|
|
|
01018b |
+ } else {
|
|
|
01018b |
+ is_remote = TRUE;
|
|
|
01018b |
+ }
|
|
|
01018b |
+
|
|
|
01018b |
+ return is_remote;
|
|
|
01018b |
+}
|
|
|
01018b |
+#endif
|
|
|
01018b |
+
|
|
|
01018b |
+static gboolean
|
|
|
01018b |
+is_remote_session (GdmManager *self,
|
|
|
01018b |
+ GDBusConnection *connection,
|
|
|
01018b |
+ const char *session_id,
|
|
|
01018b |
+ GError **error)
|
|
|
01018b |
+{
|
|
|
01018b |
+#ifdef WITH_SYSTEMD
|
|
|
01018b |
+ if (LOGIND_RUNNING()) {
|
|
|
01018b |
+ return is_systemd_remote_session (self, session_id, error);
|
|
|
01018b |
+ }
|
|
|
01018b |
+#endif
|
|
|
01018b |
+
|
|
|
01018b |
+#ifdef WITH_CONSOLE_KIT
|
|
|
01018b |
+ return is_consolekit_remote_session (self, connection, session_id, error);
|
|
|
01018b |
+#endif
|
|
|
01018b |
+
|
|
|
01018b |
+ return FALSE;
|
|
|
01018b |
+}
|
|
|
01018b |
+
|
|
|
01018b |
+#ifdef WITH_SYSTEMD
|
|
|
01018b |
+static char *
|
|
|
01018b |
+get_seat_id_for_systemd_session_id (const char *session_id,
|
|
|
01018b |
+ GError **error)
|
|
|
01018b |
+{
|
|
|
01018b |
+ int ret;
|
|
|
01018b |
+ char *seat, *out_seat;
|
|
|
01018b |
+
|
|
|
01018b |
+ seat = NULL;
|
|
|
01018b |
+ ret = sd_session_get_seat (session_id, &seat;;
|
|
|
01018b |
+
|
|
|
01018b |
+ if (ret == -ENOENT) {
|
|
|
01018b |
+ out_seat = NULL;
|
|
|
01018b |
+ } else if (ret < 0) {
|
|
|
01018b |
+ g_set_error (error,
|
|
|
01018b |
+ GDM_DISPLAY_ERROR,
|
|
|
01018b |
+ GDM_DISPLAY_ERROR_GETTING_SESSION_INFO,
|
|
|
01018b |
+ "Error getting uid for session id %s from systemd: %s",
|
|
|
01018b |
+ session_id,
|
|
|
01018b |
+ g_strerror (-ret));
|
|
|
01018b |
+ out_seat = NULL;
|
|
|
01018b |
+ } else {
|
|
|
01018b |
+ out_seat = g_strdup (seat);
|
|
|
01018b |
+ free (seat);
|
|
|
01018b |
+ }
|
|
|
01018b |
+
|
|
|
01018b |
+ return out_seat;
|
|
|
01018b |
+}
|
|
|
01018b |
+#endif
|
|
|
01018b |
+
|
|
|
01018b |
+#ifdef WITH_CONSOLE_KIT
|
|
|
01018b |
+static char *
|
|
|
01018b |
+get_seat_id_for_consolekit_session_id (GDBusConnection *connection,
|
|
|
01018b |
+ const char *session_id,
|
|
|
01018b |
+ GError **error)
|
|
|
01018b |
+{
|
|
|
01018b |
+ GVariant *reply;
|
|
|
01018b |
+ char *retval;
|
|
|
01018b |
+
|
|
|
01018b |
+ reply = g_dbus_connection_call_sync (connection,
|
|
|
01018b |
+ "org.freedesktop.ConsoleKit",
|
|
|
01018b |
+ session_id,
|
|
|
01018b |
+ "org.freedesktop.ConsoleKit.Session",
|
|
|
01018b |
+ "GetSeatId",
|
|
|
01018b |
+ NULL,
|
|
|
01018b |
+ G_VARIANT_TYPE ("(o)"),
|
|
|
01018b |
+ G_DBUS_CALL_FLAGS_NONE,
|
|
|
01018b |
+ -1,
|
|
|
01018b |
+ NULL,
|
|
|
01018b |
+ error);
|
|
|
01018b |
+ if (reply == NULL) {
|
|
|
01018b |
+ return NULL;
|
|
|
01018b |
+ }
|
|
|
01018b |
+
|
|
|
01018b |
+ g_variant_get (reply, "(o)", &retval);
|
|
|
01018b |
+ g_variant_unref (reply);
|
|
|
01018b |
+
|
|
|
01018b |
+ return retval;
|
|
|
01018b |
+}
|
|
|
01018b |
+#endif
|
|
|
01018b |
+
|
|
|
01018b |
+static char *
|
|
|
01018b |
+get_seat_id_for_session_id (GDBusConnection *connection,
|
|
|
01018b |
+ const char *session_id,
|
|
|
01018b |
+ GError **error)
|
|
|
01018b |
+{
|
|
|
01018b |
+#ifdef WITH_SYSTEMD
|
|
|
01018b |
+ if (LOGIND_RUNNING()) {
|
|
|
01018b |
+ return get_seat_id_for_systemd_session_id (session_id, error);
|
|
|
01018b |
+ }
|
|
|
01018b |
+#endif
|
|
|
01018b |
+
|
|
|
01018b |
+#ifdef WITH_CONSOLE_KIT
|
|
|
01018b |
+ return get_seat_id_for_consolekit_session_id (connection, session_id, error);
|
|
|
01018b |
+#endif
|
|
|
01018b |
+
|
|
|
01018b |
+ return NULL;
|
|
|
01018b |
+}
|
|
|
01018b |
+
|
|
|
01018b |
+static void
|
|
|
01018b |
get_display_and_details_for_bus_sender (GdmManager *self,
|
|
|
01018b |
GDBusConnection *connection,
|
|
|
01018b |
const char *sender,
|
|
|
01018b |
+ GdmDisplay **out_display,
|
|
|
01018b |
+ char **out_seat_id,
|
|
|
01018b |
+ char **out_session_id,
|
|
|
01018b |
GPid *out_pid,
|
|
|
01018b |
uid_t *out_uid,
|
|
|
01018b |
- gboolean *out_is_login_screen)
|
|
|
01018b |
+ gboolean *out_is_login_screen,
|
|
|
01018b |
+ gboolean *out_is_remote)
|
|
|
01018b |
{
|
|
|
01018b |
GdmDisplay *display = NULL;
|
|
|
01018b |
char *session_id = NULL;
|
|
|
01018b |
GError *error = NULL;
|
|
|
01018b |
int ret;
|
|
|
01018b |
GPid pid;
|
|
|
01018b |
uid_t caller_uid, session_uid;
|
|
|
01018b |
|
|
|
01018b |
ret = gdm_dbus_get_pid_for_name (sender, &pid, &error);
|
|
|
01018b |
|
|
|
01018b |
if (!ret) {
|
|
|
01018b |
g_debug ("GdmManager: Error while retrieving pid for sender: %s",
|
|
|
01018b |
error->message);
|
|
|
01018b |
g_error_free (error);
|
|
|
01018b |
goto out;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
+ if (out_pid != NULL)
|
|
|
01018b |
+ *out_pid = pid;
|
|
|
01018b |
+
|
|
|
01018b |
ret = gdm_dbus_get_uid_for_name (sender, &caller_uid, &error);
|
|
|
01018b |
|
|
|
01018b |
if (!ret) {
|
|
|
01018b |
g_debug ("GdmManager: Error while retrieving uid for sender: %s",
|
|
|
01018b |
error->message);
|
|
|
01018b |
g_error_free (error);
|
|
|
01018b |
goto out;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
session_id = get_session_id_for_pid (connection, pid, &error);
|
|
|
01018b |
|
|
|
01018b |
if (session_id == NULL) {
|
|
|
01018b |
g_debug ("GdmManager: Error while retrieving session id for sender: %s",
|
|
|
01018b |
error->message);
|
|
|
01018b |
g_error_free (error);
|
|
|
01018b |
goto out;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
+ if (out_session_id != NULL) {
|
|
|
01018b |
+ *out_session_id = g_strdup (session_id);
|
|
|
01018b |
+ }
|
|
|
01018b |
+
|
|
|
01018b |
if (out_is_login_screen != NULL) {
|
|
|
01018b |
*out_is_login_screen = is_login_session (self, connection, session_id, &error);
|
|
|
01018b |
|
|
|
01018b |
if (error != NULL) {
|
|
|
01018b |
g_debug ("GdmManager: Error while checking if sender is login screen: %s",
|
|
|
01018b |
error->message);
|
|
|
01018b |
g_error_free (error);
|
|
|
01018b |
goto out;
|
|
|
01018b |
}
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
if (!get_uid_for_session_id (connection, session_id, &session_uid, &error)) {
|
|
|
01018b |
g_debug ("GdmManager: Error while retrieving uid for session: %s",
|
|
|
01018b |
error->message);
|
|
|
01018b |
g_error_free (error);
|
|
|
01018b |
goto out;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
+ if (out_uid != NULL)
|
|
|
01018b |
+ *out_uid = session_uid;
|
|
|
01018b |
+
|
|
|
01018b |
if (caller_uid != session_uid) {
|
|
|
01018b |
g_debug ("GdmManager: uid for sender and uid for session don't match");
|
|
|
01018b |
goto out;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
+ if (out_seat_id != NULL) {
|
|
|
01018b |
+ *out_seat_id = get_seat_id_for_session_id (connection, session_id, &error);
|
|
|
01018b |
+
|
|
|
01018b |
+ if (error != NULL) {
|
|
|
01018b |
+ g_debug ("GdmManager: Error while retrieving seat id for session: %s",
|
|
|
01018b |
+ error->message);
|
|
|
01018b |
+ g_clear_error (&error);
|
|
|
01018b |
+ }
|
|
|
01018b |
+ }
|
|
|
01018b |
+
|
|
|
01018b |
+ if (out_is_remote != NULL) {
|
|
|
01018b |
+ *out_is_remote = is_remote_session (self, connection, session_id, &error);
|
|
|
01018b |
+
|
|
|
01018b |
+ if (error != NULL) {
|
|
|
01018b |
+ g_debug ("GdmManager: Error while retrieving remoteness for session: %s",
|
|
|
01018b |
+ error->message);
|
|
|
01018b |
+ g_clear_error (&error);
|
|
|
01018b |
+ }
|
|
|
01018b |
+ }
|
|
|
01018b |
+
|
|
|
01018b |
display = gdm_display_store_find (self->priv->display_store,
|
|
|
01018b |
lookup_by_session_id,
|
|
|
01018b |
(gpointer) session_id);
|
|
|
01018b |
+ if (out_display != NULL)
|
|
|
01018b |
+ *out_display = display;
|
|
|
01018b |
+
|
|
|
01018b |
out:
|
|
|
01018b |
g_free (session_id);
|
|
|
01018b |
-
|
|
|
01018b |
- if (display != NULL) {
|
|
|
01018b |
- if (out_pid != NULL)
|
|
|
01018b |
- *out_pid = pid;
|
|
|
01018b |
-
|
|
|
01018b |
- if (out_uid != NULL)
|
|
|
01018b |
- *out_uid = session_uid;
|
|
|
01018b |
- }
|
|
|
01018b |
- return display;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
static gboolean
|
|
|
01018b |
gdm_manager_handle_open_session (GdmDBusManager *manager,
|
|
|
01018b |
GDBusMethodInvocation *invocation)
|
|
|
01018b |
{
|
|
|
01018b |
GdmManager *self = GDM_MANAGER (manager);
|
|
|
01018b |
const char *sender = NULL;
|
|
|
01018b |
GError *error = NULL;
|
|
|
01018b |
GDBusConnection *connection;
|
|
|
01018b |
- GdmDisplay *display;
|
|
|
01018b |
+ GdmDisplay *display = NULL;
|
|
|
01018b |
char *address;
|
|
|
01018b |
- GPid pid;
|
|
|
01018b |
- uid_t uid;
|
|
|
01018b |
+ GPid pid = 0;
|
|
|
01018b |
+ uid_t uid = (uid_t) -1;
|
|
|
01018b |
|
|
|
01018b |
g_debug ("GdmManager: trying to open new session");
|
|
|
01018b |
|
|
|
01018b |
sender = g_dbus_method_invocation_get_sender (invocation);
|
|
|
01018b |
connection = g_dbus_method_invocation_get_connection (invocation);
|
|
|
01018b |
- display = get_display_and_details_for_bus_sender (self, connection, sender, &pid, &uid, NULL);
|
|
|
01018b |
+ get_display_and_details_for_bus_sender (self, connection, sender, &display, NULL, NULL, &pid, &uid, NULL, NULL);
|
|
|
01018b |
|
|
|
01018b |
if (display == NULL) {
|
|
|
01018b |
g_dbus_method_invocation_return_error_literal (invocation,
|
|
|
01018b |
G_DBUS_ERROR,
|
|
|
01018b |
G_DBUS_ERROR_ACCESS_DENIED,
|
|
|
01018b |
_("No session available"));
|
|
|
01018b |
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
address = gdm_display_open_session_sync (display, pid, uid, NULL, &error);
|
|
|
01018b |
|
|
|
01018b |
if (address == NULL) {
|
|
|
01018b |
g_dbus_method_invocation_return_gerror (invocation, error);
|
|
|
01018b |
g_error_free (error);
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
gdm_dbus_manager_complete_open_session (GDM_DBUS_MANAGER (manager),
|
|
|
01018b |
invocation,
|
|
|
01018b |
address);
|
|
|
01018b |
g_free (address);
|
|
|
01018b |
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
static gboolean
|
|
|
01018b |
gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager,
|
|
|
01018b |
GDBusMethodInvocation *invocation,
|
|
|
01018b |
const char *username)
|
|
|
01018b |
{
|
|
|
01018b |
GdmManager *self = GDM_MANAGER (manager);
|
|
|
01018b |
const char *sender = NULL;
|
|
|
01018b |
GError *error = NULL;
|
|
|
01018b |
GDBusConnection *connection;
|
|
|
01018b |
- GdmDisplay *display;
|
|
|
01018b |
+ GdmDisplay *display = NULL;
|
|
|
01018b |
char *address;
|
|
|
01018b |
- GPid pid;
|
|
|
01018b |
- uid_t uid;
|
|
|
01018b |
+ GPid pid = 0;
|
|
|
01018b |
+ uid_t uid = (uid_t) -1;
|
|
|
01018b |
gboolean is_login_screen = FALSE;
|
|
|
01018b |
|
|
|
01018b |
g_debug ("GdmManager: trying to open reauthentication channel for user %s", username);
|
|
|
01018b |
|
|
|
01018b |
sender = g_dbus_method_invocation_get_sender (invocation);
|
|
|
01018b |
connection = g_dbus_method_invocation_get_connection (invocation);
|
|
|
01018b |
- display = get_display_and_details_for_bus_sender (self, connection, sender, &pid, &uid, &is_login_screen);
|
|
|
01018b |
+ get_display_and_details_for_bus_sender (self, connection, sender, &display, NULL, NULL, &pid, &uid, &is_login_screen, NULL);
|
|
|
01018b |
|
|
|
01018b |
if (is_login_screen) {
|
|
|
01018b |
g_dbus_method_invocation_return_error_literal (invocation,
|
|
|
01018b |
G_DBUS_ERROR,
|
|
|
01018b |
G_DBUS_ERROR_ACCESS_DENIED,
|
|
|
01018b |
_("Login screen not allow to open reauthentication channel"));
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
if (display == NULL) {
|
|
|
01018b |
g_dbus_method_invocation_return_error_literal (invocation,
|
|
|
01018b |
G_DBUS_ERROR,
|
|
|
01018b |
G_DBUS_ERROR_ACCESS_DENIED,
|
|
|
01018b |
_("No session available"));
|
|
|
01018b |
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
address = gdm_display_open_reauthentication_channel_sync (display,
|
|
|
01018b |
username,
|
|
|
01018b |
pid,
|
|
|
01018b |
uid,
|
|
|
01018b |
NULL,
|
|
|
01018b |
&error);
|
|
|
01018b |
|
|
|
01018b |
if (address == NULL) {
|
|
|
01018b |
g_dbus_method_invocation_return_gerror (invocation, error);
|
|
|
01018b |
g_error_free (error);
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
--
|
|
|
01018b |
1.8.4.2
|
|
|
01018b |
|
|
|
01018b |
|
|
|
01018b |
From 8fe36a032eb5ce681c91d5ccc8b0719f8e360b53 Mon Sep 17 00:00:00 2001
|
|
|
01018b |
From: Ray Strode <rstrode@redhat.com>
|
|
|
01018b |
Date: Tue, 11 Mar 2014 15:25:29 -0400
|
|
|
01018b |
Subject: [PATCH 4/4] manager: support just-in-time reauthentication for
|
|
|
01018b |
non-GDM sessions
|
|
|
01018b |
|
|
|
01018b |
Right now, gnome-shell can't unlock screens running on an X server that
|
|
|
01018b |
isn't managed by GDM (say Xvnc or startx). This is because GDM handles
|
|
|
01018b |
the backend processing for unlocking, and it handles that backend
|
|
|
01018b |
processing from the worker associated with the session. If there is no
|
|
|
01018b |
worker associated with the session (as is the case with Xvnc and startx),
|
|
|
01018b |
then there's no process to handle reauthentication.
|
|
|
01018b |
|
|
|
01018b |
This commit notices that case, and creates a transient worker on the fly
|
|
|
01018b |
just to perform one off authentication for unlock of non-GDM managed
|
|
|
01018b |
sessions.
|
|
|
01018b |
---
|
|
|
01018b |
daemon/Makefile.am | 13 +++
|
|
|
01018b |
daemon/gdm-manager.c | 268 +++++++++++++++++++++++++++++++++++++++++++++++++--
|
|
|
01018b |
2 files changed, 271 insertions(+), 10 deletions(-)
|
|
|
01018b |
|
|
|
01018b |
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
|
|
|
01018b |
index ead9096..750735a 100644
|
|
|
01018b |
--- a/daemon/Makefile.am
|
|
|
01018b |
+++ b/daemon/Makefile.am
|
|
|
01018b |
@@ -289,83 +289,96 @@ endif
|
|
|
01018b |
|
|
|
01018b |
gdm_session_worker_LDFLAGS = \
|
|
|
01018b |
$(XLIB_LIBS) \
|
|
|
01018b |
$(PAM_LIBS) \
|
|
|
01018b |
$(NULL)
|
|
|
01018b |
|
|
|
01018b |
gdm_session_worker_LDADD = \
|
|
|
01018b |
$(top_builddir)/common/libgdmcommon.la \
|
|
|
01018b |
$(DAEMON_LIBS) \
|
|
|
01018b |
$(SYSTEMD_LIBS) \
|
|
|
01018b |
$(JOURNALD_LIBS) \
|
|
|
01018b |
$(LIBSELINUX_LIBS) \
|
|
|
01018b |
$(NULL)
|
|
|
01018b |
|
|
|
01018b |
sbin_PROGRAMS = \
|
|
|
01018b |
gdm \
|
|
|
01018b |
$(NULL)
|
|
|
01018b |
|
|
|
01018b |
gdm_SOURCES = \
|
|
|
01018b |
main.c \
|
|
|
01018b |
gdm-display-access-file.c \
|
|
|
01018b |
gdm-display-access-file.h \
|
|
|
01018b |
gdm-display-store.c \
|
|
|
01018b |
gdm-display-store.h \
|
|
|
01018b |
gdm-display-factory.c \
|
|
|
01018b |
gdm-display-factory.h \
|
|
|
01018b |
gdm-local-display-factory.c \
|
|
|
01018b |
gdm-local-display-factory.h \
|
|
|
01018b |
gdm-display.c \
|
|
|
01018b |
gdm-display.h \
|
|
|
01018b |
+ gdm-session.c \
|
|
|
01018b |
+ gdm-session.h \
|
|
|
01018b |
+ gdm-session-record.c \
|
|
|
01018b |
+ gdm-session-record.h \
|
|
|
01018b |
+ gdm-session-worker-common.c \
|
|
|
01018b |
+ gdm-session-worker-common.h \
|
|
|
01018b |
+ gdm-session-worker-job.c \
|
|
|
01018b |
gdm-static-display.c \
|
|
|
01018b |
gdm-static-display.h \
|
|
|
01018b |
gdm-transient-display.c \
|
|
|
01018b |
gdm-transient-display.h \
|
|
|
01018b |
gdm-manager.c \
|
|
|
01018b |
gdm-manager.h \
|
|
|
01018b |
gdm-slave-proxy.c \
|
|
|
01018b |
gdm-slave-proxy.h \
|
|
|
01018b |
gdm-dbus-util.c \
|
|
|
01018b |
gdm-dbus-util.h \
|
|
|
01018b |
$(NULL)
|
|
|
01018b |
|
|
|
01018b |
nodist_gdm_SOURCES = \
|
|
|
01018b |
gdm-display-glue.h \
|
|
|
01018b |
gdm-display-glue.c \
|
|
|
01018b |
gdm-local-display-factory-glue.h \
|
|
|
01018b |
gdm-local-display-factory-glue.c \
|
|
|
01018b |
gdm-manager-glue.h \
|
|
|
01018b |
gdm-manager-glue.c \
|
|
|
01018b |
gdm-transient-display-glue.h \
|
|
|
01018b |
gdm-transient-display-glue.c \
|
|
|
01018b |
gdm-static-display-glue.h \
|
|
|
01018b |
gdm-static-display-glue.c \
|
|
|
01018b |
+ gdm-session-enum-types.c \
|
|
|
01018b |
+ gdm-session-enum-types.h \
|
|
|
01018b |
+ gdm-session-glue.c \
|
|
|
01018b |
+ gdm-session-glue.h \
|
|
|
01018b |
+ gdm-session-worker-glue.c \
|
|
|
01018b |
+ gdm-session-worker-glue.h \
|
|
|
01018b |
gdm-slave-glue.h \
|
|
|
01018b |
gdm-slave-glue.c \
|
|
|
01018b |
$(NULL)
|
|
|
01018b |
|
|
|
01018b |
XDMCP_SOURCES = \
|
|
|
01018b |
gdm-xdmcp-display-factory.c \
|
|
|
01018b |
gdm-xdmcp-display-factory.h \
|
|
|
01018b |
gdm-xdmcp-display.c \
|
|
|
01018b |
gdm-xdmcp-display.h \
|
|
|
01018b |
gdm-xdmcp-greeter-display.c \
|
|
|
01018b |
gdm-xdmcp-greeter-display.h \
|
|
|
01018b |
gdm-xdmcp-chooser-display.c \
|
|
|
01018b |
gdm-xdmcp-chooser-display.h \
|
|
|
01018b |
$(NULL)
|
|
|
01018b |
|
|
|
01018b |
XDMCP_nodist_SOURCES = \
|
|
|
01018b |
gdm-xdmcp-display-glue.c \
|
|
|
01018b |
gdm-xdmcp-display-glue.h \
|
|
|
01018b |
gdm-xdmcp-chooser-slave-glue.c \
|
|
|
01018b |
gdm-xdmcp-chooser-slave-glue.h \
|
|
|
01018b |
$(NULL)
|
|
|
01018b |
|
|
|
01018b |
if XDMCP_SUPPORT
|
|
|
01018b |
gdm_SOURCES += $(XDMCP_SOURCES)
|
|
|
01018b |
nodist_gdm_SOURCES += $(XDMCP_nodist_SOURCES)
|
|
|
01018b |
endif
|
|
|
01018b |
|
|
|
01018b |
EXTRA_gdm_SOURCES = \
|
|
|
01018b |
$(XDMCP_SOURCES) \
|
|
|
01018b |
$(NULL)
|
|
|
01018b |
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
|
|
01018b |
index 4c47045..7eb2172 100644
|
|
|
01018b |
--- a/daemon/gdm-manager.c
|
|
|
01018b |
+++ b/daemon/gdm-manager.c
|
|
|
01018b |
@@ -16,60 +16,61 @@
|
|
|
01018b |
* along with this program; if not, write to the Free Software
|
|
|
01018b |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
01018b |
*
|
|
|
01018b |
*/
|
|
|
01018b |
|
|
|
01018b |
#include "config.h"
|
|
|
01018b |
|
|
|
01018b |
#include <stdlib.h>
|
|
|
01018b |
#include <stdio.h>
|
|
|
01018b |
#include <fcntl.h>
|
|
|
01018b |
#include <unistd.h>
|
|
|
01018b |
#include <string.h>
|
|
|
01018b |
#include <signal.h>
|
|
|
01018b |
#include <sys/stat.h>
|
|
|
01018b |
#include <sys/types.h>
|
|
|
01018b |
|
|
|
01018b |
#include <glib.h>
|
|
|
01018b |
#include <glib/gi18n.h>
|
|
|
01018b |
#include <glib/gstdio.h>
|
|
|
01018b |
#include <glib-object.h>
|
|
|
01018b |
|
|
|
01018b |
#ifdef WITH_SYSTEMD
|
|
|
01018b |
#include <systemd/sd-login.h>
|
|
|
01018b |
#endif
|
|
|
01018b |
|
|
|
01018b |
#include "gdm-common.h"
|
|
|
01018b |
|
|
|
01018b |
#include "gdm-dbus-util.h"
|
|
|
01018b |
#include "gdm-manager.h"
|
|
|
01018b |
#include "gdm-manager-glue.h"
|
|
|
01018b |
+#include "gdm-session.h"
|
|
|
01018b |
#include "gdm-display-store.h"
|
|
|
01018b |
#include "gdm-display-factory.h"
|
|
|
01018b |
#include "gdm-local-display-factory.h"
|
|
|
01018b |
#include "gdm-xdmcp-display-factory.h"
|
|
|
01018b |
|
|
|
01018b |
#define GDM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_MANAGER, GdmManagerPrivate))
|
|
|
01018b |
|
|
|
01018b |
#define GDM_DBUS_PATH "/org/gnome/DisplayManager"
|
|
|
01018b |
#define GDM_MANAGER_PATH GDM_DBUS_PATH "/Manager"
|
|
|
01018b |
#define GDM_MANAGER_DISPLAYS_PATH GDM_DBUS_PATH "/Displays"
|
|
|
01018b |
|
|
|
01018b |
struct GdmManagerPrivate
|
|
|
01018b |
{
|
|
|
01018b |
GdmDisplayStore *display_store;
|
|
|
01018b |
GdmLocalDisplayFactory *local_factory;
|
|
|
01018b |
#ifdef HAVE_LIBXDMCP
|
|
|
01018b |
GdmXdmcpDisplayFactory *xdmcp_factory;
|
|
|
01018b |
#endif
|
|
|
01018b |
gboolean xdmcp_enabled;
|
|
|
01018b |
|
|
|
01018b |
gboolean started;
|
|
|
01018b |
gboolean wait_for_go;
|
|
|
01018b |
gboolean no_console;
|
|
|
01018b |
|
|
|
01018b |
GDBusProxy *bus_proxy;
|
|
|
01018b |
GDBusConnection *connection;
|
|
|
01018b |
GDBusObjectManagerServer *object_manager;
|
|
|
01018b |
};
|
|
|
01018b |
|
|
|
01018b |
enum {
|
|
|
01018b |
@@ -648,104 +649,351 @@ gdm_manager_handle_open_session (GdmDBusManager *manager,
|
|
|
01018b |
|
|
|
01018b |
sender = g_dbus_method_invocation_get_sender (invocation);
|
|
|
01018b |
connection = g_dbus_method_invocation_get_connection (invocation);
|
|
|
01018b |
get_display_and_details_for_bus_sender (self, connection, sender, &display, NULL, NULL, &pid, &uid, NULL, NULL);
|
|
|
01018b |
|
|
|
01018b |
if (display == NULL) {
|
|
|
01018b |
g_dbus_method_invocation_return_error_literal (invocation,
|
|
|
01018b |
G_DBUS_ERROR,
|
|
|
01018b |
G_DBUS_ERROR_ACCESS_DENIED,
|
|
|
01018b |
_("No session available"));
|
|
|
01018b |
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
address = gdm_display_open_session_sync (display, pid, uid, NULL, &error);
|
|
|
01018b |
|
|
|
01018b |
if (address == NULL) {
|
|
|
01018b |
g_dbus_method_invocation_return_gerror (invocation, error);
|
|
|
01018b |
g_error_free (error);
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
gdm_dbus_manager_complete_open_session (GDM_DBUS_MANAGER (manager),
|
|
|
01018b |
invocation,
|
|
|
01018b |
address);
|
|
|
01018b |
g_free (address);
|
|
|
01018b |
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
+#ifdef WITH_SYSTEMD
|
|
|
01018b |
+static gboolean
|
|
|
01018b |
+unlock_systemd_session (GdmManager *manager,
|
|
|
01018b |
+ const char *ssid)
|
|
|
01018b |
+{
|
|
|
01018b |
+ GError *error = NULL;
|
|
|
01018b |
+ GVariant *reply;
|
|
|
01018b |
+
|
|
|
01018b |
+ reply = g_dbus_connection_call_sync (manager->priv->connection,
|
|
|
01018b |
+ "org.freedesktop.login1",
|
|
|
01018b |
+ "/org/freedesktop/login1",
|
|
|
01018b |
+ "org.freedesktop.login1.Manager",
|
|
|
01018b |
+ "UnlockSession",
|
|
|
01018b |
+ g_variant_new ("(s)", ssid),
|
|
|
01018b |
+ NULL, /* expected reply */
|
|
|
01018b |
+ G_DBUS_CALL_FLAGS_NONE,
|
|
|
01018b |
+ -1,
|
|
|
01018b |
+ NULL,
|
|
|
01018b |
+ &error);
|
|
|
01018b |
+ if (reply == NULL) {
|
|
|
01018b |
+ g_debug ("GdmManager: logind 'UnlockSession' %s raised:\n %s\n\n",
|
|
|
01018b |
+ g_dbus_error_get_remote_error (error), error->message);
|
|
|
01018b |
+ g_error_free (error);
|
|
|
01018b |
+ return FALSE;
|
|
|
01018b |
+ }
|
|
|
01018b |
+
|
|
|
01018b |
+ g_variant_unref (reply);
|
|
|
01018b |
+
|
|
|
01018b |
+ return TRUE;
|
|
|
01018b |
+}
|
|
|
01018b |
+#endif
|
|
|
01018b |
+
|
|
|
01018b |
+#ifdef WITH_CONSOLE_KIT
|
|
|
01018b |
+static gboolean
|
|
|
01018b |
+unlock_consolekit_session (GdmManager *manager,
|
|
|
01018b |
+ const char *ssid)
|
|
|
01018b |
+{
|
|
|
01018b |
+ GError *error = NULL;
|
|
|
01018b |
+ GVariant *reply;
|
|
|
01018b |
+
|
|
|
01018b |
+ reply = g_dbus_connection_call_sync (manager->priv->connection,
|
|
|
01018b |
+ "org.freedesktop.ConsoleKit",
|
|
|
01018b |
+ ssid,
|
|
|
01018b |
+ "org.freedesktop.ConsoleKit.Manager",
|
|
|
01018b |
+ "Unlock",
|
|
|
01018b |
+ NULL, /* parameters */
|
|
|
01018b |
+ NULL, /* expected reply */
|
|
|
01018b |
+ G_DBUS_CALL_FLAGS_NONE,
|
|
|
01018b |
+ -1,
|
|
|
01018b |
+ NULL,
|
|
|
01018b |
+ &error);
|
|
|
01018b |
+ if (reply == NULL) {
|
|
|
01018b |
+ g_debug ("GdmSlave: ConsoleKit %s raised:\n %s\n\n",
|
|
|
01018b |
+ g_dbus_error_get_remote_error (error), error->message);
|
|
|
01018b |
+ g_error_free (error);
|
|
|
01018b |
+ return FALSE;
|
|
|
01018b |
+ }
|
|
|
01018b |
+
|
|
|
01018b |
+ g_variant_unref (reply);
|
|
|
01018b |
+
|
|
|
01018b |
+ return TRUE;
|
|
|
01018b |
+}
|
|
|
01018b |
+#endif
|
|
|
01018b |
+
|
|
|
01018b |
+static void
|
|
|
01018b |
+unlock_session (GdmManager *manager,
|
|
|
01018b |
+ const char *ssid)
|
|
|
01018b |
+{
|
|
|
01018b |
+
|
|
|
01018b |
+ g_debug ("GdmManager: Unlocking session %s", ssid);
|
|
|
01018b |
+
|
|
|
01018b |
+#ifdef WITH_SYSTEMD
|
|
|
01018b |
+ if (LOGIND_RUNNING()) {
|
|
|
01018b |
+ unlock_systemd_session (manager, ssid);
|
|
|
01018b |
+ return;
|
|
|
01018b |
+ }
|
|
|
01018b |
+#endif
|
|
|
01018b |
+
|
|
|
01018b |
+#ifdef WITH_CONSOLE_KIT
|
|
|
01018b |
+ unlock_consolekit_session (manager, ssid);
|
|
|
01018b |
+#endif
|
|
|
01018b |
+}
|
|
|
01018b |
+static void
|
|
|
01018b |
+on_reauthentication_client_connected (GdmSession *session,
|
|
|
01018b |
+ GCredentials *credentials,
|
|
|
01018b |
+ GPid pid_of_client,
|
|
|
01018b |
+ GdmManager *self)
|
|
|
01018b |
+{
|
|
|
01018b |
+ g_debug ("GdmManager: client connected to reauthentication server");
|
|
|
01018b |
+}
|
|
|
01018b |
+
|
|
|
01018b |
+static void
|
|
|
01018b |
+on_reauthentication_client_disconnected (GdmSession *session,
|
|
|
01018b |
+ GCredentials *credentials,
|
|
|
01018b |
+ GPid pid_of_client,
|
|
|
01018b |
+ GdmManager *self)
|
|
|
01018b |
+{
|
|
|
01018b |
+ g_debug ("GdmManger: client disconnected from reauthentication server");
|
|
|
01018b |
+ gdm_session_close (session);
|
|
|
01018b |
+ g_object_unref (session);
|
|
|
01018b |
+}
|
|
|
01018b |
+
|
|
|
01018b |
+static void
|
|
|
01018b |
+on_reauthentication_cancelled (GdmSession *session,
|
|
|
01018b |
+ GdmManager *self)
|
|
|
01018b |
+{
|
|
|
01018b |
+ g_debug ("GdmManager: client cancelled reauthentication request");
|
|
|
01018b |
+ gdm_session_close (session);
|
|
|
01018b |
+ g_object_unref (session);
|
|
|
01018b |
+}
|
|
|
01018b |
+
|
|
|
01018b |
+static void
|
|
|
01018b |
+on_reauthentication_conversation_started (GdmSession *session,
|
|
|
01018b |
+ const char *service_name,
|
|
|
01018b |
+ GdmManager *self)
|
|
|
01018b |
+{
|
|
|
01018b |
+ g_debug ("GdmManager: reauthentication service '%s' started",
|
|
|
01018b |
+ service_name);
|
|
|
01018b |
+}
|
|
|
01018b |
+
|
|
|
01018b |
+static void
|
|
|
01018b |
+on_reauthentication_conversation_stopped (GdmSession *session,
|
|
|
01018b |
+ const char *service_name,
|
|
|
01018b |
+ GdmManager *self)
|
|
|
01018b |
+{
|
|
|
01018b |
+ g_debug ("GdmManager: reauthentication service '%s' stopped",
|
|
|
01018b |
+ service_name);
|
|
|
01018b |
+}
|
|
|
01018b |
+
|
|
|
01018b |
+static void
|
|
|
01018b |
+on_reauthentication_verification_complete (GdmSession *session,
|
|
|
01018b |
+ const char *service_name,
|
|
|
01018b |
+ GdmManager *self)
|
|
|
01018b |
+{
|
|
|
01018b |
+ const char *session_id;
|
|
|
01018b |
+ session_id = g_object_get_data (G_OBJECT (session), "caller-session-id");
|
|
|
01018b |
+ g_debug ("GdmManager: reauthenticated user in unmanaged session '%s' with service '%s'",
|
|
|
01018b |
+ session_id, service_name);
|
|
|
01018b |
+ unlock_session (self, session_id);
|
|
|
01018b |
+ gdm_session_close (session);
|
|
|
01018b |
+ g_object_unref (session);
|
|
|
01018b |
+}
|
|
|
01018b |
+
|
|
|
01018b |
+static void
|
|
|
01018b |
+remove_session_weak_refs (GdmManager *self,
|
|
|
01018b |
+ GdmSession *session)
|
|
|
01018b |
+{
|
|
|
01018b |
+ g_object_weak_unref (G_OBJECT (self),
|
|
|
01018b |
+ (GWeakNotify)
|
|
|
01018b |
+ gdm_session_close,
|
|
|
01018b |
+ session);
|
|
|
01018b |
+ g_object_weak_unref (G_OBJECT (self),
|
|
|
01018b |
+ (GWeakNotify)
|
|
|
01018b |
+ g_object_unref,
|
|
|
01018b |
+ session);
|
|
|
01018b |
+}
|
|
|
01018b |
+
|
|
|
01018b |
+static char *
|
|
|
01018b |
+open_temporary_reauthentication_channel (GdmManager *self,
|
|
|
01018b |
+ char *seat_id,
|
|
|
01018b |
+ char *session_id,
|
|
|
01018b |
+ GPid pid,
|
|
|
01018b |
+ uid_t uid,
|
|
|
01018b |
+ gboolean is_remote)
|
|
|
01018b |
+{
|
|
|
01018b |
+ GdmSession *session;
|
|
|
01018b |
+ char **environment;
|
|
|
01018b |
+ const char *display, *auth_file;
|
|
|
01018b |
+ char *address;
|
|
|
01018b |
+
|
|
|
01018b |
+ /* Note we're just using a minimal environment here rather than the
|
|
|
01018b |
+ * session's environment because the caller is unprivileged and the
|
|
|
01018b |
+ * associated worker will be privileged */
|
|
|
01018b |
+ environment = g_get_environ ();
|
|
|
01018b |
+ display = "";
|
|
|
01018b |
+ auth_file = "/dev/null";
|
|
|
01018b |
+
|
|
|
01018b |
+ session = gdm_session_new (GDM_SESSION_VERIFICATION_MODE_REAUTHENTICATE,
|
|
|
01018b |
+ uid,
|
|
|
01018b |
+ display,
|
|
|
01018b |
+ NULL,
|
|
|
01018b |
+ NULL,
|
|
|
01018b |
+ seat_id,
|
|
|
01018b |
+ auth_file,
|
|
|
01018b |
+ is_remote == FALSE,
|
|
|
01018b |
+ (const char * const *)
|
|
|
01018b |
+ environment);
|
|
|
01018b |
+ g_strfreev (environment);
|
|
|
01018b |
+
|
|
|
01018b |
+ g_object_set_data_full (G_OBJECT (session),
|
|
|
01018b |
+ "caller-session-id",
|
|
|
01018b |
+ g_strdup (session_id),
|
|
|
01018b |
+ (GDestroyNotify)
|
|
|
01018b |
+ g_free);
|
|
|
01018b |
+ g_object_weak_ref (G_OBJECT (self),
|
|
|
01018b |
+ (GWeakNotify)
|
|
|
01018b |
+ gdm_session_close,
|
|
|
01018b |
+ session);
|
|
|
01018b |
+ g_object_weak_ref (G_OBJECT (self),
|
|
|
01018b |
+ (GWeakNotify)
|
|
|
01018b |
+ g_object_unref,
|
|
|
01018b |
+ session);
|
|
|
01018b |
+ g_object_weak_ref (G_OBJECT (session),
|
|
|
01018b |
+ (GWeakNotify)
|
|
|
01018b |
+ remove_session_weak_refs,
|
|
|
01018b |
+ self);
|
|
|
01018b |
+
|
|
|
01018b |
+ g_signal_connect (session,
|
|
|
01018b |
+ "client-connected",
|
|
|
01018b |
+ G_CALLBACK (on_reauthentication_client_connected),
|
|
|
01018b |
+ self);
|
|
|
01018b |
+ g_signal_connect (session,
|
|
|
01018b |
+ "client-disconnected",
|
|
|
01018b |
+ G_CALLBACK (on_reauthentication_client_disconnected),
|
|
|
01018b |
+ self);
|
|
|
01018b |
+ g_signal_connect (session,
|
|
|
01018b |
+ "cancelled",
|
|
|
01018b |
+ G_CALLBACK (on_reauthentication_cancelled),
|
|
|
01018b |
+ self);
|
|
|
01018b |
+ g_signal_connect (session,
|
|
|
01018b |
+ "conversation-started",
|
|
|
01018b |
+ G_CALLBACK (on_reauthentication_conversation_started),
|
|
|
01018b |
+ self);
|
|
|
01018b |
+ g_signal_connect (session,
|
|
|
01018b |
+ "conversation-stopped",
|
|
|
01018b |
+ G_CALLBACK (on_reauthentication_conversation_stopped),
|
|
|
01018b |
+ self);
|
|
|
01018b |
+ g_signal_connect (session,
|
|
|
01018b |
+ "verification-complete",
|
|
|
01018b |
+ G_CALLBACK (on_reauthentication_verification_complete),
|
|
|
01018b |
+ self);
|
|
|
01018b |
+
|
|
|
01018b |
+ address = gdm_session_get_server_address (session);
|
|
|
01018b |
+ return address;
|
|
|
01018b |
+}
|
|
|
01018b |
+
|
|
|
01018b |
static gboolean
|
|
|
01018b |
gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager,
|
|
|
01018b |
GDBusMethodInvocation *invocation,
|
|
|
01018b |
const char *username)
|
|
|
01018b |
{
|
|
|
01018b |
GdmManager *self = GDM_MANAGER (manager);
|
|
|
01018b |
const char *sender = NULL;
|
|
|
01018b |
GError *error = NULL;
|
|
|
01018b |
GDBusConnection *connection;
|
|
|
01018b |
GdmDisplay *display = NULL;
|
|
|
01018b |
char *address;
|
|
|
01018b |
+ char *seat_id = NULL;
|
|
|
01018b |
+ char *session_id = NULL;
|
|
|
01018b |
GPid pid = 0;
|
|
|
01018b |
uid_t uid = (uid_t) -1;
|
|
|
01018b |
gboolean is_login_screen = FALSE;
|
|
|
01018b |
+ gboolean is_remote = FALSE;
|
|
|
01018b |
|
|
|
01018b |
g_debug ("GdmManager: trying to open reauthentication channel for user %s", username);
|
|
|
01018b |
|
|
|
01018b |
sender = g_dbus_method_invocation_get_sender (invocation);
|
|
|
01018b |
connection = g_dbus_method_invocation_get_connection (invocation);
|
|
|
01018b |
- get_display_and_details_for_bus_sender (self, connection, sender, &display, NULL, NULL, &pid, &uid, &is_login_screen, NULL);
|
|
|
01018b |
+ get_display_and_details_for_bus_sender (self, connection, sender, &display, &seat_id, &session_id, &pid, &uid, &is_login_screen, &is_remote);
|
|
|
01018b |
|
|
|
01018b |
if (is_login_screen) {
|
|
|
01018b |
g_dbus_method_invocation_return_error_literal (invocation,
|
|
|
01018b |
G_DBUS_ERROR,
|
|
|
01018b |
G_DBUS_ERROR_ACCESS_DENIED,
|
|
|
01018b |
_("Login screen not allow to open reauthentication channel"));
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
- if (display == NULL) {
|
|
|
01018b |
+ if (session_id == NULL || pid == 0 || uid == (uid_t) -1) {
|
|
|
01018b |
g_dbus_method_invocation_return_error_literal (invocation,
|
|
|
01018b |
G_DBUS_ERROR,
|
|
|
01018b |
G_DBUS_ERROR_ACCESS_DENIED,
|
|
|
01018b |
- _("No session available"));
|
|
|
01018b |
-
|
|
|
01018b |
+ _("Could not retrieve details about caller"));
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
- address = gdm_display_open_reauthentication_channel_sync (display,
|
|
|
01018b |
- username,
|
|
|
01018b |
- pid,
|
|
|
01018b |
- uid,
|
|
|
01018b |
- NULL,
|
|
|
01018b |
- &error);
|
|
|
01018b |
+ if (display == NULL) {
|
|
|
01018b |
+ address = open_temporary_reauthentication_channel (self,
|
|
|
01018b |
+ seat_id,
|
|
|
01018b |
+ session_id,
|
|
|
01018b |
+ pid,
|
|
|
01018b |
+ uid,
|
|
|
01018b |
+ is_remote);
|
|
|
01018b |
+ } else {
|
|
|
01018b |
+ address = gdm_display_open_reauthentication_channel_sync (display,
|
|
|
01018b |
+ username,
|
|
|
01018b |
+ pid,
|
|
|
01018b |
+ uid,
|
|
|
01018b |
+ NULL,
|
|
|
01018b |
+ &error);
|
|
|
01018b |
+ }
|
|
|
01018b |
|
|
|
01018b |
if (address == NULL) {
|
|
|
01018b |
g_dbus_method_invocation_return_gerror (invocation, error);
|
|
|
01018b |
g_error_free (error);
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
gdm_dbus_manager_complete_open_reauthentication_channel (GDM_DBUS_MANAGER (manager),
|
|
|
01018b |
invocation,
|
|
|
01018b |
address);
|
|
|
01018b |
g_free (address);
|
|
|
01018b |
|
|
|
01018b |
return TRUE;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
static void
|
|
|
01018b |
manager_interface_init (GdmDBusManagerIface *interface)
|
|
|
01018b |
{
|
|
|
01018b |
interface->handle_open_session = gdm_manager_handle_open_session;
|
|
|
01018b |
interface->handle_open_reauthentication_channel = gdm_manager_handle_open_reauthentication_channel;
|
|
|
01018b |
}
|
|
|
01018b |
|
|
|
01018b |
static void
|
|
|
01018b |
on_display_removed (GdmDisplayStore *display_store,
|
|
|
01018b |
const char *id,
|
|
|
01018b |
GdmManager *manager)
|
|
|
01018b |
{
|
|
|
01018b |
GdmDisplay *display;
|
|
|
01018b |
|
|
|
01018b |
display = gdm_display_store_lookup (display_store, id);
|
|
|
01018b |
--
|
|
|
01018b |
1.8.4.2
|
|
|
01018b |
|
|
|
7ae91c |
From a63ed886a5b232cc44938badd37daf394215d3b9 Mon Sep 17 00:00:00 2001
|
|
|
7ae91c |
From: Ray Strode <rstrode@redhat.com>
|
|
|
7ae91c |
Date: Thu, 10 Apr 2014 08:56:10 -0400
|
|
|
7ae91c |
Subject: [PATCH 1/4] session: introduce new client-rejected signal
|
|
|
7ae91c |
|
|
|
7ae91c |
If a client gets rejected because it's not allowed to connect
|
|
|
7ae91c |
to a particular session, we really need to inform the owner
|
|
|
7ae91c |
of the session object so it can do any clean up it needs to do,
|
|
|
7ae91c |
if necessary.
|
|
|
7ae91c |
---
|
|
|
7ae91c |
daemon/gdm-session.c | 24 ++++++++++++++++++++++++
|
|
|
7ae91c |
daemon/gdm-session.h | 1 +
|
|
|
7ae91c |
2 files changed, 25 insertions(+)
|
|
|
7ae91c |
|
|
|
7ae91c |
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
|
|
7ae91c |
index e24ec7c..044a57c 100644
|
|
|
7ae91c |
--- a/daemon/gdm-session.c
|
|
|
7ae91c |
+++ b/daemon/gdm-session.c
|
|
|
7ae91c |
@@ -117,60 +117,61 @@ struct _GdmSessionPrivate
|
|
|
7ae91c |
|
|
|
7ae91c |
uid_t allowed_user;
|
|
|
7ae91c |
|
|
|
7ae91c |
char *fallback_session_name;
|
|
|
7ae91c |
|
|
|
7ae91c |
GDBusServer *worker_server;
|
|
|
7ae91c |
GDBusServer *outside_server;
|
|
|
7ae91c |
GHashTable *environment;
|
|
|
7ae91c |
};
|
|
|
7ae91c |
|
|
|
7ae91c |
enum {
|
|
|
7ae91c |
PROP_0,
|
|
|
7ae91c |
PROP_VERIFICATION_MODE,
|
|
|
7ae91c |
PROP_ALLOWED_USER,
|
|
|
7ae91c |
PROP_DISPLAY_NAME,
|
|
|
7ae91c |
PROP_DISPLAY_HOSTNAME,
|
|
|
7ae91c |
PROP_DISPLAY_IS_LOCAL,
|
|
|
7ae91c |
PROP_DISPLAY_DEVICE,
|
|
|
7ae91c |
PROP_DISPLAY_SEAT_ID,
|
|
|
7ae91c |
PROP_DISPLAY_X11_AUTHORITY_FILE,
|
|
|
7ae91c |
PROP_USER_X11_AUTHORITY_FILE,
|
|
|
7ae91c |
PROP_CONVERSATION_ENVIRONMENT,
|
|
|
7ae91c |
};
|
|
|
7ae91c |
|
|
|
7ae91c |
enum {
|
|
|
7ae91c |
CONVERSATION_STARTED = 0,
|
|
|
7ae91c |
CONVERSATION_STOPPED,
|
|
|
7ae91c |
SETUP_COMPLETE,
|
|
|
7ae91c |
CANCELLED,
|
|
|
7ae91c |
HOSTNAME_SELECTED,
|
|
|
7ae91c |
+ CLIENT_REJECTED,
|
|
|
7ae91c |
CLIENT_CONNECTED,
|
|
|
7ae91c |
CLIENT_DISCONNECTED,
|
|
|
7ae91c |
CLIENT_READY_FOR_SESSION_TO_START,
|
|
|
7ae91c |
DISCONNECTED,
|
|
|
7ae91c |
VERIFICATION_COMPLETE,
|
|
|
7ae91c |
SESSION_OPENED,
|
|
|
7ae91c |
SESSION_STARTED,
|
|
|
7ae91c |
SESSION_START_FAILED,
|
|
|
7ae91c |
SESSION_EXITED,
|
|
|
7ae91c |
SESSION_DIED,
|
|
|
7ae91c |
REAUTHENTICATION_STARTED,
|
|
|
7ae91c |
REAUTHENTICATED,
|
|
|
7ae91c |
LAST_SIGNAL
|
|
|
7ae91c |
};
|
|
|
7ae91c |
|
|
|
7ae91c |
static guint signals [LAST_SIGNAL] = { 0, };
|
|
|
7ae91c |
|
|
|
7ae91c |
G_DEFINE_TYPE (GdmSession,
|
|
|
7ae91c |
gdm_session,
|
|
|
7ae91c |
G_TYPE_OBJECT);
|
|
|
7ae91c |
|
|
|
7ae91c |
static GdmSessionConversation *
|
|
|
7ae91c |
find_conversation_by_name (GdmSession *self,
|
|
|
7ae91c |
const char *service_name)
|
|
|
7ae91c |
{
|
|
|
7ae91c |
GdmSessionConversation *conversation;
|
|
|
7ae91c |
|
|
|
7ae91c |
conversation = g_hash_table_lookup (self->priv->conversations, service_name);
|
|
|
7ae91c |
|
|
|
7ae91c |
if (conversation == NULL) {
|
|
|
7ae91c |
@@ -1561,68 +1562,78 @@ setup_worker_server (GdmSession *self)
|
|
|
7ae91c |
|
|
|
7ae91c |
server = gdm_dbus_setup_private_server (observer, &error);
|
|
|
7ae91c |
g_object_unref (observer);
|
|
|
7ae91c |
|
|
|
7ae91c |
if (server == NULL) {
|
|
|
7ae91c |
g_warning ("Cannot create worker D-Bus server for the session: %s",
|
|
|
7ae91c |
error->message);
|
|
|
7ae91c |
return;
|
|
|
7ae91c |
}
|
|
|
7ae91c |
|
|
|
7ae91c |
g_signal_connect_object (server,
|
|
|
7ae91c |
"new-connection",
|
|
|
7ae91c |
G_CALLBACK (handle_connection_from_worker),
|
|
|
7ae91c |
self,
|
|
|
7ae91c |
0);
|
|
|
7ae91c |
self->priv->worker_server = server;
|
|
|
7ae91c |
|
|
|
7ae91c |
g_dbus_server_start (server);
|
|
|
7ae91c |
|
|
|
7ae91c |
g_debug ("GdmSession: D-Bus server for workers listening on %s",
|
|
|
7ae91c |
g_dbus_server_get_client_address (self->priv->worker_server));
|
|
|
7ae91c |
}
|
|
|
7ae91c |
|
|
|
7ae91c |
static gboolean
|
|
|
7ae91c |
allow_user_function (GDBusAuthObserver *observer,
|
|
|
7ae91c |
GIOStream *stream,
|
|
|
7ae91c |
GCredentials *credentials,
|
|
|
7ae91c |
GdmSession *self)
|
|
|
7ae91c |
{
|
|
|
7ae91c |
uid_t client_uid;
|
|
|
7ae91c |
+ GPid pid_of_client;
|
|
|
7ae91c |
|
|
|
7ae91c |
client_uid = g_credentials_get_unix_user (credentials, NULL);
|
|
|
7ae91c |
if (client_uid == self->priv->allowed_user) {
|
|
|
7ae91c |
return TRUE;
|
|
|
7ae91c |
}
|
|
|
7ae91c |
|
|
|
7ae91c |
g_debug ("GdmSession: User not allowed");
|
|
|
7ae91c |
|
|
|
7ae91c |
+ pid_of_client = credentials_get_unix_pid (credentials);
|
|
|
7ae91c |
+ g_signal_emit (G_OBJECT (self),
|
|
|
7ae91c |
+ signals [CLIENT_REJECTED],
|
|
|
7ae91c |
+ 0,
|
|
|
7ae91c |
+ credentials,
|
|
|
7ae91c |
+ (guint)
|
|
|
7ae91c |
+ pid_of_client);
|
|
|
7ae91c |
+
|
|
|
7ae91c |
+
|
|
|
7ae91c |
return FALSE;
|
|
|
7ae91c |
}
|
|
|
7ae91c |
|
|
|
7ae91c |
static void
|
|
|
7ae91c |
setup_outside_server (GdmSession *self)
|
|
|
7ae91c |
{
|
|
|
7ae91c |
GDBusAuthObserver *observer;
|
|
|
7ae91c |
GDBusServer *server;
|
|
|
7ae91c |
GError *error = NULL;
|
|
|
7ae91c |
|
|
|
7ae91c |
g_debug ("GdmSession: Creating D-Bus server for greeters and such");
|
|
|
7ae91c |
|
|
|
7ae91c |
observer = g_dbus_auth_observer_new ();
|
|
|
7ae91c |
g_signal_connect_object (observer,
|
|
|
7ae91c |
"authorize-authenticated-peer",
|
|
|
7ae91c |
G_CALLBACK (allow_user_function),
|
|
|
7ae91c |
self,
|
|
|
7ae91c |
0);
|
|
|
7ae91c |
|
|
|
7ae91c |
server = gdm_dbus_setup_private_server (observer, &error);
|
|
|
7ae91c |
g_object_unref (observer);
|
|
|
7ae91c |
|
|
|
7ae91c |
if (server == NULL) {
|
|
|
7ae91c |
g_warning ("Cannot create greeter D-Bus server for the session: %s",
|
|
|
7ae91c |
error->message);
|
|
|
7ae91c |
return;
|
|
|
7ae91c |
}
|
|
|
7ae91c |
|
|
|
7ae91c |
g_signal_connect_object (server,
|
|
|
7ae91c |
"new-connection",
|
|
|
7ae91c |
@@ -3186,60 +3197,73 @@ gdm_session_class_init (GdmSessionClass *session_class)
|
|
|
7ae91c |
G_STRUCT_OFFSET (GdmSessionClass, reauthentication_started),
|
|
|
7ae91c |
NULL,
|
|
|
7ae91c |
NULL,
|
|
|
7ae91c |
NULL,
|
|
|
7ae91c |
G_TYPE_NONE,
|
|
|
7ae91c |
2,
|
|
|
7ae91c |
G_TYPE_INT,
|
|
|
7ae91c |
G_TYPE_STRING);
|
|
|
7ae91c |
signals [REAUTHENTICATED] =
|
|
|
7ae91c |
g_signal_new ("reauthenticated",
|
|
|
7ae91c |
GDM_TYPE_SESSION,
|
|
|
7ae91c |
G_SIGNAL_RUN_FIRST,
|
|
|
7ae91c |
G_STRUCT_OFFSET (GdmSessionClass, reauthenticated),
|
|
|
7ae91c |
NULL,
|
|
|
7ae91c |
NULL,
|
|
|
7ae91c |
NULL,
|
|
|
7ae91c |
G_TYPE_NONE,
|
|
|
7ae91c |
1,
|
|
|
7ae91c |
G_TYPE_STRING);
|
|
|
7ae91c |
signals [CANCELLED] =
|
|
|
7ae91c |
g_signal_new ("cancelled",
|
|
|
7ae91c |
GDM_TYPE_SESSION,
|
|
|
7ae91c |
G_SIGNAL_RUN_FIRST,
|
|
|
7ae91c |
G_STRUCT_OFFSET (GdmSessionClass, cancelled),
|
|
|
7ae91c |
NULL,
|
|
|
7ae91c |
NULL,
|
|
|
7ae91c |
g_cclosure_marshal_VOID__VOID,
|
|
|
7ae91c |
G_TYPE_NONE,
|
|
|
7ae91c |
0);
|
|
|
7ae91c |
|
|
|
7ae91c |
+ signals [CLIENT_REJECTED] =
|
|
|
7ae91c |
+ g_signal_new ("client-rejected",
|
|
|
7ae91c |
+ GDM_TYPE_SESSION,
|
|
|
7ae91c |
+ G_SIGNAL_RUN_FIRST,
|
|
|
7ae91c |
+ G_STRUCT_OFFSET (GdmSessionClass, client_rejected),
|
|
|
7ae91c |
+ NULL,
|
|
|
7ae91c |
+ NULL,
|
|
|
7ae91c |
+ NULL,
|
|
|
7ae91c |
+ G_TYPE_NONE,
|
|
|
7ae91c |
+ 2,
|
|
|
7ae91c |
+ G_TYPE_CREDENTIALS,
|
|
|
7ae91c |
+ G_TYPE_UINT);
|
|
|
7ae91c |
+
|
|
|
7ae91c |
signals [CLIENT_CONNECTED] =
|
|
|
7ae91c |
g_signal_new ("client-connected",
|
|
|
7ae91c |
GDM_TYPE_SESSION,
|
|
|
7ae91c |
G_SIGNAL_RUN_FIRST,
|
|
|
7ae91c |
G_STRUCT_OFFSET (GdmSessionClass, client_connected),
|
|
|
7ae91c |
NULL,
|
|
|
7ae91c |
NULL,
|
|
|
7ae91c |
NULL,
|
|
|
7ae91c |
G_TYPE_NONE,
|
|
|
7ae91c |
2,
|
|
|
7ae91c |
G_TYPE_CREDENTIALS,
|
|
|
7ae91c |
G_TYPE_UINT);
|
|
|
7ae91c |
|
|
|
7ae91c |
signals [CLIENT_DISCONNECTED] =
|
|
|
7ae91c |
g_signal_new ("client-disconnected",
|
|
|
7ae91c |
GDM_TYPE_SESSION,
|
|
|
7ae91c |
G_SIGNAL_RUN_FIRST,
|
|
|
7ae91c |
G_STRUCT_OFFSET (GdmSessionClass, client_disconnected),
|
|
|
7ae91c |
NULL,
|
|
|
7ae91c |
NULL,
|
|
|
7ae91c |
NULL,
|
|
|
7ae91c |
G_TYPE_NONE,
|
|
|
7ae91c |
2,
|
|
|
7ae91c |
G_TYPE_CREDENTIALS,
|
|
|
7ae91c |
G_TYPE_UINT);
|
|
|
7ae91c |
signals [CLIENT_READY_FOR_SESSION_TO_START] =
|
|
|
7ae91c |
g_signal_new ("client-ready-for-session-to-start",
|
|
|
7ae91c |
GDM_TYPE_SESSION,
|
|
|
7ae91c |
G_SIGNAL_RUN_FIRST,
|
|
|
7ae91c |
G_STRUCT_OFFSET (GdmSessionClass, client_ready_for_session_to_start),
|
|
|
7ae91c |
diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h
|
|
|
7ae91c |
index 2511eca..8b93e2c 100644
|
|
|
7ae91c |
--- a/daemon/gdm-session.h
|
|
|
7ae91c |
+++ b/daemon/gdm-session.h
|
|
|
7ae91c |
@@ -30,60 +30,61 @@ G_BEGIN_DECLS
|
|
|
7ae91c |
#define GDM_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDM_TYPE_SESSION, GdmSessionClass))
|
|
|
7ae91c |
#define GDM_IS_SESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDM_TYPE_SESSION))
|
|
|
7ae91c |
#define GDM_IS_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDM_TYPE_SESSION))
|
|
|
7ae91c |
#define GDM_SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GDM_TYPE_SESSION, GdmSessionClass))
|
|
|
7ae91c |
|
|
|
7ae91c |
typedef struct _GdmSessionPrivate GdmSessionPrivate;
|
|
|
7ae91c |
|
|
|
7ae91c |
typedef enum
|
|
|
7ae91c |
{
|
|
|
7ae91c |
GDM_SESSION_VERIFICATION_MODE_LOGIN,
|
|
|
7ae91c |
GDM_SESSION_VERIFICATION_MODE_CHOOSER,
|
|
|
7ae91c |
GDM_SESSION_VERIFICATION_MODE_REAUTHENTICATE
|
|
|
7ae91c |
} GdmSessionVerificationMode;
|
|
|
7ae91c |
|
|
|
7ae91c |
typedef struct
|
|
|
7ae91c |
{
|
|
|
7ae91c |
GObject parent;
|
|
|
7ae91c |
GdmSessionPrivate *priv;
|
|
|
7ae91c |
} GdmSession;
|
|
|
7ae91c |
|
|
|
7ae91c |
typedef struct
|
|
|
7ae91c |
{
|
|
|
7ae91c |
GObjectClass parent_class;
|
|
|
7ae91c |
|
|
|
7ae91c |
/* Signals */
|
|
|
7ae91c |
void (* client_ready_for_session_to_start) (GdmSession *session,
|
|
|
7ae91c |
const char *service_name,
|
|
|
7ae91c |
gboolean client_is_ready);
|
|
|
7ae91c |
|
|
|
7ae91c |
void (* cancelled) (GdmSession *session);
|
|
|
7ae91c |
+ void (* client_rejected) (GdmSession *session);
|
|
|
7ae91c |
void (* client_connected) (GdmSession *session);
|
|
|
7ae91c |
void (* client_disconnected) (GdmSession *session);
|
|
|
7ae91c |
void (* disconnected) (GdmSession *session);
|
|
|
7ae91c |
void (* verification_complete) (GdmSession *session,
|
|
|
7ae91c |
const char *service_name);
|
|
|
7ae91c |
void (* session_opened) (GdmSession *session,
|
|
|
7ae91c |
const char *service_name,
|
|
|
7ae91c |
const char *session_id);
|
|
|
7ae91c |
void (* session_started) (GdmSession *session,
|
|
|
7ae91c |
const char *service_name,
|
|
|
7ae91c |
const char *session_id,
|
|
|
7ae91c |
int pid);
|
|
|
7ae91c |
void (* session_start_failed) (GdmSession *session,
|
|
|
7ae91c |
const char *service_name,
|
|
|
7ae91c |
const char *message);
|
|
|
7ae91c |
void (* session_exited) (GdmSession *session,
|
|
|
7ae91c |
int exit_code);
|
|
|
7ae91c |
void (* session_died) (GdmSession *session,
|
|
|
7ae91c |
int signal_number);
|
|
|
7ae91c |
void (* reauthentication_started) (GdmSession *session,
|
|
|
7ae91c |
GPid pid_of_caller);
|
|
|
7ae91c |
void (* reauthenticated) (GdmSession *session,
|
|
|
7ae91c |
const char *service_name);
|
|
|
7ae91c |
void (* conversation_started) (GdmSession *session,
|
|
|
7ae91c |
const char *service_name);
|
|
|
7ae91c |
void (* conversation_stopped) (GdmSession *session,
|
|
|
7ae91c |
const char *service_name);
|
|
|
7ae91c |
void (* setup_complete) (GdmSession *session,
|
|
|
7ae91c |
const char *service_name);
|
|
|
7ae91c |
} GdmSessionClass;
|
|
|
7ae91c |
--
|
|
|
7ae91c |
1.9.0
|
|
|
7ae91c |
|
|
|
7ae91c |
|
|
|
7ae91c |
From d11dd2511e08ab73757b8e97572c912c1f2fff8d Mon Sep 17 00:00:00 2001
|
|
|
7ae91c |
From: Ray Strode <rstrode@redhat.com>
|
|
|
7ae91c |
Date: Thu, 10 Apr 2014 09:13:57 -0400
|
|
|
7ae91c |
Subject: [PATCH 2/4] manager: stuff pid associated with transient session on
|
|
|
7ae91c |
session object
|
|
|
7ae91c |
|
|
|
7ae91c |
In the event the session object is not associated with an audit session,
|
|
|
7ae91c |
we want some way to match the object back to a client. This commit
|
|
|
7ae91c |
stores the pid of the caller on the object.
|
|
|
7ae91c |
---
|
|
|
7ae91c |
daemon/gdm-manager.c | 3 +++
|
|
|
7ae91c |
1 file changed, 3 insertions(+)
|
|
|
7ae91c |
|
|
|
7ae91c |
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
|
|
7ae91c |
index e6fd0b4..4d60ac0 100644
|
|
|
7ae91c |
--- a/daemon/gdm-manager.c
|
|
|
7ae91c |
+++ b/daemon/gdm-manager.c
|
|
|
7ae91c |
@@ -843,60 +843,63 @@ open_temporary_reauthentication_channel (GdmManager *self,
|
|
|
7ae91c |
{
|
|
|
7ae91c |
GdmSession *session;
|
|
|
7ae91c |
char **environment;
|
|
|
7ae91c |
const char *display, *auth_file;
|
|
|
7ae91c |
char *address;
|
|
|
7ae91c |
|
|
|
7ae91c |
/* Note we're just using a minimal environment here rather than the
|
|
|
7ae91c |
* session's environment because the caller is unprivileged and the
|
|
|
7ae91c |
* associated worker will be privileged */
|
|
|
7ae91c |
environment = g_get_environ ();
|
|
|
7ae91c |
display = "";
|
|
|
7ae91c |
auth_file = "/dev/null";
|
|
|
7ae91c |
|
|
|
7ae91c |
session = gdm_session_new (GDM_SESSION_VERIFICATION_MODE_REAUTHENTICATE,
|
|
|
7ae91c |
uid,
|
|
|
7ae91c |
display,
|
|
|
7ae91c |
NULL,
|
|
|
7ae91c |
NULL,
|
|
|
7ae91c |
seat_id,
|
|
|
7ae91c |
auth_file,
|
|
|
7ae91c |
is_remote == FALSE,
|
|
|
7ae91c |
(const char * const *)
|
|
|
7ae91c |
environment);
|
|
|
7ae91c |
g_strfreev (environment);
|
|
|
7ae91c |
|
|
|
7ae91c |
g_object_set_data_full (G_OBJECT (session),
|
|
|
7ae91c |
"caller-session-id",
|
|
|
7ae91c |
g_strdup (session_id),
|
|
|
7ae91c |
(GDestroyNotify)
|
|
|
7ae91c |
g_free);
|
|
|
7ae91c |
+ g_object_set_data (G_OBJECT (session),
|
|
|
7ae91c |
+ "caller-pid",
|
|
|
7ae91c |
+ GINT_TO_POINTER ((gint) pid));
|
|
|
7ae91c |
g_object_weak_ref (G_OBJECT (self),
|
|
|
7ae91c |
(GWeakNotify)
|
|
|
7ae91c |
gdm_session_close,
|
|
|
7ae91c |
session);
|
|
|
7ae91c |
g_object_weak_ref (G_OBJECT (self),
|
|
|
7ae91c |
(GWeakNotify)
|
|
|
7ae91c |
g_object_unref,
|
|
|
7ae91c |
session);
|
|
|
7ae91c |
g_object_weak_ref (G_OBJECT (session),
|
|
|
7ae91c |
(GWeakNotify)
|
|
|
7ae91c |
remove_session_weak_refs,
|
|
|
7ae91c |
self);
|
|
|
7ae91c |
|
|
|
7ae91c |
g_signal_connect (session,
|
|
|
7ae91c |
"client-connected",
|
|
|
7ae91c |
G_CALLBACK (on_reauthentication_client_connected),
|
|
|
7ae91c |
self);
|
|
|
7ae91c |
g_signal_connect (session,
|
|
|
7ae91c |
"client-disconnected",
|
|
|
7ae91c |
G_CALLBACK (on_reauthentication_client_disconnected),
|
|
|
7ae91c |
self);
|
|
|
7ae91c |
g_signal_connect (session,
|
|
|
7ae91c |
"cancelled",
|
|
|
7ae91c |
G_CALLBACK (on_reauthentication_cancelled),
|
|
|
7ae91c |
self);
|
|
|
7ae91c |
g_signal_connect (session,
|
|
|
7ae91c |
"conversation-started",
|
|
|
7ae91c |
G_CALLBACK (on_reauthentication_conversation_started),
|
|
|
7ae91c |
self);
|
|
|
7ae91c |
g_signal_connect (session,
|
|
|
7ae91c |
--
|
|
|
7ae91c |
1.9.0
|
|
|
7ae91c |
|
|
|
7ae91c |
|
|
|
7ae91c |
From 24c3d14d5336aa59d15f1cfdb59643dd254a62bd Mon Sep 17 00:00:00 2001
|
|
|
7ae91c |
From: Ray Strode <rstrode@redhat.com>
|
|
|
7ae91c |
Date: Thu, 10 Apr 2014 09:22:07 -0400
|
|
|
7ae91c |
Subject: [PATCH 3/4] manager: don't leak session objects when client is
|
|
|
7ae91c |
rejected
|
|
|
7ae91c |
|
|
|
7ae91c |
if a client creates a transient reauthentication session and then we reject
|
|
|
7ae91c |
the client when it tries to connect to it, then we need to clean up
|
|
|
7ae91c |
the associated session object.
|
|
|
7ae91c |
|
|
|
7ae91c |
This commit does that.
|
|
|
7ae91c |
---
|
|
|
7ae91c |
daemon/gdm-manager.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
7ae91c |
1 file changed, 46 insertions(+)
|
|
|
7ae91c |
|
|
|
7ae91c |
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
|
|
7ae91c |
index 4d60ac0..084fbb4 100644
|
|
|
7ae91c |
--- a/daemon/gdm-manager.c
|
|
|
7ae91c |
+++ b/daemon/gdm-manager.c
|
|
|
7ae91c |
@@ -752,60 +752,102 @@ unlock_session (GdmManager *manager,
|
|
|
7ae91c |
unlock_systemd_session (manager, ssid);
|
|
|
7ae91c |
return;
|
|
|
7ae91c |
}
|
|
|
7ae91c |
#endif
|
|
|
7ae91c |
|
|
|
7ae91c |
#ifdef WITH_CONSOLE_KIT
|
|
|
7ae91c |
unlock_consolekit_session (manager, ssid);
|
|
|
7ae91c |
#endif
|
|
|
7ae91c |
}
|
|
|
7ae91c |
static void
|
|
|
7ae91c |
on_reauthentication_client_connected (GdmSession *session,
|
|
|
7ae91c |
GCredentials *credentials,
|
|
|
7ae91c |
GPid pid_of_client,
|
|
|
7ae91c |
GdmManager *self)
|
|
|
7ae91c |
{
|
|
|
7ae91c |
g_debug ("GdmManager: client connected to reauthentication server");
|
|
|
7ae91c |
}
|
|
|
7ae91c |
|
|
|
7ae91c |
static void
|
|
|
7ae91c |
on_reauthentication_client_disconnected (GdmSession *session,
|
|
|
7ae91c |
GCredentials *credentials,
|
|
|
7ae91c |
GPid pid_of_client,
|
|
|
7ae91c |
GdmManager *self)
|
|
|
7ae91c |
{
|
|
|
7ae91c |
g_debug ("GdmManger: client disconnected from reauthentication server");
|
|
|
7ae91c |
gdm_session_close (session);
|
|
|
7ae91c |
g_object_unref (session);
|
|
|
7ae91c |
}
|
|
|
7ae91c |
|
|
|
7ae91c |
static void
|
|
|
7ae91c |
+on_reauthentication_client_rejected (GdmSession *session,
|
|
|
7ae91c |
+ GCredentials *credentials,
|
|
|
7ae91c |
+ GPid pid_of_client,
|
|
|
7ae91c |
+ GdmManager *self)
|
|
|
7ae91c |
+{
|
|
|
7ae91c |
+ GPid pid;
|
|
|
7ae91c |
+
|
|
|
7ae91c |
+ g_debug ("GdmManger: client with pid %ld rejected from reauthentication server", (long) pid_of_client);
|
|
|
7ae91c |
+
|
|
|
7ae91c |
+ if (gdm_session_client_is_connected (session)) {
|
|
|
7ae91c |
+ /* we already have a client connected, ignore this rejected one */
|
|
|
7ae91c |
+ return;
|
|
|
7ae91c |
+ }
|
|
|
7ae91c |
+
|
|
|
7ae91c |
+ pid = (GPid) GPOINTER_TO_INT (g_object_get_data (G_OBJECT (session), "caller-pid"));
|
|
|
7ae91c |
+
|
|
|
7ae91c |
+ if (pid != pid_of_client) {
|
|
|
7ae91c |
+ const char *session_id;
|
|
|
7ae91c |
+ char *client_session_id;
|
|
|
7ae91c |
+
|
|
|
7ae91c |
+ /* rejected client isn't the process that started the
|
|
|
7ae91c |
+ * transient reauthentication session. If it's not even from the
|
|
|
7ae91c |
+ * same audit session, ignore it since it doesn't "own" the
|
|
|
7ae91c |
+ * reauthentication session
|
|
|
7ae91c |
+ */
|
|
|
7ae91c |
+ client_session_id = get_session_id_for_pid (self->priv->connection,
|
|
|
7ae91c |
+ pid_of_client,
|
|
|
7ae91c |
+ NULL);
|
|
|
7ae91c |
+ session_id = g_object_get_data (G_OBJECT (session), "caller-session-id");
|
|
|
7ae91c |
+
|
|
|
7ae91c |
+ if (g_strcmp0 (session_id, client_session_id) != 0) {
|
|
|
7ae91c |
+ return;
|
|
|
7ae91c |
+ }
|
|
|
7ae91c |
+ }
|
|
|
7ae91c |
+
|
|
|
7ae91c |
+ /* client was rejected, so clean up its session object
|
|
|
7ae91c |
+ */
|
|
|
7ae91c |
+ gdm_session_close (session);
|
|
|
7ae91c |
+ g_object_unref (session);
|
|
|
7ae91c |
+}
|
|
|
7ae91c |
+
|
|
|
7ae91c |
+static void
|
|
|
7ae91c |
on_reauthentication_cancelled (GdmSession *session,
|
|
|
7ae91c |
GdmManager *self)
|
|
|
7ae91c |
{
|
|
|
7ae91c |
g_debug ("GdmManager: client cancelled reauthentication request");
|
|
|
7ae91c |
gdm_session_close (session);
|
|
|
7ae91c |
g_object_unref (session);
|
|
|
7ae91c |
}
|
|
|
7ae91c |
|
|
|
7ae91c |
static void
|
|
|
7ae91c |
on_reauthentication_conversation_started (GdmSession *session,
|
|
|
7ae91c |
const char *service_name,
|
|
|
7ae91c |
GdmManager *self)
|
|
|
7ae91c |
{
|
|
|
7ae91c |
g_debug ("GdmManager: reauthentication service '%s' started",
|
|
|
7ae91c |
service_name);
|
|
|
7ae91c |
}
|
|
|
7ae91c |
|
|
|
7ae91c |
static void
|
|
|
7ae91c |
on_reauthentication_conversation_stopped (GdmSession *session,
|
|
|
7ae91c |
const char *service_name,
|
|
|
7ae91c |
GdmManager *self)
|
|
|
7ae91c |
{
|
|
|
7ae91c |
g_debug ("GdmManager: reauthentication service '%s' stopped",
|
|
|
7ae91c |
service_name);
|
|
|
7ae91c |
}
|
|
|
7ae91c |
|
|
|
7ae91c |
static void
|
|
|
7ae91c |
on_reauthentication_verification_complete (GdmSession *session,
|
|
|
7ae91c |
const char *service_name,
|
|
|
7ae91c |
GdmManager *self)
|
|
|
7ae91c |
@@ -868,60 +910,64 @@ open_temporary_reauthentication_channel (GdmManager *self,
|
|
|
7ae91c |
g_object_set_data_full (G_OBJECT (session),
|
|
|
7ae91c |
"caller-session-id",
|
|
|
7ae91c |
g_strdup (session_id),
|
|
|
7ae91c |
(GDestroyNotify)
|
|
|
7ae91c |
g_free);
|
|
|
7ae91c |
g_object_set_data (G_OBJECT (session),
|
|
|
7ae91c |
"caller-pid",
|
|
|
7ae91c |
GINT_TO_POINTER ((gint) pid));
|
|
|
7ae91c |
g_object_weak_ref (G_OBJECT (self),
|
|
|
7ae91c |
(GWeakNotify)
|
|
|
7ae91c |
gdm_session_close,
|
|
|
7ae91c |
session);
|
|
|
7ae91c |
g_object_weak_ref (G_OBJECT (self),
|
|
|
7ae91c |
(GWeakNotify)
|
|
|
7ae91c |
g_object_unref,
|
|
|
7ae91c |
session);
|
|
|
7ae91c |
g_object_weak_ref (G_OBJECT (session),
|
|
|
7ae91c |
(GWeakNotify)
|
|
|
7ae91c |
remove_session_weak_refs,
|
|
|
7ae91c |
self);
|
|
|
7ae91c |
|
|
|
7ae91c |
g_signal_connect (session,
|
|
|
7ae91c |
"client-connected",
|
|
|
7ae91c |
G_CALLBACK (on_reauthentication_client_connected),
|
|
|
7ae91c |
self);
|
|
|
7ae91c |
g_signal_connect (session,
|
|
|
7ae91c |
"client-disconnected",
|
|
|
7ae91c |
G_CALLBACK (on_reauthentication_client_disconnected),
|
|
|
7ae91c |
self);
|
|
|
7ae91c |
g_signal_connect (session,
|
|
|
7ae91c |
+ "client-rejected",
|
|
|
7ae91c |
+ G_CALLBACK (on_reauthentication_client_rejected),
|
|
|
7ae91c |
+ self);
|
|
|
7ae91c |
+ g_signal_connect (session,
|
|
|
7ae91c |
"cancelled",
|
|
|
7ae91c |
G_CALLBACK (on_reauthentication_cancelled),
|
|
|
7ae91c |
self);
|
|
|
7ae91c |
g_signal_connect (session,
|
|
|
7ae91c |
"conversation-started",
|
|
|
7ae91c |
G_CALLBACK (on_reauthentication_conversation_started),
|
|
|
7ae91c |
self);
|
|
|
7ae91c |
g_signal_connect (session,
|
|
|
7ae91c |
"conversation-stopped",
|
|
|
7ae91c |
G_CALLBACK (on_reauthentication_conversation_stopped),
|
|
|
7ae91c |
self);
|
|
|
7ae91c |
g_signal_connect (session,
|
|
|
7ae91c |
"verification-complete",
|
|
|
7ae91c |
G_CALLBACK (on_reauthentication_verification_complete),
|
|
|
7ae91c |
self);
|
|
|
7ae91c |
|
|
|
7ae91c |
address = gdm_session_get_server_address (session);
|
|
|
7ae91c |
return address;
|
|
|
7ae91c |
}
|
|
|
7ae91c |
|
|
|
7ae91c |
static gboolean
|
|
|
7ae91c |
gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager,
|
|
|
7ae91c |
GDBusMethodInvocation *invocation,
|
|
|
7ae91c |
const char *username)
|
|
|
7ae91c |
{
|
|
|
7ae91c |
GdmManager *self = GDM_MANAGER (manager);
|
|
|
7ae91c |
const char *sender = NULL;
|
|
|
7ae91c |
GError *error = NULL;
|
|
|
7ae91c |
GDBusConnection *connection;
|
|
|
7ae91c |
GdmDisplay *display = NULL;
|
|
|
7ae91c |
--
|
|
|
7ae91c |
1.9.0
|
|
|
7ae91c |
|
|
|
7ae91c |
|
|
|
7ae91c |
From 9d67a7fd3acdc4b063020dfca53f676c2f1449d1 Mon Sep 17 00:00:00 2001
|
|
|
7ae91c |
From: Ray Strode <rstrode@redhat.com>
|
|
|
7ae91c |
Date: Thu, 10 Apr 2014 09:27:59 -0400
|
|
|
7ae91c |
Subject: [PATCH 4/4] manager: be more accepting of callers with uids different
|
|
|
7ae91c |
from their session
|
|
|
7ae91c |
|
|
|
7ae91c |
If a user runs su in their session, that switched user will now be
|
|
|
7ae91c |
running in a session that doesn't belong to it. GDM won't allow a user
|
|
|
7ae91c |
access to the worker process associated with the session in this case.
|
|
|
7ae91c |
Instead, it will try to create a temporary just-in-time reauthentication
|
|
|
7ae91c |
channel so reauthentication can happen without having the user talking to
|
|
|
7ae91c |
another user's worker. Unfortunately, a logic error in the code means,
|
|
|
7ae91c |
the user won't access to its own just-in-time channel.
|
|
|
7ae91c |
|
|
|
7ae91c |
This commit fixes that.
|
|
|
7ae91c |
---
|
|
|
7ae91c |
daemon/gdm-manager.c | 2 +-
|
|
|
7ae91c |
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
7ae91c |
|
|
|
7ae91c |
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
|
|
7ae91c |
index 084fbb4..5809792 100644
|
|
|
7ae91c |
--- a/daemon/gdm-manager.c
|
|
|
7ae91c |
+++ b/daemon/gdm-manager.c
|
|
|
7ae91c |
@@ -568,61 +568,61 @@ get_display_and_details_for_bus_sender (GdmManager *self,
|
|
|
7ae91c |
if (session_id == NULL) {
|
|
|
7ae91c |
g_debug ("GdmManager: Error while retrieving session id for sender: %s",
|
|
|
7ae91c |
error->message);
|
|
|
7ae91c |
g_error_free (error);
|
|
|
7ae91c |
goto out;
|
|
|
7ae91c |
}
|
|
|
7ae91c |
|
|
|
7ae91c |
if (out_session_id != NULL) {
|
|
|
7ae91c |
*out_session_id = g_strdup (session_id);
|
|
|
7ae91c |
}
|
|
|
7ae91c |
|
|
|
7ae91c |
if (out_is_login_screen != NULL) {
|
|
|
7ae91c |
*out_is_login_screen = is_login_session (self, connection, session_id, &error);
|
|
|
7ae91c |
|
|
|
7ae91c |
if (error != NULL) {
|
|
|
7ae91c |
g_debug ("GdmManager: Error while checking if sender is login screen: %s",
|
|
|
7ae91c |
error->message);
|
|
|
7ae91c |
g_error_free (error);
|
|
|
7ae91c |
goto out;
|
|
|
7ae91c |
}
|
|
|
7ae91c |
}
|
|
|
7ae91c |
|
|
|
7ae91c |
if (!get_uid_for_session_id (connection, session_id, &session_uid, &error)) {
|
|
|
7ae91c |
g_debug ("GdmManager: Error while retrieving uid for session: %s",
|
|
|
7ae91c |
error->message);
|
|
|
7ae91c |
g_error_free (error);
|
|
|
7ae91c |
goto out;
|
|
|
7ae91c |
}
|
|
|
7ae91c |
|
|
|
7ae91c |
if (out_uid != NULL)
|
|
|
7ae91c |
- *out_uid = session_uid;
|
|
|
7ae91c |
+ *out_uid = caller_uid;
|
|
|
7ae91c |
|
|
|
7ae91c |
if (caller_uid != session_uid) {
|
|
|
7ae91c |
g_debug ("GdmManager: uid for sender and uid for session don't match");
|
|
|
7ae91c |
goto out;
|
|
|
7ae91c |
}
|
|
|
7ae91c |
|
|
|
7ae91c |
if (out_seat_id != NULL) {
|
|
|
7ae91c |
*out_seat_id = get_seat_id_for_session_id (connection, session_id, &error);
|
|
|
7ae91c |
|
|
|
7ae91c |
if (error != NULL) {
|
|
|
7ae91c |
g_debug ("GdmManager: Error while retrieving seat id for session: %s",
|
|
|
7ae91c |
error->message);
|
|
|
7ae91c |
g_clear_error (&error);
|
|
|
7ae91c |
}
|
|
|
7ae91c |
}
|
|
|
7ae91c |
|
|
|
7ae91c |
if (out_is_remote != NULL) {
|
|
|
7ae91c |
*out_is_remote = is_remote_session (self, connection, session_id, &error);
|
|
|
7ae91c |
|
|
|
7ae91c |
if (error != NULL) {
|
|
|
7ae91c |
g_debug ("GdmManager: Error while retrieving remoteness for session: %s",
|
|
|
7ae91c |
error->message);
|
|
|
7ae91c |
g_clear_error (&error);
|
|
|
7ae91c |
}
|
|
|
7ae91c |
}
|
|
|
7ae91c |
|
|
|
7ae91c |
display = gdm_display_store_find (self->priv->display_store,
|
|
|
7ae91c |
lookup_by_session_id,
|
|
|
7ae91c |
(gpointer) session_id);
|
|
|
7ae91c |
if (out_display != NULL)
|
|
|
7ae91c |
--
|
|
|
7ae91c |
1.9.0
|
|
|
7ae91c |
|