Commit 425ce74b authored by Brian Cameron's avatar Brian Cameron Committed by Brian Cameron

Adding per-display configuration support to GDM. Now if user has a file

2006-04-26  Brian Cameron  <brian.cameron@sun.com>

        Adding per-display configuration support to GDM.  Now if user has
        a file named /etc/gdm/custom.conf:<displaynum>, the settings in this
        file will override the /usr/share/gdm/defaults.conf and
        /etc/X11/gdm/custom.conf settings.  Only keys that affect the GUI
        behavior are supported.  These include those in the "gui" and
        "greeter" sections and the security/PamStack key.

        * daemon/gdm.c: Update GET_CONFIG command so it accepts a display
          argument.  It is backwards compatible and will return the per-display
          setting if this is passed in, or the non-display value if not
          passed in.  Fix bug that caused PreFetch key to not just return
          the once as it is supposed to.
        * daemon/gdmconfig.[ch], jui/gdmconfig.c: Updated to support
          per-display configuration.
        * daemon/gdm.h: Updated documentation for new command.  Corrected some
          errors.
        * daemon/verify-pam.c, daemon/gdmconfig.c config/gdm.conf.in: Add
          security/PamStack configuration variable as a per-display setting.
          This allows the sysadmin to specify a different PAM stack, if desired
          and also allows customization per display.  Also added key info for
          some BackgroundProgram keys that were missing.
        * config/PreSession.in: now requests configuration data per-display.
          Will use normal configuration if no per-display config files.
        * gui/.cvsignore: Add gdmsetup.desktop.in
        * gui/gdmdynamic.: Improve usage warning.
        * gui/gdmlogin.c: Add some debug
        * docs/C/gdm.xml: Updated docs to reflect new per-display config.
