ChangeLog | 13 ++++++++++ configure.in | 6 +++- libpam/include/security/_pam_types.h | 6 ++-- libpam/include/security/pam_ext.h | 4 +- libpam/pam_audit.c | 2 +- libpam/pam_env.c | 8 +++--- libpam/pam_strerror.c | 2 +- libpam/pam_vprompt.c | 4 +- modules/Makefile.am | 1 + modules/pam_lastlog/pam_lastlog.c | 4 +- modules/pam_limits/pam_limits.c | 14 ++++++++++- modules/pam_mkhomedir/pam_mkhomedir.c | 40 +++++++++++++++++++++++++++----- modules/pam_namespace/namespace.init | 5 ++- modules/pam_tally/pam_tally.c | 3 ++ modules/pam_unix/pam_unix_passwd.c | 11 ++------ modules/pam_unix/passverify.c | 14 +++++----- modules/pam_wheel/pam_wheel.8.xml | 6 ++-- modules/pam_wheel/pam_wheel.c | 8 +++++- modules/pam_xauth/pam_xauth.c | 17 +++++++++++-- 19 files changed, 117 insertions(+), 51 deletions(-) diff --git a/ChangeLog b/ChangeLog index f3de7a8..9c86cdf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2009-06-26 Thorsten Kukuk + + * modules/pam_unix/pam_unix_passwd.c: Remove dead SELinux + code. + + * modules/pam_lastlog/pam_lastlog.c (last_login_failed): Fix + usage of wrong variable [bug#2809661]. + +2009-06-25 Thorsten Kukuk + + * configure.in: Rename crypt_gensalt_rn to crypt_gensalt_r + * modules/pam_unix/passverify.c: Likewise. + 2009-06-19 Thorsten Kukuk * release version 1.1.0 diff --git a/configure.in b/configure.in index ba522a5..959a8ca 100644 --- a/configure.in +++ b/configure.in @@ -363,8 +363,8 @@ AM_CONDITIONAL([HAVE_AUDIT_TTY_STATUS], AC_CHECK_HEADERS(xcrypt.h crypt.h) BACKUP_LIBS=$LIBS AC_SEARCH_LIBS([crypt],[xcrypt crypt], LIBCRYPT="-l$ac_lib", LIBCRYPT="") -AC_CHECK_FUNCS(crypt_r crypt_gensalt_rn) -LIBS=$BACKUP_LIBS +AC_CHECK_FUNCS(crypt_r crypt_gensalt_r) +Libs=$BACKUP_LIBS AC_SUBST(LIBCRYPT) if test "$LIBCRYPT" = "-lxcrypt" -a "$ac_cv_header_xcrypt_h" = "yes" ; then AC_DEFINE([HAVE_LIBXCRYPT], 1, [Define to 1 if xcrypt support should be compiled in.]) @@ -556,6 +556,8 @@ AC_CONFIG_FILES([Makefile libpam/Makefile libpamc/Makefile libpamc/test/Makefile modules/pam_umask/Makefile \ modules/pam_unix/Makefile modules/pam_userdb/Makefile \ modules/pam_warn/Makefile modules/pam_wheel/Makefile \ + modules/pam_chroot/Makefile modules/pam_console/Makefile \ + modules/pam_sameuid/Makefile \ modules/pam_xauth/Makefile doc/Makefile doc/specs/Makefile \ doc/man/Makefile doc/sag/Makefile doc/adg/Makefile \ doc/mwg/Makefile examples/Makefile tests/Makefile \ diff --git a/libpam/include/security/_pam_types.h b/libpam/include/security/_pam_types.h index 2d684bc..7a06730 100644 --- a/libpam/include/security/_pam_types.h +++ b/libpam/include/security/_pam_types.h @@ -175,16 +175,16 @@ extern int PAM_NONNULL((1)) pam_get_item(const pam_handle_t *pamh, int item_type, const void **item); extern const char * -pam_strerror(pam_handle_t *pamh, int errnum); +pam_strerror(const pam_handle_t *pamh, int errnum); extern int PAM_NONNULL((1,2)) pam_putenv(pam_handle_t *pamh, const char *name_value); extern const char * PAM_NONNULL((1,2)) -pam_getenv(pam_handle_t *pamh, const char *name); +pam_getenv(const pam_handle_t *pamh, const char *name); extern char ** PAM_NONNULL((1)) -pam_getenvlist(pam_handle_t *pamh); +pam_getenvlist(const pam_handle_t *pamh); /* ---------- Common Linux-PAM application/module PI ----------- */ diff --git a/libpam/include/security/pam_ext.h b/libpam/include/security/pam_ext.h index 26f7156..ddfd7dd 100644 --- a/libpam/include/security/pam_ext.h +++ b/libpam/include/security/pam_ext.h @@ -59,11 +59,11 @@ extern void PAM_FORMAT((printf, 3, 4)) PAM_NONNULL((3)) pam_syslog (const pam_handle_t *pamh, int priority, const char *fmt, ...); extern int PAM_FORMAT((printf, 4, 0)) PAM_NONNULL((1,4)) -pam_vprompt (pam_handle_t *pamh, int style, char **response, +pam_vprompt (const pam_handle_t *pamh, int style, char **response, const char *fmt, va_list args); extern int PAM_FORMAT((printf, 4, 5)) PAM_NONNULL((1,4)) -pam_prompt (pam_handle_t *pamh, int style, char **response, +pam_prompt (const pam_handle_t *pamh, int style, char **response, const char *fmt, ...); #define pam_error(pamh, fmt...) \ diff --git a/libpam/pam_audit.c b/libpam/pam_audit.c index 7f2e0b2..5888b75 100644 --- a/libpam/pam_audit.c +++ b/libpam/pam_audit.c @@ -46,7 +46,7 @@ _pam_audit_writelog(pam_handle_t *pamh, int audit_fd, int type, pamh->audit_state |= PAMAUDIT_LOGGED; if (rc < 0) { - if (rc == -EPERM && getuid() != 0) + if (rc == -EPERM) return 0; if (errno != old_errno) { old_errno = errno; diff --git a/libpam/pam_env.c b/libpam/pam_env.c index dcdac7a..fb3b0f5 100644 --- a/libpam/pam_env.c +++ b/libpam/pam_env.c @@ -22,7 +22,7 @@ /* helper functions */ #ifdef DEBUG -static void _pam_dump_env(pam_handle_t *pamh) +static void _pam_dump_env(const pam_handle_t *pamh) { int i; @@ -282,7 +282,7 @@ int pam_putenv(pam_handle_t *pamh, const char *name_value) * Return the value of the requested environment variable */ -const char *pam_getenv(pam_handle_t *pamh, const char *name) +const char *pam_getenv(const pam_handle_t *pamh, const char *name) { int item; @@ -316,7 +316,7 @@ const char *pam_getenv(pam_handle_t *pamh, const char *name) } } -static char **_copy_env(pam_handle_t *pamh) +static char **_copy_env(const pam_handle_t *pamh) { char **dump; int i = pamh->env->requested; /* reckon size of environment */ @@ -355,7 +355,7 @@ static char **_copy_env(pam_handle_t *pamh) return dump; } -char **pam_getenvlist(pam_handle_t *pamh) +char **pam_getenvlist(const pam_handle_t *pamh) { int i; diff --git a/libpam/pam_strerror.c b/libpam/pam_strerror.c index 17c8194..f296d55 100644 --- a/libpam/pam_strerror.c +++ b/libpam/pam_strerror.c @@ -33,7 +33,7 @@ #include "pam_private.h" -const char *pam_strerror(pam_handle_t *pamh UNUSED, int errnum) +const char *pam_strerror(const pam_handle_t *pamh UNUSED, int errnum) { switch (errnum) { case PAM_SUCCESS: diff --git a/libpam/pam_vprompt.c b/libpam/pam_vprompt.c index c53079b..8e852fe 100644 --- a/libpam/pam_vprompt.c +++ b/libpam/pam_vprompt.c @@ -46,7 +46,7 @@ #include "pam_private.h" int -pam_vprompt (pam_handle_t *pamh, int style, char **response, +pam_vprompt (const pam_handle_t *pamh, int style, char **response, const char *fmt, va_list args) { struct pam_message msg; @@ -101,7 +101,7 @@ pam_vprompt (pam_handle_t *pamh, int style, char **response, } int -pam_prompt (pam_handle_t *pamh, int style, char **response, +pam_prompt (const pam_handle_t *pamh, int style, char **response, const char *fmt, ...) { va_list args; diff --git a/modules/Makefile.am b/modules/Makefile.am index 0c80cea..828265d 100644 --- a/modules/Makefile.am +++ b/modules/Makefile.am @@ -11,6 +11,7 @@ SUBDIRS = pam_access pam_cracklib pam_debug pam_deny pam_echo \ pam_selinux pam_sepermit pam_shells pam_stress \ pam_succeed_if pam_tally pam_tally2 pam_time pam_timestamp \ pam_tty_audit pam_umask \ + pam_chroot pam_console pam_sameuid \ pam_unix pam_userdb pam_warn pam_wheel pam_xauth CLEANFILES = *~ diff --git a/modules/pam_lastlog/pam_lastlog.c b/modules/pam_lastlog/pam_lastlog.c index 8af6b9e..b44c175 100644 --- a/modules/pam_lastlog/pam_lastlog.c +++ b/modules/pam_lastlog/pam_lastlog.c @@ -454,7 +454,7 @@ last_login_failed(pam_handle_t *pamh, int announce, const char *user, time_t llt goto cleanup; } } - + if (line != NULL || date != NULL || host != NULL) { /* TRANSLATORS: "Last failed login: from on " */ pam_info(pamh, _("Last failed login:%s%s%s"), @@ -471,7 +471,7 @@ last_login_failed(pam_handle_t *pamh, int announce, const char *user, time_t llt failed), failed); #else - if (daysleft == 1) + if (failed == 1) retval = asprintf(&line, _("There was %d failed login attempt since the last successful login."), failed); diff --git a/modules/pam_limits/pam_limits.c b/modules/pam_limits/pam_limits.c index f446f9e..5ccac6e 100644 --- a/modules/pam_limits/pam_limits.c +++ b/modules/pam_limits/pam_limits.c @@ -800,14 +800,24 @@ pam_sm_close_session (pam_handle_t *pamh UNUSED, int flags UNUSED, } #ifdef PAM_STATIC +#define pam_sm_acct_mgmt pam_sm_open_session +#elif defined(__linux__) && defined(__ELF__) +__asm__(".globl pam_sm_acct_mgmt; pam_sm_acct_mgmt = pam_sm_open_session"); +#else +PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, + int argc, const char **argv) +{ + return pam_sm_open_session(pamh, flags, argc, argv); +} +#endif +#ifdef PAM_STATIC /* static module data */ - struct pam_module _pam_limits_modstruct = { "pam_limits", NULL, NULL, - NULL, + pam_sm_acct_mgmt, pam_sm_open_session, pam_sm_close_session, NULL diff --git a/modules/pam_mkhomedir/pam_mkhomedir.c b/modules/pam_mkhomedir/pam_mkhomedir.c index dfc4979..16f7d76 100644 --- a/modules/pam_mkhomedir/pam_mkhomedir.c +++ b/modules/pam_mkhomedir/pam_mkhomedir.c @@ -43,6 +43,7 @@ #include #include #include +#include /* * here, we make a definition for the externally accessible function @@ -136,14 +137,27 @@ create_homedir (pam_handle_t *pamh, options_t *opt, static char *envp[] = { NULL }; char *args[] = { NULL, NULL, NULL, NULL, NULL }; - if (getrlimit(RLIMIT_NOFILE, &rlim)==0) { - if (rlim.rlim_max >= MAX_FD_NO) - rlim.rlim_max = MAX_FD_NO; - for (i=0; i < (int)rlim.rlim_max; i++) { - close(i); - } + if (getrlimit(RLIMIT_NOFILE, &rlim) || + rlim.rlim_max > MAX_FD_NO) + rlim.rlim_max = MAX_FD_NO; + for (i = STDERR_FILENO + 1; i < (int)rlim.rlim_max; ++i) + close(i); + + if ((i = open("/dev/null", O_RDWR)) < 0) { + pam_syslog(pamh, LOG_ERR, "failed to open %s: %m", "/dev/null"); + _exit(PAM_SYSTEM_ERR); + } + + if ((i != STDIN_FILENO && dup2(i, STDIN_FILENO) != STDIN_FILENO) || + (i != STDOUT_FILENO && dup2(i, STDOUT_FILENO) != STDOUT_FILENO) || + (i != STDERR_FILENO && dup2(i, STDERR_FILENO) != STDERR_FILENO)) { + pam_syslog(pamh, LOG_ERR, "failed to redirect STDIN/OUT/ERR: %m"); + _exit(PAM_SYSTEM_ERR); } + if (i > STDERR_FILENO) + close(i); + /* exec the mkhomedir helper */ args[0] = x_strdup(MKHOMEDIR_HELPER); args[1] = pwd->pw_name; @@ -242,6 +256,18 @@ int pam_sm_close_session (pam_handle_t * pamh UNUSED, int flags UNUSED, } #ifdef PAM_STATIC +#define pam_sm_acct_mgmt pam_sm_open_session +#elif defined(__linux__) && defined(__ELF__) +__asm__(".globl pam_sm_acct_mgmt; pam_sm_acct_mgmt = pam_sm_open_session"); +#else +PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, + int argc, const char **argv) +{ + return pam_sm_open_session(pamh, flags, argc, argv); +} +#endif + +#ifdef PAM_STATIC /* static module data */ struct pam_module _pam_mkhomedir_modstruct = @@ -249,7 +275,7 @@ struct pam_module _pam_mkhomedir_modstruct = "pam_mkhomedir", NULL, NULL, - NULL, + pam_sm_acct_mgmt, pam_sm_open_session, pam_sm_close_session, NULL, diff --git a/modules/pam_namespace/namespace.init b/modules/pam_namespace/namespace.init index 424c6d0..07ba984 100755 --- a/modules/pam_namespace/namespace.init +++ b/modules/pam_namespace/namespace.init @@ -7,7 +7,8 @@ # newly created home directory. if [ "$3" = 1 ]; then # This line will fix the labeling on all newly created directories - [ -x /sbin/restorecon ] && /sbin/restorecon "$1" + restorecon=/sbin/restorecon + [ -x "$restorecon" ] && "$restorecon" "$1" user="$4" passwd=$(getent passwd "$user") homedir=$(echo "$passwd" | cut -f6 -d":") @@ -17,7 +18,7 @@ if [ "$3" = 1 ]; then chown -R "$user":"$gid" "$homedir" mode=$(awk '/^UMASK/{gsub("#.*$", "", $2); printf "%o", and(0777,compl(strtonum("0" $2))); exit}' /etc/login.defs) chmod ${mode:-700} "$homedir" - [ -x /sbin/restorecon ] && /sbin/restorecon -R "$homedir" + [ -x "$restorecon" ] && "$restorecon" -R "$homedir" fi fi diff --git a/modules/pam_tally/pam_tally.c b/modules/pam_tally/pam_tally.c index dffbc89..a929193 100644 --- a/modules/pam_tally/pam_tally.c +++ b/modules/pam_tally/pam_tally.c @@ -333,6 +333,7 @@ get_tally(pam_handle_t *pamh, tally_t *tally, uid_t uid, } lstat_ret = fstat(fileno(*TALLY),&fileinfo); fclose(*TALLY); + *TALLY = NULL; } if ( lstat_ret ) { @@ -363,6 +364,7 @@ get_tally(pam_handle_t *pamh, tally_t *tally, uid_t uid, if ( fseeko( *TALLY, (off_t) uid * sizeof(struct faillog), SEEK_SET ) ) { pam_syslog(pamh, LOG_ALERT, "fseek failed for %s", filename); fclose(*TALLY); + *TALLY = NULL; return PAM_AUTH_ERR; } @@ -411,6 +413,7 @@ set_tally(pam_handle_t *pamh, tally_t tally, uid_t uid, } if ( fclose(*TALLY) ) { + *TALLY = NULL; pam_syslog(pamh, LOG_ALERT, "update (fclose) failed for %s", filename); return PAM_AUTH_ERR; } diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c index 30ea668..29b9c67 100644 --- a/modules/pam_unix/pam_unix_passwd.c +++ b/modules/pam_unix/pam_unix_passwd.c @@ -1,7 +1,7 @@ /* * Main coding by Elliot Lee , Red Hat Software. * Copyright (C) 1996. - * Copyright (c) Jan Rêkorajski, 1999. + * Copyright (c) Jan Rêkorajski, 1999. * Copyright (c) Red Hat, Inc., 2007, 2008. * * Redistribution and use in source and binary forms, with or without @@ -61,11 +61,6 @@ #include #include #include -#ifdef WITH_SELINUX -static int selinux_enabled=-1; -#include -#define SELINUX_ENABLED (selinux_enabled!=-1 ? selinux_enabled : (selinux_enabled=is_selinux_enabled()>0)) -#endif #include @@ -196,7 +191,7 @@ static int _unix_run_update_binary(pam_handle_t *pamh, unsigned int ctrl, const snprintf(buffer, sizeof(buffer), "%d", remember); args[4] = x_strdup(buffer); - + execve(UPDATE_HELPER, args, envp); /* should not get here: exit with error */ @@ -698,7 +693,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags, pass_new = NULL; } retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new); - + if (retval != PAM_SUCCESS && off(UNIX_NOT_SET_PASS, ctrl)) { pam_set_item(pamh, PAM_AUTHTOK, NULL); } diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c index 8cf95c3..489e856 100644 --- a/modules/pam_unix/passverify.c +++ b/modules/pam_unix/passverify.c @@ -274,7 +274,7 @@ PAMH_ARG_DECL(int check_shadow_expiry, } if ((curdays - spent->sp_lstchg < spent->sp_min) && (spent->sp_min != -1)) { - /* + /* * The last password change was too recent. This error will be ignored * if no password change is attempted. */ @@ -403,11 +403,11 @@ PAMH_ARG_DECL(char * create_password_hash, return crypted; } -#ifdef HAVE_CRYPT_GENSALT_RN +#ifdef HAVE_CRYPT_GENSALT_R if (on(UNIX_BLOWFISH_PASS, ctrl)) { char entropy[17]; crypt_make_salt(entropy, sizeof(entropy) - 1); - sp = crypt_gensalt_rn(algoid, rounds, + sp = crypt_gensalt_r (algoid, rounds, entropy, sizeof(entropy), salt, sizeof(salt)); } else { @@ -420,7 +420,7 @@ PAMH_ARG_DECL(char * create_password_hash, /* For now be conservative so the resulting hashes * are not too long. 8 bytes of salt prevents dictionary * attacks well enough. */ -#ifdef HAVE_CRYPT_GENSALT_RN +#ifdef HAVE_CRYPT_GENSALT_R } #endif sp = crypt(password, salt); @@ -684,7 +684,7 @@ save_old_password(pam_handle_t *pamh, const char *forwho, const char *oldpass, D(("fflush or fsync error writing entries to old passwords file: %m")); err = 1; } - + if (fclose(pwfile)) { D(("fclose error writing entries to old passwords file: %m")); err = 1; @@ -804,7 +804,7 @@ PAMH_ARG_DECL(int unix_update_passwd, D(("fflush or fsync error writing entries to password file: %m")); err = 1; } - + if (fclose(pwfile)) { D(("fclose error writing entries to password file: %m")); err = 1; @@ -930,7 +930,7 @@ PAMH_ARG_DECL(int unix_update_shadow, D(("fflush or fsync error writing entries to shadow file: %m")); err = 1; } - + if (fclose(pwfile)) { D(("fclose error writing entries to shadow file: %m")); err = 1; diff --git a/modules/pam_wheel/pam_wheel.8.xml b/modules/pam_wheel/pam_wheel.8.xml index c0ae68c..07087d4 100644 --- a/modules/pam_wheel/pam_wheel.8.xml +++ b/modules/pam_wheel/pam_wheel.8.xml @@ -121,9 +121,9 @@ - The check for wheel membership will be done against - the current uid instead of the original one (useful when - jumping with su from one account to another for example). + The check for wheel membership will be done against the + current uid; this version of pam_wheel can only work in this + way and ignores the argument. diff --git a/modules/pam_wheel/pam_wheel.c b/modules/pam_wheel/pam_wheel.c index d7d8096..fa4c92c 100644 --- a/modules/pam_wheel/pam_wheel.c +++ b/modules/pam_wheel/pam_wheel.c @@ -110,7 +110,7 @@ perform_check (pam_handle_t *pamh, int ctrl, const char *use_group) retval = pam_get_user(pamh, &username, NULL); if ((retval != PAM_SUCCESS) || (!username)) { if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_DEBUG, "can not get the username"); + pam_syslog(pamh, LOG_DEBUG, "cannot get the username"); } return PAM_SERVICE_ERR; } @@ -118,7 +118,7 @@ perform_check (pam_handle_t *pamh, int ctrl, const char *use_group) pwd = pam_modutil_getpwnam (pamh, username); if (!pwd) { if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_NOTICE, "unknown user %s", username); + pam_syslog(pamh, LOG_NOTICE, "unknown username"); } return PAM_USER_UNKNOWN; } @@ -129,7 +129,9 @@ perform_check (pam_handle_t *pamh, int ctrl, const char *use_group) } } +#if 0 if (ctrl & PAM_USE_UID_ARG) { +#endif tpwd = pam_modutil_getpwuid (pamh, getuid()); if (!tpwd) { if (ctrl & PAM_DEBUG_ARG) { @@ -138,6 +140,7 @@ perform_check (pam_handle_t *pamh, int ctrl, const char *use_group) return PAM_SERVICE_ERR; } fromsu = tpwd->pw_name; +#if 0 } else { fromsu = pam_modutil_getlogin(pamh); if (fromsu) { @@ -150,6 +153,7 @@ perform_check (pam_handle_t *pamh, int ctrl, const char *use_group) return PAM_SERVICE_ERR; } } +#endif /* * At this point fromsu = username-of-invoker; tpwd = pwd ptr for fromsu diff --git a/modules/pam_xauth/pam_xauth.c b/modules/pam_xauth/pam_xauth.c index bc72a8c..3a20b59 100644 --- a/modules/pam_xauth/pam_xauth.c +++ b/modules/pam_xauth/pam_xauth.c @@ -37,6 +37,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -209,8 +212,8 @@ check_acl(pam_handle_t *pamh, { char path[PATH_MAX]; struct passwd *pwd; - FILE *fp; - int i; + FILE *fp = 0; + int fd, i; uid_t euid; /* Check this user's file. */ pwd = pam_modutil_getpwnam(pamh, this_user); @@ -229,8 +232,16 @@ check_acl(pam_handle_t *pamh, } euid = geteuid(); setfsuid(pwd->pw_uid); - fp = fopen(path, "r"); + fd = open(path, O_RDONLY | O_NOCTTY); setfsuid(euid); + if (fd >= 0) { + struct stat st; + + if (fstat(fd, &st) || + !S_ISREG(st.st_mode) || + !(fp = fdopen(fd, "r"))) + close(fd); + } if (fp != NULL) { char buf[LINE_MAX], *tmp; /* Scan the file for a list of specs of users to "trust". */