567
user_changed_cb (GDBusConnection *connection,
568
const gchar *sender_name,
569
const gchar *object_path,
570
const gchar *interface_name,
571
const gchar *signal_name,
572
GVariant *parameters,
575
LdmGreeter *greeter = user_data;
576
gchar *username, *real_name, *image;
580
if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sssb)")))
582
g_warning ("Unknown type in %s signal", signal_name);
586
g_variant_get (parameters, "(sssb)", &username, &real_name, &image, &logged_in);
588
user = get_user_by_name (greeter, username);
591
g_debug ("User %s changed", username);
592
ldm_user_set_real_name (user, real_name);
593
ldm_user_set_image (user, image);
594
ldm_user_set_logged_in (user, logged_in);
595
g_signal_emit (greeter, signals[USER_CHANGED], 0, user);
599
g_debug ("User %s added", username);
600
user = ldm_user_new (greeter, username, real_name, image, logged_in);
601
greeter->priv->users = g_list_append (greeter->priv->users, user);
602
g_signal_emit (greeter, signals[USER_ADDED], 0, user);
611
user_removed_cb (GDBusConnection *connection,
612
const gchar *sender_name,
613
const gchar *object_path,
614
const gchar *interface_name,
615
const gchar *signal_name,
616
GVariant *parameters,
619
LdmGreeter *greeter = user_data;
623
if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(s)")))
625
g_warning ("Unknown type in %s signal", signal_name);
629
g_variant_get (parameters, "(s)", &username);
631
user = get_user_by_name (greeter, username);
634
g_debug ("User %s removed", username);
635
greeter->priv->users = g_list_remove (greeter->priv->users, user);
636
g_signal_emit (greeter, signals[USER_REMOVED], 0, user);
637
g_object_unref (user);
587
compare_user (gconstpointer a, gconstpointer b)
589
LdmUser *user_a = (LdmUser *) a, *user_b = (LdmUser *) b;
590
return strcmp (ldm_user_get_display_name (user_a), ldm_user_get_display_name (user_b));
594
load_config (LdmGreeter *greeter)
597
const gchar *config_path = NULL;
599
if (greeter->priv->config)
602
result = g_dbus_proxy_get_cached_property (greeter->priv->lightdm_proxy,
606
g_warning ("No ConfigFile property");
610
if (g_variant_is_of_type (result, G_VARIANT_TYPE_STRING))
611
config_path = g_variant_get_string (result, NULL);
613
g_warning ("Invalid type for config file: %s, expected string", g_variant_get_type_string (result));
617
GError *error = NULL;
619
g_debug ("Loading config from %s", config_path);
621
greeter->priv->config = g_key_file_new ();
622
if (!g_key_file_load_from_file (greeter->priv->config, config_path, G_KEY_FILE_NONE, &error))
623
g_warning ("Failed to load configuration from %s: %s", config_path, error->message); // FIXME: Don't make warning on no file, just info
624
g_clear_error (&error);
627
g_variant_unref (result);
631
load_users (LdmGreeter *greeter)
633
gchar **hidden_users, **hidden_shells;
636
GList *users = NULL, *old_users, *new_users = NULL, *changed_users = NULL, *link;
638
load_config (greeter);
640
if (g_key_file_has_key (greeter->priv->config, "UserManager", "minimum-uid", NULL))
641
minimum_uid = g_key_file_get_integer (greeter->priv->config, "UserManager", "minimum-uid", NULL);
645
value = g_key_file_get_string (greeter->priv->config, "UserManager", "hidden-users", NULL);
647
value = g_strdup ("nobody nobody4 noaccess");
648
hidden_users = g_strsplit (value, " ", -1);
651
value = g_key_file_get_string (greeter->priv->config, "UserManager", "hidden-shells", NULL);
653
value = g_strdup ("/bin/false /usr/sbin/nologin");
654
hidden_shells = g_strsplit (value, " ", -1);
661
struct passwd *entry;
664
gchar *real_name, *image_path, *image;
672
/* Ignore system users */
673
if (entry->pw_uid < minimum_uid)
676
/* Ignore users disabled by shell */
679
for (i = 0; hidden_shells[i] && strcmp (entry->pw_shell, hidden_shells[i]) != 0; i++);
680
if (hidden_shells[i])
684
/* Ignore certain users */
685
for (i = 0; hidden_users[i] && strcmp (entry->pw_name, hidden_users[i]) != 0; i++);
689
tokens = g_strsplit (entry->pw_gecos, ",", -1);
690
if (tokens[0] != NULL && tokens[0][0] != '\0')
691
real_name = g_strdup (tokens[0]);
696
image_path = g_build_filename (entry->pw_dir, ".face", NULL);
697
if (!g_file_test (image_path, G_FILE_TEST_EXISTS))
700
image_path = g_build_filename (entry->pw_dir, ".face.icon", NULL);
701
if (!g_file_test (image_path, G_FILE_TEST_EXISTS))
708
image = g_filename_to_uri (image_path, NULL, NULL);
713
user = ldm_user_new (greeter, entry->pw_name, real_name, entry->pw_dir, image, FALSE);
717
/* Update existing users if have them */
718
for (link = greeter->priv->users; link; link = link->next)
720
LdmUser *info = link->data;
721
if (strcmp (ldm_user_get_name (info), ldm_user_get_name (user)) == 0)
723
// FIXME: Use changed signal from user object?
724
if (g_strcmp0 (ldm_user_get_real_name (info), ldm_user_get_real_name (user)) != 0 ||
725
g_strcmp0 (ldm_user_get_image (info), ldm_user_get_image (user)) != 0 ||
726
g_strcmp0 (ldm_user_get_home_directory (info), ldm_user_get_home_directory (user)) != 0 ||
727
ldm_user_get_logged_in (info) != ldm_user_get_logged_in (user))
729
ldm_user_set_real_name (info, ldm_user_get_real_name (user));
730
ldm_user_set_image (info, ldm_user_get_image (user));
731
ldm_user_set_home_directory (info, ldm_user_get_home_directory (user));
732
ldm_user_set_logged_in (info, ldm_user_get_logged_in (user));
733
g_object_unref (user);
735
changed_users = g_list_insert_sorted (changed_users, user, compare_user);
739
g_object_unref (user);
747
/* Only notify once we have loaded the user list */
748
if (greeter->priv->have_users)
749
new_users = g_list_insert_sorted (new_users, user, compare_user);
751
users = g_list_insert_sorted (users, user, compare_user);
753
g_strfreev (hidden_users);
754
g_strfreev (hidden_shells);
757
g_warning ("Failed to read password database: %s", strerror (errno));
761
/* Use new user list */
762
old_users = greeter->priv->users;
763
greeter->priv->users = users;
765
/* Notify of changes */
766
for (link = new_users; link; link = link->next)
768
LdmUser *info = link->data;
769
g_debug ("User %s added", ldm_user_get_name (info));
770
g_signal_emit (greeter, signals[USER_ADDED], 0, info);
772
g_list_free (new_users);
773
for (link = changed_users; link; link = link->next)
775
LdmUser *info = link->data;
776
g_debug ("User %s changed", ldm_user_get_name (info));
777
g_signal_emit (greeter, signals[USER_CHANGED], 0, info);
779
g_list_free (changed_users);
780
for (link = old_users; link; link = link->next)
784
/* See if this user is in the current list */
785
for (new_link = greeter->priv->users; new_link; new_link = new_link->next)
787
if (new_link->data == link->data)
793
LdmUser *info = link->data;
794
g_debug ("User %s removed", ldm_user_get_name (info));
795
g_signal_emit (greeter, signals[USER_REMOVED], 0, info);
796
g_object_unref (info);
799
g_list_free (old_users);
803
passwd_changed_cb (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, LdmGreeter *greeter)
805
if (event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT)
807
g_debug ("%s changed, reloading user list", g_file_get_path (file));
808
load_users (greeter);
644
813
update_users (LdmGreeter *greeter)
646
GVariant *result, *user_array;
648
gchar *name, *real_name, *image;
650
816
GError *error = NULL;
652
818
if (greeter->priv->have_users)
655
g_dbus_connection_signal_subscribe (greeter->priv->lightdm_bus,
656
"org.lightdm.LightDisplayManager",
657
"org.lightdm.LightDisplayManager.Users",
659
"/org/lightdm/LightDisplayManager/Users",
661
G_DBUS_SIGNAL_FLAGS_NONE,
665
g_dbus_connection_signal_subscribe (greeter->priv->lightdm_bus,
666
"org.lightdm.LightDisplayManager",
667
"org.lightdm.LightDisplayManager.Users",
669
"/org/lightdm/LightDisplayManager/Users",
671
G_DBUS_SIGNAL_FLAGS_NONE,
675
g_dbus_connection_signal_subscribe (greeter->priv->lightdm_bus,
676
"org.lightdm.LightDisplayManager",
677
"org.lightdm.LightDisplayManager.Users",
679
"/org/lightdm/LightDisplayManager/Users",
681
G_DBUS_SIGNAL_FLAGS_NONE,
686
g_debug ("Getting user list...");
687
result = g_dbus_proxy_call_sync (greeter->priv->user_proxy,
690
G_DBUS_CALL_FLAGS_NONE,
695
g_warning ("Failed to get users: %s", error->message);
821
load_config (greeter);
823
/* User listing is disabled */
824
if (g_key_file_has_key (greeter->priv->config, "UserManager", "load-users", NULL) &&
825
!g_key_file_get_boolean (greeter->priv->config, "UserManager", "load-users", NULL))
827
greeter->priv->have_users = TRUE;
831
load_users (greeter);
833
/* Watch for changes to user list */
834
passwd_file = g_file_new_for_path ("/etc/passwd");
835
greeter->priv->passwd_monitor = g_file_monitor (passwd_file, G_FILE_MONITOR_NONE, NULL, &error);
836
g_object_unref (passwd_file);
837
if (!greeter->priv->passwd_monitor)
838
g_warning ("Error monitoring /etc/passwd: %s", error->message);
840
g_signal_connect (greeter->priv->passwd_monitor, "changed", G_CALLBACK (passwd_changed_cb), greeter);
696
841
g_clear_error (&error);
700
if (!g_variant_is_of_type (result, G_VARIANT_TYPE ("(a(sssb))")))
702
g_warning ("Unknown type returned");
703
g_variant_unref (result);
706
user_array = g_variant_get_child_value (result, 0);
707
g_debug ("Got %zi users", g_variant_n_children (user_array));
708
g_variant_iter_init (&iter, user_array);
709
while (g_variant_iter_next (&iter, "(&s&s&sb)", &name, &real_name, &image, &logged_in))
713
user = ldm_user_new (greeter, name, real_name, image, logged_in);
714
greeter->priv->users = g_list_append (greeter->priv->users, user);
717
843
greeter->priv->have_users = TRUE;
719
g_variant_unref (result);