parent 9f7de058
2006-04-26 Brian Cameron <brian.cameron@sun.com>
Adding per-display configuration support to GDM. Now if user has
a file named /etc/gdm/custom.conf:<displaynum>, the settings in this
file will override the /usr/share/gdm/defaults.conf and
/etc/X11/gdm/custom.conf settings. Only keys that affect the GUI
behavior are supported. These include those in the "gui" and
"greeter" sections and the security/PamStack key.
* daemon/gdm.c: Update GET_CONFIG command so it accepts a display
argument. It is backwards compatible and will return the per-display
setting if this is passed in, or the non-display value if not
passed in. Fix bug that caused PreFetch key to not just return
the once as it is supposed to.
* daemon/gdmconfig.[ch], jui/gdmconfig.c: Updated to support
per-display configuration.
* daemon/gdm.h: Updated documentation for new command. Corrected some
errors.
* daemon/verify-pam.c, daemon/gdmconfig.c config/gdm.conf.in: Add
security/PamStack configuration variable as a per-display setting.
This allows the sysadmin to specify a different PAM stack, if desired
and also allows customization per display. Also added key info for
some BackgroundProgram keys that were missing.
* config/PreSession.in: now requests configuration data per-display.
Will use normal configuration if no per-display config files.
* gui/.cvsignore: Add gdmsetup.desktop.in
* gui/gdmdynamic.: Improve usage warning.
* gui/gdmlogin.c: Add some debug
* docs/C/gdm.xml: Updated docs to reflect new per-display config.
2006-04-25 Brian Cameron <brian.cameron@sun.com> 2006-04-25 Brian Cameron <brian.cameron@sun.com>
* docs/C/gdm.xml. Add units information to TimedLoginDelay. * docs/C/gdm.xml. Add units information to TimedLoginDelay.
......
...@@ -31,7 +31,7 @@ if [ "x$XSETROOT" != "x" ] ; then ...@@ -31,7 +31,7 @@ if [ "x$XSETROOT" != "x" ] ; then
CHECKBACKCOLOR="OK" CHECKBACKCOLOR="OK"
if [ "x$GDM_GREETER_TYPE" = "xTHEMED" ]; then if [ "x$GDM_GREETER_TYPE" = "xTHEMED" ]; then
BACKCOLOR=`gdmflexiserver --command="GET_CONFIG greeter/GraphicalThemedColor"` BACKCOLOR=`gdmflexiserver --command="GET_CONFIG greeter/GraphicalThemedColor $DISPLAY"`
CHECKBACKCOLOR=`echo $BACKCOLOR | sed 's/^\([^ ]*\) .*$/\1/'` CHECKBACKCOLOR=`echo $BACKCOLOR | sed 's/^\([^ ]*\) .*$/\1/'`
if [ "x$CHECKBACKCOLOR" = "xOK" ]; then if [ "x$CHECKBACKCOLOR" = "xOK" ]; then
...@@ -45,11 +45,11 @@ if [ "x$XSETROOT" != "x" ] ; then ...@@ -45,11 +45,11 @@ if [ "x$XSETROOT" != "x" ] ; then
if [ "x$CHECKBACKCOLOR" != "xOK" ] || [ "x$GDM_GREETER_TYPE" = "xPLAIN" ]; then if [ "x$CHECKBACKCOLOR" != "xOK" ] || [ "x$GDM_GREETER_TYPE" = "xPLAIN" ]; then
# Background type can be 0=None, 1=Image & Color, 2=Color, or 3=Image # Background type can be 0=None, 1=Image & Color, 2=Color, or 3=Image
BACKTYPE=`gdmflexiserver --command="GET_CONFIG greeter/BackgroundType"` BACKTYPE=`gdmflexiserver --command="GET_CONFIG greeter/BackgroundType $DISPLAY"`
# Skip if background type does not include a color # Skip if background type does not include a color
if [ "x$BACKTYPE" = "xOK 1" ] || [ "x$BACKTYPE" = "xOK 2" ]; then if [ "x$BACKTYPE" = "xOK 1" ] || [ "x$BACKTYPE" = "xOK 2" ]; then
BACKCOLOR=`gdmflexiserver --command="GET_CONFIG greeter/BackgroundColor"` BACKCOLOR=`gdmflexiserver --command="GET_CONFIG greeter/BackgroundColor $DISPLAY"`
CHECKBACKCOLOR=`echo $BACKCOLOR | sed 's/^\([^ ]*\) .*$/\1/'` CHECKBACKCOLOR=`echo $BACKCOLOR | sed 's/^\([^ ]*\) .*$/\1/'`
if [ "x$CHECKBACKCOLOR" = "xOK" ]; then if [ "x$CHECKBACKCOLOR" = "xOK" ]; then
......
...@@ -239,6 +239,8 @@ CheckDirOwner=true ...@@ -239,6 +239,8 @@ CheckDirOwner=true
# overridden with the value from /etc/default/login if it contains # overridden with the value from /etc/default/login if it contains
# "PASSREQ=[YES|NO]" # "PASSREQ=[YES|NO]"
#PasswordRequired=false #PasswordRequired=false
# Specifies the PAM Stack to use, "gdm" by default.
PamStack=gdm
# XDMCP is the protocol that allows remote login. If you want to log into GDM # XDMCP is the protocol that allows remote login. If you want to log into GDM
# remotely (I'd never turn this on on open network, use ssh for such remote # remotely (I'd never turn this on on open network, use ssh for such remote
...@@ -413,9 +415,15 @@ GraphicalThemedColor=#76848F ...@@ -413,9 +415,15 @@ GraphicalThemedColor=#76848F
# Program to run to draw the background in the standard greeter. Perhaps # Program to run to draw the background in the standard greeter. Perhaps
# something like an xscreensaver hack or some such. # something like an xscreensaver hack or some such.
#BackgroundProgram= #BackgroundProgram=
# if this is true then the background program is run always, otherwise it is # If this is true then the background program is run always, otherwise it is
# only run when the BackgroundType is 0 (None). # only run when the BackgroundType is 0 (None).
#RunBackgroundProgramAlways=false #RunBackgroundProgramAlways=false
# Delay before starting background program
#BackgroundProgramInitialDelay=30
# Should the background program be restarted if it is exited.
#RestartBackgroundProgram=true
# Delay before restarting background program
#BackgroundProgramRestartDelay=30
# Show the Failsafe sessions. These are much MUCH nicer (focus for xterm for # Show the Failsafe sessions. These are much MUCH nicer (focus for xterm for
# example) and more failsafe then those supplied by scripts so distros should # example) and more failsafe then those supplied by scripts so distros should
......
...@@ -3109,31 +3109,48 @@ gdm_handle_user_message (GdmConnection *conn, const gchar *msg, gpointer data) ...@@ -3109,31 +3109,48 @@ gdm_handle_user_message (GdmConnection *conn, const gchar *msg, gpointer data)
gdm_connection_write (conn, "OK\n"); gdm_connection_write (conn, "OK\n");
} else if (strncmp (msg, GDM_SUP_GET_CONFIG " ", } else if (strncmp (msg, GDM_SUP_GET_CONFIG " ",
strlen (GDM_SUP_GET_CONFIG " ")) == 0) { strlen (GDM_SUP_GET_CONFIG " ")) == 0) {
const gchar *key = &msg[strlen (GDM_SUP_GET_CONFIG " ")]; const gchar *parms = &msg[strlen (GDM_SUP_GET_CONFIG " ")];
gchar *retval; gchar **splitstr = g_strsplit (parms, " ", 2);
gchar *retval = NULL;
static gboolean done_prefetch = FALSE; static gboolean done_prefetch = FALSE;
/* /*
* If key is for prefetch do it only once * If the key is for prefetch do it only once
*
* This key is not managed in per-display fashion, only config
* values that affect the GUI are. So okay to process this
* first.
*/ */
if (strcmp(key, GDM_KEY_PRE_FETCH_PROGRAM) == 0) { if (strcmp (splitstr[0], GDM_KEY_PRE_FETCH_PROGRAM) == 0) {
if (done_prefetch) { if (done_prefetch) {
gdm_connection_printf (conn, "OK \n"); gdm_connection_printf (conn, "OK \n");
return;
} else { } else {
gdm_connection_printf (conn, "ERROR 50 Unsupported key <%s>\n", splitstr[0]);
done_prefetch = TRUE; done_prefetch = TRUE;
} }
return;
} }
gdm_config_to_string ((gchar *)key, &retval); if (splitstr[0] != NULL) {
if (retval != NULL) { /*
gdm_connection_printf (conn, "OK %s\n", retval); * Note passing in the display is backwards compatible
g_free (retval); * since if it is NULL, it won't try to load the display
} else { * value at all.
if (gdm_is_valid_key ((gchar *)key)) */
gdm_connection_printf (conn, "OK \n"); gdm_config_to_string (splitstr[0], splitstr[1], &retval);
else
gdm_connection_printf (conn, "ERROR 50 Unsupported key <%s>\n", key); if (retval != NULL) {
gdm_connection_printf (conn, "OK %s\n", retval);
g_free (retval);
} else {
if (gdm_is_valid_key ((gchar *)splitstr[0]))
gdm_connection_printf (conn, "OK \n");
else
gdm_connection_printf (conn,
"ERROR 50 Unsupported key <%s>\n",
splitstr[0]);
}
g_strfreev (splitstr);
} }
} else if (strcmp (msg, GDM_SUP_GET_CONFIG_FILE) == 0) { } else if (strcmp (msg, GDM_SUP_GET_CONFIG_FILE) == 0) {
GString *msg; GString *msg;
......
...@@ -146,10 +146,13 @@ enum { ...@@ -146,10 +146,13 @@ enum {
* Developers who add new configuration options should ensure that they do the * Developers who add new configuration options should ensure that they do the
* following: * following:
* *
* + Edit the config/gdm.conf file to include the default setting.
*
* + Specify the same default in this file as in the config/gdm.conf.in file. * + Specify the same default in this file as in the config/gdm.conf.in file.
* *
* + Update the gdm_config_init function in daemon/gdmconfig.c to add the * + Update the gdm_config_init function in daemon/gdmconfig.c to add the
* new key. * new key. Include some documentation about the new key, following the
* style of existing comments.
* *
* + Add any validation to the _gdm_set_value_string, _gdm_set_value_int, * + Add any validation to the _gdm_set_value_string, _gdm_set_value_int,
* and/or _gdm_set_value_bool functions (depending on the type of the new * and/or _gdm_set_value_bool functions (depending on the type of the new
...@@ -163,17 +166,34 @@ enum { ...@@ -163,17 +166,34 @@ enum {
* *
* + If the option should cause the greeter (gdmlogin/gdmgreeter) program to * + If the option should cause the greeter (gdmlogin/gdmgreeter) program to
* be updated immediately, make sure to update the appropriate * be updated immediately, make sure to update the appropriate
* _gdm_set_value_* function in gdmconfig.c causes a call to * _gdm_set_value_* function in gdmconfig.c. This function calls the
* notify_displays_* when this value is changed. Supporting logic will * notify_displays_* function to call when this value is changed, so you
* also be needed in the gdm_slave_handle_notify function in slave.c. * will need to add your new config value to the list of values sending
* It should be simple to see how to do this from the other examples. * such notification. Supporting logic will need to be added to
* gdm_slave_handle_notify function in slave.c to process the notify.
* It should be clear to see how to do this from the existing code.
* *
* + Add the key to the gdm_read_config and gdm_reread_config functions in * + Add the key to the gdm_read_config and gdm_reread_config functions in
* gui/gdmlogin.c, gui/gdmchooser.c, and gui/greeter/greeter.c * gui/gdmlogin.c, gui/gdmchooser.c, and gui/greeter/greeter.c
* if the key is used by those programs. * if the key is used by those programs. Note that all GDM slaves load
* all their configuration data between calls to gdmcomm_comm_bulk_start()
* and gdmcomm_comm_bulk_stop(). This makes sure that the slave only uses
* a single sockets connection to get all configuration data. If a new
* config value is read by a slave, make sure to load the key in this
* code section for best performance.
* *
* + The gui/gdmsetup.c program should be updated to support the new option * + The gui/gdmsetup.c program should be updated to support the new option
* unless there's a good reason not to. * unless there's a good reason not to (like it is a configuration value
* that only someone who really knows what they are doing should change
* like GDM_KEY_PID_FILE).
*
* + Currently GDM treats any key in the "gui" and "greeter" categories,
* and security/PamStack as available for per-display configuration.
* If a key is appropriate for per-display configuration, and is not
* in the "gui" or "greeter" categories, then it will need to be added
* to the gdm_config_key_to_string_per_display function. It may make
* sense for some keys used by the daemon to be per-display so this
* will need to be coded (refer to GDM_KEY_PAM_STACK for an example).
* *
* + Update the docs/C/gdm.xml file to include information about the new * + Update the docs/C/gdm.xml file to include information about the new
* option. Include information about any other interfaces (such as * option. Include information about any other interfaces (such as
...@@ -275,6 +295,7 @@ enum { ...@@ -275,6 +295,7 @@ enum {
#define GDM_KEY_CHECK_DIR_OWNER "security/CheckDirOwner=true" #define GDM_KEY_CHECK_DIR_OWNER "security/CheckDirOwner=true"
#define GDM_KEY_RETRY_DELAY "security/RetryDelay=1" #define GDM_KEY_RETRY_DELAY "security/RetryDelay=1"
#define GDM_KEY_DISALLOW_TCP "security/DisallowTCP=true" #define GDM_KEY_DISALLOW_TCP "security/DisallowTCP=true"
#define GDM_KEY_PAM_STACK "security/PamStack=gdm"
#define GDM_KEY_NEVER_PLACE_COOKIES_ON_NFS "security/NeverPlaceCookiesOnNFS=true" #define GDM_KEY_NEVER_PLACE_COOKIES_ON_NFS "security/NeverPlaceCookiesOnNFS=true"
#define GDM_KEY_PASSWORD_REQUIRED "security/PasswordRequired=false" #define GDM_KEY_PASSWORD_REQUIRED "security/PasswordRequired=false"
...@@ -858,14 +879,15 @@ void gdm_final_cleanup (void); ...@@ -858,14 +879,15 @@ void gdm_final_cleanup (void);
*/ */
#define GDM_SUP_RELEASE_DYNAMIC_DISPLAYS "RELEASE_DYNAMIC_DISPLAYS" #define GDM_SUP_RELEASE_DYNAMIC_DISPLAYS "RELEASE_DYNAMIC_DISPLAYS"
/* /*
* RELEASE_DYNAMIC_DISPLAYS: Release dynamic displays currently in * RELEASE_DYNAMIC_DISPLAYS: Release and begin managing dynamic displays
* DISPLAY_CONFIG state * currently in DISPLAY_CONFIG state
* Supported since: 2.8.0.0 * Supported since: 2.8.0.0
* Arguments: None * Arguments: <display to release>
* Answers: * Answers:
* OK * OK
* ERROR * ERROR
* 0 = Not implemented * 0 = Not implemented
* 1 = Bad display number
* 100 = Not authenticated * 100 = Not authenticated
* 200 = Dynamic Displays not allowed * 200 = Dynamic Displays not allowed
* 999 = Unknown error * 999 = Unknown error
...@@ -880,6 +902,7 @@ void gdm_final_cleanup (void); ...@@ -880,6 +902,7 @@ void gdm_final_cleanup (void);
* OK * OK
* ERROR * ERROR
* 0 = Not implemented * 0 = Not implemented
* 1 = Bad display number
* 100 = Not authenticated * 100 = Not authenticated
* 200 = Dynamic Displays not allowed * 200 = Dynamic Displays not allowed
* 999 = Unknown error * 999 = Unknown error
...@@ -974,14 +997,18 @@ void gdm_final_cleanup (void); ...@@ -974,14 +997,18 @@ void gdm_final_cleanup (void);
/* GET_CONFIG: Get configuration value for key. Useful so /* GET_CONFIG: Get configuration value for key. Useful so
* that other applications can request configuration * that other applications can request configuration
* information from GDM. Any key defined as GDM_KEY_* * information from GDM. Any key defined as GDM_KEY_*
* in gdm.h is * supported. Starting with version 2.13.0.2 * in gdm.h is supported. Starting with version 2.13.0.2
* translated keys (such as "greeter/GdmWelcome[cs]" are * translated keys (such as "greeter/GdmWelcome[cs]" are
* supported via GET_CONFIG. Also starting with version * supported via GET_CONFIG. Also starting with version
* 2.13.0.2 it is no longer necessary to include the * 2.13.0.2 it is no longer necessary to include the
* default value (i.e. you can use key "greeter/IncludeAll" * default value (i.e. you can use key "greeter/IncludeAll"
* instead of having to use "greeter/IncludeAll=false". * instead of having to use "greeter/IncludeAll=false".
* Starting with version 2.14.4, GDM supports per-display
* configuration (for GUI slave clients only) and accepts
* the display argument to retrieve per-display value (if
* any.
* Supported since: 2.6.0.9 * Supported since: 2.6.0.9
* Arguments: <key> * Arguments: <key> [<display>]
* Answers: * Answers:
* OK <value> * OK <value>
* ERROR <err number> <english error description> * ERROR <err number> <english error description>
...@@ -1010,7 +1037,7 @@ void gdm_final_cleanup (void); ...@@ -1010,7 +1037,7 @@ void gdm_final_cleanup (void);
* Supported since: 2.14.0.0 * Supported since: 2.14.0.0
* Arguments: None * Arguments: None
* Answers: * Answers:
* OK <full path to GDM configuration file> * OK <full path to GDM custom configuration file>
* ERROR <err number> <english error description> * ERROR <err number> <english error description>
* 0 = Not implemented * 0 = Not implemented
* 1 = File not found * 1 = File not found
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include "vicious.h" #include "vicious.h"
#include "gdm.h" #include "gdm.h"
#include "gdmconfig.h"
#include "verify.h" #include "verify.h"
#include "gdm-net.h" #include "gdm-net.h"
#include "misc.h" #include "misc.h"
...@@ -136,6 +137,7 @@ static gchar *GdmSoundOnLoginFile = NULL; ...@@ -136,6 +137,7 @@ static gchar *GdmSoundOnLoginFile = NULL;
static gchar *GdmSoundOnLoginSuccessFile = NULL; static gchar *GdmSoundOnLoginSuccessFile = NULL;
static gchar *GdmSoundOnLoginFailureFile = NULL; static gchar *GdmSoundOnLoginFailureFile = NULL;
static gchar *GdmConsoleCannotHandle = NULL; static gchar *GdmConsoleCannotHandle = NULL;
static gchar *GdmPamStack = NULL;
static gint GdmXineramaScreen = 0; static gint GdmXineramaScreen = 0;
static gint GdmUserMaxFile = 0; static gint GdmUserMaxFile = 0;
...@@ -504,6 +506,7 @@ gdm_config_init (void) ...@@ -504,6 +506,7 @@ gdm_config_init (void)
gdm_config_add_hash (GDM_KEY_HOSTS, &GdmHosts, &string_type); gdm_config_add_hash (GDM_KEY_HOSTS, &GdmHosts, &string_type);
gdm_config_add_hash (GDM_KEY_PRE_FETCH_PROGRAM, gdm_config_add_hash (GDM_KEY_PRE_FETCH_PROGRAM,
&GdmPreFetchProgram, &string_type); &GdmPreFetchProgram, &string_type);
gdm_config_add_hash (GDM_KEY_PAM_STACK, &GdmPamStack, &string_type);
/* int values */ /* int values */
gdm_config_add_hash (GDM_KEY_XINERAMA_SCREEN, &GdmXineramaScreen, &int_type); gdm_config_add_hash (GDM_KEY_XINERAMA_SCREEN, &GdmXineramaScreen, &int_type);
...@@ -609,6 +612,19 @@ gdm_get_custom_config (struct stat *statbuf) ...@@ -609,6 +612,19 @@ gdm_get_custom_config (struct stat *statbuf)
} }
} }
/**
* gdm_get_display_custom_config_file
*
* Returns the per-display config file for a given display
* This is always the custom config file name with the display
* appended, and never gdm.conf.
*/
gchar *
gdm_get_display_custom_config_file (gchar *display)
{
g_strdup_printf ("%s%s", custom_config_file, display);
}
/** /**
* gdm_get_custom_config_file * gdm_get_custom_config_file
* *
...@@ -704,6 +720,91 @@ gdm_get_value_bool (char *key) ...@@ -704,6 +720,91 @@ gdm_get_value_bool (char *key)
return FALSE; return FALSE;
} }
/**
* gdm_config_key_to_string_per_display
*
* If the key makes sense to be per-display, return the value,
* otherwise return NULL. Keys that only apply to the daemon
* process do not make sense for per-display configuration
* Valid keys include any key in the greeter or gui categories,
* and the GDM_KEY_PAM_STACK key.
*
* If additional keys make sense for per-display usage, make
* sure they are added to the if-test below.
*/
void
gdm_config_key_to_string_per_display (gchar *display, gchar *key, gchar **retval)
{
gchar *file = gdm_get_display_custom_config_file (display);
gchar **splitstr = g_strsplit (key, "/", 2);
*retval = NULL;
if (display == NULL)
return;
if (strcmp (ve_sure_string (splitstr[0]), "greeter") == 0 ||
strcmp (ve_sure_string (splitstr[0]), "gui") == 0 ||
strcmp (ve_sure_string (key), GDM_KEY_PAM_STACK) == 0) {
gdm_config_key_to_string (file, key, retval);
}
return;
}
/**
* gdm_config_key_to_string
*
* Returns a specific key from the config file, or NULL if not found.
* Note this returns the value in string form, so the caller needs
* to parse it properly if it is a bool or int.
*/
void
gdm_config_key_to_string (gchar *file, gchar *key, gchar **retval)
{
VeConfig *cfg = ve_config_get (file);
GdmConfigType *type = gdm_config_hash_lookup (type_hash, key);
gchar **splitstr = g_strsplit (key, "/", 2);
*retval = NULL;
/* Should not fail, all keys should have a category. */
if (splitstr[0] == NULL)
return;
/* If file doesn't exist, then just return */
if (cfg == NULL)
return;
GList *list = ve_config_get_keys (cfg, splitstr[0]);
while (list != NULL) {
gchar *display_key = (char *)list->data;
gchar *display_fullkey = g_strdup_printf ("%s/%s", splitstr[0], display_key);
if (is_key (key, display_fullkey)) {
gdm_debug ("Returning value for key <%s>\n", key);
if (*type == CONFIG_BOOL) {
gboolean value = ve_config_get_bool (cfg, key);
if (value)
*retval = g_strdup ("true");
else
*retval = g_strdup ("false");
return;
} else if (*type == CONFIG_INT) {
gint value = ve_config_get_int (cfg, key);
*retval = g_strdup_printf ("%d", value);
return;
} else if (*type == CONFIG_STRING) {
gchar *value = ve_config_get_string (cfg, key);
if (value != NULL)
*retval = g_strdup (value);
return;
}
}
g_free (display_fullkey);
list = list->next;
}
return;
}
/** /**
* gdm_config_to_string * gdm_config_to_string
* *
...@@ -711,9 +812,20 @@ gdm_get_value_bool (char *key) ...@@ -711,9 +812,20 @@ gdm_get_value_bool (char *key)
* GET_CONFIG socket command. * GET_CONFIG socket command.
*/ */
void void
gdm_config_to_string (gchar *key, gchar **retval) gdm_config_to_string (gchar *key, gchar *display, gchar **retval)
{ {
GdmConfigType *type; GdmConfigType *type = gdm_config_hash_lookup (type_hash, key);
*retval = NULL;
/*
* See if there is a per-display config file, returning that value
* if it exists.
*/
if (display) {
gdm_config_key_to_string_per_display (display, key, retval);
if (*retval != NULL)
return;
}
/* First look in translated_hash */ /* First look in translated_hash */
if (translated_hash != NULL) { if (translated_hash != NULL) {
...@@ -724,9 +836,6 @@ gdm_config_to_string (gchar *key, gchar **retval) ...@@ -724,9 +836,6 @@ gdm_config_to_string (gchar *key, gchar **retval)
} }
} }
type = gdm_config_hash_lookup (type_hash, key);
*retval = NULL;
if (type != NULL) { if (type != NULL) {
if (*type == CONFIG_BOOL) { if (*type == CONFIG_BOOL) {
gboolean value = gdm_get_value_bool (key); gboolean value = gdm_get_value_bool (key);
...@@ -2067,39 +2176,6 @@ gdm_set_high_display_num (gint val) ...@@ -2067,39 +2176,6 @@ gdm_set_high_display_num (gint val)
high_display_num = val; high_display_num = val;
} }
/**
* gdm_print_config_option
*
* Called by gdm_print_all_config in a loop to print each key.
*
*/
void
gdm_print_config_option (gpointer key_in, gpointer value_in, gpointer data)
{
gchar *key = (gchar *)key_in;
gchar *retval;
gdm_config_to_string (key, &retval);
if (retval != NULL) {
gdm_debug ("key is %s, value is %s\n", key, retval);
g_free (retval);
} else
gdm_debug ("key is %s, value is <NULL>\n", key);
}
/**
* gdm_print_all_config
*
* Not used by GDM, but useful for debug purposes.
*/
void
gdm_print_all_config (void)
{
gdm_config_parse ();
g_hash_table_foreach (type_hash, gdm_print_config_option, NULL);
}
/** /**
* gdm_is_valid_key * gdm_is_valid_key
* *
......
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#include "ve-misc.h" #include "ve-misc.h"
gchar* gdm_get_display_custom_config_file
(gchar *display);
gchar* gdm_get_custom_config_file (void); gchar* gdm_get_custom_config_file (void);
gchar* gdm_get_value_string (gchar *key); gchar* gdm_get_value_string (gchar *key);
gboolean gdm_get_value_bool (gchar *key); gboolean gdm_get_value_bool (gchar *key);
...@@ -33,7 +35,15 @@ void gdm_set_value_bool (gchar *key, ...@@ -33,7 +35,15 @@ void gdm_set_value_bool (gchar *key,
gboolean value); gboolean value);
void gdm_set_value_int (gchar *key, void gdm_set_value_int (gchar *key,
gint value); gint value);
gboolean gdm_config_to_string (gchar *key, void gdm_config_key_to_string_per_display
(gchar *file,
gchar *key,
gchar **retval);
void gdm_config_key_to_string (gchar *file,
gchar *key,
gchar **retval);
void gdm_config_to_string (gchar *key,
gchar *display,
gchar **retval); gchar **retval);
gboolean gdm_update_config (gchar *key); gboolean gdm_update_config (gchar *key);
void gdm_config_init (void); void gdm_config_init (void);
...@@ -46,7 +56,6 @@ uid_t gdm_get_gdmuid (void); ...@@ -46,7 +56,6 @@ uid_t gdm_get_gdmuid (void);
uid_t gdm_get_gdmgid (void); uid_t gdm_get_gdmgid (void);
gint gdm_get_high_display_num (void); gint gdm_get_high_display_num (void);
void gdm_set_high_display_num (gint val); void gdm_set_high_display_num (gint val);
void gdm_print_all_config (void);
gboolean gdm_is_valid_key (gchar *key); gboolean gdm_is_valid_key (gchar *key);
gboolean gdm_signal_terminthup_was_notified (void); gboolean gdm_signal_terminthup_was_notified (void);
......
...@@ -456,7 +456,7 @@ perhaps_translate_message (const char *msg) ...@@ -456,7 +456,7 @@ perhaps_translate_message (const char *msg)
* authentication system and the actual greeter program */ * authentication system and the actual greeter program */
static gint static gint
gdm_verify_pam_conv (int num_msg, const struct pam_message **msg, gdm_verify_pam_conv (int num_msg, struct pam_message **msg,
struct pam_response **resp, struct pam_response **resp,
void *appdata_ptr) void *appdata_ptr)
{ {
...@@ -486,7 +486,7 @@ gdm_verify_pam_conv (int num_msg, const struct pam_message **msg, ...@@ -486,7 +486,7 @@ gdm_verify_pam_conv (int num_msg, const struct pam_message **msg,
/* Here we set the login if it wasn't already set, /* Here we set the login if it wasn't already set,
* this is kind of anal, but this way we guarantee that * this is kind of anal, but this way we guarantee that
* the greeter always is up to date on the login */ * the greeter always is up to date on the login */
if (pam_get_item (pamh, PAM_USER, &p) == PAM_SUCCESS || if (pam_get_item (pamh, PAM_USER, (void **)&p) == PAM_SUCCESS ||
tmp_PAM_USER != NULL) { tmp_PAM_USER != NULL) {
login = (const char *)p; login = (const char *)p;
...@@ -625,7 +625,7 @@ static struct pam_conv pamc = { ...@@ -625,7 +625,7 @@ static struct pam_conv pamc = {
static char *extra_standalone_message = NULL; static char *extra_standalone_message = NULL;
static gint static gint
gdm_verify_standalone_pam_conv (int num_msg, const struct pam_message **msg, gdm_verify_standalone_pam_conv (int num_msg, struct pam_message **msg,
struct pam_response **resp, struct pam_response **resp,
void *appdata_ptr) void *appdata_ptr)
{ {
...@@ -806,6 +806,7 @@ gdm_verify_user (GdmDisplay *d, ...@@ -806,6 +806,7 @@ gdm_verify_user (GdmDisplay *d,
struct passwd *pwent = NULL; struct passwd *pwent = NULL;
const void *p; const void *p;
char *login, *passreq, *consoleonly; char *login, *passreq, *consoleonly;
char *pam_stack = NULL;
int null_tok = 0; int null_tok = 0;
gboolean credentials_set = FALSE; gboolean credentials_set = FALSE;
gboolean error_msg_given = FALSE; gboolean error_msg_given = FALSE;
...@@ -845,11 +846,20 @@ authenticate_again: ...@@ -845,11 +846,20 @@ authenticate_again:
tmp_PAM_USER = g_strdup (login); tmp_PAM_USER = g_strdup (login);
/* Initialize a PAM session for the user */ /* Initialize a PAM session for the user */
if ( ! create_pamh (d, "gdm", login, &pamc, display, &pamerr)) { /* First try to get value from a per-display config file, then use default */
gdm_config_key_to_string_per_display (
gdm_get_display_custom_config_file ((gchar *)display),
GDM_KEY_PAM_STACK, &pam_stack);
if (pam_stack == NULL)
pam_stack = g_strdup (gdm_get_value_string (GDM_KEY_PAM_STACK));
if ( ! create_pamh (d, pam_stack, login, &pamc, display, &pamerr)) {
if (started_timer) if (started_timer)
gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, ""); gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
g_free (pam_stack);
goto pamerr; goto pamerr;
} }
g_free (pam_stack);
pam_set_item (pamh, PAM_USER_PROMPT, _("Username:")); pam_set_item (pamh, PAM_USER_PROMPT, _("Username:"));
...@@ -924,7 +934,7 @@ authenticate_again: ...@@ -924,7 +934,7 @@ authenticate_again:
g_free (login); g_free (login);
login = NULL; login = NULL;
if ((pamerr = pam_get_item (pamh, PAM_USER, &p)) != PAM_SUCCESS) { if ((pamerr = pam_get_item (pamh, PAM_USER, (void **)&p)) != PAM_SUCCESS) {
login = NULL; login = NULL;
/* is not really an auth problem, but it will /* is not really an auth problem, but it will
pretty much look as such, it shouldn't really pretty much look as such, it shouldn't really
...@@ -1188,6 +1198,7 @@ gdm_verify_setup_user (GdmDisplay *d, const gchar *login, const gchar *display, ...@@ -1188,6 +1198,7 @@ gdm_verify_setup_user (GdmDisplay *d, const gchar *login, const gchar *display,
struct passwd *pwent = NULL; struct passwd *pwent = NULL;
const void *p; const void *p;
char *passreq; char *passreq;
char *pam_stack = NULL;
int null_tok = 0; int null_tok = 0;
gboolean credentials_set; gboolean credentials_set;
const char *after_login; const char *after_login;
...@@ -1211,10 +1222,19 @@ gdm_verify_setup_user (GdmDisplay *d, const gchar *login, const gchar *display, ...@@ -1211,10 +1222,19 @@ gdm_verify_setup_user (GdmDisplay *d, const gchar *login, const gchar *display,
login); login);
/* Initialize a PAM session for the user */ /* Initialize a PAM session for the user */
/* First try to get value from a per-display config file, then use default */
gdm_config_key_to_string_per_display (
gdm_get_display_custom_config_file ((gchar *)display),
GDM_KEY_PAM_STACK, &pam_stack);
if (pam_stack == NULL)
pam_stack = g_strdup (gdm_get_value_string (GDM_KEY_PAM_STACK));