From d9719b48ab49957f5b983bfcfadf25d23e6674ed Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Tue, 2 Dec 2008 15:13:43 +0000 Subject: Relevant BUGIDs: Purpose of commit: new features Commit summary: --------------- 2008-12-02 Thorsten Kukuk * modules/pam_env/pam_env.c: Add support for user specific environment file. Based on a patch from Ubuntu. * modules/pam_env/pam_env.8.xml: Document new options. --- modules/pam_env/pam_env.8.xml | 39 +++++++++++ modules/pam_env/pam_env.c | 156 +++++++++++++++++++++++------------------- 2 files changed, 125 insertions(+), 70 deletions(-) (limited to 'modules') diff --git a/modules/pam_env/pam_env.8.xml b/modules/pam_env/pam_env.8.xml index 9e9a96a5..e8cd561b 100644 --- a/modules/pam_env/pam_env.8.xml +++ b/modules/pam_env/pam_env.8.xml @@ -34,6 +34,12 @@ readenv=0|1 + + user_envfile=env-file + + + user_readenv=0|1 + @@ -115,6 +121,33 @@ + + + + + + + + Indicate an alternative .pam_environment + file to override the default. This can be useful when different + services need different environments. The filename is relativ to + the user home directory. + + + + + + + + + + + Turns on or off the reading of the user specific environment + file. 0 is off, 1 is on. By default this option is on. + + + + @@ -179,6 +212,12 @@ Default environment file + + $HOME/.pam_environment + + User specific environment file + + diff --git a/modules/pam_env/pam_env.c b/modules/pam_env/pam_env.c index a8cd2c8f..395ada21 100644 --- a/modules/pam_env/pam_env.c +++ b/modules/pam_env/pam_env.c @@ -1,8 +1,6 @@ /* pam_env module */ /* - * $Id$ - * * Written by Dave Kinchlea 1997/01/31 * Inspired by Andrew Morgan , who also supplied the * template for this file (via pam_mail) @@ -11,6 +9,9 @@ #define DEFAULT_ETC_ENVFILE "/etc/environment" #define DEFAULT_READ_ENVFILE 1 +#define DEFAULT_USER_ENVFILE ".pam_environment" +#define DEFAULT_USER_READ_ENVFILE 1 + #include "config.h" #include @@ -38,6 +39,7 @@ #define PAM_SM_ACCOUNT /* "" */ #include +#include #include #include @@ -75,16 +77,19 @@ static char quote='Z'; /* argument parsing */ #define PAM_DEBUG_ARG 0x01 -#define PAM_NEW_CONF_FILE 0x02 -#define PAM_ENV_SILENT 0x04 -#define PAM_NEW_ENV_FILE 0x10 static int _pam_parse (const pam_handle_t *pamh, int argc, const char **argv, - const char **conffile, const char **envfile, int *readenv) + const char **conffile, const char **envfile, int *readenv, + const char **user_envfile, int *user_readenv) { int ctrl=0; + *user_envfile = DEFAULT_USER_ENVFILE; + *envfile = DEFAULT_ETC_ENVFILE; + *readenv = DEFAULT_READ_ENVFILE; + *user_readenv = DEFAULT_USER_READ_ENVFILE; + *conffile = DEFAULT_CONF_FILE; /* step through arguments */ for (; argc-- > 0; ++argv) { @@ -94,49 +99,51 @@ _pam_parse (const pam_handle_t *pamh, int argc, const char **argv, if (!strcmp(*argv,"debug")) ctrl |= PAM_DEBUG_ARG; else if (!strncmp(*argv,"conffile=",9)) { - *conffile = 9 + *argv; - if (**conffile != '\0') { - D(("new Configuration File: %s", *conffile)); - ctrl |= PAM_NEW_CONF_FILE; - } else { - pam_syslog(pamh, LOG_ERR, - "conffile= specification missing argument - ignored"); - } + if (*argv+9 == '\0') { + pam_syslog(pamh, LOG_ERR, + "conffile= specification missing argument - ignored"); + } else { + *conffile = 9+*argv; + D(("new Configuration File: %s", *conffile)); + } } else if (!strncmp(*argv,"envfile=",8)) { - *envfile = 8 + *argv; - if (**envfile != '\0') { - D(("new Env File: %s", *envfile)); - ctrl |= PAM_NEW_ENV_FILE; - } else { - pam_syslog (pamh, LOG_ERR, - "envfile= specification missing argument - ignored"); - } + if (*argv+8 == '\0') { + pam_syslog (pamh, LOG_ERR, + "envfile= specification missing argument - ignored"); + } else { + *envfile = 8+*argv; + D(("new Env File: %s", *envfile)); + } + } else if (!strncmp(*argv,"user_envfile=",13)) { + if (*argv+13 == '\0') { + pam_syslog (pamh, LOG_ERR, + "user_envfile= specification missing argument - ignored"); + } else { + *user_envfile = 13+*argv; + D(("new User Env File: %s", *user_env_file)); + } } else if (!strncmp(*argv,"readenv=",8)) - *readenv = atoi(8+*argv); + *readenv = atoi(8+*argv); + else if (!strncmp(*argv,"user_readenv=",13)) + *user_readenv = atoi(13+*argv); else - pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); + pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); } return ctrl; } static int -_parse_config_file(pam_handle_t *pamh, int ctrl, const char *conffile) +_parse_config_file(pam_handle_t *pamh, const char *file) { int retval; - const char *file; char buffer[BUF_SIZE]; FILE *conf; VAR Var, *var=&Var; - var->name=NULL; var->defval=NULL; var->override=NULL; D(("Called.")); - if (ctrl & PAM_NEW_CONF_FILE) { - file = conffile; - } else { - file = DEFAULT_CONF_FILE; - } + var->name=NULL; var->defval=NULL; var->override=NULL; D(("Config file name is: %s", file)); @@ -184,18 +191,12 @@ _parse_config_file(pam_handle_t *pamh, int ctrl, const char *conffile) } static int -_parse_env_file(pam_handle_t *pamh, int ctrl, const char *env_file) +_parse_env_file(pam_handle_t *pamh, const char *file) { int retval=PAM_SUCCESS, i, t; - const char *file; char buffer[BUF_SIZE], *key, *mark; FILE *conf; - if (ctrl & PAM_NEW_ENV_FILE) - file = env_file; - else - file = DEFAULT_ETC_ENVFILE; - D(("Env file name is: %s", file)); if ((conf = fopen(file,"r")) == NULL) { @@ -702,7 +703,7 @@ static int _define_var(pam_handle_t *pamh, VAR *var) pam_syslog(pamh, LOG_ERR, "out of memory"); return PAM_BUF_ERR; } - + retval = pam_putenv(pamh, envvar); _pam_drop(envvar); D(("Exit.")); @@ -746,30 +747,57 @@ pam_sm_authenticate (pam_handle_t *pamh UNUSED, int flags UNUSED, return PAM_IGNORE; } -PAM_EXTERN int -pam_sm_setcred (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) +static int +handle_env (pam_handle_t *pamh, int argc, const char **argv) { int retval, ctrl, readenv=DEFAULT_READ_ENVFILE; - const char *conf_file = NULL, *env_file = NULL; + int user_readenv = DEFAULT_USER_READ_ENVFILE; + const char *conf_file = NULL, *env_file = NULL, *user_env_file = NULL; /* * this module sets environment variables read in from a file */ D(("Called.")); - ctrl = _pam_parse(pamh, argc, argv, &conf_file, &env_file, &readenv); + ctrl = _pam_parse(pamh, argc, argv, &conf_file, &env_file, + &readenv, &user_env_file, &user_readenv); - retval = _parse_config_file(pamh, ctrl, conf_file); + retval = _parse_config_file(pamh, conf_file); if(readenv && retval == PAM_SUCCESS) { - retval = _parse_env_file(pamh, ctrl, env_file); + retval = _parse_env_file(pamh, env_file); if (retval == PAM_IGNORE) retval = PAM_SUCCESS; } - /* indicate success or failure */ + if(user_readenv && retval == PAM_SUCCESS) { + char *envpath = NULL; + struct passwd *user_entry; + const char *username; + struct stat statbuf; + + username = _pam_get_item_byname(pamh, "PAM_USER"); + user_entry = pam_modutil_getpwnam (pamh, username); + if (!user_entry) { + pam_syslog(pamh, LOG_ERR, "No such user!?"); + } + else { + if (asprintf(&envpath, "%s/%s", user_entry->pw_dir, user_env_file) < 0) + { + pam_syslog(pamh, LOG_ERR, "Out of memory"); + return PAM_BUF_ERR; + } + if (stat(envpath, &statbuf) == 0) { + retval = _parse_config_file(pamh, envpath); + if (retval == PAM_IGNORE) + retval = PAM_SUCCESS; + } + free(envpath); + } + } + + /* indicate success or failure */ D(("Exit.")); return retval; } @@ -782,32 +810,20 @@ pam_sm_acct_mgmt (pam_handle_t *pamh UNUSED, int flags UNUSED, return PAM_SERVICE_ERR; } +PAM_EXTERN int +pam_sm_setcred (pam_handle_t *pamh, int flags UNUSED, + int argc, const char **argv) +{ + D(("Called")); + return handle_env (pamh, argc, argv); +} + PAM_EXTERN int pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED, int argc, const char **argv) { - int retval, ctrl, readenv=DEFAULT_READ_ENVFILE; - const char *conf_file = NULL, *env_file = NULL; - - /* - * this module sets environment variables read in from a file - */ - - D(("Called.")); - ctrl = _pam_parse(pamh, argc, argv, &conf_file, &env_file, &readenv); - - retval = _parse_config_file(pamh, ctrl, conf_file); - - if(readenv && retval == PAM_SUCCESS) { - retval = _parse_env_file(pamh, ctrl, env_file); - if (retval == PAM_IGNORE) - retval = PAM_SUCCESS; - } - - /* indicate success or failure */ - - D(("Exit.")); - return retval; + D(("Called")); + return handle_env (pamh, argc, argv); } PAM_EXTERN int -- cgit v1.2.3