moving to accounts service library Resolves: #678236 - Add requires for accounts service to spec since it isn't optional (and hasn't been for a while)
3962 lines
136 KiB
Diff
3962 lines
136 KiB
Diff
From 4dad44a175493f1c495a90ba67270ba11c9c1802 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 18 Feb 2011 17:56:09 -0500
|
|
Subject: [PATCH 1/2] greeter: fix swapped LHS/RHS in icon loading error path
|
|
|
|
This nasty bug means in some obscure cases we're going to
|
|
end up using freed memory.
|
|
---
|
|
gui/simple-greeter/gdm-user-chooser-widget.c | 2 +-
|
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-user-chooser-widget.c b/gui/simple-greeter/gdm-user-chooser-widget.c
|
|
index 9447e59..4b5a80f 100644
|
|
--- a/gui/simple-greeter/gdm-user-chooser-widget.c
|
|
+++ b/gui/simple-greeter/gdm-user-chooser-widget.c
|
|
@@ -900,7 +900,7 @@ get_pixbuf_from_icon_names (GdmUserChooserWidget *widget,
|
|
TRUE, 8, 1, 1, 1, NULL, NULL);
|
|
scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf, size, size, GDK_INTERP_NEAREST);
|
|
g_object_unref (pixbuf);
|
|
- scaled_pixbuf = pixbuf;
|
|
+ pixbuf = scaled_pixbuf;
|
|
}
|
|
|
|
return pixbuf;
|
|
--
|
|
1.7.4.1
|
|
|
|
|
|
From ec034f78dcb27baf240658323892ac2a665c6580 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 18 Feb 2011 17:54:08 -0500
|
|
Subject: [PATCH 2/2] greeter: port to account service library
|
|
|
|
The current user manager code is a mess of dbus code for
|
|
talking to the accounts daemon and code for falling back if
|
|
it isn't there. The accounts daemon is no longer optional,
|
|
so drop all that and just use the accounts service library
|
|
directly.
|
|
---
|
|
configure.ac | 1 +
|
|
gui/simple-greeter/Makefile.am | 27 -
|
|
gui/simple-greeter/gdm-user-chooser-widget.c | 370 +++-
|
|
gui/simple-greeter/gdm-user-manager.c | 3082 --------------------------
|
|
gui/simple-greeter/gdm-user-manager.h | 91 -
|
|
gui/simple-greeter/test-user-manager.c | 27 +-
|
|
6 files changed, 316 insertions(+), 3282 deletions(-)
|
|
delete mode 100644 gui/simple-greeter/gdm-user-manager.c
|
|
delete mode 100644 gui/simple-greeter/gdm-user-manager.h
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index fe612e7..48be019 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -125,6 +125,7 @@ PKG_CHECK_MODULES(SIMPLE_GREETER,
|
|
gtk+-3.0 >= $GTK_REQUIRED_VERSION
|
|
gconf-2.0 >= $GCONF_REQUIRED_VERSION
|
|
fontconfig >= $FONTCONFIG_REQUIRED_VERSION
|
|
+ accountsservice >= $ACCOUNTS_SERVICE_REQUIRED_VERSION
|
|
x11
|
|
)
|
|
SIMPLE_GREETER_LIBS="$SIMPLE_GREETER_LIBS -lm"
|
|
diff --git a/gui/simple-greeter/Makefile.am b/gui/simple-greeter/Makefile.am
|
|
index aa78504..a842c7b 100644
|
|
--- a/gui/simple-greeter/Makefile.am
|
|
+++ b/gui/simple-greeter/Makefile.am
|
|
@@ -26,29 +26,6 @@ schemasdir = @GCONF_SCHEMA_FILE_DIR@
|
|
schemas_in_files = gdm-simple-greeter.schemas.in
|
|
schemas_DATA = $(schemas_in_files:.schemas.in=.schemas)
|
|
|
|
-noinst_LTLIBRARIES = \
|
|
- libgdmuser.la \
|
|
- $(null)
|
|
-
|
|
-libgdmuser_la_SOURCES = \
|
|
- gdm-user.c \
|
|
- gdm-user.h \
|
|
- gdm-user-private.h \
|
|
- gdm-user-manager.c \
|
|
- gdm-user-manager.h \
|
|
- $(NULL)
|
|
-
|
|
-libgdmuser_la_CFLAGS = \
|
|
- $(SIMPLE_GREETER_CFLAGS) \
|
|
- $(NULL)
|
|
-
|
|
-libgdmuser_la_LIBADD = \
|
|
- $(NULL)
|
|
-
|
|
-libgdmuser_la_LDFLAGS = \
|
|
- -export-dynamic \
|
|
- $(NULL)
|
|
-
|
|
noinst_PROGRAMS = \
|
|
test-filesystem-type \
|
|
test-greeter-login-window \
|
|
@@ -87,7 +64,6 @@ test_greeter_login_window_SOURCES = \
|
|
|
|
test_greeter_login_window_LDADD = \
|
|
$(top_builddir)/common/libgdmcommon.la \
|
|
- libgdmuser.la \
|
|
$(COMMON_LIBS) \
|
|
$(SIMPLE_GREETER_LIBS) \
|
|
$(RBAC_LIBS) \
|
|
@@ -216,7 +192,6 @@ test_user_chooser_SOURCES = \
|
|
$(NULL)
|
|
|
|
test_user_chooser_LDADD = \
|
|
- libgdmuser.la \
|
|
$(top_builddir)/common/libgdmcommon.la \
|
|
$(COMMON_LIBS) \
|
|
$(SIMPLE_GREETER_LIBS) \
|
|
@@ -227,7 +202,6 @@ test_user_manager_SOURCES = \
|
|
$(NULL)
|
|
|
|
test_user_manager_LDADD = \
|
|
- libgdmuser.la \
|
|
$(top_builddir)/common/libgdmcommon.la \
|
|
$(COMMON_LIBS) \
|
|
$(SIMPLE_GREETER_LIBS) \
|
|
@@ -281,7 +255,6 @@ gdm_simple_greeter_SOURCES = \
|
|
|
|
gdm_simple_greeter_LDADD = \
|
|
$(top_builddir)/common/libgdmcommon.la \
|
|
- libgdmuser.la \
|
|
$(COMMON_LIBS) \
|
|
$(EXTRA_GREETER_LIBS) \
|
|
$(SIMPLE_GREETER_LIBS) \
|
|
diff --git a/gui/simple-greeter/gdm-user-chooser-widget.c b/gui/simple-greeter/gdm-user-chooser-widget.c
|
|
index 4b5a80f..a385218 100644
|
|
--- a/gui/simple-greeter/gdm-user-chooser-widget.c
|
|
+++ b/gui/simple-greeter/gdm-user-chooser-widget.c
|
|
@@ -37,7 +37,9 @@
|
|
|
|
#include <gconf/gconf-client.h>
|
|
|
|
-#include "gdm-user-manager.h"
|
|
+#include <act/act-user-manager.h>
|
|
+#include <act/act-user.h>
|
|
+
|
|
#include "gdm-user-chooser-widget.h"
|
|
#include "gdm-settings-keys.h"
|
|
#include "gdm-settings-client.h"
|
|
@@ -59,7 +61,7 @@ enum {
|
|
|
|
struct GdmUserChooserWidgetPrivate
|
|
{
|
|
- GdmUserManager *manager;
|
|
+ ActUserManager *manager;
|
|
GtkIconTheme *icon_theme;
|
|
|
|
GSList *users_to_add;
|
|
@@ -170,45 +172,307 @@ queue_update_other_user_visibility (GdmUserChooserWidget *widget)
|
|
}
|
|
|
|
static void
|
|
+rounded_rectangle (cairo_t *cr,
|
|
+ gdouble aspect,
|
|
+ gdouble x,
|
|
+ gdouble y,
|
|
+ gdouble corner_radius,
|
|
+ gdouble width,
|
|
+ gdouble height)
|
|
+{
|
|
+ gdouble radius;
|
|
+ gdouble degrees;
|
|
+
|
|
+ radius = corner_radius / aspect;
|
|
+ degrees = G_PI / 180.0;
|
|
+
|
|
+ cairo_new_sub_path (cr);
|
|
+ cairo_arc (cr,
|
|
+ x + width - radius,
|
|
+ y + radius,
|
|
+ radius,
|
|
+ -90 * degrees,
|
|
+ 0 * degrees);
|
|
+ cairo_arc (cr,
|
|
+ x + width - radius,
|
|
+ y + height - radius,
|
|
+ radius,
|
|
+ 0 * degrees,
|
|
+ 90 * degrees);
|
|
+ cairo_arc (cr,
|
|
+ x + radius,
|
|
+ y + height - radius,
|
|
+ radius,
|
|
+ 90 * degrees,
|
|
+ 180 * degrees);
|
|
+ cairo_arc (cr,
|
|
+ x + radius,
|
|
+ y + radius,
|
|
+ radius,
|
|
+ 180 * degrees,
|
|
+ 270 * degrees);
|
|
+ cairo_close_path (cr);
|
|
+}
|
|
+
|
|
+static cairo_surface_t *
|
|
+surface_from_pixbuf (GdkPixbuf *pixbuf)
|
|
+{
|
|
+ cairo_surface_t *surface;
|
|
+ cairo_t *cr;
|
|
+
|
|
+ surface = cairo_image_surface_create (gdk_pixbuf_get_has_alpha (pixbuf) ?
|
|
+ CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
|
|
+ gdk_pixbuf_get_width (pixbuf),
|
|
+ gdk_pixbuf_get_height (pixbuf));
|
|
+ cr = cairo_create (surface);
|
|
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
|
|
+ cairo_paint (cr);
|
|
+ cairo_destroy (cr);
|
|
+
|
|
+ return surface;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * go_cairo_convert_data_to_pixbuf:
|
|
+ * @src: a pointer to pixel data in cairo format
|
|
+ * @dst: a pointer to pixel data in pixbuf format
|
|
+ * @width: image width
|
|
+ * @height: image height
|
|
+ * @rowstride: data rowstride
|
|
+ *
|
|
+ * Converts the pixel data stored in @src in CAIRO_FORMAT_ARGB32 cairo format
|
|
+ * to GDK_COLORSPACE_RGB pixbuf format and move them
|
|
+ * to @dst. If @src == @dst, pixel are converted in place.
|
|
+ **/
|
|
+
|
|
+static void
|
|
+go_cairo_convert_data_to_pixbuf (unsigned char *dst,
|
|
+ unsigned char const *src,
|
|
+ int width,
|
|
+ int height,
|
|
+ int rowstride)
|
|
+{
|
|
+ int i,j;
|
|
+ unsigned int t;
|
|
+ unsigned char a, b, c;
|
|
+
|
|
+ g_return_if_fail (dst != NULL);
|
|
+
|
|
+#define MULT(d,c,a,t) G_STMT_START { t = (a)? c * 255 / a: 0; d = t;} G_STMT_END
|
|
+
|
|
+ if (src == dst || src == NULL) {
|
|
+ for (i = 0; i < height; i++) {
|
|
+ for (j = 0; j < width; j++) {
|
|
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
|
+ MULT(a, dst[2], dst[3], t);
|
|
+ MULT(b, dst[1], dst[3], t);
|
|
+ MULT(c, dst[0], dst[3], t);
|
|
+ dst[0] = a;
|
|
+ dst[1] = b;
|
|
+ dst[2] = c;
|
|
+#else
|
|
+ MULT(a, dst[1], dst[0], t);
|
|
+ MULT(b, dst[2], dst[0], t);
|
|
+ MULT(c, dst[3], dst[0], t);
|
|
+ dst[3] = dst[0];
|
|
+ dst[0] = a;
|
|
+ dst[1] = b;
|
|
+ dst[2] = c;
|
|
+#endif
|
|
+ dst += 4;
|
|
+ }
|
|
+ dst += rowstride - width * 4;
|
|
+ }
|
|
+ } else {
|
|
+ for (i = 0; i < height; i++) {
|
|
+ for (j = 0; j < width; j++) {
|
|
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
|
+ MULT(dst[0], src[2], src[3], t);
|
|
+ MULT(dst[1], src[1], src[3], t);
|
|
+ MULT(dst[2], src[0], src[3], t);
|
|
+ dst[3] = src[3];
|
|
+#else
|
|
+ MULT(dst[0], src[1], src[0], t);
|
|
+ MULT(dst[1], src[2], src[0], t);
|
|
+ MULT(dst[2], src[3], src[0], t);
|
|
+ dst[3] = src[0];
|
|
+#endif
|
|
+ src += 4;
|
|
+ dst += 4;
|
|
+ }
|
|
+ src += rowstride - width * 4;
|
|
+ dst += rowstride - width * 4;
|
|
+ }
|
|
+ }
|
|
+#undef MULT
|
|
+}
|
|
+
|
|
+static void
|
|
+cairo_to_pixbuf (guint8 *src_data,
|
|
+ GdkPixbuf *dst_pixbuf)
|
|
+{
|
|
+ unsigned char *src;
|
|
+ unsigned char *dst;
|
|
+ guint w;
|
|
+ guint h;
|
|
+ guint rowstride;
|
|
+
|
|
+ w = gdk_pixbuf_get_width (dst_pixbuf);
|
|
+ h = gdk_pixbuf_get_height (dst_pixbuf);
|
|
+ rowstride = gdk_pixbuf_get_rowstride (dst_pixbuf);
|
|
+
|
|
+ dst = gdk_pixbuf_get_pixels (dst_pixbuf);
|
|
+ src = src_data;
|
|
+
|
|
+ go_cairo_convert_data_to_pixbuf (dst, src, w, h, rowstride);
|
|
+}
|
|
+
|
|
+static GdkPixbuf *
|
|
+frame_pixbuf (GdkPixbuf *source)
|
|
+{
|
|
+ GdkPixbuf *dest;
|
|
+ cairo_t *cr;
|
|
+ cairo_surface_t *surface;
|
|
+ guint w;
|
|
+ guint h;
|
|
+ guint rowstride;
|
|
+ int frame_width;
|
|
+ double radius;
|
|
+ guint8 *data;
|
|
+
|
|
+ frame_width = 2;
|
|
+
|
|
+ w = gdk_pixbuf_get_width (source) + frame_width * 2;
|
|
+ h = gdk_pixbuf_get_height (source) + frame_width * 2;
|
|
+ radius = w / 10;
|
|
+
|
|
+ dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
|
|
+ TRUE,
|
|
+ 8,
|
|
+ w,
|
|
+ h);
|
|
+ rowstride = gdk_pixbuf_get_rowstride (dest);
|
|
+
|
|
+
|
|
+ data = g_new0 (guint8, h * rowstride);
|
|
+
|
|
+ surface = cairo_image_surface_create_for_data (data,
|
|
+ CAIRO_FORMAT_ARGB32,
|
|
+ w,
|
|
+ h,
|
|
+ rowstride);
|
|
+ cr = cairo_create (surface);
|
|
+ cairo_surface_destroy (surface);
|
|
+
|
|
+ /* set up image */
|
|
+ cairo_rectangle (cr, 0, 0, w, h);
|
|
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
|
|
+ cairo_fill (cr);
|
|
+
|
|
+ rounded_rectangle (cr,
|
|
+ 1.0,
|
|
+ frame_width + 0.5,
|
|
+ frame_width + 0.5,
|
|
+ radius,
|
|
+ w - frame_width * 2 - 1,
|
|
+ h - frame_width * 2 - 1);
|
|
+ cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 0.3);
|
|
+ cairo_fill_preserve (cr);
|
|
+
|
|
+ surface = surface_from_pixbuf (source);
|
|
+ cairo_set_source_surface (cr, surface, frame_width, frame_width);
|
|
+ cairo_fill (cr);
|
|
+ cairo_surface_destroy (surface);
|
|
+
|
|
+ cairo_to_pixbuf (data, dest);
|
|
+
|
|
+ cairo_destroy (cr);
|
|
+ g_free (data);
|
|
+
|
|
+ return dest;
|
|
+}
|
|
+
|
|
+static GdkPixbuf *
|
|
+render_user_icon (GdmUserChooserWidget *widget,
|
|
+ ActUser *user)
|
|
+{
|
|
+ int size;
|
|
+ const char *file;
|
|
+ GdkPixbuf *pixbuf;
|
|
+ GdkPixbuf *framed;
|
|
+
|
|
+ pixbuf = NULL;
|
|
+
|
|
+ size = get_icon_height_for_widget (GTK_WIDGET (widget));
|
|
+ file = act_user_get_icon_file (user);
|
|
+
|
|
+ if (file) {
|
|
+ pixbuf = gdk_pixbuf_new_from_file_at_size (file, size, size, NULL);
|
|
+ }
|
|
+
|
|
+ if (pixbuf == NULL) {
|
|
+ GError *error;
|
|
+
|
|
+ error = NULL;
|
|
+ pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
|
|
+ "avatar-default",
|
|
+ size,
|
|
+ GTK_ICON_LOOKUP_FORCE_SIZE,
|
|
+ &error);
|
|
+ if (error != NULL) {
|
|
+ g_warning ("%s", error->message);
|
|
+ g_error_free (error);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (pixbuf != NULL) {
|
|
+ framed = frame_pixbuf (pixbuf);
|
|
+ g_object_unref (pixbuf);
|
|
+
|
|
+ pixbuf = framed;
|
|
+ }
|
|
+
|
|
+ return pixbuf;
|
|
+}
|
|
+
|
|
+static void
|
|
update_item_for_user (GdmUserChooserWidget *widget,
|
|
- GdmUser *user)
|
|
+ ActUser *user)
|
|
{
|
|
GdkPixbuf *pixbuf;
|
|
char *tooltip;
|
|
gboolean is_logged_in;
|
|
- int size;
|
|
char *escaped_username;
|
|
char *escaped_real_name;
|
|
|
|
- if (!gdm_user_is_loaded (user)) {
|
|
+ if (!act_user_is_loaded (user)) {
|
|
return;
|
|
}
|
|
|
|
- size = get_icon_height_for_widget (GTK_WIDGET (widget));
|
|
- pixbuf = gdm_user_render_icon (user, size);
|
|
+ pixbuf = render_user_icon (widget, user);
|
|
|
|
if (pixbuf == NULL && widget->priv->stock_person_pixbuf != NULL) {
|
|
pixbuf = g_object_ref (widget->priv->stock_person_pixbuf);
|
|
}
|
|
|
|
tooltip = g_strdup_printf (_("Log in as %s"),
|
|
- gdm_user_get_user_name (user));
|
|
+ act_user_get_user_name (user));
|
|
|
|
- is_logged_in = gdm_user_is_logged_in (user);
|
|
+ is_logged_in = act_user_is_logged_in (user);
|
|
|
|
g_debug ("GdmUserChooserWidget: User added name:%s logged-in:%d pixbuf:%p",
|
|
- gdm_user_get_user_name (user),
|
|
+ act_user_get_user_name (user),
|
|
is_logged_in,
|
|
pixbuf);
|
|
|
|
- escaped_username = g_markup_escape_text (gdm_user_get_user_name (user), -1);
|
|
- escaped_real_name = g_markup_escape_text (gdm_user_get_real_name (user), -1);
|
|
+ escaped_username = g_markup_escape_text (act_user_get_user_name (user), -1);
|
|
+ escaped_real_name = g_markup_escape_text (act_user_get_real_name (user), -1);
|
|
gdm_chooser_widget_update_item (GDM_CHOOSER_WIDGET (widget),
|
|
escaped_username,
|
|
pixbuf,
|
|
escaped_real_name,
|
|
tooltip,
|
|
- gdm_user_get_login_frequency (user),
|
|
+ act_user_get_login_frequency (user),
|
|
is_logged_in,
|
|
FALSE);
|
|
g_free (escaped_real_name);
|
|
@@ -225,7 +489,7 @@ on_item_load (GdmChooserWidget *widget,
|
|
const char *id,
|
|
GdmUserChooserWidget *user_chooser)
|
|
{
|
|
- GdmUser *user;
|
|
+ ActUser *user;
|
|
|
|
g_debug ("GdmUserChooserWidget: Loading item for id=%s", id);
|
|
|
|
@@ -241,7 +505,7 @@ on_item_load (GdmChooserWidget *widget,
|
|
return;
|
|
}
|
|
|
|
- user = gdm_user_manager_get_user (user_chooser->priv->manager, id);
|
|
+ user = act_user_manager_get_user (user_chooser->priv->manager, id);
|
|
if (user != NULL) {
|
|
update_item_for_user (user_chooser, user);
|
|
}
|
|
@@ -467,7 +731,7 @@ is_user_list_disabled (GdmUserChooserWidget *widget)
|
|
|
|
static void
|
|
add_user (GdmUserChooserWidget *widget,
|
|
- GdmUser *user)
|
|
+ ActUser *user)
|
|
{
|
|
GdkPixbuf *pixbuf;
|
|
char *tooltip;
|
|
@@ -486,18 +750,18 @@ add_user (GdmUserChooserWidget *widget,
|
|
}
|
|
|
|
tooltip = g_strdup_printf (_("Log in as %s"),
|
|
- gdm_user_get_user_name (user));
|
|
+ act_user_get_user_name (user));
|
|
|
|
- is_logged_in = gdm_user_is_logged_in (user);
|
|
+ is_logged_in = act_user_is_logged_in (user);
|
|
|
|
- escaped_username = g_markup_escape_text (gdm_user_get_user_name (user), -1);
|
|
- escaped_real_name = g_markup_escape_text (gdm_user_get_real_name (user), -1);
|
|
+ escaped_username = g_markup_escape_text (act_user_get_user_name (user), -1);
|
|
+ escaped_real_name = g_markup_escape_text (act_user_get_real_name (user), -1);
|
|
gdm_chooser_widget_add_item (GDM_CHOOSER_WIDGET (widget),
|
|
escaped_username,
|
|
pixbuf,
|
|
escaped_real_name,
|
|
tooltip,
|
|
- gdm_user_get_login_frequency (user),
|
|
+ act_user_get_login_frequency (user),
|
|
is_logged_in,
|
|
FALSE,
|
|
(GdmChooserWidgetItemLoadFunc) on_item_load,
|
|
@@ -514,8 +778,8 @@ add_user (GdmUserChooserWidget *widget,
|
|
}
|
|
|
|
static void
|
|
-on_user_added (GdmUserManager *manager,
|
|
- GdmUser *user,
|
|
+on_user_added (ActUserManager *manager,
|
|
+ ActUser *user,
|
|
GdmUserChooserWidget *widget)
|
|
{
|
|
/* wait for all users to be loaded */
|
|
@@ -526,19 +790,19 @@ on_user_added (GdmUserManager *manager,
|
|
}
|
|
|
|
static void
|
|
-on_user_removed (GdmUserManager *manager,
|
|
- GdmUser *user,
|
|
+on_user_removed (ActUserManager *manager,
|
|
+ ActUser *user,
|
|
GdmUserChooserWidget *widget)
|
|
{
|
|
const char *user_name;
|
|
|
|
- g_debug ("GdmUserChooserWidget: User removed: %s", gdm_user_get_user_name (user));
|
|
+ g_debug ("GdmUserChooserWidget: User removed: %s", act_user_get_user_name (user));
|
|
/* wait for all users to be loaded */
|
|
if (! widget->priv->loaded) {
|
|
return;
|
|
}
|
|
|
|
- user_name = gdm_user_get_user_name (user);
|
|
+ user_name = act_user_get_user_name (user);
|
|
|
|
gdm_chooser_widget_remove_item (GDM_CHOOSER_WIDGET (widget),
|
|
user_name);
|
|
@@ -547,17 +811,17 @@ on_user_removed (GdmUserManager *manager,
|
|
}
|
|
|
|
static void
|
|
-on_user_is_logged_in_changed (GdmUserManager *manager,
|
|
- GdmUser *user,
|
|
+on_user_is_logged_in_changed (ActUserManager *manager,
|
|
+ ActUser *user,
|
|
GdmUserChooserWidget *widget)
|
|
{
|
|
const char *user_name;
|
|
gboolean is_logged_in;
|
|
|
|
- g_debug ("GdmUserChooserWidget: User logged in changed: %s", gdm_user_get_user_name (user));
|
|
+ g_debug ("GdmUserChooserWidget: User logged in changed: %s", act_user_get_user_name (user));
|
|
|
|
- user_name = gdm_user_get_user_name (user);
|
|
- is_logged_in = gdm_user_is_logged_in (user);
|
|
+ user_name = act_user_get_user_name (user);
|
|
+ is_logged_in = act_user_is_logged_in (user);
|
|
|
|
gdm_chooser_widget_set_item_in_use (GDM_CHOOSER_WIDGET (widget),
|
|
user_name,
|
|
@@ -565,8 +829,8 @@ on_user_is_logged_in_changed (GdmUserManager *manager,
|
|
}
|
|
|
|
static void
|
|
-on_user_changed (GdmUserManager *manager,
|
|
- GdmUser *user,
|
|
+on_user_changed (ActUserManager *manager,
|
|
+ ActUser *user,
|
|
GdmUserChooserWidget *widget)
|
|
{
|
|
/* wait for all users to be loaded */
|
|
@@ -612,7 +876,7 @@ queue_add_users (GdmUserChooserWidget *widget)
|
|
}
|
|
|
|
static void
|
|
-on_is_loaded_changed (GdmUserManager *manager,
|
|
+on_is_loaded_changed (ActUserManager *manager,
|
|
GParamSpec *pspec,
|
|
GdmUserChooserWidget *widget)
|
|
{
|
|
@@ -622,7 +886,7 @@ on_is_loaded_changed (GdmUserManager *manager,
|
|
|
|
g_debug ("GdmUserChooserWidget: Users loaded");
|
|
|
|
- users = gdm_user_manager_list_users (manager);
|
|
+ users = act_user_manager_list_users (manager);
|
|
g_slist_foreach (users, (GFunc) g_object_ref, NULL);
|
|
widget->priv->users_to_add = g_slist_concat (widget->priv->users_to_add, g_slist_copy (users));
|
|
|
|
@@ -658,38 +922,7 @@ load_users (GdmUserChooserWidget *widget)
|
|
{
|
|
|
|
if (widget->priv->show_normal_users) {
|
|
- char *temp;
|
|
- gboolean res;
|
|
- gboolean include_all;
|
|
- GSList *includes;
|
|
- GSList *excludes;
|
|
-
|
|
- widget->priv->manager = gdm_user_manager_ref_default ();
|
|
-
|
|
- /* exclude/include */
|
|
- g_debug ("Setting users to include:");
|
|
- res = gdm_settings_client_get_string (GDM_KEY_INCLUDE,
|
|
- &temp);
|
|
- parse_string_list (temp, &includes);
|
|
-
|
|
- g_debug ("Setting users to exclude:");
|
|
- res = gdm_settings_client_get_string (GDM_KEY_EXCLUDE,
|
|
- &temp);
|
|
- parse_string_list (temp, &excludes);
|
|
-
|
|
- include_all = FALSE;
|
|
- res = gdm_settings_client_get_boolean (GDM_KEY_INCLUDE_ALL,
|
|
- &include_all);
|
|
- g_object_set (widget->priv->manager,
|
|
- "include-all", include_all,
|
|
- "include-usernames-list", includes,
|
|
- "exclude-usernames-list", excludes,
|
|
- NULL);
|
|
-
|
|
- g_slist_foreach (includes, (GFunc) g_free, NULL);
|
|
- g_slist_free (includes);
|
|
- g_slist_foreach (excludes, (GFunc) g_free, NULL);
|
|
- g_slist_free (excludes);
|
|
+ widget->priv->manager = act_user_manager_get_default ();
|
|
|
|
g_signal_connect (widget->priv->manager,
|
|
"user-added",
|
|
@@ -711,7 +944,6 @@ load_users (GdmUserChooserWidget *widget)
|
|
"user-changed",
|
|
G_CALLBACK (on_user_changed),
|
|
widget);
|
|
- gdm_user_manager_queue_load (widget->priv->manager);
|
|
} else {
|
|
gdm_chooser_widget_loaded (GDM_CHOOSER_WIDGET (widget));
|
|
}
|
|
diff --git a/gui/simple-greeter/gdm-user-manager.c b/gui/simple-greeter/gdm-user-manager.c
|
|
deleted file mode 100644
|
|
index c631989..0000000
|
|
--- a/gui/simple-greeter/gdm-user-manager.c
|
|
+++ /dev/null
|
|
@@ -1,3082 +0,0 @@
|
|
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
|
- *
|
|
- * Copyright (C) 2007-2008 William Jon McCann <mccann@jhu.edu>
|
|
- *
|
|
- * This program is free software; you can redistribute it and/or modify
|
|
- * it under the terms of the GNU General Public License as published by
|
|
- * the Free Software Foundation; either version 2 of the License, or
|
|
- * (at your option) any later version.
|
|
- *
|
|
- * This program is distributed in the hope that it will be useful,
|
|
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
- * GNU General Public License for more details.
|
|
- *
|
|
- * You should have received a copy of the GNU General Public License
|
|
- * along with this program; if not, write to the Free Software
|
|
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
- *
|
|
- */
|
|
-
|
|
-#include "config.h"
|
|
-
|
|
-#include <stdlib.h>
|
|
-#include <stdio.h>
|
|
-#include <fcntl.h>
|
|
-#include <unistd.h>
|
|
-#include <string.h>
|
|
-#include <signal.h>
|
|
-#include <errno.h>
|
|
-#include <sys/stat.h>
|
|
-#include <sys/types.h>
|
|
-
|
|
-#ifdef HAVE_PATHS_H
|
|
-#include <paths.h>
|
|
-#endif /* HAVE_PATHS_H */
|
|
-
|
|
-#include <glib.h>
|
|
-#include <glib/gi18n.h>
|
|
-#include <glib/gstdio.h>
|
|
-#include <glib-object.h>
|
|
-#include <gio/gio.h>
|
|
-
|
|
-#include <dbus/dbus.h>
|
|
-#include <dbus/dbus-glib.h>
|
|
-#include <dbus/dbus-glib-lowlevel.h>
|
|
-
|
|
-#include "gdm-user-manager.h"
|
|
-#include "gdm-user-private.h"
|
|
-
|
|
-#define GDM_USER_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_USER_MANAGER, GdmUserManagerPrivate))
|
|
-
|
|
-#define CK_NAME "org.freedesktop.ConsoleKit"
|
|
-
|
|
-#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager"
|
|
-#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
|
|
-#define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat"
|
|
-#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
|
|
-
|
|
-#define GDM_DBUS_TYPE_G_OBJECT_PATH_ARRAY (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH))
|
|
-
|
|
-/* Prefs Defaults */
|
|
-
|
|
-#ifdef __sun
|
|
-#define FALLBACK_MINIMAL_UID 100
|
|
-#else
|
|
-#define FALLBACK_MINIMAL_UID 500
|
|
-#endif
|
|
-
|
|
-#ifndef _PATH_SHELLS
|
|
-#define _PATH_SHELLS "/etc/shells"
|
|
-#endif
|
|
-#define PATH_PASSWD "/etc/passwd"
|
|
-
|
|
-#ifndef GDM_USERNAME
|
|
-#define GDM_USERNAME "gdm"
|
|
-#endif
|
|
-
|
|
-#define RELOAD_PASSWD_THROTTLE_SECS 5
|
|
-
|
|
-/* approximately two months */
|
|
-#define LOGIN_FREQUENCY_TIME_WINDOW_SECS (60 * 24 * 60 * 60)
|
|
-
|
|
-#define ACCOUNTS_NAME "org.freedesktop.Accounts"
|
|
-#define ACCOUNTS_PATH "/org/freedesktop/Accounts"
|
|
-#define ACCOUNTS_INTERFACE "org.freedesktop.Accounts"
|
|
-
|
|
-typedef enum {
|
|
- GDM_USER_MANAGER_SEAT_STATE_UNLOADED = 0,
|
|
- GDM_USER_MANAGER_SEAT_STATE_GET_SESSION_ID,
|
|
- GDM_USER_MANAGER_SEAT_STATE_GET_ID,
|
|
- GDM_USER_MANAGER_SEAT_STATE_GET_PROXY,
|
|
- GDM_USER_MANAGER_SEAT_STATE_LOADED,
|
|
-} GdmUserManagerSeatState;
|
|
-
|
|
-typedef struct
|
|
-{
|
|
- GdmUserManagerSeatState state;
|
|
- char *id;
|
|
- char *session_id;
|
|
- union {
|
|
- DBusGProxyCall *get_current_session_call;
|
|
- DBusGProxyCall *get_seat_id_call;
|
|
- };
|
|
-
|
|
- DBusGProxy *proxy;
|
|
-} GdmUserManagerSeat;
|
|
-
|
|
-typedef enum {
|
|
- GDM_USER_MANAGER_NEW_SESSION_STATE_UNLOADED = 0,
|
|
- GDM_USER_MANAGER_NEW_SESSION_STATE_GET_PROXY,
|
|
- GDM_USER_MANAGER_NEW_SESSION_STATE_GET_UID,
|
|
- GDM_USER_MANAGER_NEW_SESSION_STATE_GET_X11_DISPLAY,
|
|
- GDM_USER_MANAGER_NEW_SESSION_STATE_MAYBE_ADD,
|
|
- GDM_USER_MANAGER_NEW_SESSION_STATE_LOADED,
|
|
-} GdmUserManagerNewSessionState;
|
|
-
|
|
-typedef struct
|
|
-{
|
|
- GdmUserManager *manager;
|
|
- GdmUserManagerNewSessionState state;
|
|
- char *id;
|
|
-
|
|
- union {
|
|
- DBusGProxyCall *get_unix_user_call;
|
|
- DBusGProxyCall *get_x11_display_call;
|
|
- };
|
|
-
|
|
- DBusGProxy *proxy;
|
|
-
|
|
- uid_t uid;
|
|
- char *x11_display;
|
|
-} GdmUserManagerNewSession;
|
|
-
|
|
-typedef enum {
|
|
- GDM_USER_MANAGER_GET_USER_STATE_UNFETCHED = 0,
|
|
- GDM_USER_MANAGER_GET_USER_STATE_WAIT_FOR_LOADED,
|
|
- GDM_USER_MANAGER_GET_USER_STATE_ASK_ACCOUNTS_SERVICE,
|
|
- GDM_USER_MANAGER_GET_USER_STATE_FETCHED
|
|
-} GdmUserManagerGetUserState;
|
|
-
|
|
-typedef struct
|
|
-{
|
|
- GdmUserManager *manager;
|
|
- GdmUserManagerGetUserState state;
|
|
- GdmUser *user;
|
|
- char *username;
|
|
- char *object_path;
|
|
-
|
|
- DBusGProxyCall *call;
|
|
-} GdmUserManagerFetchUserRequest;
|
|
-
|
|
-struct GdmUserManagerPrivate
|
|
-{
|
|
- GHashTable *users_by_name;
|
|
- GHashTable *users_by_object_path;
|
|
- GHashTable *sessions;
|
|
- GHashTable *shells;
|
|
- DBusGConnection *connection;
|
|
- DBusGProxyCall *get_sessions_call;
|
|
- DBusGProxy *accounts_proxy;
|
|
-
|
|
- GdmUserManagerSeat seat;
|
|
-
|
|
- GSList *new_sessions;
|
|
- GSList *new_users;
|
|
- GSList *fetch_user_requests;
|
|
-
|
|
- GFileMonitor *passwd_monitor;
|
|
- GFileMonitor *shells_monitor;
|
|
-
|
|
- GSList *exclude_usernames;
|
|
- GSList *include_usernames;
|
|
- gboolean include_all;
|
|
-
|
|
- gboolean load_passwd_pending;
|
|
-
|
|
- guint load_id;
|
|
- guint reload_passwd_id;
|
|
- guint ck_history_id;
|
|
- guint ck_history_watchdog_id;
|
|
- GPid ck_history_pid;
|
|
-
|
|
- gboolean is_loaded;
|
|
- gboolean has_multiple_users;
|
|
- gboolean listing_cached_users;
|
|
-};
|
|
-
|
|
-enum {
|
|
- PROP_0,
|
|
- PROP_INCLUDE_ALL,
|
|
- PROP_INCLUDE_USERNAMES_LIST,
|
|
- PROP_EXCLUDE_USERNAMES_LIST,
|
|
- PROP_IS_LOADED,
|
|
- PROP_HAS_MULTIPLE_USERS
|
|
-};
|
|
-
|
|
-enum {
|
|
- USER_ADDED,
|
|
- USER_REMOVED,
|
|
- USER_IS_LOGGED_IN_CHANGED,
|
|
- USER_CHANGED,
|
|
- LAST_SIGNAL
|
|
-};
|
|
-
|
|
-static guint signals [LAST_SIGNAL] = { 0, };
|
|
-
|
|
-static void gdm_user_manager_class_init (GdmUserManagerClass *klass);
|
|
-static void gdm_user_manager_init (GdmUserManager *user_manager);
|
|
-static void gdm_user_manager_finalize (GObject *object);
|
|
-
|
|
-static void load_users_manually (GdmUserManager *manager);
|
|
-static void monitor_local_users (GdmUserManager *manager);
|
|
-static void load_seat_incrementally (GdmUserManager *manager);
|
|
-static void unload_seat (GdmUserManager *manager);
|
|
-static void load_users (GdmUserManager *manager);
|
|
-static void queue_load_seat_and_users (GdmUserManager *manager);
|
|
-static void monitor_local_users (GdmUserManager *manager);
|
|
-
|
|
-static void load_new_session_incrementally (GdmUserManagerNewSession *new_session);
|
|
-static void set_is_loaded (GdmUserManager *manager, gboolean is_loaded);
|
|
-
|
|
-static void on_new_user_loaded (GdmUser *user,
|
|
- GParamSpec *pspec,
|
|
- GdmUserManager *manager);
|
|
-static void give_up_and_fetch_user_locally (GdmUserManager *manager,
|
|
- GdmUserManagerFetchUserRequest *request);
|
|
-static void fetch_user_locally (GdmUserManager *manager,
|
|
- GdmUser *user,
|
|
- const char *username);
|
|
-static void fetch_user_incrementally (GdmUserManagerFetchUserRequest *request);
|
|
-
|
|
-static void maybe_set_is_loaded (GdmUserManager *manager);
|
|
-static gpointer user_manager_object = NULL;
|
|
-
|
|
-G_DEFINE_TYPE (GdmUserManager, gdm_user_manager, G_TYPE_OBJECT)
|
|
-
|
|
-GQuark
|
|
-gdm_user_manager_error_quark (void)
|
|
-{
|
|
- static GQuark ret = 0;
|
|
- if (ret == 0) {
|
|
- ret = g_quark_from_static_string ("gdm_user_manager_error");
|
|
- }
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static gboolean
|
|
-start_new_login_session (GdmUserManager *manager)
|
|
-{
|
|
- GError *error;
|
|
- gboolean res;
|
|
-
|
|
- res = g_spawn_command_line_async ("gdmflexiserver -s", &error);
|
|
- if (! res) {
|
|
- if (error != NULL) {
|
|
- g_warning ("Unable to start new login: %s", error->message);
|
|
- g_error_free (error);
|
|
- } else {
|
|
- g_warning ("Unable to start new login");
|
|
- }
|
|
- }
|
|
-
|
|
- return res;
|
|
-}
|
|
-
|
|
-static gboolean
|
|
-activate_session_id (GdmUserManager *manager,
|
|
- const char *seat_id,
|
|
- const char *session_id)
|
|
-{
|
|
- DBusError local_error;
|
|
- DBusMessage *message;
|
|
- DBusMessage *reply;
|
|
- gboolean ret;
|
|
-
|
|
- ret = FALSE;
|
|
- reply = NULL;
|
|
-
|
|
- dbus_error_init (&local_error);
|
|
- message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
|
|
- seat_id,
|
|
- "org.freedesktop.ConsoleKit.Seat",
|
|
- "ActivateSession");
|
|
- if (message == NULL) {
|
|
- goto out;
|
|
- }
|
|
-
|
|
- if (! dbus_message_append_args (message,
|
|
- DBUS_TYPE_OBJECT_PATH, &session_id,
|
|
- DBUS_TYPE_INVALID)) {
|
|
- goto out;
|
|
- }
|
|
-
|
|
-
|
|
- dbus_error_init (&local_error);
|
|
- reply = dbus_connection_send_with_reply_and_block (dbus_g_connection_get_connection (manager->priv->connection),
|
|
- message,
|
|
- -1,
|
|
- &local_error);
|
|
- if (reply == NULL) {
|
|
- if (dbus_error_is_set (&local_error)) {
|
|
- g_warning ("Unable to activate session: %s", local_error.message);
|
|
- dbus_error_free (&local_error);
|
|
- goto out;
|
|
- }
|
|
- }
|
|
-
|
|
- ret = TRUE;
|
|
- out:
|
|
- if (message != NULL) {
|
|
- dbus_message_unref (message);
|
|
- }
|
|
- if (reply != NULL) {
|
|
- dbus_message_unref (reply);
|
|
- }
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static gboolean
|
|
-session_is_login_window (GdmUserManager *manager,
|
|
- const char *session_id)
|
|
-{
|
|
- DBusGProxy *proxy;
|
|
- GError *error;
|
|
- gboolean res;
|
|
- gboolean ret;
|
|
- char *session_type;
|
|
-
|
|
- ret = FALSE;
|
|
-
|
|
- proxy = dbus_g_proxy_new_for_name (manager->priv->connection,
|
|
- CK_NAME,
|
|
- session_id,
|
|
- CK_SESSION_INTERFACE);
|
|
- if (proxy == NULL) {
|
|
- g_warning ("Failed to connect to the ConsoleKit seat object");
|
|
- goto out;
|
|
- }
|
|
-
|
|
- session_type = NULL;
|
|
- error = NULL;
|
|
- res = dbus_g_proxy_call (proxy,
|
|
- "GetSessionType",
|
|
- &error,
|
|
- G_TYPE_INVALID,
|
|
- G_TYPE_STRING, &session_type,
|
|
- G_TYPE_INVALID);
|
|
- if (! res) {
|
|
- if (error != NULL) {
|
|
- g_debug ("GdmUserManager: Failed to identify the session type: %s", error->message);
|
|
- g_error_free (error);
|
|
- } else {
|
|
- g_debug ("GdmUserManager: Failed to identify the session type");
|
|
- }
|
|
- goto out;
|
|
- }
|
|
-
|
|
- if (session_type == NULL || session_type[0] == '\0' || strcmp (session_type, "LoginWindow") != 0) {
|
|
- goto out;
|
|
- }
|
|
-
|
|
- ret = TRUE;
|
|
-
|
|
- out:
|
|
- if (proxy != NULL) {
|
|
- g_object_unref (proxy);
|
|
- }
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static char *
|
|
-_get_login_window_session_id (GdmUserManager *manager)
|
|
-{
|
|
- gboolean res;
|
|
- gboolean can_activate_sessions;
|
|
- GError *error;
|
|
- GPtrArray *sessions;
|
|
- char *primary_ssid;
|
|
- int i;
|
|
-
|
|
- if (manager->priv->seat.id == NULL || manager->priv->seat.id[0] == '\0') {
|
|
- g_debug ("GdmUserManager: display seat ID is not set; can't switch sessions");
|
|
- return NULL;
|
|
- }
|
|
-
|
|
- primary_ssid = NULL;
|
|
- sessions = NULL;
|
|
-
|
|
- can_activate_sessions = gdm_user_manager_can_switch (manager);
|
|
-
|
|
- if (! can_activate_sessions) {
|
|
- g_debug ("GdmUserManager: seat is unable to activate sessions");
|
|
- goto out;
|
|
- }
|
|
-
|
|
- error = NULL;
|
|
- res = dbus_g_proxy_call (manager->priv->seat.proxy,
|
|
- "GetSessions",
|
|
- &error,
|
|
- G_TYPE_INVALID,
|
|
- dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &sessions,
|
|
- G_TYPE_INVALID);
|
|
- if (! res) {
|
|
- if (error != NULL) {
|
|
- g_warning ("unable to determine sessions for user: %s",
|
|
- error->message);
|
|
- g_error_free (error);
|
|
- } else {
|
|
- g_warning ("unable to determine sessions for user");
|
|
- }
|
|
- goto out;
|
|
- }
|
|
-
|
|
- for (i = 0; i < sessions->len; i++) {
|
|
- char *ssid;
|
|
-
|
|
- ssid = g_ptr_array_index (sessions, i);
|
|
-
|
|
- if (session_is_login_window (manager, ssid)) {
|
|
- primary_ssid = g_strdup (ssid);
|
|
- break;
|
|
- }
|
|
- }
|
|
- g_ptr_array_foreach (sessions, (GFunc)g_free, NULL);
|
|
- g_ptr_array_free (sessions, TRUE);
|
|
-
|
|
- out:
|
|
-
|
|
- return primary_ssid;
|
|
-}
|
|
-
|
|
-gboolean
|
|
-gdm_user_manager_goto_login_session (GdmUserManager *manager)
|
|
-{
|
|
- gboolean ret;
|
|
- gboolean res;
|
|
- char *ssid;
|
|
-
|
|
- g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), FALSE);
|
|
- g_return_val_if_fail (manager->priv->is_loaded, FALSE);
|
|
-
|
|
- ret = FALSE;
|
|
-
|
|
- /* First look for any existing LoginWindow sessions on the seat.
|
|
- If none are found, create a new one. */
|
|
-
|
|
- ssid = _get_login_window_session_id (manager);
|
|
- if (ssid != NULL) {
|
|
- res = activate_session_id (manager, manager->priv->seat.id, ssid);
|
|
- if (res) {
|
|
- ret = TRUE;
|
|
- }
|
|
- }
|
|
-
|
|
- if (! ret) {
|
|
- res = start_new_login_session (manager);
|
|
- if (res) {
|
|
- ret = TRUE;
|
|
- }
|
|
- }
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-gboolean
|
|
-gdm_user_manager_can_switch (GdmUserManager *manager)
|
|
-{
|
|
- gboolean res;
|
|
- gboolean can_activate_sessions;
|
|
- GError *error;
|
|
-
|
|
- if (!manager->priv->is_loaded) {
|
|
- g_debug ("GdmUserManager: Unable to switch sessions until fully loaded");
|
|
- return FALSE;
|
|
- }
|
|
-
|
|
- if (manager->priv->seat.id == NULL || manager->priv->seat.id[0] == '\0') {
|
|
- g_debug ("GdmUserManager: display seat ID is not set; can't switch sessions");
|
|
- return FALSE;
|
|
- }
|
|
-
|
|
- g_debug ("GdmUserManager: checking if seat can activate sessions");
|
|
-
|
|
- error = NULL;
|
|
- res = dbus_g_proxy_call (manager->priv->seat.proxy,
|
|
- "CanActivateSessions",
|
|
- &error,
|
|
- G_TYPE_INVALID,
|
|
- G_TYPE_BOOLEAN, &can_activate_sessions,
|
|
- G_TYPE_INVALID);
|
|
- if (! res) {
|
|
- if (error != NULL) {
|
|
- g_warning ("unable to determine if seat can activate sessions: %s",
|
|
- error->message);
|
|
- g_error_free (error);
|
|
- } else {
|
|
- g_warning ("unable to determine if seat can activate sessions");
|
|
- }
|
|
- return FALSE;
|
|
- }
|
|
-
|
|
- return can_activate_sessions;
|
|
-}
|
|
-
|
|
-gboolean
|
|
-gdm_user_manager_activate_user_session (GdmUserManager *manager,
|
|
- GdmUser *user)
|
|
-{
|
|
- gboolean ret;
|
|
- const char *ssid;
|
|
- gboolean res;
|
|
-
|
|
- gboolean can_activate_sessions;
|
|
- g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), FALSE);
|
|
- g_return_val_if_fail (GDM_IS_USER (user), FALSE);
|
|
- g_return_val_if_fail (manager->priv->is_loaded, FALSE);
|
|
-
|
|
- ret = FALSE;
|
|
-
|
|
- can_activate_sessions = gdm_user_manager_can_switch (manager);
|
|
-
|
|
- if (! can_activate_sessions) {
|
|
- g_debug ("GdmUserManager: seat is unable to activate sessions");
|
|
- goto out;
|
|
- }
|
|
-
|
|
- ssid = gdm_user_get_primary_session_id (user);
|
|
- if (ssid == NULL) {
|
|
- goto out;
|
|
- }
|
|
-
|
|
- res = activate_session_id (manager, manager->priv->seat.id, ssid);
|
|
- if (! res) {
|
|
- g_debug ("GdmUserManager: unable to activate session: %s", ssid);
|
|
- goto out;
|
|
- }
|
|
-
|
|
- ret = TRUE;
|
|
- out:
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static void
|
|
-on_user_sessions_changed (GdmUser *user,
|
|
- GdmUserManager *manager)
|
|
-{
|
|
- guint nsessions;
|
|
-
|
|
- if (! manager->priv->is_loaded) {
|
|
- return;
|
|
- }
|
|
-
|
|
- nsessions = gdm_user_get_num_sessions (user);
|
|
-
|
|
- g_debug ("GdmUserManager: sessions changed user=%s num=%d",
|
|
- gdm_user_get_user_name (user),
|
|
- nsessions);
|
|
-
|
|
- /* only signal on zero and one */
|
|
- if (nsessions > 1) {
|
|
- return;
|
|
- }
|
|
-
|
|
- g_signal_emit (manager, signals [USER_IS_LOGGED_IN_CHANGED], 0, user);
|
|
-}
|
|
-
|
|
-static void
|
|
-on_user_changed (GdmUser *user,
|
|
- GdmUserManager *manager)
|
|
-{
|
|
- if (manager->priv->is_loaded) {
|
|
- g_debug ("GdmUserManager: user changed");
|
|
- g_signal_emit (manager, signals[USER_CHANGED], 0, user);
|
|
- }
|
|
-}
|
|
-
|
|
-static void
|
|
-on_get_seat_id_finished (DBusGProxy *proxy,
|
|
- DBusGProxyCall *call,
|
|
- GdmUserManager *manager)
|
|
-{
|
|
- GError *error;
|
|
- char *seat_id;
|
|
- gboolean res;
|
|
-
|
|
- g_assert (manager->priv->seat.get_seat_id_call == call);
|
|
-
|
|
- error = NULL;
|
|
- seat_id = NULL;
|
|
- res = dbus_g_proxy_end_call (proxy,
|
|
- call,
|
|
- &error,
|
|
- DBUS_TYPE_G_OBJECT_PATH,
|
|
- &seat_id,
|
|
- G_TYPE_INVALID);
|
|
- manager->priv->seat.get_seat_id_call = NULL;
|
|
- g_object_unref (proxy);
|
|
-
|
|
- if (! res) {
|
|
- if (error != NULL) {
|
|
- g_debug ("Failed to identify the seat of the "
|
|
- "current session: %s",
|
|
- error->message);
|
|
- g_error_free (error);
|
|
- } else {
|
|
- g_debug ("Failed to identify the seat of the "
|
|
- "current session");
|
|
- }
|
|
- unload_seat (manager);
|
|
- maybe_set_is_loaded (manager);
|
|
- return;
|
|
- }
|
|
-
|
|
- g_debug ("GdmUserManager: Found current seat: %s", seat_id);
|
|
-
|
|
- manager->priv->seat.id = seat_id;
|
|
- manager->priv->seat.state++;
|
|
-
|
|
- load_seat_incrementally (manager);
|
|
-}
|
|
-
|
|
-static void
|
|
-get_seat_id_for_current_session (GdmUserManager *manager)
|
|
-{
|
|
- DBusGProxy *proxy;
|
|
- DBusGProxyCall *call;
|
|
-
|
|
- proxy = dbus_g_proxy_new_for_name (manager->priv->connection,
|
|
- CK_NAME,
|
|
- manager->priv->seat.session_id,
|
|
- CK_SESSION_INTERFACE);
|
|
- if (proxy == NULL) {
|
|
- g_warning ("Failed to connect to the ConsoleKit session object");
|
|
- goto failed;
|
|
- }
|
|
-
|
|
- call = dbus_g_proxy_begin_call (proxy,
|
|
- "GetSeatId",
|
|
- (DBusGProxyCallNotify)
|
|
- on_get_seat_id_finished,
|
|
- manager,
|
|
- NULL,
|
|
- G_TYPE_INVALID);
|
|
- if (call == NULL) {
|
|
- g_warning ("GdmUserManager: failed to make GetSeatId call");
|
|
- goto failed;
|
|
- }
|
|
-
|
|
- manager->priv->seat.get_seat_id_call = call;
|
|
-
|
|
- return;
|
|
-
|
|
-failed:
|
|
- if (proxy != NULL) {
|
|
- g_object_unref (proxy);
|
|
- }
|
|
-
|
|
- unload_seat (manager);
|
|
-}
|
|
-
|
|
-static gint
|
|
-match_name_cmpfunc (gconstpointer a,
|
|
- gconstpointer b)
|
|
-{
|
|
- return g_strcmp0 ((char *) a,
|
|
- (char *) b);
|
|
-}
|
|
-
|
|
-static gboolean
|
|
-username_in_exclude_list (GdmUserManager *manager,
|
|
- const char *username)
|
|
-{
|
|
- GSList *found;
|
|
- gboolean ret = FALSE;
|
|
-
|
|
- /* always exclude the "gdm" user. */
|
|
- if (username == NULL || (strcmp (username, GDM_USERNAME) == 0)) {
|
|
- return TRUE;
|
|
- }
|
|
-
|
|
- if (manager->priv->exclude_usernames != NULL) {
|
|
- found = g_slist_find_custom (manager->priv->exclude_usernames,
|
|
- username,
|
|
- match_name_cmpfunc);
|
|
- if (found != NULL) {
|
|
- ret = TRUE;
|
|
- }
|
|
- }
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static void
|
|
-add_session_for_user (GdmUserManager *manager,
|
|
- GdmUser *user,
|
|
- const char *ssid)
|
|
-{
|
|
- g_hash_table_insert (manager->priv->sessions,
|
|
- g_strdup (ssid),
|
|
- g_strdup (gdm_user_get_user_name (user)));
|
|
-
|
|
- _gdm_user_add_session (user, ssid);
|
|
- g_debug ("GdmUserManager: added session for user: %s", gdm_user_get_user_name (user));
|
|
-}
|
|
-
|
|
-static void
|
|
-set_has_multiple_users (GdmUserManager *manager,
|
|
- gboolean has_multiple_users)
|
|
-{
|
|
- if (manager->priv->has_multiple_users != has_multiple_users) {
|
|
- manager->priv->has_multiple_users = has_multiple_users;
|
|
- g_object_notify (G_OBJECT (manager), "has-multiple-users");
|
|
- }
|
|
-}
|
|
-
|
|
-static GdmUser *
|
|
-create_new_user (GdmUserManager *manager)
|
|
-{
|
|
- GdmUser *user;
|
|
-
|
|
- user = g_object_new (GDM_TYPE_USER, NULL);
|
|
-
|
|
- manager->priv->new_users = g_slist_prepend (manager->priv->new_users, user);
|
|
-
|
|
- g_signal_connect (user, "notify::is-loaded", G_CALLBACK (on_new_user_loaded), manager);
|
|
-
|
|
- return g_object_ref (user);
|
|
-}
|
|
-
|
|
-static void
|
|
-add_user (GdmUserManager *manager,
|
|
- GdmUser *user)
|
|
-{
|
|
- const char *object_path;
|
|
-
|
|
- g_hash_table_insert (manager->priv->users_by_name,
|
|
- g_strdup (gdm_user_get_user_name (user)),
|
|
- g_object_ref (user));
|
|
-
|
|
- object_path = gdm_user_get_object_path (user);
|
|
- if (object_path != NULL) {
|
|
- g_hash_table_insert (manager->priv->users_by_object_path,
|
|
- (gpointer) object_path,
|
|
- g_object_ref (user));
|
|
- }
|
|
-
|
|
- g_signal_connect (user,
|
|
- "sessions-changed",
|
|
- G_CALLBACK (on_user_sessions_changed),
|
|
- manager);
|
|
- g_signal_connect (user,
|
|
- "changed",
|
|
- G_CALLBACK (on_user_changed),
|
|
- manager);
|
|
-
|
|
- if (manager->priv->is_loaded) {
|
|
- g_signal_emit (manager, signals[USER_ADDED], 0, user);
|
|
- }
|
|
-
|
|
- if (g_hash_table_size (manager->priv->users_by_name) > 1) {
|
|
- set_has_multiple_users (manager, TRUE);
|
|
- }
|
|
-}
|
|
-
|
|
-static void
|
|
-remove_user (GdmUserManager *manager,
|
|
- GdmUser *user)
|
|
-{
|
|
- g_object_ref (user);
|
|
-
|
|
- g_signal_handlers_disconnect_by_func (user, on_user_changed, manager);
|
|
- g_signal_handlers_disconnect_by_func (user, on_user_sessions_changed, manager);
|
|
- if (gdm_user_get_object_path (user) != NULL) {
|
|
- g_hash_table_remove (manager->priv->users_by_object_path, gdm_user_get_object_path (user));
|
|
- }
|
|
- g_hash_table_remove (manager->priv->users_by_name, gdm_user_get_user_name (user));
|
|
-
|
|
- if (manager->priv->is_loaded) {
|
|
- g_signal_emit (manager, signals[USER_REMOVED], 0, user);
|
|
- }
|
|
-
|
|
- g_object_unref (user);
|
|
-
|
|
- if (g_hash_table_size (manager->priv->users_by_name) > 1) {
|
|
- set_has_multiple_users (manager, FALSE);
|
|
- }
|
|
-}
|
|
-
|
|
-static void
|
|
-on_new_user_loaded (GdmUser *user,
|
|
- GParamSpec *pspec,
|
|
- GdmUserManager *manager)
|
|
-{
|
|
- const char *username;
|
|
- GdmUser *old_user;
|
|
-
|
|
- if (!gdm_user_is_loaded (user)) {
|
|
- return;
|
|
- }
|
|
-
|
|
- g_signal_handlers_disconnect_by_func (user, on_new_user_loaded, manager);
|
|
- manager->priv->new_users = g_slist_remove (manager->priv->new_users,
|
|
- user);
|
|
-
|
|
- username = gdm_user_get_user_name (user);
|
|
-
|
|
- if (username == NULL) {
|
|
- const char *object_path;
|
|
-
|
|
- object_path = gdm_user_get_object_path (user);
|
|
-
|
|
- if (object_path != NULL) {
|
|
- g_warning ("GdmUserManager: user has no username "
|
|
- "(object path: %s, uid: %lu)",
|
|
- object_path, gdm_user_get_uid (user));
|
|
- } else {
|
|
- g_warning ("GdmUserManager: user has no username (uid: %lu)",
|
|
- gdm_user_get_uid (user));
|
|
- }
|
|
- g_object_unref (user);
|
|
- return;
|
|
- }
|
|
-
|
|
- if (username_in_exclude_list (manager, username)) {
|
|
- g_debug ("GdmUserManager: excluding user '%s'", username);
|
|
- g_object_unref (user);
|
|
- return;
|
|
- }
|
|
-
|
|
- old_user = g_hash_table_lookup (manager->priv->users_by_name, username);
|
|
-
|
|
- /* If username got added earlier by a different means, trump it now.
|
|
- */
|
|
- if (old_user != NULL) {
|
|
- remove_user (manager, old_user);
|
|
- }
|
|
-
|
|
- add_user (manager, user);
|
|
- g_object_unref (user);
|
|
-
|
|
- if (manager->priv->new_users == NULL) {
|
|
- set_is_loaded (manager, TRUE);
|
|
- }
|
|
-}
|
|
-
|
|
-static GdmUser *
|
|
-add_new_user_for_object_path (const char *object_path,
|
|
- GdmUserManager *manager)
|
|
-{
|
|
- GdmUser *user;
|
|
-
|
|
- user = g_hash_table_lookup (manager->priv->users_by_object_path, object_path);
|
|
-
|
|
- if (user != NULL) {
|
|
- return user;
|
|
- }
|
|
- user = create_new_user (manager);
|
|
- _gdm_user_update_from_object_path (user, object_path);
|
|
-
|
|
- return user;
|
|
-}
|
|
-
|
|
-static void
|
|
-on_new_user_in_accounts_service (DBusGProxy *proxy,
|
|
- const char *object_path,
|
|
- gpointer user_data)
|
|
-{
|
|
- GdmUserManager *manager = GDM_USER_MANAGER (user_data);
|
|
-
|
|
- add_new_user_for_object_path (object_path, manager);
|
|
-}
|
|
-
|
|
-static void
|
|
-on_user_removed_in_accounts_service (DBusGProxy *proxy,
|
|
- const char *object_path,
|
|
- gpointer user_data)
|
|
-{
|
|
- GdmUserManager *manager = GDM_USER_MANAGER (user_data);
|
|
- GdmUser *user;
|
|
-
|
|
- user = g_hash_table_lookup (manager->priv->users_by_object_path, object_path);
|
|
-
|
|
- manager->priv->new_users = g_slist_remove (manager->priv->new_users, user);
|
|
-
|
|
- remove_user (manager, user);
|
|
-}
|
|
-
|
|
-static void
|
|
-on_get_current_session_finished (DBusGProxy *proxy,
|
|
- DBusGProxyCall *call,
|
|
- GdmUserManager *manager)
|
|
-{
|
|
- GError *error;
|
|
- char *session_id;
|
|
- gboolean res;
|
|
-
|
|
- g_assert (manager->priv->seat.get_current_session_call == call);
|
|
- g_assert (manager->priv->seat.state == GDM_USER_MANAGER_SEAT_STATE_GET_SESSION_ID);
|
|
-
|
|
- error = NULL;
|
|
- session_id = NULL;
|
|
- res = dbus_g_proxy_end_call (proxy,
|
|
- call,
|
|
- &error,
|
|
- DBUS_TYPE_G_OBJECT_PATH,
|
|
- &session_id,
|
|
- G_TYPE_INVALID);
|
|
- manager->priv->seat.get_current_session_call = NULL;
|
|
- g_object_unref (proxy);
|
|
-
|
|
- if (! res) {
|
|
- if (error != NULL) {
|
|
- g_debug ("Failed to identify the current session: %s",
|
|
- error->message);
|
|
- g_error_free (error);
|
|
- } else {
|
|
- g_debug ("Failed to identify the current session");
|
|
- }
|
|
- unload_seat (manager);
|
|
- maybe_set_is_loaded (manager);
|
|
- return;
|
|
- }
|
|
-
|
|
- manager->priv->seat.session_id = session_id;
|
|
- manager->priv->seat.state++;
|
|
-
|
|
- load_seat_incrementally (manager);
|
|
-}
|
|
-
|
|
-static void
|
|
-get_current_session_id (GdmUserManager *manager)
|
|
-{
|
|
- DBusGProxy *proxy;
|
|
- DBusGProxyCall *call;
|
|
-
|
|
- proxy = dbus_g_proxy_new_for_name (manager->priv->connection,
|
|
- CK_NAME,
|
|
- CK_MANAGER_PATH,
|
|
- CK_MANAGER_INTERFACE);
|
|
- if (proxy == NULL) {
|
|
- g_warning ("Failed to connect to the ConsoleKit manager object");
|
|
- goto failed;
|
|
- }
|
|
-
|
|
- call = dbus_g_proxy_begin_call (proxy,
|
|
- "GetCurrentSession",
|
|
- (DBusGProxyCallNotify)
|
|
- on_get_current_session_finished,
|
|
- manager,
|
|
- NULL,
|
|
- G_TYPE_INVALID);
|
|
- if (call == NULL) {
|
|
- g_warning ("GdmUserManager: failed to make GetCurrentSession call");
|
|
- goto failed;
|
|
- }
|
|
-
|
|
- manager->priv->seat.get_current_session_call = call;
|
|
-
|
|
- return;
|
|
-
|
|
-failed:
|
|
- if (proxy != NULL) {
|
|
- g_object_unref (proxy);
|
|
- }
|
|
-
|
|
- unload_seat (manager);
|
|
-}
|
|
-
|
|
-static void
|
|
-unload_new_session (GdmUserManagerNewSession *new_session)
|
|
-{
|
|
- GdmUserManager *manager;
|
|
-
|
|
- manager = new_session->manager;
|
|
-
|
|
- manager->priv->new_sessions = g_slist_remove (manager->priv->new_sessions,
|
|
- new_session);
|
|
-
|
|
- if (new_session->proxy != NULL) {
|
|
- g_object_unref (new_session->proxy);
|
|
- }
|
|
-
|
|
- g_free (new_session->x11_display);
|
|
- g_free (new_session->id);
|
|
-
|
|
- g_slice_free (GdmUserManagerNewSession, new_session);
|
|
-}
|
|
-
|
|
-static void
|
|
-get_proxy_for_new_session (GdmUserManagerNewSession *new_session)
|
|
-{
|
|
- GdmUserManager *manager;
|
|
- DBusGProxy *proxy;
|
|
-
|
|
- manager = new_session->manager;
|
|
-
|
|
- proxy = dbus_g_proxy_new_for_name (manager->priv->connection,
|
|
- CK_NAME,
|
|
- new_session->id,
|
|
- CK_SESSION_INTERFACE);
|
|
- if (proxy == NULL) {
|
|
- g_warning ("Failed to connect to the ConsoleKit '%s' object",
|
|
- new_session->id);
|
|
- unload_new_session (new_session);
|
|
- return;
|
|
- }
|
|
-
|
|
- new_session->proxy = proxy;
|
|
- new_session->state++;
|
|
-
|
|
- load_new_session_incrementally (new_session);
|
|
-}
|
|
-
|
|
-static void
|
|
-on_get_unix_user_finished (DBusGProxy *proxy,
|
|
- DBusGProxyCall *call,
|
|
- GdmUserManagerNewSession *new_session)
|
|
-{
|
|
- GdmUserManager *manager;
|
|
- GError *error;
|
|
- guint uid;
|
|
- gboolean res;
|
|
-
|
|
- manager = new_session->manager;
|
|
-
|
|
- g_assert (new_session->get_unix_user_call == call);
|
|
-
|
|
- error = NULL;
|
|
-
|
|
- uid = (guint) -1;
|
|
- res = dbus_g_proxy_end_call (proxy,
|
|
- call,
|
|
- &error,
|
|
- G_TYPE_UINT, &uid,
|
|
- G_TYPE_INVALID);
|
|
- new_session->get_unix_user_call = NULL;
|
|
-
|
|
- if (! res) {
|
|
- if (error != NULL) {
|
|
- g_debug ("Failed to get uid of session '%s': %s",
|
|
- new_session->id, error->message);
|
|
- g_error_free (error);
|
|
- } else {
|
|
- g_debug ("Failed to get uid of session '%s'",
|
|
- new_session->id);
|
|
- }
|
|
- unload_new_session (new_session);
|
|
- return;
|
|
- }
|
|
-
|
|
- g_debug ("GdmUserManager: Found uid of session '%s': %u",
|
|
- new_session->id, uid);
|
|
-
|
|
- new_session->uid = (uid_t) uid;
|
|
- new_session->state++;
|
|
-
|
|
- load_new_session_incrementally (new_session);
|
|
-}
|
|
-
|
|
-static void
|
|
-get_uid_for_new_session (GdmUserManagerNewSession *new_session)
|
|
-{
|
|
- DBusGProxyCall *call;
|
|
-
|
|
- g_assert (new_session->proxy != NULL);
|
|
-
|
|
- call = dbus_g_proxy_begin_call (new_session->proxy,
|
|
- "GetUnixUser",
|
|
- (DBusGProxyCallNotify)
|
|
- on_get_unix_user_finished,
|
|
- new_session,
|
|
- NULL,
|
|
- G_TYPE_INVALID);
|
|
- if (call == NULL) {
|
|
- g_warning ("GdmUserManager: failed to make GetUnixUser call");
|
|
- goto failed;
|
|
- }
|
|
-
|
|
- new_session->get_unix_user_call = call;
|
|
- return;
|
|
-
|
|
-failed:
|
|
- unload_new_session (new_session);
|
|
-}
|
|
-
|
|
-static void
|
|
-on_find_user_by_name_finished (DBusGProxy *proxy,
|
|
- DBusGProxyCall *call,
|
|
- GdmUserManagerFetchUserRequest *request)
|
|
-{
|
|
- GdmUserManager *manager;
|
|
- GError *error;
|
|
- char *object_path;
|
|
- gboolean res;
|
|
-
|
|
- g_assert (request->call == call);
|
|
-
|
|
- error = NULL;
|
|
- object_path = NULL;
|
|
- manager = request->manager;
|
|
- res = dbus_g_proxy_end_call (manager->priv->accounts_proxy,
|
|
- call,
|
|
- &error,
|
|
- DBUS_TYPE_G_OBJECT_PATH,
|
|
- &object_path,
|
|
- G_TYPE_INVALID);
|
|
- if (! res) {
|
|
- if (error != NULL) {
|
|
- g_debug ("GdmUserManager: Failed to find user %s: %s",
|
|
- request->username, error->message);
|
|
- g_error_free (error);
|
|
- } else {
|
|
- g_debug ("GdmUserManager: Failed to find user %s",
|
|
- request->username);
|
|
- }
|
|
- give_up_and_fetch_user_locally (manager, request);
|
|
- return;
|
|
- }
|
|
-
|
|
- g_debug ("GdmUserManager: Found object path of user '%s': %s",
|
|
- request->username, object_path);
|
|
- request->object_path = object_path;
|
|
- request->state++;
|
|
-
|
|
- fetch_user_incrementally (request);
|
|
-}
|
|
-
|
|
-static void
|
|
-find_user_in_accounts_service (GdmUserManager *manager,
|
|
- GdmUserManagerFetchUserRequest *request)
|
|
-{
|
|
- DBusGProxyCall *call;
|
|
-
|
|
- g_debug ("GdmUserManager: Looking for user %s in accounts service",
|
|
- request->username);
|
|
-
|
|
- g_assert (manager->priv->accounts_proxy != NULL);
|
|
-
|
|
- call = dbus_g_proxy_begin_call (manager->priv->accounts_proxy,
|
|
- "FindUserByName",
|
|
- (DBusGProxyCallNotify)
|
|
- on_find_user_by_name_finished,
|
|
- request,
|
|
- NULL,
|
|
- G_TYPE_STRING,
|
|
- request->username,
|
|
- G_TYPE_INVALID);
|
|
-
|
|
- if (call == NULL) {
|
|
- g_warning ("GdmUserManager: failed to make FindUserByName('%s') call",
|
|
- request->username);
|
|
- goto failed;
|
|
- }
|
|
-
|
|
- request->call = call;
|
|
- return;
|
|
-
|
|
-failed:
|
|
- give_up_and_fetch_user_locally (manager, request);
|
|
-}
|
|
-
|
|
-static void
|
|
-set_is_loaded (GdmUserManager *manager,
|
|
- gboolean is_loaded)
|
|
-{
|
|
- if (manager->priv->is_loaded != is_loaded) {
|
|
- manager->priv->is_loaded = is_loaded;
|
|
- g_object_notify (G_OBJECT (manager), "is-loaded");
|
|
- }
|
|
-}
|
|
-
|
|
-static void
|
|
-on_list_cached_users_finished (DBusGProxy *proxy,
|
|
- DBusGProxyCall *call_id,
|
|
- gpointer data)
|
|
-{
|
|
- GdmUserManager *manager = data;
|
|
- GError *error = NULL;
|
|
- GPtrArray *paths;
|
|
-
|
|
- manager->priv->listing_cached_users = FALSE;
|
|
- if (!dbus_g_proxy_end_call (proxy,
|
|
- call_id,
|
|
- &error,
|
|
- dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &paths,
|
|
- G_TYPE_INVALID)) {
|
|
- g_debug ("GdmUserManager: ListCachedUsers failed: %s", error->message);
|
|
- g_error_free (error);
|
|
-
|
|
- g_object_unref (manager->priv->accounts_proxy);
|
|
- manager->priv->accounts_proxy = NULL;
|
|
-
|
|
- load_users_manually (manager);
|
|
-
|
|
- return;
|
|
- }
|
|
-
|
|
- maybe_set_is_loaded (manager);
|
|
-
|
|
- g_ptr_array_foreach (paths, (GFunc)add_new_user_for_object_path, manager);
|
|
-
|
|
- g_ptr_array_foreach (paths, (GFunc)g_free, NULL);
|
|
- g_ptr_array_free (paths, TRUE);
|
|
-
|
|
- /* Add users who are specifically included */
|
|
- if (manager->priv->include_usernames != NULL) {
|
|
- GSList *l;
|
|
-
|
|
- for (l = manager->priv->include_usernames; l != NULL; l = l->next) {
|
|
- GdmUser *user;
|
|
-
|
|
- g_debug ("GdmUserManager: Adding included user %s", (char *)l->data);
|
|
- /*
|
|
- * The call to gdm_user_manager_get_user will add the user if it is
|
|
- * valid and not already in the hash.
|
|
- */
|
|
- user = gdm_user_manager_get_user (manager, l->data);
|
|
- if (user == NULL) {
|
|
- g_debug ("GdmUserManager: unable to lookup user '%s'", (char *)l->data);
|
|
- }
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-static void
|
|
-on_get_x11_display_finished (DBusGProxy *proxy,
|
|
- DBusGProxyCall *call,
|
|
- GdmUserManagerNewSession *new_session)
|
|
-{
|
|
- GError *error;
|
|
- char *x11_display;
|
|
- gboolean res;
|
|
-
|
|
- g_assert (new_session->get_x11_display_call == call);
|
|
-
|
|
- error = NULL;
|
|
- x11_display = NULL;
|
|
- res = dbus_g_proxy_end_call (proxy,
|
|
- call,
|
|
- &error,
|
|
- G_TYPE_STRING,
|
|
- &x11_display,
|
|
- G_TYPE_INVALID);
|
|
- new_session->get_x11_display_call = NULL;
|
|
-
|
|
- if (! res) {
|
|
- if (error != NULL) {
|
|
- g_debug ("Failed to get the x11 display of session '%s': %s",
|
|
- new_session->id, error->message);
|
|
- g_error_free (error);
|
|
- } else {
|
|
- g_debug ("Failed to get the x11 display of session '%s'",
|
|
- new_session->id);
|
|
- }
|
|
- unload_new_session (new_session);
|
|
- return;
|
|
- }
|
|
-
|
|
- g_debug ("GdmUserManager: Found x11 display of session '%s': %s",
|
|
- new_session->id, x11_display);
|
|
-
|
|
- new_session->x11_display = x11_display;
|
|
- new_session->state++;
|
|
-
|
|
- load_new_session_incrementally (new_session);
|
|
-}
|
|
-
|
|
-static void
|
|
-get_x11_display_for_new_session (GdmUserManagerNewSession *new_session)
|
|
-{
|
|
- DBusGProxyCall *call;
|
|
-
|
|
- g_assert (new_session->proxy != NULL);
|
|
-
|
|
- call = dbus_g_proxy_begin_call (new_session->proxy,
|
|
- "GetX11Display",
|
|
- (DBusGProxyCallNotify)
|
|
- on_get_x11_display_finished,
|
|
- new_session,
|
|
- NULL,
|
|
- G_TYPE_INVALID);
|
|
- if (call == NULL) {
|
|
- g_warning ("GdmUserManager: failed to make GetX11Display call");
|
|
- goto failed;
|
|
- }
|
|
-
|
|
- new_session->get_x11_display_call = call;
|
|
- return;
|
|
-
|
|
-failed:
|
|
- unload_new_session (new_session);
|
|
-}
|
|
-
|
|
-static gboolean
|
|
-get_pwent_for_name (const char *name,
|
|
- struct passwd **pwentp)
|
|
-{
|
|
- struct passwd *pwent;
|
|
-
|
|
- do {
|
|
- errno = 0;
|
|
- pwent = getpwnam (name);
|
|
- } while (pwent == NULL && errno == EINTR);
|
|
-
|
|
- if (pwentp != NULL) {
|
|
- *pwentp = pwent;
|
|
- }
|
|
-
|
|
- return (pwent != NULL);
|
|
-}
|
|
-
|
|
-static gboolean
|
|
-get_pwent_for_uid (uid_t uid,
|
|
- struct passwd **pwentp)
|
|
-{
|
|
- struct passwd *pwent;
|
|
-
|
|
- do {
|
|
- errno = 0;
|
|
- pwent = getpwuid (uid);
|
|
- } while (pwent == NULL && errno == EINTR);
|
|
-
|
|
- if (pwentp != NULL) {
|
|
- *pwentp = pwent;
|
|
- }
|
|
-
|
|
- return (pwent != NULL);
|
|
-}
|
|
-
|
|
-static void
|
|
-maybe_add_new_session (GdmUserManagerNewSession *new_session)
|
|
-{
|
|
- GdmUserManager *manager;
|
|
- struct passwd *pwent;
|
|
- GdmUser *user;
|
|
-
|
|
- manager = GDM_USER_MANAGER (new_session->manager);
|
|
-
|
|
- errno = 0;
|
|
- get_pwent_for_uid (new_session->uid, &pwent);
|
|
- if (pwent == NULL) {
|
|
- g_warning ("Unable to lookup user ID %d: %s",
|
|
- (int) new_session->uid, g_strerror (errno));
|
|
- goto failed;
|
|
- }
|
|
-
|
|
- /* check exclusions up front */
|
|
- if (username_in_exclude_list (manager, pwent->pw_name)) {
|
|
- g_debug ("GdmUserManager: excluding user '%s'", pwent->pw_name);
|
|
- goto failed;
|
|
- }
|
|
-
|
|
- user = gdm_user_manager_get_user (manager, pwent->pw_name);
|
|
- if (user == NULL) {
|
|
- return;
|
|
- }
|
|
-
|
|
- add_session_for_user (manager, user, new_session->id);
|
|
-
|
|
- /* if we haven't yet gotten the login frequency
|
|
- then at least add one because the session exists */
|
|
- if (gdm_user_get_login_frequency (user) == 0) {
|
|
- _gdm_user_update_login_frequency (user, 1);
|
|
- }
|
|
-
|
|
- manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_LOADED;
|
|
- unload_new_session (new_session);
|
|
- return;
|
|
-
|
|
-failed:
|
|
- unload_new_session (new_session);
|
|
-}
|
|
-
|
|
-static void
|
|
-load_new_session (GdmUserManager *manager,
|
|
- const char *session_id)
|
|
-{
|
|
- GdmUserManagerNewSession *new_session;
|
|
-
|
|
- new_session = g_slice_new0 (GdmUserManagerNewSession);
|
|
-
|
|
- new_session->manager = manager;
|
|
- new_session->id = g_strdup (session_id);
|
|
- new_session->state = GDM_USER_MANAGER_NEW_SESSION_STATE_UNLOADED + 1;
|
|
-
|
|
- manager->priv->new_sessions = g_slist_prepend (manager->priv->new_sessions,
|
|
- new_session);
|
|
- load_new_session_incrementally (new_session);
|
|
-}
|
|
-
|
|
-static void
|
|
-seat_session_added (DBusGProxy *seat_proxy,
|
|
- const char *session_id,
|
|
- GdmUserManager *manager)
|
|
-{
|
|
- g_debug ("GdmUserManager: Session added: %s", session_id);
|
|
-
|
|
- load_new_session (manager, session_id);
|
|
-}
|
|
-
|
|
-static gint
|
|
-match_new_session_cmpfunc (gconstpointer a,
|
|
- gconstpointer b)
|
|
-{
|
|
- GdmUserManagerNewSession *new_session;
|
|
- const char *session_id;
|
|
-
|
|
- new_session = (GdmUserManagerNewSession *) a;
|
|
- session_id = (const char *) b;
|
|
-
|
|
- return strcmp (new_session->id, session_id);
|
|
-}
|
|
-
|
|
-static void
|
|
-seat_session_removed (DBusGProxy *seat_proxy,
|
|
- const char *session_id,
|
|
- GdmUserManager *manager)
|
|
-{
|
|
- GdmUser *user;
|
|
- GSList *found;
|
|
- char *username;
|
|
-
|
|
- g_debug ("GdmUserManager: Session removed: %s", session_id);
|
|
-
|
|
- found = g_slist_find_custom (manager->priv->new_sessions,
|
|
- session_id,
|
|
- match_new_session_cmpfunc);
|
|
-
|
|
- if (found != NULL) {
|
|
- GdmUserManagerNewSession *new_session;
|
|
-
|
|
- new_session = (GdmUserManagerNewSession *) found->data;
|
|
-
|
|
- if (new_session->state > GDM_USER_MANAGER_NEW_SESSION_STATE_GET_X11_DISPLAY) {
|
|
- g_debug ("GdmUserManager: New session for uid %d on "
|
|
- "x11 display %s removed before fully loading",
|
|
- (int) new_session->uid, new_session->x11_display);
|
|
- } else if (new_session->state > GDM_USER_MANAGER_NEW_SESSION_STATE_GET_UID) {
|
|
- g_debug ("GdmUserManager: New session for uid %d "
|
|
- "removed before fully loading",
|
|
- (int) new_session->uid);
|
|
- } else {
|
|
- g_debug ("GdmUserManager: New session removed "
|
|
- "before fully loading");
|
|
- }
|
|
- unload_new_session (new_session);
|
|
- return;
|
|
- }
|
|
-
|
|
- /* since the session object may already be gone
|
|
- * we can't query CK directly */
|
|
-
|
|
- username = g_hash_table_lookup (manager->priv->sessions, session_id);
|
|
- if (username == NULL) {
|
|
- return;
|
|
- }
|
|
-
|
|
- user = g_hash_table_lookup (manager->priv->users_by_name, username);
|
|
- if (user == NULL) {
|
|
- /* nothing to do */
|
|
- return;
|
|
- }
|
|
-
|
|
- g_debug ("GdmUserManager: Session removed for %s", username);
|
|
- _gdm_user_remove_session (user, session_id);
|
|
-}
|
|
-
|
|
-static void
|
|
-on_seat_proxy_destroy (DBusGProxy *proxy,
|
|
- GdmUserManager *manager)
|
|
-{
|
|
- g_debug ("GdmUserManager: seat proxy destroyed");
|
|
-
|
|
- manager->priv->seat.proxy = NULL;
|
|
-}
|
|
-
|
|
-static void
|
|
-get_seat_proxy (GdmUserManager *manager)
|
|
-{
|
|
- DBusGProxy *proxy;
|
|
- GError *error;
|
|
-
|
|
- g_assert (manager->priv->seat.proxy == NULL);
|
|
-
|
|
- error = NULL;
|
|
- proxy = dbus_g_proxy_new_for_name_owner (manager->priv->connection,
|
|
- CK_NAME,
|
|
- manager->priv->seat.id,
|
|
- CK_SEAT_INTERFACE,
|
|
- &error);
|
|
-
|
|
- if (proxy == NULL) {
|
|
- if (error != NULL) {
|
|
- g_warning ("Failed to connect to the ConsoleKit seat object: %s",
|
|
- error->message);
|
|
- g_error_free (error);
|
|
- } else {
|
|
- g_warning ("Failed to connect to the ConsoleKit seat object");
|
|
- }
|
|
- unload_seat (manager);
|
|
- return;
|
|
- }
|
|
-
|
|
- g_signal_connect (proxy, "destroy", G_CALLBACK (on_seat_proxy_destroy), manager);
|
|
-
|
|
- dbus_g_proxy_add_signal (proxy,
|
|
- "SessionAdded",
|
|
- DBUS_TYPE_G_OBJECT_PATH,
|
|
- G_TYPE_INVALID);
|
|
- dbus_g_proxy_add_signal (proxy,
|
|
- "SessionRemoved",
|
|
- DBUS_TYPE_G_OBJECT_PATH,
|
|
- G_TYPE_INVALID);
|
|
- dbus_g_proxy_connect_signal (proxy,
|
|
- "SessionAdded",
|
|
- G_CALLBACK (seat_session_added),
|
|
- manager,
|
|
- NULL);
|
|
- dbus_g_proxy_connect_signal (proxy,
|
|
- "SessionRemoved",
|
|
- G_CALLBACK (seat_session_removed),
|
|
- manager,
|
|
- NULL);
|
|
- manager->priv->seat.proxy = proxy;
|
|
- manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_LOADED;
|
|
-}
|
|
-
|
|
-static void
|
|
-unload_seat (GdmUserManager *manager)
|
|
-{
|
|
- manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_UNLOADED;
|
|
-
|
|
- if (manager->priv->seat.proxy != NULL) {
|
|
- g_object_unref (manager->priv->seat.proxy);
|
|
- manager->priv->seat.proxy = NULL;
|
|
- }
|
|
-
|
|
- g_free (manager->priv->seat.id);
|
|
- manager->priv->seat.id = NULL;
|
|
-
|
|
- g_free (manager->priv->seat.session_id);
|
|
- manager->priv->seat.session_id = NULL;
|
|
-}
|
|
-
|
|
-static void
|
|
-get_accounts_proxy (GdmUserManager *manager)
|
|
-{
|
|
- DBusGProxy *proxy;
|
|
- GError *error;
|
|
-
|
|
- g_assert (manager->priv->accounts_proxy == NULL);
|
|
-
|
|
- error = NULL;
|
|
- proxy = dbus_g_proxy_new_for_name (manager->priv->connection,
|
|
- ACCOUNTS_NAME,
|
|
- ACCOUNTS_PATH,
|
|
- ACCOUNTS_INTERFACE);
|
|
- manager->priv->accounts_proxy = proxy;
|
|
-
|
|
- dbus_g_proxy_add_signal (proxy,
|
|
- "UserAdded",
|
|
- DBUS_TYPE_G_OBJECT_PATH,
|
|
- G_TYPE_INVALID);
|
|
- dbus_g_proxy_add_signal (proxy,
|
|
- "UserDeleted",
|
|
- DBUS_TYPE_G_OBJECT_PATH,
|
|
- G_TYPE_INVALID);
|
|
-
|
|
- dbus_g_proxy_connect_signal (proxy,
|
|
- "UserAdded",
|
|
- G_CALLBACK (on_new_user_in_accounts_service),
|
|
- manager,
|
|
- NULL);
|
|
- dbus_g_proxy_connect_signal (proxy,
|
|
- "UserDeleted",
|
|
- G_CALLBACK (on_user_removed_in_accounts_service),
|
|
- manager,
|
|
- NULL);
|
|
-}
|
|
-
|
|
-static void
|
|
-load_new_session_incrementally (GdmUserManagerNewSession *new_session)
|
|
-{
|
|
- switch (new_session->state) {
|
|
- case GDM_USER_MANAGER_NEW_SESSION_STATE_GET_PROXY:
|
|
- get_proxy_for_new_session (new_session);
|
|
- break;
|
|
- case GDM_USER_MANAGER_NEW_SESSION_STATE_GET_UID:
|
|
- get_uid_for_new_session (new_session);
|
|
- break;
|
|
- case GDM_USER_MANAGER_NEW_SESSION_STATE_GET_X11_DISPLAY:
|
|
- get_x11_display_for_new_session (new_session);
|
|
- break;
|
|
- case GDM_USER_MANAGER_NEW_SESSION_STATE_MAYBE_ADD:
|
|
- maybe_add_new_session (new_session);
|
|
- break;
|
|
- case GDM_USER_MANAGER_NEW_SESSION_STATE_LOADED:
|
|
- break;
|
|
- default:
|
|
- g_assert_not_reached ();
|
|
- }
|
|
-}
|
|
-
|
|
-static void
|
|
-free_fetch_user_request (GdmUserManagerFetchUserRequest *request)
|
|
-{
|
|
- GdmUserManager *manager;
|
|
-
|
|
- manager = request->manager;
|
|
-
|
|
- manager->priv->fetch_user_requests = g_slist_remove (manager->priv->fetch_user_requests, request);
|
|
- g_free (request->username);
|
|
- g_free (request->object_path);
|
|
- g_slice_free (GdmUserManagerFetchUserRequest, request);
|
|
-}
|
|
-
|
|
-static void
|
|
-give_up_and_fetch_user_locally (GdmUserManager *manager,
|
|
- GdmUserManagerFetchUserRequest *request)
|
|
-{
|
|
-
|
|
- g_debug ("GdmUserManager: account service unavailable, "
|
|
- "fetching user %s locally",
|
|
- request->username);
|
|
- fetch_user_locally (manager, request->user, request->username);
|
|
- request->state = GDM_USER_MANAGER_GET_USER_STATE_UNFETCHED;
|
|
-}
|
|
-
|
|
-static void
|
|
-on_user_manager_maybe_ready_for_request (GdmUserManager *manager,
|
|
- GParamSpec *pspec,
|
|
- GdmUserManagerFetchUserRequest *request)
|
|
-{
|
|
- if (!manager->priv->is_loaded) {
|
|
- return;
|
|
- }
|
|
-
|
|
- g_signal_handlers_disconnect_by_func (manager, on_user_manager_maybe_ready_for_request, request);
|
|
-
|
|
- request->state++;
|
|
- fetch_user_incrementally (request);
|
|
-}
|
|
-
|
|
-static void
|
|
-fetch_user_incrementally (GdmUserManagerFetchUserRequest *request)
|
|
-{
|
|
- GdmUserManager *manager;
|
|
-
|
|
- g_debug ("GdmUserManager: finding user %s state %d",
|
|
- request->username, request->state);
|
|
- manager = request->manager;
|
|
- switch (request->state) {
|
|
- case GDM_USER_MANAGER_GET_USER_STATE_WAIT_FOR_LOADED:
|
|
- if (manager->priv->is_loaded) {
|
|
- request->state++;
|
|
- fetch_user_incrementally (request);
|
|
- } else {
|
|
- g_debug ("GdmUserManager: waiting for user manager to load before finding user %s",
|
|
- request->username);
|
|
- g_signal_connect (manager, "notify::is-loaded",
|
|
- G_CALLBACK (on_user_manager_maybe_ready_for_request), request);
|
|
-
|
|
- }
|
|
- break;
|
|
-
|
|
- case GDM_USER_MANAGER_GET_USER_STATE_ASK_ACCOUNTS_SERVICE:
|
|
- if (manager->priv->accounts_proxy == NULL) {
|
|
- give_up_and_fetch_user_locally (manager, request);
|
|
- } else {
|
|
- find_user_in_accounts_service (manager, request);
|
|
- }
|
|
- break;
|
|
- case GDM_USER_MANAGER_GET_USER_STATE_FETCHED:
|
|
- g_debug ("GdmUserManager: user %s fetched", request->username);
|
|
- _gdm_user_update_from_object_path (request->user, request->object_path);
|
|
- break;
|
|
- case GDM_USER_MANAGER_GET_USER_STATE_UNFETCHED:
|
|
- g_debug ("GdmUserManager: user %s was not fetched", request->username);
|
|
- break;
|
|
- default:
|
|
- g_assert_not_reached ();
|
|
- }
|
|
-
|
|
- if (request->state == GDM_USER_MANAGER_GET_USER_STATE_FETCHED ||
|
|
- request->state == GDM_USER_MANAGER_GET_USER_STATE_UNFETCHED) {
|
|
- g_debug ("GdmUserManager: finished handling request for user %s",
|
|
- request->username);
|
|
- free_fetch_user_request (request);
|
|
- }
|
|
-}
|
|
-
|
|
-static void
|
|
-fetch_user_from_accounts_service (GdmUserManager *manager,
|
|
- GdmUser *user,
|
|
- const char *username)
|
|
-{
|
|
- GdmUserManagerFetchUserRequest *request;
|
|
-
|
|
- request = g_slice_new0 (GdmUserManagerFetchUserRequest);
|
|
-
|
|
- request->manager = manager;
|
|
- request->username = g_strdup (username);
|
|
- request->user = user;
|
|
- request->state = GDM_USER_MANAGER_GET_USER_STATE_UNFETCHED + 1;
|
|
-
|
|
- manager->priv->fetch_user_requests = g_slist_prepend (manager->priv->fetch_user_requests,
|
|
- request);
|
|
- fetch_user_incrementally (request);
|
|
-}
|
|
-
|
|
-static void
|
|
-fetch_user_locally (GdmUserManager *manager,
|
|
- GdmUser *user,
|
|
- const char *username)
|
|
-{
|
|
- struct passwd *pwent;
|
|
-
|
|
- get_pwent_for_name (username, &pwent);
|
|
-
|
|
- if (pwent != NULL) {
|
|
- _gdm_user_update_from_pwent (user, pwent);
|
|
- }
|
|
-}
|
|
-
|
|
-/**
|
|
- * gdm_user_manager_get_user:
|
|
- * @manager: the manager to query.
|
|
- * @username: the login name of the user to get.
|
|
- *
|
|
- * Retrieves a pointer to the #GdmUser object for the login @username
|
|
- * from @manager. Trying to use this object before its
|
|
- * #GdmUser:is-loaded property is %TRUE will result in undefined
|
|
- * behavior.
|
|
- *
|
|
- * Returns: (transfer none): #GdmUser object
|
|
- **/
|
|
-GdmUser *
|
|
-gdm_user_manager_get_user (GdmUserManager *manager,
|
|
- const char *username)
|
|
-{
|
|
- GdmUser *user;
|
|
-
|
|
- g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), NULL);
|
|
- g_return_val_if_fail (username != NULL && username[0] != '\0', NULL);
|
|
-
|
|
- user = g_hash_table_lookup (manager->priv->users_by_name, username);
|
|
-
|
|
- /* if we don't have it loaded try to load it now */
|
|
- if (user == NULL) {
|
|
- user = create_new_user (manager);
|
|
-
|
|
- if (manager->priv->accounts_proxy != NULL) {
|
|
- fetch_user_from_accounts_service (manager, user, username);
|
|
- } else {
|
|
- fetch_user_locally (manager, user, username);
|
|
- }
|
|
- }
|
|
-
|
|
- return user;
|
|
-}
|
|
-
|
|
-/**
|
|
- * gdm_user_manager_get_user_by_uid:
|
|
- * @manager: the manager to query.
|
|
- * @uid: the uid of the user to get.
|
|
- *
|
|
- * Retrieves a pointer to the #GdmUser object for the uid @uid
|
|
- * from @manager. Trying to use this object before its
|
|
- * #GdmUser:is-loaded property is %TRUE will result in undefined
|
|
- * behavior.
|
|
- *
|
|
- * Returns: (transfer none): #GdmUser object
|
|
- */
|
|
-GdmUser *
|
|
-gdm_user_manager_get_user_by_uid (GdmUserManager *manager,
|
|
- gulong uid)
|
|
-{
|
|
- struct passwd *pwent;
|
|
-
|
|
- g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), NULL);
|
|
-
|
|
- get_pwent_for_uid (uid, &pwent);
|
|
- if (pwent == NULL) {
|
|
- g_warning ("GdmUserManager: unable to lookup uid %d", (int)uid);
|
|
- return NULL;
|
|
- }
|
|
-
|
|
- return gdm_user_manager_get_user (manager, pwent->pw_name);
|
|
-}
|
|
-
|
|
-static void
|
|
-listify_hash_values_hfunc (gpointer key,
|
|
- gpointer value,
|
|
- gpointer user_data)
|
|
-{
|
|
- GSList **list = user_data;
|
|
-
|
|
- *list = g_slist_prepend (*list, value);
|
|
-}
|
|
-
|
|
-/**
|
|
- * gdm_user_manager_list_users:
|
|
- * @manager: a #GdmUserManager
|
|
- *
|
|
- * Get a list of system user accounts
|
|
- *
|
|
- * Returns: (element-type GdmUser) (transfer full): List of #GdmUser objects
|
|
- */
|
|
-GSList *
|
|
-gdm_user_manager_list_users (GdmUserManager *manager)
|
|
-{
|
|
- GSList *retval;
|
|
-
|
|
- g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), NULL);
|
|
-
|
|
- retval = NULL;
|
|
- g_hash_table_foreach (manager->priv->users_by_name, listify_hash_values_hfunc, &retval);
|
|
-
|
|
- return g_slist_sort (retval, (GCompareFunc) gdm_user_collate);
|
|
-}
|
|
-
|
|
-static gboolean
|
|
-parse_value_as_ulong (const char *value,
|
|
- gulong *ulongval)
|
|
-{
|
|
- char *end_of_valid_long;
|
|
- glong long_value;
|
|
- gulong ulong_value;
|
|
-
|
|
- errno = 0;
|
|
- long_value = strtol (value, &end_of_valid_long, 10);
|
|
-
|
|
- if (*value == '\0' || *end_of_valid_long != '\0') {
|
|
- return FALSE;
|
|
- }
|
|
-
|
|
- ulong_value = long_value;
|
|
- if (ulong_value != long_value || errno == ERANGE) {
|
|
- return FALSE;
|
|
- }
|
|
-
|
|
- *ulongval = ulong_value;
|
|
-
|
|
- return TRUE;
|
|
-}
|
|
-
|
|
-static gboolean
|
|
-parse_ck_history_line (const char *line,
|
|
- char **user_namep,
|
|
- gulong *frequencyp)
|
|
-{
|
|
- GRegex *re;
|
|
- GMatchInfo *match_info;
|
|
- gboolean res;
|
|
- gboolean ret;
|
|
- GError *error;
|
|
-
|
|
- ret = FALSE;
|
|
- re = NULL;
|
|
- match_info = NULL;
|
|
-
|
|
- error = NULL;
|
|
- re = g_regex_new ("(?P<username>[0-9a-zA-Z]+)[ ]+(?P<frequency>[0-9]+)", 0, 0, &error);
|
|
- if (re == NULL) {
|
|
- if (error != NULL) {
|
|
- g_critical ("%s", error->message);
|
|
- } else {
|
|
- g_critical ("Error in regex call");
|
|
- }
|
|
- goto out;
|
|
- }
|
|
-
|
|
- g_regex_match (re, line, 0, &match_info);
|
|
-
|
|
- res = g_match_info_matches (match_info);
|
|
- if (! res) {
|
|
- g_warning ("Unable to parse history: %s", line);
|
|
- goto out;
|
|
- }
|
|
-
|
|
- if (user_namep != NULL) {
|
|
- *user_namep = g_match_info_fetch_named (match_info, "username");
|
|
- }
|
|
-
|
|
- if (frequencyp != NULL) {
|
|
- char *freq;
|
|
- freq = g_match_info_fetch_named (match_info, "frequency");
|
|
- res = parse_value_as_ulong (freq, frequencyp);
|
|
- g_free (freq);
|
|
- if (! res) {
|
|
- goto out;
|
|
- }
|
|
- }
|
|
-
|
|
- ret = TRUE;
|
|
-
|
|
- out:
|
|
- if (match_info != NULL) {
|
|
- g_match_info_free (match_info);
|
|
- }
|
|
- if (re != NULL) {
|
|
- g_regex_unref (re);
|
|
- }
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static void
|
|
-process_ck_history_line (GdmUserManager *manager,
|
|
- const char *line)
|
|
-{
|
|
- gboolean res;
|
|
- char *username;
|
|
- gulong frequency;
|
|
- GdmUser *user;
|
|
-
|
|
- frequency = 0;
|
|
- username = NULL;
|
|
- res = parse_ck_history_line (line, &username, &frequency);
|
|
- if (! res) {
|
|
- return;
|
|
- }
|
|
-
|
|
- if (username_in_exclude_list (manager, username)) {
|
|
- g_debug ("GdmUserManager: excluding user '%s'", username);
|
|
- g_free (username);
|
|
- return;
|
|
- }
|
|
-
|
|
- user = gdm_user_manager_get_user (manager, username);
|
|
- if (user == NULL) {
|
|
- g_debug ("GdmUserManager: unable to lookup user '%s'", username);
|
|
- g_free (username);
|
|
- return;
|
|
- }
|
|
-
|
|
- _gdm_user_update_login_frequency (user, frequency);
|
|
- g_free (username);
|
|
-}
|
|
-
|
|
-static void
|
|
-maybe_set_is_loaded (GdmUserManager *manager)
|
|
-{
|
|
- if (manager->priv->is_loaded) {
|
|
- return;
|
|
- }
|
|
-
|
|
- if (manager->priv->ck_history_pid != 0) {
|
|
- return;
|
|
- }
|
|
-
|
|
- if (manager->priv->load_passwd_pending) {
|
|
- return;
|
|
- }
|
|
-
|
|
- if (manager->priv->get_sessions_call != NULL) {
|
|
- return;
|
|
- }
|
|
-
|
|
- if (manager->priv->listing_cached_users) {
|
|
- return;
|
|
- }
|
|
-
|
|
- /* Don't set is_loaded yet unless the seat is already loaded
|
|
- * or failed to load.
|
|
- */
|
|
- if (manager->priv->seat.state != GDM_USER_MANAGER_SEAT_STATE_LOADED
|
|
- && manager->priv->seat.state != GDM_USER_MANAGER_SEAT_STATE_UNLOADED) {
|
|
- return;
|
|
- }
|
|
-
|
|
- set_is_loaded (manager, TRUE);
|
|
-}
|
|
-
|
|
-static gboolean
|
|
-ck_history_watch (GIOChannel *source,
|
|
- GIOCondition condition,
|
|
- GdmUserManager *manager)
|
|
-{
|
|
- GIOStatus status;
|
|
- gboolean done = FALSE;
|
|
-
|
|
- g_return_val_if_fail (manager != NULL, FALSE);
|
|
-
|
|
- if (condition & G_IO_IN) {
|
|
- char *str;
|
|
- GError *error;
|
|
-
|
|
- error = NULL;
|
|
- status = g_io_channel_read_line (source, &str, NULL, NULL, &error);
|
|
- if (error != NULL) {
|
|
- g_warning ("GdmUserManager: unable to read line: %s", error->message);
|
|
- g_error_free (error);
|
|
- }
|
|
-
|
|
- if (status == G_IO_STATUS_NORMAL) {
|
|
- g_debug ("GdmUserManager: history output: %s", str);
|
|
- process_ck_history_line (manager, str);
|
|
- } else if (status == G_IO_STATUS_EOF) {
|
|
- done = TRUE;
|
|
- }
|
|
-
|
|
- g_free (str);
|
|
- } else if (condition & G_IO_HUP) {
|
|
- done = TRUE;
|
|
- }
|
|
-
|
|
- if (done) {
|
|
- manager->priv->ck_history_id = 0;
|
|
- if (manager->priv->ck_history_watchdog_id != 0) {
|
|
- g_source_remove (manager->priv->ck_history_watchdog_id);
|
|
- manager->priv->ck_history_watchdog_id = 0;
|
|
- }
|
|
- manager->priv->ck_history_pid = 0;
|
|
-
|
|
- maybe_set_is_loaded (manager);
|
|
-
|
|
- return FALSE;
|
|
- }
|
|
-
|
|
- return TRUE;
|
|
-}
|
|
-
|
|
-static int
|
|
-signal_pid (int pid,
|
|
- int signal)
|
|
-{
|
|
- int status = -1;
|
|
-
|
|
- status = kill (pid, signal);
|
|
-
|
|
- if (status < 0) {
|
|
- if (errno == ESRCH) {
|
|
- g_debug ("Child process %lu was already dead.",
|
|
- (unsigned long) pid);
|
|
- } else {
|
|
- char buf [1024];
|
|
- snprintf (buf,
|
|
- sizeof (buf),
|
|
- "Couldn't kill child process %lu",
|
|
- (unsigned long) pid);
|
|
- perror (buf);
|
|
- }
|
|
- }
|
|
-
|
|
- return status;
|
|
-}
|
|
-
|
|
-static gboolean
|
|
-ck_history_watchdog (GdmUserManager *manager)
|
|
-{
|
|
- if (manager->priv->ck_history_pid > 0) {
|
|
- g_debug ("Killing ck-history process");
|
|
- signal_pid (manager->priv->ck_history_pid, SIGTERM);
|
|
- manager->priv->ck_history_pid = 0;
|
|
- }
|
|
-
|
|
- manager->priv->ck_history_watchdog_id = 0;
|
|
- return FALSE;
|
|
-}
|
|
-
|
|
-static gboolean
|
|
-load_ck_history (GdmUserManager *manager)
|
|
-{
|
|
- char *command;
|
|
- char *since;
|
|
- const char *seat_id;
|
|
- GError *error;
|
|
- gboolean res;
|
|
- char **argv;
|
|
- int standard_out;
|
|
- GIOChannel *channel;
|
|
- GTimeVal tv;
|
|
-
|
|
- g_assert (manager->priv->ck_history_id == 0);
|
|
-
|
|
- command = NULL;
|
|
-
|
|
- seat_id = NULL;
|
|
- if (manager->priv->seat.id != NULL
|
|
- && g_str_has_prefix (manager->priv->seat.id, "/org/freedesktop/ConsoleKit/")) {
|
|
-
|
|
- seat_id = manager->priv->seat.id + strlen ("/org/freedesktop/ConsoleKit/");
|
|
- }
|
|
-
|
|
- if (seat_id == NULL) {
|
|
- g_warning ("Unable to load CK history: no seat-id found");
|
|
- goto out;
|
|
- }
|
|
-
|
|
- g_get_current_time (&tv);
|
|
- tv.tv_sec -= LOGIN_FREQUENCY_TIME_WINDOW_SECS;
|
|
- since = g_time_val_to_iso8601 (&tv);
|
|
-
|
|
- command = g_strdup_printf ("ck-history --frequent --since='%s' --seat='%s' --session-type=''",
|
|
- since,
|
|
- seat_id);
|
|
- g_free (since);
|
|
- g_debug ("GdmUserManager: running '%s'", command);
|
|
- error = NULL;
|
|
- if (! g_shell_parse_argv (command, NULL, &argv, &error)) {
|
|
- if (error != NULL) {
|
|
- g_warning ("Could not parse command: %s", error->message);
|
|
- g_error_free (error);
|
|
- } else {
|
|
- g_warning ("Could not parse command");
|
|
- }
|
|
- goto out;
|
|
- }
|
|
-
|
|
- error = NULL;
|
|
- res = g_spawn_async_with_pipes (NULL,
|
|
- argv,
|
|
- NULL,
|
|
- G_SPAWN_SEARCH_PATH,
|
|
- NULL,
|
|
- NULL,
|
|
- &manager->priv->ck_history_pid, /* pid */
|
|
- NULL,
|
|
- &standard_out,
|
|
- NULL,
|
|
- &error);
|
|
- g_strfreev (argv);
|
|
- if (! res) {
|
|
- if (error != NULL) {
|
|
- g_warning ("Unable to run ck-history: %s", error->message);
|
|
- g_error_free (error);
|
|
- } else {
|
|
- g_warning ("Unable to run ck-history");
|
|
- }
|
|
- goto out;
|
|
- }
|
|
-
|
|
- channel = g_io_channel_unix_new (standard_out);
|
|
- g_io_channel_set_close_on_unref (channel, TRUE);
|
|
- g_io_channel_set_flags (channel,
|
|
- g_io_channel_get_flags (channel) | G_IO_FLAG_NONBLOCK,
|
|
- NULL);
|
|
- manager->priv->ck_history_watchdog_id = g_timeout_add_seconds (1, (GSourceFunc) ck_history_watchdog, manager);
|
|
- manager->priv->ck_history_id = g_io_add_watch (channel,
|
|
- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
|
|
- (GIOFunc)ck_history_watch,
|
|
- manager);
|
|
- g_io_channel_unref (channel);
|
|
-
|
|
- out:
|
|
-
|
|
- g_free (command);
|
|
-
|
|
- return manager->priv->ck_history_id != 0;
|
|
-}
|
|
-
|
|
-static void
|
|
-reload_passwd_file (GHashTable *valid_shells,
|
|
- GSList *exclude_users,
|
|
- GSList *include_users,
|
|
- gboolean include_all,
|
|
- GHashTable *current_users_by_name,
|
|
- GSList **added_users,
|
|
- GSList **removed_users)
|
|
-{
|
|
- FILE *fp;
|
|
- GHashTableIter iter;
|
|
- GHashTable *new_users_by_name;
|
|
- GdmUser *user;
|
|
- char *name;
|
|
-
|
|
- new_users_by_name = g_hash_table_new_full (g_str_hash,
|
|
- g_str_equal,
|
|
- NULL,
|
|
- g_object_unref);
|
|
-
|
|
- errno = 0;
|
|
- fp = fopen (PATH_PASSWD, "r");
|
|
- if (fp == NULL) {
|
|
- g_warning ("Unable to open %s: %s", PATH_PASSWD, g_strerror (errno));
|
|
- goto out;
|
|
- }
|
|
-
|
|
- /* Make sure we keep users who are logged in no matter what. */
|
|
- g_hash_table_iter_init (&iter, current_users_by_name);
|
|
- while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &user)) {
|
|
- struct passwd *pwent;
|
|
-
|
|
- get_pwent_for_name (name, &pwent);
|
|
- if (pwent == NULL) {
|
|
- continue;
|
|
- }
|
|
-
|
|
- g_object_freeze_notify (G_OBJECT (user));
|
|
- _gdm_user_update_from_pwent (user, pwent);
|
|
- g_hash_table_insert (new_users_by_name, (char *)gdm_user_get_user_name (user), g_object_ref (user));
|
|
- }
|
|
-
|
|
- if (include_users != NULL) {
|
|
- GSList *l;
|
|
- for (l = include_users; l != NULL; l = l->next) {
|
|
- struct passwd *pwent;
|
|
-
|
|
- get_pwent_for_name (l->data, &pwent);
|
|
- if (pwent == NULL) {
|
|
- continue;
|
|
- }
|
|
-
|
|
- user = g_hash_table_lookup (new_users_by_name, pwent->pw_name);
|
|
- if (user != NULL) {
|
|
- /* already there */
|
|
- continue;
|
|
- }
|
|
-
|
|
- user = g_hash_table_lookup (current_users_by_name, pwent->pw_name);
|
|
- if (user == NULL) {
|
|
- user = g_object_new (GDM_TYPE_USER, NULL);
|
|
- } else {
|
|
- g_object_ref (user);
|
|
- }
|
|
- g_object_freeze_notify (G_OBJECT (user));
|
|
- _gdm_user_update_from_pwent (user, pwent);
|
|
- g_hash_table_insert (new_users_by_name, (char *)gdm_user_get_user_name (user), user);
|
|
- }
|
|
- }
|
|
-
|
|
- if (include_all != TRUE) {
|
|
- g_debug ("GdmUserManager: include_all is FALSE");
|
|
- } else {
|
|
- struct passwd *pwent;
|
|
-
|
|
- g_debug ("GdmUserManager: include_all is TRUE");
|
|
-
|
|
- for (pwent = fgetpwent (fp);
|
|
- pwent != NULL;
|
|
- pwent = fgetpwent (fp)) {
|
|
-
|
|
- /* Skip users below MinimalUID... */
|
|
- if (pwent->pw_uid < FALLBACK_MINIMAL_UID) {
|
|
- continue;
|
|
- }
|
|
-
|
|
- /* ...And users w/ invalid shells... */
|
|
- if (pwent->pw_shell == NULL
|
|
- || !g_hash_table_lookup (valid_shells, pwent->pw_shell)) {
|
|
- g_debug ("GdmUserManager: skipping user with bad shell: %s", pwent->pw_name);
|
|
- continue;
|
|
- }
|
|
-
|
|
- /* always exclude the "gdm" user. */
|
|
- if (strcmp (pwent->pw_name, GDM_USERNAME) == 0) {
|
|
- continue;
|
|
- }
|
|
-
|
|
- /* ...And explicitly excluded users */
|
|
- if (exclude_users != NULL) {
|
|
- GSList *found;
|
|
-
|
|
- found = g_slist_find_custom (exclude_users,
|
|
- pwent->pw_name,
|
|
- match_name_cmpfunc);
|
|
- if (found != NULL) {
|
|
- g_debug ("GdmUserManager: explicitly skipping user: %s", pwent->pw_name);
|
|
- continue;
|
|
- }
|
|
- }
|
|
-
|
|
- user = g_hash_table_lookup (new_users_by_name, pwent->pw_name);
|
|
- if (user != NULL) {
|
|
- /* already there */
|
|
- continue;
|
|
- }
|
|
-
|
|
- user = g_hash_table_lookup (current_users_by_name, pwent->pw_name);
|
|
- if (user == NULL) {
|
|
- user = g_object_new (GDM_TYPE_USER, NULL);
|
|
- } else {
|
|
- g_object_ref (user);
|
|
- }
|
|
-
|
|
- /* Freeze & update users not already in the new list */
|
|
- g_object_freeze_notify (G_OBJECT (user));
|
|
- _gdm_user_update_from_pwent (user, pwent);
|
|
- g_hash_table_insert (new_users_by_name, (char *)gdm_user_get_user_name (user), user);
|
|
- }
|
|
- }
|
|
-
|
|
- /* Go through and handle added users */
|
|
- g_hash_table_iter_init (&iter, new_users_by_name);
|
|
- while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &user)) {
|
|
- GdmUser *user2;
|
|
- user2 = g_hash_table_lookup (current_users_by_name, name);
|
|
- if (user2 == NULL) {
|
|
- *added_users = g_slist_prepend (*added_users, g_object_ref (user));
|
|
- }
|
|
- }
|
|
-
|
|
- /* Go through and handle removed users */
|
|
- g_hash_table_iter_init (&iter, current_users_by_name);
|
|
- while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &user)) {
|
|
- GdmUser *user2;
|
|
- user2 = g_hash_table_lookup (new_users_by_name, name);
|
|
- if (user2 == NULL) {
|
|
- *removed_users = g_slist_prepend (*removed_users, g_object_ref (user));
|
|
- }
|
|
- }
|
|
-
|
|
- out:
|
|
- /* Cleanup */
|
|
-
|
|
- fclose (fp);
|
|
-
|
|
- g_hash_table_iter_init (&iter, new_users_by_name);
|
|
- while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &user)) {
|
|
- g_object_thaw_notify (G_OBJECT (user));
|
|
- }
|
|
-
|
|
- g_hash_table_destroy (new_users_by_name);
|
|
-}
|
|
-
|
|
-typedef struct {
|
|
- GdmUserManager *manager;
|
|
- GSList *exclude_users;
|
|
- GSList *include_users;
|
|
- gboolean include_all;
|
|
- GHashTable *shells;
|
|
- GHashTable *current_users_by_name;
|
|
- GSList *added_users;
|
|
- GSList *removed_users;
|
|
-} PasswdData;
|
|
-
|
|
-static void
|
|
-passwd_data_free (PasswdData *data)
|
|
-{
|
|
- if (data->manager != NULL) {
|
|
- g_object_unref (data->manager);
|
|
- }
|
|
-
|
|
- g_slist_foreach (data->added_users, (GFunc) g_object_unref, NULL);
|
|
- g_slist_free (data->added_users);
|
|
-
|
|
- g_slist_foreach (data->removed_users, (GFunc) g_object_unref, NULL);
|
|
- g_slist_free (data->removed_users);
|
|
-
|
|
- g_slist_foreach (data->exclude_users, (GFunc) g_free, NULL);
|
|
- g_slist_free (data->exclude_users);
|
|
-
|
|
- g_slist_foreach (data->include_users, (GFunc) g_free, NULL);
|
|
- g_slist_free (data->include_users);
|
|
-
|
|
- g_slice_free (PasswdData, data);
|
|
-}
|
|
-
|
|
-static gboolean
|
|
-reload_passwd_job_done (PasswdData *data)
|
|
-{
|
|
- GSList *l;
|
|
-
|
|
- g_debug ("GdmUserManager: done reloading passwd file");
|
|
-
|
|
- /* Go through and handle added users */
|
|
- for (l = data->added_users; l != NULL; l = l->next) {
|
|
- add_user (data->manager, l->data);
|
|
- }
|
|
-
|
|
- /* Go through and handle removed users */
|
|
- for (l = data->removed_users; l != NULL; l = l->next) {
|
|
- remove_user (data->manager, l->data);
|
|
- }
|
|
-
|
|
- data->manager->priv->load_passwd_pending = FALSE;
|
|
-
|
|
- if (! data->manager->priv->is_loaded) {
|
|
- maybe_set_is_loaded (data->manager);
|
|
-
|
|
- if (data->manager->priv->include_all == TRUE) {
|
|
- monitor_local_users (data->manager);
|
|
- }
|
|
- }
|
|
-
|
|
- passwd_data_free (data);
|
|
-
|
|
- return FALSE;
|
|
-}
|
|
-
|
|
-static gboolean
|
|
-do_reload_passwd_job (GIOSchedulerJob *job,
|
|
- GCancellable *cancellable,
|
|
- PasswdData *data)
|
|
-{
|
|
- g_debug ("GdmUserManager: reloading passwd file worker");
|
|
-
|
|
- reload_passwd_file (data->shells,
|
|
- data->exclude_users,
|
|
- data->include_users,
|
|
- data->include_all,
|
|
- data->current_users_by_name,
|
|
- &data->added_users,
|
|
- &data->removed_users);
|
|
-
|
|
- g_io_scheduler_job_send_to_mainloop_async (job,
|
|
- (GSourceFunc) reload_passwd_job_done,
|
|
- data,
|
|
- NULL);
|
|
-
|
|
- return FALSE;
|
|
-}
|
|
-
|
|
-static GSList *
|
|
-slist_deep_copy (const GSList *list)
|
|
-{
|
|
- GSList *retval;
|
|
- GSList *l;
|
|
-
|
|
- if (list == NULL)
|
|
- return NULL;
|
|
-
|
|
- retval = g_slist_copy ((GSList *) list);
|
|
- for (l = retval; l != NULL; l = l->next) {
|
|
- l->data = g_strdup (l->data);
|
|
- }
|
|
-
|
|
- return retval;
|
|
-}
|
|
-
|
|
-static void
|
|
-schedule_reload_passwd (GdmUserManager *manager)
|
|
-{
|
|
- PasswdData *passwd_data;
|
|
-
|
|
- manager->priv->load_passwd_pending = TRUE;
|
|
-
|
|
- passwd_data = g_slice_new0 (PasswdData);
|
|
- passwd_data->manager = g_object_ref (manager);
|
|
- passwd_data->shells = manager->priv->shells;
|
|
- passwd_data->exclude_users = slist_deep_copy (manager->priv->exclude_usernames);
|
|
- passwd_data->include_users = slist_deep_copy (manager->priv->include_usernames);
|
|
- passwd_data->include_all = manager->priv->include_all;
|
|
- passwd_data->current_users_by_name = manager->priv->users_by_name;
|
|
- passwd_data->added_users = NULL;
|
|
- passwd_data->removed_users = NULL;
|
|
-
|
|
- g_debug ("GdmUserManager: scheduling a passwd file update");
|
|
-
|
|
- g_io_scheduler_push_job ((GIOSchedulerJobFunc) do_reload_passwd_job,
|
|
- passwd_data,
|
|
- NULL,
|
|
- G_PRIORITY_DEFAULT,
|
|
- NULL);
|
|
-}
|
|
-
|
|
-static void
|
|
-load_sessions_from_array (GdmUserManager *manager,
|
|
- const char * const *session_ids,
|
|
- int number_of_sessions)
|
|
-{
|
|
- int i;
|
|
-
|
|
- for (i = 0; i < number_of_sessions; i++) {
|
|
- load_new_session (manager, session_ids[i]);
|
|
- }
|
|
-}
|
|
-
|
|
-static void
|
|
-on_get_sessions_finished (DBusGProxy *proxy,
|
|
- DBusGProxyCall *call,
|
|
- GdmUserManager *manager)
|
|
-{
|
|
- GError *error;
|
|
- gboolean res;
|
|
- GPtrArray *sessions;
|
|
-
|
|
- g_assert (manager->priv->get_sessions_call == call);
|
|
-
|
|
- error = NULL;
|
|
- sessions = NULL;
|
|
- res = dbus_g_proxy_end_call (proxy,
|
|
- call,
|
|
- &error,
|
|
- GDM_DBUS_TYPE_G_OBJECT_PATH_ARRAY,
|
|
- &sessions,
|
|
- G_TYPE_INVALID);
|
|
-
|
|
- if (! res) {
|
|
- if (error != NULL) {
|
|
- g_warning ("unable to determine sessions for seat: %s",
|
|
- error->message);
|
|
- g_error_free (error);
|
|
- } else {
|
|
- g_warning ("unable to determine sessions for seat");
|
|
- }
|
|
- return;
|
|
- }
|
|
-
|
|
- manager->priv->get_sessions_call = NULL;
|
|
- g_assert (sessions->len <= G_MAXINT);
|
|
- load_sessions_from_array (manager,
|
|
- (const char * const *) sessions->pdata,
|
|
- (int) sessions->len);
|
|
- g_ptr_array_foreach (sessions, (GFunc) g_free, NULL);
|
|
- g_ptr_array_free (sessions, TRUE);
|
|
- maybe_set_is_loaded (manager);
|
|
-}
|
|
-
|
|
-static void
|
|
-load_sessions (GdmUserManager *manager)
|
|
-{
|
|
- DBusGProxyCall *call;
|
|
-
|
|
- if (manager->priv->seat.proxy == NULL) {
|
|
- g_debug ("GdmUserManager: no seat proxy; can't load sessions");
|
|
- return;
|
|
- }
|
|
-
|
|
- call = dbus_g_proxy_begin_call (manager->priv->seat.proxy,
|
|
- "GetSessions",
|
|
- (DBusGProxyCallNotify)
|
|
- on_get_sessions_finished,
|
|
- manager,
|
|
- NULL,
|
|
- G_TYPE_INVALID);
|
|
-
|
|
- if (call == NULL) {
|
|
- g_warning ("GdmUserManager: failed to make GetSessions call");
|
|
- return;
|
|
- }
|
|
-
|
|
- manager->priv->get_sessions_call = call;
|
|
-}
|
|
-
|
|
-static void
|
|
-reload_shells (GdmUserManager *manager)
|
|
-{
|
|
- char *shell;
|
|
-
|
|
- setusershell ();
|
|
-
|
|
- g_hash_table_remove_all (manager->priv->shells);
|
|
- for (shell = getusershell (); shell != NULL; shell = getusershell ()) {
|
|
- /* skip well known not-real shells */
|
|
- if (shell == NULL
|
|
- || strcmp (shell, "/sbin/nologin") == 0
|
|
- || strcmp (shell, "/bin/false") == 0) {
|
|
- g_debug ("GdmUserManager: skipping shell %s", shell);
|
|
- continue;
|
|
- }
|
|
- g_hash_table_insert (manager->priv->shells,
|
|
- g_strdup (shell),
|
|
- GUINT_TO_POINTER (TRUE));
|
|
- }
|
|
-
|
|
- endusershell ();
|
|
-}
|
|
-
|
|
-static void
|
|
-load_users_manually (GdmUserManager *manager)
|
|
-{
|
|
- gboolean res;
|
|
-
|
|
- manager->priv->shells = g_hash_table_new_full (g_str_hash,
|
|
- g_str_equal,
|
|
- g_free,
|
|
- NULL);
|
|
- reload_shells (manager);
|
|
-
|
|
- load_sessions (manager);
|
|
-
|
|
- res = load_ck_history (manager);
|
|
- schedule_reload_passwd (manager);
|
|
-}
|
|
-
|
|
-static void
|
|
-load_users (GdmUserManager *manager)
|
|
-{
|
|
- g_assert (manager->priv->accounts_proxy != NULL);
|
|
- g_debug ("GdmUserManager: calling 'ListCachedUsers'");
|
|
-
|
|
- dbus_g_proxy_begin_call (manager->priv->accounts_proxy,
|
|
- "ListCachedUsers",
|
|
- on_list_cached_users_finished,
|
|
- manager,
|
|
- NULL,
|
|
- G_TYPE_INVALID);
|
|
- manager->priv->listing_cached_users = TRUE;
|
|
-}
|
|
-
|
|
-static void
|
|
-load_seat_incrementally (GdmUserManager *manager)
|
|
-{
|
|
- g_assert (manager->priv->seat.proxy == NULL);
|
|
-
|
|
- switch (manager->priv->seat.state) {
|
|
- case GDM_USER_MANAGER_SEAT_STATE_GET_SESSION_ID:
|
|
- get_current_session_id (manager);
|
|
- break;
|
|
- case GDM_USER_MANAGER_SEAT_STATE_GET_ID:
|
|
- get_seat_id_for_current_session (manager);
|
|
- break;
|
|
- case GDM_USER_MANAGER_SEAT_STATE_GET_PROXY:
|
|
- get_seat_proxy (manager);
|
|
- break;
|
|
- case GDM_USER_MANAGER_SEAT_STATE_LOADED:
|
|
- break;
|
|
- default:
|
|
- g_assert_not_reached ();
|
|
- }
|
|
-
|
|
- if (manager->priv->seat.state == GDM_USER_MANAGER_SEAT_STATE_LOADED) {
|
|
- gboolean res;
|
|
-
|
|
- load_sessions (manager);
|
|
- res = load_ck_history (manager);
|
|
- }
|
|
-
|
|
- maybe_set_is_loaded (manager);
|
|
-}
|
|
-
|
|
-static gboolean
|
|
-load_idle (GdmUserManager *manager)
|
|
-{
|
|
- manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_UNLOADED + 1;
|
|
- load_seat_incrementally (manager);
|
|
- load_users (manager);
|
|
- manager->priv->load_id = 0;
|
|
-
|
|
- return FALSE;
|
|
-}
|
|
-
|
|
-static void
|
|
-queue_load_seat_and_users (GdmUserManager *manager)
|
|
-{
|
|
- if (manager->priv->load_id > 0) {
|
|
- return;
|
|
- }
|
|
-
|
|
- manager->priv->load_id = g_idle_add ((GSourceFunc)load_idle, manager);
|
|
-}
|
|
-
|
|
-static gboolean
|
|
-reload_passwd_idle (GdmUserManager *manager)
|
|
-{
|
|
- schedule_reload_passwd (manager);
|
|
- manager->priv->reload_passwd_id = 0;
|
|
-
|
|
- return FALSE;
|
|
-}
|
|
-
|
|
-static void
|
|
-queue_reload_passwd (GdmUserManager *manager)
|
|
-{
|
|
- if (manager->priv->reload_passwd_id > 0) {
|
|
- g_source_remove (manager->priv->reload_passwd_id);
|
|
- }
|
|
-
|
|
- manager->priv->reload_passwd_id = g_timeout_add_seconds (RELOAD_PASSWD_THROTTLE_SECS, (GSourceFunc)reload_passwd_idle, manager);
|
|
-}
|
|
-
|
|
-static void
|
|
-on_shells_monitor_changed (GFileMonitor *monitor,
|
|
- GFile *file,
|
|
- GFile *other_file,
|
|
- GFileMonitorEvent event_type,
|
|
- GdmUserManager *manager)
|
|
-{
|
|
- if (event_type != G_FILE_MONITOR_EVENT_CHANGED &&
|
|
- event_type != G_FILE_MONITOR_EVENT_CREATED) {
|
|
- return;
|
|
- }
|
|
-
|
|
- reload_shells (manager);
|
|
- queue_reload_passwd (manager);
|
|
-}
|
|
-
|
|
-static void
|
|
-on_passwd_monitor_changed (GFileMonitor *monitor,
|
|
- GFile *file,
|
|
- GFile *other_file,
|
|
- GFileMonitorEvent event_type,
|
|
- GdmUserManager *manager)
|
|
-{
|
|
- if (event_type != G_FILE_MONITOR_EVENT_CHANGED &&
|
|
- event_type != G_FILE_MONITOR_EVENT_CREATED) {
|
|
- return;
|
|
- }
|
|
-
|
|
- queue_reload_passwd (manager);
|
|
-}
|
|
-
|
|
-static void
|
|
-gdm_user_manager_get_property (GObject *object,
|
|
- guint prop_id,
|
|
- GValue *value,
|
|
- GParamSpec *pspec)
|
|
-{
|
|
- GdmUserManager *manager;
|
|
-
|
|
- manager = GDM_USER_MANAGER (object);
|
|
-
|
|
- switch (prop_id) {
|
|
- case PROP_IS_LOADED:
|
|
- g_value_set_boolean (value, manager->priv->is_loaded);
|
|
- break;
|
|
- case PROP_HAS_MULTIPLE_USERS:
|
|
- g_value_set_boolean (value, manager->priv->has_multiple_users);
|
|
- break;
|
|
- case PROP_INCLUDE_ALL:
|
|
- g_value_set_boolean (value, manager->priv->include_all);
|
|
- break;
|
|
- case PROP_INCLUDE_USERNAMES_LIST:
|
|
- g_value_set_pointer (value, manager->priv->include_usernames);
|
|
- break;
|
|
- case PROP_EXCLUDE_USERNAMES_LIST:
|
|
- g_value_set_pointer (value, manager->priv->exclude_usernames);
|
|
- break;
|
|
- default:
|
|
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
- break;
|
|
- }
|
|
-}
|
|
-
|
|
-static void
|
|
-set_include_usernames (GdmUserManager *manager,
|
|
- GSList *list)
|
|
-{
|
|
- if (manager->priv->include_usernames != NULL) {
|
|
- g_slist_foreach (manager->priv->include_usernames, (GFunc) g_free, NULL);
|
|
- g_slist_free (manager->priv->include_usernames);
|
|
- }
|
|
- manager->priv->include_usernames = slist_deep_copy (list);
|
|
-}
|
|
-
|
|
-static void
|
|
-set_exclude_usernames (GdmUserManager *manager,
|
|
- GSList *list)
|
|
-{
|
|
- if (manager->priv->exclude_usernames != NULL) {
|
|
- g_slist_foreach (manager->priv->exclude_usernames, (GFunc) g_free, NULL);
|
|
- g_slist_free (manager->priv->exclude_usernames);
|
|
- }
|
|
- manager->priv->exclude_usernames = slist_deep_copy (list);
|
|
-}
|
|
-
|
|
-static void
|
|
-set_include_all (GdmUserManager *manager,
|
|
- gboolean all)
|
|
-{
|
|
- if (manager->priv->include_all != all) {
|
|
- manager->priv->include_all = all;
|
|
- }
|
|
-}
|
|
-
|
|
-static void
|
|
-gdm_user_manager_set_property (GObject *object,
|
|
- guint prop_id,
|
|
- const GValue *value,
|
|
- GParamSpec *pspec)
|
|
-{
|
|
- GdmUserManager *self;
|
|
-
|
|
- self = GDM_USER_MANAGER (object);
|
|
-
|
|
- switch (prop_id) {
|
|
- case PROP_INCLUDE_ALL:
|
|
- set_include_all (self, g_value_get_boolean (value));
|
|
- break;
|
|
- case PROP_INCLUDE_USERNAMES_LIST:
|
|
- set_include_usernames (self, g_value_get_pointer (value));
|
|
- break;
|
|
- case PROP_EXCLUDE_USERNAMES_LIST:
|
|
- set_exclude_usernames (self, g_value_get_pointer (value));
|
|
- break;
|
|
- default:
|
|
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
- break;
|
|
- }
|
|
-}
|
|
-
|
|
-static void
|
|
-monitor_local_users (GdmUserManager *manager)
|
|
-{
|
|
- GFile *file;
|
|
- GError *error;
|
|
-
|
|
- g_debug ("GdmUserManager: Monitoring local users");
|
|
-
|
|
- /* /etc/shells */
|
|
- file = g_file_new_for_path (_PATH_SHELLS);
|
|
- error = NULL;
|
|
- manager->priv->shells_monitor = g_file_monitor_file (file,
|
|
- G_FILE_MONITOR_NONE,
|
|
- NULL,
|
|
- &error);
|
|
- if (manager->priv->shells_monitor != NULL) {
|
|
- g_signal_connect (manager->priv->shells_monitor,
|
|
- "changed",
|
|
- G_CALLBACK (on_shells_monitor_changed),
|
|
- manager);
|
|
- } else {
|
|
- g_warning ("Unable to monitor %s: %s", _PATH_SHELLS, error->message);
|
|
- g_error_free (error);
|
|
- }
|
|
- g_object_unref (file);
|
|
-
|
|
- /* /etc/passwd */
|
|
- file = g_file_new_for_path (PATH_PASSWD);
|
|
- manager->priv->passwd_monitor = g_file_monitor_file (file,
|
|
- G_FILE_MONITOR_NONE,
|
|
- NULL,
|
|
- &error);
|
|
- if (manager->priv->passwd_monitor != NULL) {
|
|
- g_signal_connect (manager->priv->passwd_monitor,
|
|
- "changed",
|
|
- G_CALLBACK (on_passwd_monitor_changed),
|
|
- manager);
|
|
- } else {
|
|
- g_warning ("Unable to monitor %s: %s", PATH_PASSWD, error->message);
|
|
- g_error_free (error);
|
|
- }
|
|
- g_object_unref (file);
|
|
-}
|
|
-
|
|
-static void
|
|
-gdm_user_manager_class_init (GdmUserManagerClass *klass)
|
|
-{
|
|
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
-
|
|
- object_class->finalize = gdm_user_manager_finalize;
|
|
- object_class->get_property = gdm_user_manager_get_property;
|
|
- object_class->set_property = gdm_user_manager_set_property;
|
|
-
|
|
- g_object_class_install_property (object_class,
|
|
- PROP_IS_LOADED,
|
|
- g_param_spec_boolean ("is-loaded",
|
|
- NULL,
|
|
- NULL,
|
|
- FALSE,
|
|
- G_PARAM_READABLE));
|
|
- g_object_class_install_property (object_class,
|
|
- PROP_HAS_MULTIPLE_USERS,
|
|
- g_param_spec_boolean ("has-multiple-users",
|
|
- NULL,
|
|
- NULL,
|
|
- FALSE,
|
|
- G_PARAM_READABLE));
|
|
- g_object_class_install_property (object_class,
|
|
- PROP_INCLUDE_ALL,
|
|
- g_param_spec_boolean ("include-all",
|
|
- NULL,
|
|
- NULL,
|
|
- FALSE,
|
|
- G_PARAM_READWRITE));
|
|
- g_object_class_install_property (object_class,
|
|
- PROP_INCLUDE_USERNAMES_LIST,
|
|
- g_param_spec_pointer ("include-usernames-list",
|
|
- NULL,
|
|
- NULL,
|
|
- G_PARAM_READWRITE));
|
|
-
|
|
- g_object_class_install_property (object_class,
|
|
- PROP_EXCLUDE_USERNAMES_LIST,
|
|
- g_param_spec_pointer ("exclude-usernames-list",
|
|
- NULL,
|
|
- NULL,
|
|
- G_PARAM_READWRITE));
|
|
-
|
|
- signals [USER_ADDED] =
|
|
- g_signal_new ("user-added",
|
|
- G_TYPE_FROM_CLASS (klass),
|
|
- G_SIGNAL_RUN_LAST,
|
|
- G_STRUCT_OFFSET (GdmUserManagerClass, user_added),
|
|
- NULL, NULL,
|
|
- g_cclosure_marshal_VOID__OBJECT,
|
|
- G_TYPE_NONE, 1, GDM_TYPE_USER);
|
|
- signals [USER_REMOVED] =
|
|
- g_signal_new ("user-removed",
|
|
- G_TYPE_FROM_CLASS (klass),
|
|
- G_SIGNAL_RUN_LAST,
|
|
- G_STRUCT_OFFSET (GdmUserManagerClass, user_removed),
|
|
- NULL, NULL,
|
|
- g_cclosure_marshal_VOID__OBJECT,
|
|
- G_TYPE_NONE, 1, GDM_TYPE_USER);
|
|
- signals [USER_IS_LOGGED_IN_CHANGED] =
|
|
- g_signal_new ("user-is-logged-in-changed",
|
|
- G_TYPE_FROM_CLASS (klass),
|
|
- G_SIGNAL_RUN_LAST,
|
|
- G_STRUCT_OFFSET (GdmUserManagerClass, user_is_logged_in_changed),
|
|
- NULL, NULL,
|
|
- g_cclosure_marshal_VOID__OBJECT,
|
|
- G_TYPE_NONE, 1, GDM_TYPE_USER);
|
|
- signals [USER_CHANGED] =
|
|
- g_signal_new ("user-changed",
|
|
- G_TYPE_FROM_CLASS (klass),
|
|
- G_SIGNAL_RUN_LAST,
|
|
- G_STRUCT_OFFSET (GdmUserManagerClass, user_changed),
|
|
- NULL, NULL,
|
|
- g_cclosure_marshal_VOID__OBJECT,
|
|
- G_TYPE_NONE, 1, GDM_TYPE_USER);
|
|
-
|
|
- g_type_class_add_private (klass, sizeof (GdmUserManagerPrivate));
|
|
-}
|
|
-
|
|
-/**
|
|
- * gdm_user_manager_queue_load:
|
|
- * @manager: a #GdmUserManager
|
|
- *
|
|
- * Queue loading users into user manager. This must be called, and the
|
|
- * #GdmUserManager:is-loaded property must be %TRUE before calling
|
|
- * gdm_user_manager_list_users()
|
|
- */
|
|
-void
|
|
-gdm_user_manager_queue_load (GdmUserManager *manager)
|
|
-{
|
|
- g_return_if_fail (GDM_IS_USER_MANAGER (manager));
|
|
-
|
|
- if (! manager->priv->is_loaded) {
|
|
- queue_load_seat_and_users (manager);
|
|
- }
|
|
-}
|
|
-
|
|
-static void
|
|
-gdm_user_manager_init (GdmUserManager *manager)
|
|
-{
|
|
- GError *error;
|
|
-
|
|
- manager->priv = GDM_USER_MANAGER_GET_PRIVATE (manager);
|
|
-
|
|
- /* sessions */
|
|
- manager->priv->sessions = g_hash_table_new_full (g_str_hash,
|
|
- g_str_equal,
|
|
- g_free,
|
|
- g_free);
|
|
-
|
|
- /* users */
|
|
- manager->priv->users_by_name = g_hash_table_new_full (g_str_hash,
|
|
- g_str_equal,
|
|
- g_free,
|
|
- g_object_unref);
|
|
-
|
|
- manager->priv->users_by_object_path = g_hash_table_new_full (g_str_hash,
|
|
- g_str_equal,
|
|
- NULL,
|
|
- g_object_unref);
|
|
-
|
|
- g_assert (manager->priv->seat.proxy == NULL);
|
|
-
|
|
- error = NULL;
|
|
- manager->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
|
|
- if (manager->priv->connection == NULL) {
|
|
- if (error != NULL) {
|
|
- g_warning ("Failed to connect to the D-Bus daemon: %s", error->message);
|
|
- g_error_free (error);
|
|
- } else {
|
|
- g_warning ("Failed to connect to the D-Bus daemon");
|
|
- }
|
|
- return;
|
|
- }
|
|
-
|
|
- get_accounts_proxy (manager);
|
|
-
|
|
- manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_UNLOADED;
|
|
-}
|
|
-
|
|
-static void
|
|
-gdm_user_manager_finalize (GObject *object)
|
|
-{
|
|
- GdmUserManager *manager;
|
|
- GSList *node;
|
|
-
|
|
- g_return_if_fail (object != NULL);
|
|
- g_return_if_fail (GDM_IS_USER_MANAGER (object));
|
|
-
|
|
- manager = GDM_USER_MANAGER (object);
|
|
-
|
|
- g_return_if_fail (manager->priv != NULL);
|
|
-
|
|
- if (manager->priv->ck_history_pid > 0) {
|
|
- g_debug ("Killing ck-history process");
|
|
- signal_pid (manager->priv->ck_history_pid, SIGTERM);
|
|
- }
|
|
-
|
|
- g_slist_foreach (manager->priv->new_sessions,
|
|
- (GFunc) unload_new_session, NULL);
|
|
- g_slist_free (manager->priv->new_sessions);
|
|
-
|
|
- g_slist_foreach (manager->priv->fetch_user_requests,
|
|
- (GFunc) free_fetch_user_request, NULL);
|
|
- g_slist_free (manager->priv->fetch_user_requests);
|
|
-
|
|
- node = manager->priv->new_users;
|
|
- while (node != NULL) {
|
|
- GdmUser *user;
|
|
- GSList *next_node;
|
|
-
|
|
- user = GDM_USER (node->data);
|
|
- next_node = node->next;
|
|
-
|
|
- g_signal_handlers_disconnect_by_func (user, on_new_user_loaded, manager);
|
|
- g_object_unref (user);
|
|
- manager->priv->new_users = g_slist_delete_link (manager->priv->new_users, node);
|
|
- node = next_node;
|
|
- }
|
|
-
|
|
- unload_seat (manager);
|
|
-
|
|
- if (manager->priv->exclude_usernames != NULL) {
|
|
- g_slist_foreach (manager->priv->exclude_usernames, (GFunc) g_free, NULL);
|
|
- g_slist_free (manager->priv->exclude_usernames);
|
|
- }
|
|
-
|
|
- if (manager->priv->include_usernames != NULL) {
|
|
- g_slist_foreach (manager->priv->include_usernames, (GFunc) g_free, NULL);
|
|
- g_slist_free (manager->priv->include_usernames);
|
|
- }
|
|
-
|
|
- if (manager->priv->seat.proxy != NULL) {
|
|
- g_object_unref (manager->priv->seat.proxy);
|
|
- }
|
|
-
|
|
- if (manager->priv->accounts_proxy != NULL) {
|
|
- g_object_unref (manager->priv->accounts_proxy);
|
|
- }
|
|
-
|
|
- if (manager->priv->ck_history_id != 0) {
|
|
- g_source_remove (manager->priv->ck_history_id);
|
|
- manager->priv->ck_history_id = 0;
|
|
- }
|
|
-
|
|
- if (manager->priv->ck_history_watchdog_id != 0) {
|
|
- g_source_remove (manager->priv->ck_history_watchdog_id);
|
|
- manager->priv->ck_history_watchdog_id = 0;
|
|
- }
|
|
-
|
|
- if (manager->priv->load_id > 0) {
|
|
- g_source_remove (manager->priv->load_id);
|
|
- manager->priv->load_id = 0;
|
|
- }
|
|
-
|
|
- if (manager->priv->reload_passwd_id > 0) {
|
|
- g_source_remove (manager->priv->reload_passwd_id);
|
|
- manager->priv->reload_passwd_id = 0;
|
|
- }
|
|
-
|
|
- g_hash_table_destroy (manager->priv->sessions);
|
|
-
|
|
- if (manager->priv->passwd_monitor != NULL) {
|
|
- g_file_monitor_cancel (manager->priv->passwd_monitor);
|
|
- }
|
|
-
|
|
- g_hash_table_destroy (manager->priv->users_by_name);
|
|
- g_hash_table_destroy (manager->priv->users_by_object_path);
|
|
-
|
|
- if (manager->priv->shells_monitor != NULL) {
|
|
- g_file_monitor_cancel (manager->priv->shells_monitor);
|
|
- }
|
|
-
|
|
- if (manager->priv->shells != NULL) {
|
|
- g_hash_table_destroy (manager->priv->shells);
|
|
- }
|
|
-
|
|
- G_OBJECT_CLASS (gdm_user_manager_parent_class)->finalize (object);
|
|
-}
|
|
-
|
|
-/**
|
|
- * gdm_user_manager_ref_default:
|
|
- *
|
|
- * Queue loading users into user manager. This must be called, and the
|
|
- * #GdmUserManager:is-loaded property must be %TRUE before calling
|
|
- * gdm_user_manager_list_users()
|
|
- *
|
|
- * Returns: (transfer full): user manager object
|
|
- */
|
|
-GdmUserManager *
|
|
-gdm_user_manager_ref_default (void)
|
|
-{
|
|
- if (user_manager_object != NULL) {
|
|
- g_object_ref (user_manager_object);
|
|
- } else {
|
|
- user_manager_object = g_object_new (GDM_TYPE_USER_MANAGER, NULL);
|
|
- g_object_add_weak_pointer (user_manager_object,
|
|
- (gpointer *) &user_manager_object);
|
|
- }
|
|
-
|
|
- return GDM_USER_MANAGER (user_manager_object);
|
|
-}
|
|
diff --git a/gui/simple-greeter/gdm-user-manager.h b/gui/simple-greeter/gdm-user-manager.h
|
|
deleted file mode 100644
|
|
index 8dd9ede..0000000
|
|
--- a/gui/simple-greeter/gdm-user-manager.h
|
|
+++ /dev/null
|
|
@@ -1,91 +0,0 @@
|
|
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
|
- *
|
|
- * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
|
|
- *
|
|
- * This program is free software; you can redistribute it and/or modify
|
|
- * it under the terms of the GNU General Public License as published by
|
|
- * the Free Software Foundation; either version 2 of the License, or
|
|
- * (at your option) any later version.
|
|
- *
|
|
- * This program is distributed in the hope that it will be useful,
|
|
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
- * GNU General Public License for more details.
|
|
- *
|
|
- * You should have received a copy of the GNU General Public License
|
|
- * along with this program; if not, write to the Free Software
|
|
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
- *
|
|
- */
|
|
-
|
|
-#ifndef __GDM_USER_MANAGER_H__
|
|
-#define __GDM_USER_MANAGER_H__
|
|
-
|
|
-#include <glib-object.h>
|
|
-
|
|
-#include "gdm-user.h"
|
|
-
|
|
-G_BEGIN_DECLS
|
|
-
|
|
-#define GDM_TYPE_USER_MANAGER (gdm_user_manager_get_type ())
|
|
-#define GDM_USER_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_USER_MANAGER, GdmUserManager))
|
|
-#define GDM_USER_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_USER_MANAGER, GdmUserManagerClass))
|
|
-#define GDM_IS_USER_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_USER_MANAGER))
|
|
-#define GDM_IS_USER_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_USER_MANAGER))
|
|
-#define GDM_USER_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_USER_MANAGER, GdmUserManagerClass))
|
|
-
|
|
-typedef struct GdmUserManagerPrivate GdmUserManagerPrivate;
|
|
-typedef struct GdmUserManager GdmUserManager;
|
|
-typedef struct GdmUserManagerClass GdmUserManagerClass;
|
|
-typedef enum GdmUserManagerError GdmUserManagerError;
|
|
-
|
|
-struct GdmUserManager
|
|
-{
|
|
- GObject parent;
|
|
- GdmUserManagerPrivate *priv;
|
|
-};
|
|
-
|
|
-struct GdmUserManagerClass
|
|
-{
|
|
- GObjectClass parent_class;
|
|
-
|
|
- void (* user_added) (GdmUserManager *user_manager,
|
|
- GdmUser *user);
|
|
- void (* user_removed) (GdmUserManager *user_manager,
|
|
- GdmUser *user);
|
|
- void (* user_is_logged_in_changed) (GdmUserManager *user_manager,
|
|
- GdmUser *user);
|
|
- void (* user_changed) (GdmUserManager *user_manager,
|
|
- GdmUser *user);
|
|
-};
|
|
-
|
|
-enum GdmUserManagerError
|
|
-{
|
|
- GDM_USER_MANAGER_ERROR_GENERAL,
|
|
- GDM_USER_MANAGER_ERROR_KEY_NOT_FOUND
|
|
-};
|
|
-
|
|
-#define GDM_USER_MANAGER_ERROR gdm_user_manager_error_quark ()
|
|
-
|
|
-GQuark gdm_user_manager_error_quark (void);
|
|
-GType gdm_user_manager_get_type (void);
|
|
-
|
|
-GdmUserManager * gdm_user_manager_ref_default (void);
|
|
-
|
|
-void gdm_user_manager_queue_load (GdmUserManager *manager);
|
|
-GSList * gdm_user_manager_list_users (GdmUserManager *manager);
|
|
-GdmUser * gdm_user_manager_get_user (GdmUserManager *manager,
|
|
- const char *username);
|
|
-GdmUser * gdm_user_manager_get_user_by_uid (GdmUserManager *manager,
|
|
- gulong uid);
|
|
-
|
|
-gboolean gdm_user_manager_activate_user_session (GdmUserManager *manager,
|
|
- GdmUser *user);
|
|
-
|
|
-gboolean gdm_user_manager_can_switch (GdmUserManager *manager);
|
|
-
|
|
-gboolean gdm_user_manager_goto_login_session (GdmUserManager *manager);
|
|
-
|
|
-G_END_DECLS
|
|
-
|
|
-#endif /* __GDM_USER_MANAGER_H */
|
|
diff --git a/gui/simple-greeter/test-user-manager.c b/gui/simple-greeter/test-user-manager.c
|
|
index d0f6427..03b7a21 100644
|
|
--- a/gui/simple-greeter/test-user-manager.c
|
|
+++ b/gui/simple-greeter/test-user-manager.c
|
|
@@ -30,10 +30,12 @@
|
|
#include <glib/gi18n.h>
|
|
#include <gtk/gtk.h>
|
|
|
|
-#include "gdm-user-manager.h"
|
|
+#include <act/act-user-manager.h>
|
|
+#include <act/act-user.h>
|
|
+
|
|
#include "gdm-settings-client.h"
|
|
|
|
-static GdmUserManager *manager = NULL;
|
|
+static ActUserManager *manager = NULL;
|
|
static GMainLoop *main_loop = NULL;
|
|
|
|
static gboolean do_monitor = FALSE;
|
|
@@ -45,7 +47,7 @@ static GOptionEntry entries [] = {
|
|
};
|
|
|
|
static void
|
|
-on_is_loaded_changed (GdmUserManager *manager,
|
|
+on_is_loaded_changed (ActUserManager *manager,
|
|
GParamSpec *pspec,
|
|
gpointer data)
|
|
{
|
|
@@ -53,9 +55,9 @@ on_is_loaded_changed (GdmUserManager *manager,
|
|
|
|
g_debug ("Users loaded");
|
|
|
|
- users = gdm_user_manager_list_users (manager);
|
|
+ users = act_user_manager_list_users (manager);
|
|
while (users != NULL) {
|
|
- g_print ("User: %s\n", gdm_user_get_user_name (users->data));
|
|
+ g_print ("User: %s\n", act_user_get_user_name (users->data));
|
|
users = g_slist_delete_link (users, users);
|
|
}
|
|
|
|
@@ -65,19 +67,19 @@ on_is_loaded_changed (GdmUserManager *manager,
|
|
}
|
|
|
|
static void
|
|
-on_user_added (GdmUserManager *manager,
|
|
- GdmUser *user,
|
|
+on_user_added (ActUserManager *manager,
|
|
+ ActUser *user,
|
|
gpointer data)
|
|
{
|
|
- g_debug ("User added: %s", gdm_user_get_user_name (user));
|
|
+ g_debug ("User added: %s", act_user_get_user_name (user));
|
|
}
|
|
|
|
static void
|
|
-on_user_removed (GdmUserManager *manager,
|
|
- GdmUser *user,
|
|
+on_user_removed (ActUserManager *manager,
|
|
+ ActUser *user,
|
|
gpointer data)
|
|
{
|
|
- g_debug ("User removed: %s", gdm_user_get_user_name (user));
|
|
+ g_debug ("User removed: %s", act_user_get_user_name (user));
|
|
}
|
|
|
|
int
|
|
@@ -123,7 +125,7 @@ main (int argc, char *argv[])
|
|
exit (1);
|
|
}
|
|
|
|
- manager = gdm_user_manager_ref_default ();
|
|
+ manager = act_user_manager_get_default ();
|
|
g_object_set (manager, "include-all", TRUE, NULL);
|
|
g_signal_connect (manager,
|
|
"notify::is-loaded",
|
|
@@ -137,7 +139,6 @@ main (int argc, char *argv[])
|
|
"user-removed",
|
|
G_CALLBACK (on_user_removed),
|
|
NULL);
|
|
- gdm_user_manager_queue_load (manager);
|
|
|
|
main_loop = g_main_loop_new (NULL, FALSE);
|
|
|
|
--
|
|
1.7.4.1
|
|
|
|
From f100b21d67382dbdfdc5305f8cbb7f6bc9233f98 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 18 Feb 2011 18:34:31 -0500
|
|
Subject: [PATCH] greeter: filter out root and gdm users from list
|
|
|
|
While the accounts service filters out most of the names
|
|
we care about, it doesn't filter out the above two, so make
|
|
sure they get filtered.
|
|
---
|
|
gui/simple-greeter/gdm-user-chooser-widget.c | 8 ++++++++
|
|
1 files changed, 8 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-user-chooser-widget.c b/gui/simple-greeter/gdm-user-chooser-widget.c
|
|
index a385218..dd06bc4 100644
|
|
--- a/gui/simple-greeter/gdm-user-chooser-widget.c
|
|
+++ b/gui/simple-greeter/gdm-user-chooser-widget.c
|
|
@@ -743,6 +743,14 @@ add_user (GdmUserChooserWidget *widget,
|
|
return;
|
|
}
|
|
|
|
+ if (strcmp (act_user_get_user_name (user), GDM_USERNAME) == 0) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (act_user_get_uid (user) == 0) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
if (widget->priv->stock_person_pixbuf != NULL) {
|
|
pixbuf = g_object_ref (widget->priv->stock_person_pixbuf);
|
|
} else {
|
|
--
|
|
1.7.4.1
|
|
|