348
+ g_signal_emit (user, signals[ICON_CHANGED], 0);
395
+ _gdm_user_icon_changed (user);
352
399
+update_icon_monitor (GdmUser *user)
355
+ GError *error = NULL;
357
+ if (user->icon_url != NULL) {
358
+ g_free (user->icon_url);
359
+ user->icon_url = NULL;
361
+ if (user->home_dir != NULL) {
363
+ filename = g_build_filename (user->home_dir, ".face", NULL);
364
+ user->icon_url = g_strjoin(NULL, "file://", filename, NULL);
367
+ g_object_notify (G_OBJECT (user), "icon-url");
405
+ if (user->home_dir == NULL) {
369
409
+ if (user->icon_monitor != NULL) {
370
410
+ g_file_monitor_cancel (user->icon_monitor);
371
411
+ user->icon_monitor = NULL;
374
+ if (user->icon_url == NULL) {
378
+ g_debug ("adding monitor for '%s'", user->icon_url);
379
+ file = g_file_new_for_uri (user->icon_url);
414
+ path = g_build_filename (user->home_dir, ".face", NULL);
415
+ g_debug ("adding monitor for '%s'", path);
416
+ file = g_file_new_for_path (path);
380
418
+ user->icon_monitor = g_file_monitor_file (file,
381
419
+ G_FILE_MONITOR_NONE,
387
425
+ G_CALLBACK (on_icon_monitor_changed),
390
+ g_warning ("Unable to monitor %s: %s", user->icon_url, error->message);
428
+ g_warning ("Unable to monitor %s: %s", path, error->message);
391
429
+ g_error_free (error);
393
431
+ g_object_unref (file);
433
+ g_free (user->icon_url);
434
+ user->icon_url = g_strjoin(NULL, "file://", path, NULL);
435
+ g_object_notify (G_OBJECT (user), "icon-url");
397
441
+gdm_user_init (GdmUser *user)
443
+ user->manager = NULL;
399
444
+ user->user_name = NULL;
400
445
+ user->real_name = NULL;
446
+ user->display_name = NULL;
401
447
+ user->sessions = NULL;
448
+ user->icon_url = NULL;
440
489
+ /* Display Name */
441
490
+ if (pwent->pw_gecos && pwent->pw_gecos[0] != '\0') {
442
+ gchar *first_comma;
443
+ gchar *real_name_utf8;
445
+ real_name_utf8 = g_locale_to_utf8 (pwent->pw_gecos, -1, NULL, NULL, NULL);
447
+ first_comma = strchr (real_name_utf8, ',');
491
+ gchar *first_comma = NULL;
492
+ gchar *valid_utf8_name = NULL;
494
+ if (g_utf8_validate (pwent->pw_gecos, -1, NULL)) {
495
+ valid_utf8_name = pwent->pw_gecos;
496
+ first_comma = g_utf8_strchr (valid_utf8_name, -1, ',');
498
+ g_warning ("User %s has invalid UTF-8 in GECOS field. "
499
+ "It would be a good thing to check /etc/passwd.",
500
+ pwent->pw_name ? pwent->pw_name : "");
448
503
+ if (first_comma) {
449
+ real_name = g_strndup (real_name_utf8, first_comma - real_name_utf8);
450
+ g_free (real_name_utf8);
504
+ real_name = g_strndup (valid_utf8_name,
505
+ (first_comma - valid_utf8_name));
506
+ } else if (valid_utf8_name) {
507
+ real_name = g_strdup (valid_utf8_name);
452
+ real_name = real_name_utf8;
455
+ if (real_name[0] == '\0') {
512
+ if (real_name && real_name[0] == '\0') {
456
513
+ g_free (real_name);
457
514
+ real_name = NULL;
622
725
+ return user->login_frequency;
625
+G_CONST_RETURN gchar *
729
+gdm_user_collate (GdmUser *user1,
737
+ g_return_val_if_fail (GDM_IS_USER (user1), 0);
738
+ g_return_val_if_fail (GDM_IS_USER (user2), 0);
740
+ if (user1->real_name != NULL) {
741
+ str1 = user1->real_name;
743
+ str1 = user1->user_name;
746
+ if (user2->real_name != NULL) {
747
+ str2 = user2->real_name;
749
+ str2 = user2->user_name;
752
+ num1 = user1->login_frequency;
753
+ num2 = user2->login_frequency;
754
+ g_debug ("Login freq 1=%u 2=%u", (guint)num1, (guint)num2);
763
+ /* if login frequency is equal try names */
764
+ if (str1 == NULL && str2 != NULL) {
768
+ if (str1 != NULL && str2 == NULL) {
772
+ if (str1 == NULL && str2 == NULL) {
776
+ return g_utf8_collate (str1, str2);
779
+G_CONST_RETURN char *
626
780
+gdm_user_get_icon_url (GdmUser *user)
628
782
+ g_return_val_if_fail (GDM_IS_USER (user), NULL);
680
834
+typedef struct _GdmUser GdmUser;
682
+GType gdm_user_get_type (void) G_GNUC_CONST;
684
+uid_t gdm_user_get_uid (GdmUser *user);
685
+G_CONST_RETURN gchar *gdm_user_get_user_name (GdmUser *user);
686
+G_CONST_RETURN gchar *gdm_user_get_real_name (GdmUser *user);
687
+G_CONST_RETURN gchar *gdm_user_get_home_directory (GdmUser *user);
688
+G_CONST_RETURN gchar *gdm_user_get_shell (GdmUser *user);
689
+guint gdm_user_get_num_sessions (GdmUser *user);
690
+GList *gdm_user_get_sessions (GdmUser *user);
691
+gulong gdm_user_get_login_frequency (GdmUser *user);
692
+G_CONST_RETURN gchar *gdm_user_get_icon_url (GdmUser *user);
836
+GType gdm_user_get_type (void) G_GNUC_CONST;
838
+uid_t gdm_user_get_uid (GdmUser *user);
839
+G_CONST_RETURN char *gdm_user_get_user_name (GdmUser *user);
840
+G_CONST_RETURN char *gdm_user_get_real_name (GdmUser *user);
841
+G_CONST_RETURN char *gdm_user_get_display_name (GdmUser *user);
842
+G_CONST_RETURN char *gdm_user_get_home_directory (GdmUser *user);
843
+G_CONST_RETURN char *gdm_user_get_shell (GdmUser *user);
844
+guint gdm_user_get_num_sessions (GdmUser *user);
845
+GList *gdm_user_get_sessions (GdmUser *user);
846
+gulong gdm_user_get_login_frequency (GdmUser *user);
847
+G_CONST_RETURN char *gdm_user_get_icon_url (GdmUser *user);
849
+gint gdm_user_collate (GdmUser *user1,
697
diff -Nur -x '*.orig' -x '*~' gdm-2.28.1/daemon/gdm-user-manager.c gdm-2.28.1.new/daemon/gdm-user-manager.c
698
--- gdm-2.28.1/daemon/gdm-user-manager.c 1970-01-01 01:00:00.000000000 +0100
699
+++ gdm-2.28.1.new/daemon/gdm-user-manager.c 2009-11-26 17:07:31.437723273 +0100
855
diff -Nur -x '*.orig' -x '*~' gdm-2.30.2/daemon/gdm-user-manager.c gdm-2.30.2.new/daemon/gdm-user-manager.c
856
--- gdm-2.30.2/daemon/gdm-user-manager.c 1970-01-01 10:00:00.000000000 +1000
857
+++ gdm-2.30.2.new/daemon/gdm-user-manager.c 2010-06-09 14:09:31.967221528 +1000
701
859
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
703
861
+ * Copyright (C) 2007-2008 William Jon McCann <mccann@jhu.edu>
1282
+match_real_name_cmpfunc (gconstpointer a,
1288
+ return g_strcmp0 (gdm_user_get_real_name ((GdmUser *) a),
1289
+ gdm_user_get_real_name ((GdmUser *) b));
1293
+match_real_name_hrfunc (gpointer key,
1295
+ gpointer user_data)
1297
+ return (g_strcmp0 (user_data, gdm_user_get_real_name (value)) == 0);
1093
1301
+add_user (GdmUserManager *manager,
1094
1302
+ GdmUser *user)
1096
1306
+ add_sessions_for_user (manager, user);
1307
+ dup = g_hash_table_find (manager->priv->users,
1308
+ match_real_name_hrfunc,
1309
+ (char *) gdm_user_get_real_name (user));
1310
+ if (dup != NULL) {
1311
+ //_gdm_user_show_full_display_name (user);
1312
+ //_gdm_user_show_full_display_name (dup);
1097
1314
+ g_hash_table_insert (manager->priv->users,
1098
1315
+ g_strdup (gdm_user_get_user_name (user)),
1099
1316
+ g_object_ref (user));
1949
+add_included_user (char *username, GdmUserManager *manager)
1953
+ g_debug ("Adding included user %s", username);
1955
+ * The call to gdm_user_manager_get_user will add the user if it is
1956
+ * valid and not already in the hash.
1958
+ user = gdm_user_manager_get_user (manager, username);
1959
+ if (user == NULL) {
1960
+ g_debug ("GdmUserManager: unable to lookup user '%s'", username);
1961
+ g_free (username);
1967
+add_included_users (GdmUserManager *manager)
1969
+ /* Add users who are specifically included */
1970
+ if (manager->priv->include != NULL) {
1971
+ g_slist_foreach (manager->priv->include,
1972
+ (GFunc)add_included_user,
1973
+ (gpointer)manager);
1714
1978
+reload_passwd (GdmUserManager *manager)
1716
1980
+ struct passwd *pwent;
1717
1981
+ GSList *old_users;
1718
1982
+ GSList *new_users;
1719
1983
+ GSList *list;
1722
1987
+ old_users = NULL;
1736
2001
+ for (list = old_users; list; list = list->next) {
1737
2002
+ if (gdm_user_get_num_sessions (list->data) > 0) {
1738
2003
+ g_object_freeze_notify (G_OBJECT (list->data));
2004
+ //_gdm_user_show_short_display_name (list->data);
1739
2005
+ new_users = g_slist_prepend (new_users, g_object_ref (list->data));
1743
+ for (pwent = fgetpwent (fp); pwent != NULL; pwent = fgetpwent (fp)) {
1748
+ /* Skip users below MinimalUID... */
1749
+ if (pwent->pw_uid < DEFAULT_MINIMAL_UID) {
1753
+ /* ...And users w/ invalid shells... */
1754
+ if (pwent->pw_shell == NULL ||
1755
+ !g_hash_table_lookup (manager->priv->shells, pwent->pw_shell)) {
1756
+ g_debug ("GdmUserManager: skipping user with bad shell: %s", pwent->pw_name);
1760
+ /* ...And explicitly excluded users */
1761
+ if (g_hash_table_lookup (manager->priv->exclusions, pwent->pw_name)) {
1762
+ g_debug ("GdmUserManager: explicitly skipping user: %s", pwent->pw_name);
1766
+ user = g_hash_table_lookup (manager->priv->users, pwent->pw_name);
1768
+ /* Update users already in the *new* list */
1769
+ if (g_slist_find (new_users, user)) {
2009
+ if (manager->priv->include_all != TRUE) {
2010
+ g_debug ("GdmUserManager: include_all is FALSE");
2012
+ g_debug ("GdmUserManager: include_all is TRUE");
2014
+ for (pwent = fgetpwent (fp);
2016
+ pwent = fgetpwent (fp)) {
2021
+ /* Skip users below MinimalUID... */
2022
+ if (pwent->pw_uid < DEFAULT_MINIMAL_UID) {
2026
+ /* ...And users w/ invalid shells... */
2027
+ if (pwent->pw_shell == NULL ||
2028
+ !g_hash_table_lookup (manager->priv->shells,
2029
+ pwent->pw_shell)) {
2030
+ g_debug ("GdmUserManager: skipping user with bad shell: %s", pwent->pw_name);
2034
+ /* ...And explicitly excluded users */
2035
+ if (user_in_exclude_list (manager, pwent->pw_name)) {
2036
+ g_debug ("GdmUserManager: explicitly skipping user: %s", pwent->pw_name);
2040
+ user = g_hash_table_lookup (manager->priv->users,
2043
+ /* Update users already in the *new* list */
2044
+ if (g_slist_find (new_users, user)) {
2045
+ _gdm_user_update (user, pwent);
2049
+ if (user == NULL) {
2050
+ user = create_user (manager);
2052
+ g_object_ref (user);
2055
+ /* Freeze & update users not already in the new list */
2056
+ g_object_freeze_notify (G_OBJECT (user));
1770
2057
+ _gdm_user_update (user, pwent);
1774
+ if (user == NULL) {
1775
+ user = create_user (manager);
1777
+ g_object_ref (user);
1780
+ /* Freeze & update users not already in the new list */
1781
+ g_object_freeze_notify (G_OBJECT (user));
1782
+ _gdm_user_update (user, pwent);
1784
+ new_users = g_slist_prepend (new_users, user);
2059
+ new_users = g_slist_prepend (new_users, user);
1787
2063
+ /* Go through and handle removed users */
1796
+ /* Go through and handle added users */
2072
+ /* Go through and handle added users or update display names */
1797
2073
+ for (list = new_users; list; list = list->next) {
1798
+ if (!g_slist_find (old_users, list->data)) {
2074
+ if (g_slist_find (old_users, list->data)) {
2075
+ dup = g_slist_find_custom (new_users,
2077
+ match_real_name_cmpfunc);
2078
+ if (dup != NULL) {
2079
+ //_gdm_user_show_full_display_name (list->data);
2080
+ //_gdm_user_show_full_display_name (dup->data);
1799
2083
+ add_user (manager, list->data);
2087
+ add_included_users (manager);
1803
2089
+ if (!manager->priv->loaded_passwd) {
1804
2090
+ g_signal_emit (manager, signals[USERS_LOADED], 0);
1805
2091
+ manager->priv->loaded_passwd = TRUE;
1929
2222
+ object_class->finalize = gdm_user_manager_finalize;
2224
+ signals [LOADING_USERS] =
2225
+ g_signal_new ("loading-users",
2226
+ G_TYPE_FROM_CLASS (klass),
2227
+ G_SIGNAL_RUN_LAST,
2228
+ G_STRUCT_OFFSET (GdmUserManagerClass, loading_users),
2230
+ g_cclosure_marshal_VOID__VOID,
1931
2232
+ signals [USERS_LOADED] =
1932
2233
+ g_signal_new ("users-loaded",
1933
2234
+ G_TYPE_FROM_CLASS (klass),
1934
2235
+ G_SIGNAL_RUN_LAST,
1935
2236
+ G_STRUCT_OFFSET (GdmUserManagerClass, users_loaded),
1937
+ g_cclosure_marshal_VOID__OBJECT,
2238
+ g_cclosure_marshal_VOID__VOID,
1938
2239
+ G_TYPE_NONE, 0);
1939
2240
+ signals [USER_ADDED] =
1940
2241
+ g_signal_new ("user-added",
2271
+gdm_set_string_list (char *value, GSList **retval)
2273
+ char **temp_array;
2278
+ if (value == NULL || *value == '\0') {
2279
+ g_debug ("Not adding NULL user");
2284
+ temp_array = g_strsplit (value, ",", 0);
2285
+ for (i = 0; temp_array[i] != NULL; i++) {
2286
+ g_debug ("Adding value %s", temp_array[i]);
2287
+ g_strstrip (temp_array[i]);
2288
+ *retval = g_slist_prepend (*retval, g_strdup (temp_array[i]));
2291
+ g_strfreev (temp_array);
1970
2295
+gdm_user_manager_init (GdmUserManager *manager)
1974
2299
+ GError *error;
1975
+ const char *exclude_default[] = DEFAULT_EXCLUDE;
1977
2303
+ manager->priv = GDM_USER_MANAGER_GET_PRIVATE (manager);
2305
+ /* exclude/include */
2306
+ g_debug ("Setting users to include:");
2307
+ res = gdm_settings_direct_get_string (GDM_KEY_INCLUDE,
2309
+ gdm_set_string_list (temp, &manager->priv->include);
2311
+ g_debug ("Setting users to exclude:");
2312
+ res = gdm_settings_direct_get_string (GDM_KEY_EXCLUDE,
2314
+ gdm_set_string_list (temp, &manager->priv->exclude);
2316
+ res = gdm_settings_direct_get_boolean (GDM_KEY_INCLUDE_ALL,
2317
+ &manager->priv->include_all);
1979
2319
+ /* sessions */
1980
2320
+ manager->priv->sessions = g_hash_table_new_full (g_str_hash,
1986
+ manager->priv->exclusions = g_hash_table_new_full (g_str_hash,
1990
+ for (i = 0; exclude_default[i] != NULL; i++) {
1991
+ g_hash_table_insert (manager->priv->exclusions,
1992
+ g_strdup (exclude_default [i]),
1993
+ GUINT_TO_POINTER (TRUE));
1997
+ manager->priv->shells = g_hash_table_new_full (g_str_hash,
2001
+ reload_shells (manager);
2002
+ file = g_file_new_for_path (_PATH_SHELLS);
2004
+ manager->priv->shells_monitor = g_file_monitor_file (file,
2005
+ G_FILE_MONITOR_NONE,
2008
+ if (manager->priv->shells_monitor != NULL) {
2009
+ g_signal_connect (manager->priv->shells_monitor,
2011
+ G_CALLBACK (on_shells_monitor_changed),
2014
+ g_warning ("Unable to monitor %s: %s", _PATH_SHELLS, error->message);
2015
+ g_error_free (error);
2017
+ g_object_unref (file);
2020
2326
+ manager->priv->users = g_hash_table_new_full (g_str_hash,
2023
2329
+ (GDestroyNotify) g_object_run_dispose);
2024
+ file = g_file_new_for_path (PATH_PASSWD);
2025
+ manager->priv->passwd_monitor = g_file_monitor_file (file,
2026
+ G_FILE_MONITOR_NONE,
2029
+ if (manager->priv->passwd_monitor != NULL) {
2030
+ g_signal_connect (manager->priv->passwd_monitor,
2032
+ G_CALLBACK (on_passwd_monitor_changed),
2035
+ g_warning ("Unable to monitor %s: %s", PATH_PASSWD, error->message);
2036
+ g_error_free (error);
2331
+ if (manager->priv->include_all == TRUE) {
2333
+ manager->priv->shells = g_hash_table_new_full (g_str_hash,
2337
+ reload_shells (manager);
2338
+ file = g_file_new_for_path (_PATH_SHELLS);
2340
+ manager->priv->shells_monitor = g_file_monitor_file (file,
2341
+ G_FILE_MONITOR_NONE,
2344
+ if (manager->priv->shells_monitor != NULL) {
2345
+ g_signal_connect (manager->priv->shells_monitor,
2347
+ G_CALLBACK (on_shells_monitor_changed),
2350
+ g_warning ("Unable to monitor %s: %s", _PATH_SHELLS, error->message);
2351
+ g_error_free (error);
2353
+ g_object_unref (file);
2356
+ file = g_file_new_for_path (PATH_PASSWD);
2357
+ manager->priv->passwd_monitor = g_file_monitor_file (file,
2358
+ G_FILE_MONITOR_NONE,
2361
+ if (manager->priv->passwd_monitor != NULL) {
2362
+ g_signal_connect (manager->priv->passwd_monitor,
2364
+ G_CALLBACK (on_passwd_monitor_changed),
2367
+ g_warning ("Unable to monitor %s: %s", PATH_PASSWD, error->message);
2368
+ g_error_free (error);
2370
+ g_object_unref (file);
2038
+ g_object_unref (file);
2041
2373
+ get_seat_proxy (manager);
2043
2375
+ queue_reload_users (manager);
2377
+ manager->priv->users_dirty = FALSE;
2045
2379
+ dbus_g_connection_register_g_object (manager->priv->connection, GDM_USER_MANAGER_DBUS_PATH, G_OBJECT (manager));
2298
2649
+} GdmUserManagerClass;
2653
+ GDM_USER_MANAGER_ERROR_GENERAL,
2654
+ GDM_USER_MANAGER_ERROR_KEY_NOT_FOUND
2655
+} GdmUserManagerError;
2300
2657
+#define GDM_USER_MANAGER_ERROR gdm_user_manager_error_quark ()
2302
2659
+GQuark gdm_user_manager_error_quark (void);
2303
2660
+GType gdm_user_manager_get_type (void);
2305
+GdmUserManager * gdm_user_manager_new (void);
2662
+GdmUserManager * gdm_user_manager_ref_default (void);
2664
+GSList * gdm_user_manager_list_users (GdmUserManager *manager);
2665
+GdmUser * gdm_user_manager_get_user (GdmUserManager *manager,
2666
+ const char *user_name);
2667
+GdmUser * gdm_user_manager_get_user_by_uid (GdmUserManager *manager,
2307
2670
+gboolean gdm_user_manager_count_users (GdmUserManager *user_manager,
2308
2671
+ gint *user_count,
2436
2799
+void _gdm_user_remove_session (GdmUser *user,
2437
2800
+ const char *session_id);
2802
+void _gdm_user_icon_changed (GdmUser *user);
2441
2807
+#endif /* !__GDM_USER_PRIVATE__ */
2442
diff -Nur -x '*.orig' -x '*~' gdm-2.28.1/daemon/main.c gdm-2.28.1.new/daemon/main.c
2443
--- gdm-2.28.1/daemon/main.c 2009-10-20 00:12:45.000000000 +0200
2444
+++ gdm-2.28.1.new/daemon/main.c 2009-11-26 17:07:31.437723273 +0100
2808
diff -Nur -x '*.orig' -x '*~' gdm-2.30.2/daemon/main.c gdm-2.30.2.new/daemon/main.c
2809
--- gdm-2.30.2/daemon/main.c 2010-03-18 08:27:16.000000000 +1100
2810
+++ gdm-2.30.2.new/daemon/main.c 2010-06-09 14:09:08.137025806 +1000
2445
2811
@@ -43,6 +43,7 @@
2446
2812
#include <dbus/dbus-glib.h>
2447
2813
#include <dbus/dbus-glib-lowlevel.h>
2450
2816
#include "gdm-manager.h"
2451
2817
#include "gdm-log.h"
2452
2818
#include "gdm-common.h"
2455
extern char **environ;
2457
+static GdmUserManager *user_manager = NULL;
2458
static GdmManager *manager = NULL;
2459
static GdmSettings *settings = NULL;
2460
static uid_t gdm_uid = -1;
2461
@@ -580,6 +582,12 @@
2465
+ user_manager = gdm_user_manager_new ();
2466
+ if (user_manager == NULL) {
2467
+ g_warning ("Could not construct user manager object");
2823
+ gdm_user_manager_ref_default ();
2471
if (! gdm_settings_direct_init (settings, GDMCONFDIR "/gdm.schemas", "/")) {
2472
g_warning ("Unable to initialize settings");
2474
diff -Nur -x '*.orig' -x '*~' gdm-2.28.1/daemon/Makefile.am gdm-2.28.1.new/daemon/Makefile.am
2475
--- gdm-2.28.1/daemon/Makefile.am 2009-11-26 17:07:26.267716612 +0100
2476
+++ gdm-2.28.1.new/daemon/Makefile.am 2009-11-26 17:07:31.437723273 +0100
2825
gdm_log_set_debug (is_debug_set ());
2827
gdm_daemon_change_user (&gdm_uid, &gdm_gid);
2828
diff -Nur -x '*.orig' -x '*~' gdm-2.30.2/daemon/Makefile.am gdm-2.30.2.new/daemon/Makefile.am
2829
--- gdm-2.30.2/daemon/Makefile.am 2010-03-27 00:28:03.000000000 +1100
2830
+++ gdm-2.30.2.new/daemon/Makefile.am 2010-06-09 14:09:08.137025806 +1000
2477
2831
@@ -9,6 +9,7 @@
2478
2832
-DDATADIR=\"$(datadir)\" \
2479
2833
-DDMCONFDIR=\"$(dmconfdir)\" \