[gdm] Add Include/Exclude/IncludeAll configuration options to GDM. Fixes bug
- From: Brian Cameron <bcameron src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gdm] Add Include/Exclude/IncludeAll configuration options to GDM. Fixes bug
- Date: Mon, 16 Nov 2009 23:59:59 +0000 (UTC)
commit 14f686a863dacffd1a192a309b3ab0f4cbc18b22
Author: Brian Cameron <Brian Cameron sun com>
Date: Mon Nov 16 17:59:07 2009 -0600
Add Include/Exclude/IncludeAll configuration options to GDM. Fixes bug
common/gdm-settings-keys.h | 4 +
data/gdm.conf-custom.in | 6 +-
data/gdm.schemas.in.in | 16 ++
docs/C/gdm.xml | 66 +++++++
gui/simple-greeter/Makefile.am | 2 +
gui/simple-greeter/gdm-user-manager.c | 322 ++++++++++++++++++++------------
gui/simple-greeter/test-user-manager.c | 6 +
gui/user-switch-applet/Makefile.am | 3 +
gui/user-switch-applet/applet.c | 6 +
9 files changed, 314 insertions(+), 117 deletions(-)
---
diff --git a/common/gdm-settings-keys.h b/common/gdm-settings-keys.h
index e0637f5..65a1628 100644
--- a/common/gdm-settings-keys.h
+++ b/common/gdm-settings-keys.h
@@ -35,6 +35,10 @@ G_BEGIN_DECLS
#define GDM_KEY_DEBUG "debug/Enable"
+#define GDM_KEY_INCLUDE "greeter/Include"
+#define GDM_KEY_EXCLUDE "greeter/Exclude"
+#define GDM_KEY_INCLUDE_ALL "greeter/IncludeAll"
+
#define GDM_KEY_DISALLOW_TCP "security/DisallowTCP"
#define GDM_KEY_XDMCP_ENABLE "xdmcp/Enable"
diff --git a/data/gdm.conf-custom.in b/data/gdm.conf-custom.in
index 6cbfaeb..36591e3 100644
--- a/data/gdm.conf-custom.in
+++ b/data/gdm.conf-custom.in
@@ -2,11 +2,13 @@
[daemon]
+[security]
+
[xdmcp]
-[chooser]
+[greeter]
-[security]
+[chooser]
[debug]
diff --git a/data/gdm.schemas.in.in b/data/gdm.schemas.in.in
index a3e06f2..b7e39e2 100644
--- a/data/gdm.schemas.in.in
+++ b/data/gdm.schemas.in.in
@@ -61,6 +61,22 @@
</schema>
<schema>
+ <key>greeter/Include</key>
+ <signature>s</signature>
+ <default></default>
+ </schema>
+ <schema>
+ <key>greeter/Exclude</key>
+ <signature>s</signature>
+ <default>bin,root,daemon,adm,lp,sync,shutdown,halt,mail,news,uucp,operator,nobody,nobody4,noaccess,postgres,pvm,rpm,nfsnobody,pcap</default>
+ </schema>
+ <schema>
+ <key>greeter/IncludeAll</key>
+ <signature>b</signature>
+ <default>false</default>
+ </schema>
+
+ <schema>
<key>xdmcp/Enable</key>
<signature>b</signature>
<default>false</default>
diff --git a/docs/C/gdm.xml b/docs/C/gdm.xml
index d2c38f7..09c5340 100644
--- a/docs/C/gdm.xml
+++ b/docs/C/gdm.xml
@@ -1292,6 +1292,72 @@ TimedLogin=you
</variablelist>
</sect3>
+ <sect3 id="greetersection">
+ <title>Greeter Options</title>
+
+ <variablelist>
+ <title>[greeter]</title>
+
+ <varlistentry>
+ <term>IncludeAll</term>
+ <listitem>
+ <synopsis>IncludeAll=true</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>
+ When this key is true, GDM will call fgetpwent() to get a list
+ of local users on the system. Any users with a user id less
+ than 500 (or 100 if running on Solaris) are filtered out. 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 <command>ck-history</command>
+ ConsoleKit interface. It will also filter out any users which
+ do not have a valid shell (valid shells are any shell that
+ getusershell() returns - /sbin/nologin or /bin/false 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 <command>ck-history</command> ConsoleKit interface.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Include</term>
+ <listitem>
+ <synopsis>Include=</synopsis>
+ <para>
+ Set to a list of users to always include in the Face Browser.
+ This value is set to a list of users separated by commas. By
+ default, the value is empty.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Exclude</term>
+ <listitem>
+ <synopsis>Exclude=bin,root,daemon,adm,lp,sync,shutdown,halt,mail,news,uucp,operator,nobody,nobody4,noaccess,postgres,pvm,rpm,nfsnobody,pcap</synopsis>
+ <para>
+ Set to a list of users to always exclude in the Face Browser.
+ This value is set to a list of users separated by commas. Note
+ that the setting in the <filename>custom.conf</filename>
+ overrides the default value, so if you wish to add additional
+ users to the list, then you need to set the value to the
+ default value with additional users appended to the list.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
<sect3 id="securitysection">
<title>Security Options</title>
diff --git a/gui/simple-greeter/Makefile.am b/gui/simple-greeter/Makefile.am
index 519e652..1fa87cf 100644
--- a/gui/simple-greeter/Makefile.am
+++ b/gui/simple-greeter/Makefile.am
@@ -250,6 +250,7 @@ test_user_chooser_SOURCES = \
test_user_chooser_LDADD = \
libgdmuser.la \
+ $(top_builddir)/common/libgdmcommon.la \
$(COMMON_LIBS) \
$(SIMPLE_GREETER_LIBS) \
$(NULL)
@@ -260,6 +261,7 @@ test_user_manager_SOURCES = \
test_user_manager_LDADD = \
libgdmuser.la \
+ $(top_builddir)/common/libgdmcommon.la \
$(COMMON_LIBS) \
$(SIMPLE_GREETER_LIBS) \
$(NULL)
diff --git a/gui/simple-greeter/gdm-user-manager.c b/gui/simple-greeter/gdm-user-manager.c
index 56ef045..c4fb246 100644
--- a/gui/simple-greeter/gdm-user-manager.c
+++ b/gui/simple-greeter/gdm-user-manager.c
@@ -46,6 +46,7 @@
#include "gdm-user-manager.h"
#include "gdm-user-private.h"
+#include "gdm-settings-keys.h"
#define GDM_USER_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_USER_MANAGER, GdmUserManagerPrivate))
@@ -76,34 +77,11 @@
#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 }
struct GdmUserManagerPrivate
{
GHashTable *users;
GHashTable *sessions;
- GHashTable *exclusions;
GHashTable *shells;
DBusGConnection *connection;
DBusGProxy *seat_proxy;
@@ -112,6 +90,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 +581,43 @@ 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
+user_in_exclude_list (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 (user_in_exclude_list (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 (user_in_exclude_list (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 (user_in_exclude_list (manager, username)) {
g_debug ("GdmUserManager: excluding user '%s'", username);
g_free (username);
return;
@@ -1359,6 +1378,35 @@ reload_ck_history (GdmUserManager *manager)
}
static void
+add_included_user (char *username, GdmUserManager *manager)
+{
+ GdmUser *user;
+
+ g_debug ("Adding included user %s", username);
+ /*
+ * 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, username);
+ if (user == NULL) {
+ g_debug ("GdmUserManager: unable to lookup user '%s'", username);
+ g_free (username);
+ return;
+ }
+}
+
+static void
+add_included_users (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);
+ }
+}
+
+static void
reload_passwd (GdmUserManager *manager)
{
struct passwd *pwent;
@@ -1390,48 +1438,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 (user_in_exclude_list (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);
+ }
- new_users = g_slist_prepend (new_users, 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);
+ }
}
/* Go through and handle removed users */
@@ -1458,6 +1516,8 @@ reload_passwd (GdmUserManager *manager)
}
}
+ add_included_users (manager);
+
out:
/* Cleanup */
@@ -1613,84 +1673,108 @@ gdm_user_manager_class_init (GdmUserManagerClass *klass)
}
static void
+gdm_set_string_list (char *value, GSList **retval)
+{
+ char **temp_array;
+ int i;
+
+ *retval = NULL;
+
+ if (value == NULL || *value == '\0') {
+ g_debug ("Not adding NULL user");
+ *retval = NULL;
+ return;
+ }
+
+ temp_array = g_strsplit (value, ",", 0);
+ for (i = 0; temp_array[i] != NULL; i++) {
+ g_debug ("Adding value %s", temp_array[i]);
+ g_strstrip (temp_array[i]);
+ *retval = g_slist_prepend (*retval, g_strdup (temp_array[i]));
+ }
+
+ g_strfreev (temp_array);
+}
+
+
+static void
gdm_user_manager_init (GdmUserManager *manager)
{
int i;
GFile *file;
GError *error;
- const char *exclude_default[] = DEFAULT_EXCLUDE;
+ char *temp;
+ gboolean res;
manager->priv = GDM_USER_MANAGER_GET_PRIVATE (manager);
+ /* exclude/include */
+ g_debug ("Setting users to include:");
+ res = gdm_settings_client_get_string (GDM_KEY_INCLUDE,
+ &temp);
+ gdm_set_string_list (temp, &manager->priv->include);
+
+ g_debug ("Setting users to exclude:");
+ res = gdm_settings_client_get_string (GDM_KEY_EXCLUDE,
+ &temp);
+ gdm_set_string_list (temp, &manager->priv->exclude);
+
+ res = gdm_settings_client_get_boolean (GDM_KEY_INCLUDE_ALL,
+ &manager->priv->include_all);
+
/* sessions */
manager->priv->sessions = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
g_free);
- /* 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));
- }
-
- /* /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 */
+ /* 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);
+
+ 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 {
+ 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", PATH_PASSWD);
+ g_warning ("Unable to monitor %s: %s", PATH_PASSWD, error->message);
+ g_error_free (error);
}
+ g_object_unref (file);
}
- g_object_unref (file);
-
get_seat_proxy (manager);
@@ -1711,6 +1795,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);
}
diff --git a/gui/simple-greeter/test-user-manager.c b/gui/simple-greeter/test-user-manager.c
index f714e0b..e4c2952 100644
--- a/gui/simple-greeter/test-user-manager.c
+++ b/gui/simple-greeter/test-user-manager.c
@@ -31,6 +31,7 @@
#include <gtk/gtk.h>
#include "gdm-user-manager.h"
+#include "gdm-settings-client.h"
static GdmUserManager *manager = NULL;
@@ -78,6 +79,11 @@ main (int argc, char *argv[])
gtk_init (&argc, &argv);
+ if (! gdm_settings_client_init (GDMCONFDIR "/gdm.schemas", "/")) {
+ g_critical ("Unable to initialize settings client");
+ exit (1);
+ }
+
manager = gdm_user_manager_ref_default ();
g_signal_connect (manager,
"users-loaded",
diff --git a/gui/user-switch-applet/Makefile.am b/gui/user-switch-applet/Makefile.am
index 151fa38..2d2cdc0 100644
--- a/gui/user-switch-applet/Makefile.am
+++ b/gui/user-switch-applet/Makefile.am
@@ -2,6 +2,7 @@ NULL =
AM_CPPFLAGS = \
-I$(top_srcdir)/gui/simple-greeter \
+ -I$(top_srcdir)/common \
-DPREFIX=\""$(prefix)"\" \
-DLIBDIR=\""$(libdir)"\" \
-DDATADIR=\""$(datadir)"\" \
@@ -11,6 +12,7 @@ AM_CPPFLAGS = \
-DGLADEDIR=\""$(pkgdatadir)"\" \
-DLIBEXECDIR=\""$(libexecdir)"\" \
-DSBINDIR=\""$(sbindir)"\" \
+ -DGDMCONFDIR=\"$(gdmconfdir)\" \
$(GTK_CFLAGS) \
$(APPLET_CFLAGS) \
$(NULL)
@@ -27,6 +29,7 @@ gdm_user_switch_applet_SOURCES = \
gdm_user_switch_applet_LDADD = \
$(top_builddir)/gui/simple-greeter/libgdmuser.la \
+ $(top_builddir)/common/libgdmcommon.la \
$(COMMON_LIBS) \
$(APPLET_LIBS) \
$(NULL)
diff --git a/gui/user-switch-applet/applet.c b/gui/user-switch-applet/applet.c
index a72997b..3d5b2e7 100644
--- a/gui/user-switch-applet/applet.c
+++ b/gui/user-switch-applet/applet.c
@@ -42,6 +42,7 @@
#include "gdm-user-manager.h"
#include "gdm-entry-menu-item.h"
+#include "gdm-settings-client.h"
#define LOCKDOWN_DIR "/desktop/gnome/lockdown"
#define LOCKDOWN_USER_SWITCHING_KEY LOCKDOWN_DIR "/disable_user_switching"
@@ -1424,6 +1425,11 @@ fill_applet (PanelApplet *applet)
adata->applet = applet;
adata->panel_size = 24;
+ if (! gdm_settings_client_init (GDMCONFDIR "/gdm.schemas", "/")) {
+ g_critical ("Unable to initialize settings client");
+ exit (1);
+ }
+
adata->client = gconf_client_get_default ();
gtk_widget_set_tooltip_text (GTK_WIDGET (applet), _("Change account settings and status"));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]