aboutsummaryrefslogtreecommitdiff
path: root/src/users-service-dbus.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/users-service-dbus.c')
-rw-r--r--src/users-service-dbus.c211
1 files changed, 125 insertions, 86 deletions
diff --git a/src/users-service-dbus.c b/src/users-service-dbus.c
index 4aefdff..86007c3 100644
--- a/src/users-service-dbus.c
+++ b/src/users-service-dbus.c
@@ -31,10 +31,16 @@
#include <dbus/dbus-glib-lowlevel.h>
#include "dbus-shared-names.h"
+#include "gdm-local-display-factory-client.h"
#include "users-service-dbus.h"
#include "users-service-client.h"
#include "users-service-marshal.h"
#include "consolekit-manager-client.h"
+#include "consolekit-session-client.h"
+
+#define CK_ADDR "org.freedesktop.ConsoleKit"
+#define CK_SESSION_IFACE "org.freedesktop.ConsoleKit.Session"
+
static void users_service_dbus_class_init (UsersServiceDbusClass *klass);
static void users_service_dbus_init (UsersServiceDbus *self);
@@ -65,7 +71,7 @@ static void seat_proxy_session_removed (DBusGProxy *seat_
static gboolean do_add_session (UsersServiceDbus *service,
UserData *user,
const gchar *ssid);
-static gchar * get_seat_internal (UsersServiceDbus *self);
+static gchar * get_seat_internal (DBusGProxy *proxy);
/* Private */
typedef struct _UsersServiceDbusPrivate UsersServiceDbusPrivate;
@@ -80,12 +86,16 @@ struct _UsersServiceDbusPrivate
DBusGConnection *system_bus;
DBusGProxy *gdm_proxy;
+ DBusGProxy *gdm_local_proxy;
DBusGProxy *ck_proxy;
DBusGProxy *seat_proxy;
DBusGProxy *session_proxy;
GHashTable *exclusions;
GHashTable *sessions;
+
+ DbusmenuMenuitem * guest_item;
+ gchar * guest_session_id;
};
#define USERS_SERVICE_DBUS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), USERS_SERVICE_DBUS_TYPE, UsersServiceDbusPrivate))
@@ -155,6 +165,8 @@ users_service_dbus_init (UsersServiceDbus *self)
priv->users = NULL;
priv->count = 0;
+ priv->guest_item = NULL;
+ priv->guest_session_id = NULL;
/* Get the system bus */
priv->system_bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
@@ -198,6 +210,13 @@ users_service_dbus_dispose (GObject *object)
static void
users_service_dbus_finalize (GObject *object)
{
+ UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (object);
+
+ if (priv->guest_session_id != NULL) {
+ g_free(priv->guest_session_id);
+ priv->guest_session_id = NULL;
+ }
+
G_OBJECT_CLASS (users_service_dbus_parent_class)->finalize (object);
}
@@ -266,6 +285,11 @@ create_gdm_proxy (UsersServiceDbus *self)
G_CALLBACK (user_updated),
self,
NULL);
+
+ priv->gdm_local_proxy = dbus_g_proxy_new_for_name (priv->system_bus,
+ "org.gnome.DisplayManager",
+ "/org/gnome/DisplayManager/LocalDisplayFactory",
+ "org.gnome.DisplayManager.LocalDisplayFactory");
}
static void
@@ -341,9 +365,9 @@ create_cksession_proxy (UsersServiceDbus *service)
UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service);
priv->session_proxy = dbus_g_proxy_new_for_name (priv->system_bus,
- "org.freedesktop.ConsoleKit",
+ CK_ADDR,
priv->ssid,
- "org.freedesktop.ConsoleKit.Session");
+ CK_SESSION_IFACE);
if (!priv->session_proxy)
{
@@ -383,24 +407,18 @@ get_seat (UsersServiceDbus *service)
priv->ssid = ssid;
create_cksession_proxy (service);
- seat = get_seat_internal (service);
+ seat = get_seat_internal (priv->session_proxy);
return seat;
}
static gchar *
-get_seat_internal (UsersServiceDbus *self)
+get_seat_internal (DBusGProxy *proxy)
{
- UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self);
GError *error = NULL;
gchar *seat = NULL;
- if (!dbus_g_proxy_call (priv->session_proxy,
- "GetSeatId",
- &error,
- G_TYPE_INVALID,
- DBUS_TYPE_G_OBJECT_PATH, &seat,
- G_TYPE_INVALID))
+ if (!org_freedesktop_ConsoleKit_Session_get_seat_id (proxy, &seat, &error))
{
if (error)
{
@@ -421,13 +439,22 @@ get_unix_user (UsersServiceDbus *service,
UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service);
GError *error = NULL;
guint uid;
+ DBusGProxy *session_proxy;
+
+ g_debug("Building session proxy for: %s", session_id);
+ session_proxy = dbus_g_proxy_new_for_name_owner(priv->system_bus,
+ CK_ADDR,
+ session_id,
+ CK_SESSION_IFACE,
+ &error);
+
+ if (error != NULL) {
+ g_warning("Unable to get CK Session proxy: %s", error->message);
+ g_error_free(error);
+ return FALSE;
+ }
- if (dbus_g_proxy_call (priv->session_proxy,
- "GetUnixUser",
- &error,
- G_TYPE_INVALID,
- G_TYPE_UINT, &uid,
- G_TYPE_INVALID))
+ if (!org_freedesktop_ConsoleKit_Session_get_unix_user(session_proxy, &uid, &error))
{
if (error)
{
@@ -435,6 +462,7 @@ get_unix_user (UsersServiceDbus *service,
g_error_free (error);
}
+ g_object_unref(session_proxy);
return FALSE;
}
@@ -443,6 +471,7 @@ get_unix_user (UsersServiceDbus *service,
*uidp = (uid_t)uid;
}
+ g_object_unref(session_proxy);
return TRUE;
}
@@ -455,19 +484,29 @@ do_add_session (UsersServiceDbus *service,
GError *error = NULL;
gchar *seat = NULL;
gchar *xdisplay = NULL;
+ DBusGProxy * session_proxy;
GList *l;
- seat = get_seat_internal (service);
+ session_proxy = dbus_g_proxy_new_for_name_owner(priv->system_bus,
+ CK_ADDR,
+ ssid,
+ CK_SESSION_IFACE,
+ &error);
- if (!seat || !priv->seat || strcmp (seat, priv->seat) != 0)
+ if (error != NULL) {
+ g_warning("Unable to get CK Session proxy: %s", error->message);
+ g_error_free(error);
return FALSE;
+ }
- if (!dbus_g_proxy_call (priv->session_proxy,
- "GetX11Display",
- &error,
- G_TYPE_INVALID,
- G_TYPE_STRING, &xdisplay,
- G_TYPE_INVALID))
+ seat = get_seat_internal (session_proxy);
+
+ if (!seat || !priv->seat || strcmp (seat, priv->seat) != 0) {
+ g_object_unref(session_proxy);
+ return FALSE;
+ }
+
+ if (!org_freedesktop_ConsoleKit_Session_get_x11_display (session_proxy, &xdisplay, &error))
{
if (error)
{
@@ -475,9 +514,12 @@ do_add_session (UsersServiceDbus *service,
g_error_free (error);
}
+ g_object_unref(session_proxy);
return FALSE;
}
+ g_object_unref(session_proxy);
+
if (!xdisplay || xdisplay[0] == '\0')
return FALSE;
@@ -491,6 +533,10 @@ do_add_session (UsersServiceDbus *service,
g_debug ("Adding session %s", ssid);
user->sessions = g_list_prepend (user->sessions, g_strdup (ssid));
+
+ if (user->menuitem != NULL) {
+ dbusmenu_menuitem_property_set_bool(user->menuitem, USER_ITEM_PROP_LOGGED_IN, TRUE);
+ }
}
else
{
@@ -556,6 +602,17 @@ seat_proxy_session_added (DBusGProxy *seat_proxy,
return;
}
+ /* We need to special case guest here because it doesn't
+ show up in the GDM user tables. */
+ if (g_strcmp0("guest", pwent->pw_name) == 0) {
+ if (priv->guest_item != NULL) {
+ dbusmenu_menuitem_property_set_bool(priv->guest_item, USER_ITEM_PROP_LOGGED_IN, TRUE);
+ }
+ priv->guest_session_id = g_strdup(session_id);
+ g_debug("Found guest session: %s", priv->guest_session_id);
+ return;
+ }
+
user = g_hash_table_lookup (priv->users, pwent->pw_name);
if (!user)
{
@@ -576,8 +633,17 @@ seat_proxy_session_removed (DBusGProxy *seat_proxy,
GList *l;
username = g_hash_table_lookup (priv->sessions, session_id);
- if (!username)
+ if (!username) {
+ if (g_strcmp0(session_id, priv->guest_session_id) == 0) {
+ g_debug("Removing guest session: %s", priv->guest_session_id);
+ if (priv->guest_item != NULL) {
+ dbusmenu_menuitem_property_set_bool(priv->guest_item, USER_ITEM_PROP_LOGGED_IN, FALSE);
+ }
+ g_free(priv->guest_session_id);
+ priv->guest_session_id = NULL;
+ }
return;
+ }
user = g_hash_table_lookup (priv->users, username);
if (!user)
@@ -592,6 +658,9 @@ seat_proxy_session_removed (DBusGProxy *seat_proxy,
g_free (l->data);
user->sessions = g_list_delete_link (user->sessions, l);
+ if (user->menuitem != NULL && user->sessions == NULL) {
+ dbusmenu_menuitem_property_set_bool(user->menuitem, USER_ITEM_PROP_LOGGED_IN, FALSE);
+ }
}
else
{
@@ -657,6 +726,7 @@ sync_users (UsersServiceDbus *self)
user->login_count = g_value_get_int (g_value_array_get_nth (values, 4));
user->icon_url = g_strdup (g_value_get_string (g_value_array_get_nth (values, 5)));
user->real_name_conflict = FALSE;
+ user->menuitem = NULL;
g_hash_table_insert (priv->users,
g_strdup (user->user_name),
@@ -706,21 +776,16 @@ session_is_login_window (UsersServiceDbus *self,
char *type = NULL;
if (!(proxy = dbus_g_proxy_new_for_name (priv->system_bus,
- "org.freedesktop.ConsoleKit",
+ CK_ADDR,
ssid,
- "org.freedesktop.ConsoleKit.Session")))
+ CK_SESSION_IFACE)))
{
g_warning ("Failed to get ConsoleKit proxy");
return FALSE;
}
- if (!dbus_g_proxy_call (proxy,
- "GetSessionType",
- &error,
- G_TYPE_INVALID,
- G_TYPE_STRING, &type,
- G_TYPE_INVALID))
+ if (!org_freedesktop_ConsoleKit_Session_get_session_type (proxy, &type, &error))
{
g_warning ("Can't call GetSessionType: %s", error->message);
g_error_free (error);
@@ -1005,61 +1070,21 @@ users_service_dbus_get_user_list (UsersServiceDbus *self)
return g_hash_table_get_values (priv->users);
}
+/* Activates the guest account if it can. */
+gboolean
+users_service_dbus_activate_guest_session (UsersServiceDbus *self)
+{
+ UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self);
+ return org_gnome_DisplayManager_LocalDisplayFactory_switch_to_user(priv->gdm_local_proxy, "guest", NULL, NULL);
+}
+
+/* Activates a specific user */
gboolean
users_service_dbus_activate_user_session (UsersServiceDbus *self,
UserData *user)
{
- UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self);
- DBusMessage *message = NULL;
- DBusMessage *reply = NULL;
- DBusError error;
-
- dbus_error_init (&error);
-
- if (!(message = dbus_message_new_method_call ("org.gnome.DisplayManager",
- "/org/gnome/DisplayManager/LocalDisplayFactory",
- "org.gnome.DisplayManager.LocalDisplayFactory",
- "SwitchToUser")))
- {
- g_warning ("failed to create new message");
- return FALSE;
- }
-
- if (!dbus_message_append_args (message,
- DBUS_TYPE_STRING, &user->user_name,
- DBUS_TYPE_INVALID))
- {
- g_warning ("failed to append args");
- return FALSE;
- }
-
- if (!(reply = dbus_connection_send_with_reply_and_block (dbus_g_connection_get_connection (priv->system_bus),
- message,
- -1,
- &error)))
- {
- if (dbus_error_is_set (&error))
- {
- g_warning ("Failed to send message: %s", error.message);
- dbus_error_free (&error);
-
- return FALSE;
- }
- }
-
- if (message)
- {
- dbus_message_unref (message);
- }
-
- if (reply)
- {
- dbus_message_unref (reply);
- }
-
- dbus_error_free (&error);
-
- return TRUE;
+ UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self);
+ return org_gnome_DisplayManager_LocalDisplayFactory_switch_to_user(priv->gdm_local_proxy, user->user_name, NULL, NULL);
}
gboolean
@@ -1094,3 +1119,17 @@ users_service_dbus_can_activate_session (UsersServiceDbus *self)
return can_activate;
}
+
+/* Sets the menu item that represents the guest account */
+void
+users_service_dbus_set_guest_item (UsersServiceDbus * self, DbusmenuMenuitem * mi)
+{
+ UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self);
+ priv->guest_item = mi;
+
+ if (priv->guest_session_id != NULL) {
+ dbusmenu_menuitem_property_set_bool(priv->guest_item, USER_ITEM_PROP_LOGGED_IN, TRUE);
+ }
+
+ return;
+}