[gdm] Add support for include, exclude, and include_all configuration options in
- From: Brian Cameron <bcameron src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gdm] Add support for include, exclude, and include_all configuration options in
- Date: Thu, 10 Sep 2009 01:13:22 +0000 (UTC)
commit 7c29be20c07c7200f2bff89883f9d5436fc0dadc
Author: Brian Cameron <Brian Cameron sun com>
Date: Wed Sep 9 20:11:28 2009 -0500
Add support for include, exclude, and include_all configuration options in
the login GUI. Fixes bug #557553.
docs/C/gdm.xml | 56 ++++
gui/simple-greeter/gdm-simple-greeter.schemas.in | 35 +++
gui/simple-greeter/gdm-user-manager.c | 310 ++++++++++++++--------
3 files changed, 285 insertions(+), 116 deletions(-)
---
diff --git a/docs/C/gdm.xml b/docs/C/gdm.xml
index 60ae5cf..17ce2a8 100644
--- a/docs/C/gdm.xml
+++ b/docs/C/gdm.xml
@@ -1569,6 +1569,62 @@ gdm:.my.domain
</varlistentry>
<varlistentry>
+ <term>/apps/gdm/simple-greeter/include</term>
+ <listitem>
+ <synopsis>[] (string list)</synopsis>
+ <para>
+ Set to a list of users to always include in the Face Browser.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>/apps/gdm/simple-greeter/include_all</term>
+ <listitem>
+ <synopsis>true (boolean)</synopsis>
+ <para>
+ If true, then the face browser will show all users on the
+ local machine. If false, the face browser will only show
+ users who have recently logged in.
+ </para>
+ <para>
+ To provide more detail on how this option works. When this key
+ is true, GDM will call fgetpwent() to get a list of local users
+ on the system. The Face Browser also will display any users
+ that have previously logged in on the system (for example
+ NIS/LDAP users). It gets this list via calling the ck-history
+ ConsoleKit interface. It will also filter out any users which
+ do not have a valid shell (valid shells are any shell that
+ getusershell() returns. <filename>/sbin/nologin</filename> or
+ <filename>/bin/false</filename> are considered invalid shells
+ even if getusershell() returns them).
+ </para>
+
+ <para>
+ If false, then GDM more simply only displays users that have
+ previously logged in on the system (local or NIS/LDAP users) by
+ calling the ck-history ConsoleKit interface.
+ </para>
+
+ <para>
+ In both cases, GDM filters out any users with a UID less than
+ 500 (or 100 if running on Solaris). Such users are considered
+ system users.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>/apps/gdm/simple-greeter/exclude</term>
+ <listitem>
+ <synopsis>[] (string list)</synopsis>
+ <para>
+ Set to a list of users to always exclude in the Face Browser.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>/apps/gdm/simple-greeter/logo_icon_name</term>
<listitem>
<synopsis>computer (string)</synopsis>
diff --git a/gui/simple-greeter/gdm-simple-greeter.schemas.in b/gui/simple-greeter/gdm-simple-greeter.schemas.in
index f6e9a6b..e9507e8 100644
--- a/gui/simple-greeter/gdm-simple-greeter.schemas.in
+++ b/gui/simple-greeter/gdm-simple-greeter.schemas.in
@@ -281,6 +281,41 @@
<long></long>
</locale>
</schema>
+ <schema>
+ <key>/schemas/apps/gdm/simple-greeter/include_all</key>
+ <applyto>/apps/gdm/simple-greeter/include_all</applyto>
+ <owner>gdm-simple-greeter</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C">
+ <short>Include local users in Face Browser</short>
+ <long>Set to true to include system local users in Face Browser</long>
+ </locale>
+ </schema>
+ <schema>
+ <key>/schemas/apps/gdm/simple-greeter/include</key>
+ <applyto>/apps/gdm/simple-greeter/include</applyto>
+ <owner>gdm-simple-greeter</owner>
+ <type>list</type>
+ <list_type>string</list_type>
+ <default>[]</default>
+ <locale name="C">
+ <short>Users to include in the Face Browser</short>
+ <long>Set to a list of users to be shown by default in the Face Browser.</long>
+ </locale>
+ </schema>
+ <schema>
+ <key>/schemas/apps/gdm/simple-greeter/exclude</key>
+ <applyto>/apps/gdm/simple-greeter/exclude</applyto>
+ <owner>gdm-simple-greeter</owner>
+ <type>list</type>
+ <list_type>string</list_type>
+ <default>[bin,root,daemon,adm,lp,sync,shutdown,halt,mail,news,uucp,operator,nobody,nobody4,noaccess,postgres,pvm,rpm,nfsnobody,pcap]</default>
+ <locale name="C">
+ <short>Users to exclude in the Face Browser</short>
+ <long>Set to a list of users not to be shown in the Face Browser.</long>
+ </locale>
+ </schema>
</schemalist>
</gconfschemafile>
diff --git a/gui/simple-greeter/gdm-user-manager.c b/gui/simple-greeter/gdm-user-manager.c
index 6c91b3b..bf93cac 100644
--- a/gui/simple-greeter/gdm-user-manager.c
+++ b/gui/simple-greeter/gdm-user-manager.c
@@ -40,6 +40,8 @@
#include <glib-object.h>
#include <gio/gio.h>
+#include <gconf/gconf-client.h>
+
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
@@ -76,34 +78,14 @@
#define DEFAULT_GLOBAL_FACE_DIR DATADIR "/faces"
#define DEFAULT_USER_ICON "stock_person"
-#define DEFAULT_EXCLUDE { "bin", \
- "root", \
- "daemon", \
- "adm", \
- "lp", \
- "sync", \
- "shutdown", \
- "halt", \
- "mail", \
- "news", \
- "uucp", \
- "operator", \
- "nobody", \
- "nobody4", \
- "noaccess", \
- GDM_USERNAME, \
- "postgres", \
- "pvm", \
- "rpm", \
- "nfsnobody", \
- "pcap", \
- NULL }
+#define KEY_INCLUDE_ALL "/apps/gdm/simple-greeter/include_all"
+#define KEY_INCLUDE "/apps/gdm/simple-greeter/include"
+#define KEY_EXCLUDE "/apps/gdm/simple-greeter/exclude"
struct GdmUserManagerPrivate
{
GHashTable *users;
GHashTable *sessions;
- GHashTable *exclusions;
GHashTable *shells;
DBusGConnection *connection;
DBusGProxy *seat_proxy;
@@ -112,6 +94,10 @@ struct GdmUserManagerPrivate
GFileMonitor *passwd_monitor;
GFileMonitor *shells_monitor;
+ GSList *exclude;
+ GSList *include;
+ gboolean include_all;
+
guint reload_id;
guint ck_history_id;
@@ -599,6 +585,39 @@ get_x11_display_for_session (DBusGConnection *connection,
return x11_display;
}
+static gint
+match_name_cmpfunc (gconstpointer a,
+ gconstpointer b)
+{
+ if (a == NULL || b == NULL)
+ return -1;
+
+ return g_strcmp0 ((char *) a,
+ (char *) b);
+}
+
+static gboolean
+check_excludes (GdmUserManager *manager, const char *user)
+{
+ GSList *found;
+ gboolean ret = FALSE;
+
+ g_debug ("checking exclude list");
+
+ /* always exclude the "gdm" user. */
+ if (user == NULL || (strcmp (user, GDM_USERNAME) == 0))
+ return TRUE;
+
+ if (manager->priv->exclude != NULL) {
+ found = g_slist_find_custom (manager->priv->exclude,
+ user,
+ match_name_cmpfunc);
+ if (found != NULL)
+ ret = TRUE;
+ }
+ return ret;
+}
+
static gboolean
maybe_add_session_for_user (GdmUserManager *manager,
GdmUser *user,
@@ -628,7 +647,7 @@ maybe_add_session_for_user (GdmUserManager *manager,
goto out;
}
- if (g_hash_table_lookup (manager->priv->exclusions, gdm_user_get_user_name (user))) {
+ if (check_excludes (manager, gdm_user_get_user_name (user))) {
g_debug ("GdmUserManager: excluding user '%s'", gdm_user_get_user_name (user));
goto out;
}
@@ -906,7 +925,7 @@ seat_session_added (DBusGProxy *seat_proxy,
}
/* check exclusions up front */
- if (g_hash_table_lookup (manager->priv->exclusions, pwent->pw_name)) {
+ if (check_excludes (manager, pwent->pw_name)) {
g_debug ("GdmUserManager: excluding user '%s'", pwent->pw_name);
return;
}
@@ -1222,7 +1241,7 @@ process_ck_history_line (GdmUserManager *manager,
return;
}
- if (g_hash_table_lookup (manager->priv->exclusions, username)) {
+ if (check_excludes (manager, username)) {
g_debug ("GdmUserManager: excluding user '%s'", username);
g_free (username);
return;
@@ -1359,6 +1378,20 @@ reload_ck_history (GdmUserManager *manager)
}
static void
+add_included_user (char *username, GdmUserManager *manager)
+{
+ GdmUser *user;
+
+ g_debug ("Adding included user %s", username);
+ user = gdm_user_manager_get_user (manager, username);
+ if (user == NULL) {
+ g_debug ("GdmUserManager: unable to lookup user '%s'", username);
+ g_free (username);
+ return;
+ }
+}
+
+static void
reload_passwd (GdmUserManager *manager)
{
struct passwd *pwent;
@@ -1390,48 +1423,58 @@ reload_passwd (GdmUserManager *manager)
}
}
- for (pwent = fgetpwent (fp); pwent != NULL; pwent = fgetpwent (fp)) {
- GdmUser *user;
+ if (manager->priv->include_all != TRUE) {
+ g_debug ("GdmUserManager: include_all is FALSE");
+ } else {
+ g_debug ("GdmUserManager: include_all is TRUE");
- user = NULL;
+ for (pwent = fgetpwent (fp);
+ pwent != NULL;
+ pwent = fgetpwent (fp)) {
+ GdmUser *user;
- /* Skip users below MinimalUID... */
- if (pwent->pw_uid < DEFAULT_MINIMAL_UID) {
- continue;
- }
+ user = NULL;
- /* ...And users w/ invalid shells... */
- if (pwent->pw_shell == NULL ||
- !g_hash_table_lookup (manager->priv->shells, pwent->pw_shell)) {
- g_debug ("GdmUserManager: skipping user with bad shell: %s", pwent->pw_name);
- continue;
- }
+ /* Skip users below MinimalUID... */
+ if (pwent->pw_uid < DEFAULT_MINIMAL_UID) {
+ continue;
+ }
- /* ...And explicitly excluded users */
- if (g_hash_table_lookup (manager->priv->exclusions, pwent->pw_name)) {
- g_debug ("GdmUserManager: explicitly skipping user: %s", pwent->pw_name);
- continue;
- }
+ /* ...And users w/ invalid shells... */
+ if (pwent->pw_shell == NULL ||
+ !g_hash_table_lookup (manager->priv->shells,
+ pwent->pw_shell)) {
+ g_debug ("GdmUserManager: skipping user with bad shell: %s", pwent->pw_name);
+ continue;
+ }
- user = g_hash_table_lookup (manager->priv->users, pwent->pw_name);
+ /* ...And explicitly excluded users */
+ if (check_excludes (manager, pwent->pw_name)) {
+ g_debug ("GdmUserManager: explicitly skipping user: %s", pwent->pw_name);
+ continue;
+ }
- /* Update users already in the *new* list */
- if (g_slist_find (new_users, user)) {
- _gdm_user_update (user, pwent);
- continue;
- }
+ user = g_hash_table_lookup (manager->priv->users,
+ pwent->pw_name);
- if (user == NULL) {
- user = create_user (manager);
- } else {
- g_object_ref (user);
- }
+ /* Update users already in the *new* list */
+ if (g_slist_find (new_users, user)) {
+ _gdm_user_update (user, pwent);
+ continue;
+ }
- /* Freeze & update users not already in the new list */
- g_object_freeze_notify (G_OBJECT (user));
- _gdm_user_update (user, pwent);
+ if (user == NULL) {
+ user = create_user (manager);
+ } else {
+ g_object_ref (user);
+ }
+
+ /* Freeze & update users not already in the new list */
+ g_object_freeze_notify (G_OBJECT (user));
+ _gdm_user_update (user, pwent);
- new_users = g_slist_prepend (new_users, user);
+ new_users = g_slist_prepend (new_users, user);
+ }
}
/* Go through and handle removed users */
@@ -1458,6 +1501,13 @@ reload_passwd (GdmUserManager *manager)
}
}
+ /* Add users who are specifically included */
+ if (manager->priv->include != NULL) {
+ g_slist_foreach (manager->priv->include,
+ (GFunc)add_included_user,
+ (gpointer)manager);
+ }
+
out:
/* Cleanup */
@@ -1618,79 +1668,99 @@ gdm_user_manager_init (GdmUserManager *manager)
int i;
GFile *file;
GError *error;
- const char *exclude_default[] = DEFAULT_EXCLUDE;
+ GConfClient *client;
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);
+ /* exclude/include */
+ error = NULL;
+ client = gconf_client_get_default ();
+ manager->priv->exclude = gconf_client_get_list (client, KEY_EXCLUDE, GCONF_VALUE_STRING, &error);
+ if (error != NULL) {
+ g_debug ("GdmUserManager: unable to get exclude configuration: %s", error->message);
+ g_error_free (error);
+ manager->priv->exclude = NULL;
+ }
- /* exclusions */
- manager->priv->exclusions = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- NULL);
- for (i = 0; exclude_default[i] != NULL; i++) {
- g_hash_table_insert (manager->priv->exclusions,
- g_strdup (exclude_default [i]),
- GUINT_TO_POINTER (TRUE));
+ error = NULL;
+ manager->priv->include = gconf_client_get_list (client, KEY_INCLUDE, GCONF_VALUE_STRING, &error);
+ if (error != NULL) {
+ g_debug ("GdmUserManager: unable to get include configuration: %s", error->message);
+ g_error_free (error);
+ manager->priv->include = NULL;
}
- /* /etc/shells */
- manager->priv->shells = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- NULL);
- reload_shells (manager);
- 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 {
- if (error != NULL) {
- g_warning ("Unable to monitor %s: %s", _PATH_SHELLS, error->message);
- g_error_free (error);
- } else {
- g_warning ("Unable to monitor %s", _PATH_SHELLS);
- }
+ manager->priv->include_all = gconf_client_get_bool (client, KEY_INCLUDE_ALL, &error);
+
+ if (error != NULL) {
+ g_debug ("GdmUserManager: unable to get include_all configuration: %s", error->message);
+ g_error_free (error);
+ manager->priv->include_all = TRUE;
}
- g_object_unref (file);
+ g_object_unref (client);
- /* /etc/passwd */
+ /* sessions */
+ manager->priv->sessions = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ g_free);
+
+ /* users */
manager->priv->users = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
(GDestroyNotify) g_object_run_dispose);
- 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 {
- if (error != NULL) {
- g_warning ("Unable to monitor %s: %s", PATH_PASSWD, error->message);
- g_error_free (error);
+
+ if (manager->priv->include_all == TRUE) {
+ /* /etc/shells */
+ manager->priv->shells = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ NULL);
+ reload_shells (manager);
+ 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 {
+ if (error != NULL) {
+ g_warning ("Unable to monitor %s: %s", _PATH_SHELLS, error->message);
+ g_error_free (error);
+ } else {
+ g_warning ("Unable to monitor %s", _PATH_SHELLS);
+ }
+ }
+ 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", PATH_PASSWD);
+ if (error != NULL) {
+ g_warning ("Unable to monitor %s: %s", PATH_PASSWD, error->message);
+ g_error_free (error);
+ } else {
+ g_warning ("Unable to monitor %s", PATH_PASSWD);
+ }
}
+ g_object_unref (file);
}
- g_object_unref (file);
-
get_seat_proxy (manager);
@@ -1711,6 +1781,14 @@ gdm_user_manager_finalize (GObject *object)
g_return_if_fail (manager->priv != NULL);
+ if (manager->priv->exclude != NULL) {
+ g_slist_free (manager->priv->exclude);
+ }
+
+ if (manager->priv->include != NULL) {
+ g_slist_free (manager->priv->include);
+ }
+
if (manager->priv->seat_proxy != NULL) {
g_object_unref (manager->priv->seat_proxy);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]