mirror of
https://github.com/linux-pam/linux-pam.git
synced 2024-11-24 10:22:47 +08:00
Relevant BUGIDs:
Purpose of commit: Commit summary: --------------- bugfix: Last part of fixes from Red Hat
This commit is contained in:
parent
b651aa8d81
commit
3f42e813b6
@ -119,6 +119,7 @@ BerliOS Bugs are marked with (BerliOS #XXXX).
|
||||
* Add patches to make PAM modules reentrant (Bug 440107 - kukuk)
|
||||
* Merge patches from Red Hat (Bug 477000 and other - kukuk)
|
||||
* Fix pam_rhosts option parsing (Bug 922648 - kukuk)
|
||||
* Add $ISA support in config files (from Red Hat - kukuk)
|
||||
|
||||
0.77: Mon Sep 23 10:25:42 PDT 2002
|
||||
|
||||
|
@ -97,4 +97,8 @@
|
||||
# include <security/pam_malloc.h>
|
||||
#endif /* MEMORY_DEBUG */
|
||||
|
||||
/* the path, relative to SECUREDIR, where PAMs specific to this architecture
|
||||
* can be found */
|
||||
#undef _PAM_ISA
|
||||
|
||||
#endif /* PAM_ACONF_H */
|
||||
|
25
configure
vendored
25
configure
vendored
@ -846,6 +846,7 @@ Optional Features:
|
||||
--enable-libdebug specify you are building debugging libraries
|
||||
--enable-fakeroot=<path to packaging directory>
|
||||
--enable-securedir=<path to location of PAMs> default \$libdir/security
|
||||
--enable-isadir=<path to arch-specific module files> default ../../\`basename \$libdir\`/security
|
||||
--enable-sconfigdir=<path to module conf files> default \$sysconfdir/security
|
||||
--enable-suplementedir=<path to module helper binaries> default \$sbindir
|
||||
--enable-includedir=<path to include location> - where to put <security>
|
||||
@ -2795,6 +2796,22 @@ else
|
||||
fi;
|
||||
|
||||
|
||||
# Check whether --enable-isadir or --disable-isadir was given.
|
||||
if test "${enable_isadir+set}" = set; then
|
||||
enableval="$enable_isadir"
|
||||
ISA=$enableval
|
||||
else
|
||||
ISA=../../`basename $libdir`/security
|
||||
fi;
|
||||
unset mylibdirbase
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define _PAM_ISA "$ISA"
|
||||
_ACEOF
|
||||
|
||||
echo "$as_me:$LINENO: result: Defining \$ISA to \\"$ISA\\"." >&5
|
||||
echo "${ECHO_T}Defining \$ISA to \\"$ISA\\"." >&6
|
||||
|
||||
# Check whether --enable-sconfigdir or --disable-sconfigdir was given.
|
||||
if test "${enable_sconfigdir+set}" = set; then
|
||||
enableval="$enable_sconfigdir"
|
||||
@ -4410,13 +4427,17 @@ else
|
||||
fi
|
||||
|
||||
|
||||
|
||||
if test $HAVE_LIBNSL = yes ; then
|
||||
pwdblibs="$pwdblibs -lnsl"
|
||||
fi
|
||||
echo "$as_me:$LINENO: checking for pwdb_db_name in -lpwdb" >&5
|
||||
echo $ECHO_N "checking for pwdb_db_name in -lpwdb... $ECHO_C" >&6
|
||||
if test "${ac_cv_lib_pwdb_pwdb_db_name+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lpwdb $LIBS"
|
||||
LIBS="-lpwdb $pwdblibs $LIBS"
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
@ -4484,6 +4505,8 @@ else
|
||||
fi
|
||||
|
||||
|
||||
unset pwdblibs
|
||||
|
||||
echo "$as_me:$LINENO: checking for yywrap in -lfl" >&5
|
||||
echo $ECHO_N "checking for yywrap in -lfl... $ECHO_C" >&6
|
||||
if test "${ac_cv_lib_fl_yywrap+set}" = set; then
|
||||
|
16
configure.in
16
configure.in
@ -87,6 +87,14 @@ AC_ARG_ENABLE(securedir,
|
||||
SECUREDIR=$enableval, SECUREDIR=$libdir/security)
|
||||
AC_SUBST(SECUREDIR)
|
||||
|
||||
AC_ARG_ENABLE(isadir,
|
||||
[ --enable-isadir=<path to arch-specific module files> [default ../../\`basename \$libdir\`/security]],
|
||||
ISA=$enableval,
|
||||
ISA=../../`basename $libdir`/security)
|
||||
unset mylibdirbase
|
||||
AC_DEFINE_UNQUOTED(_PAM_ISA,"$ISA",[Define to the path, relative to SECUREDIR, where PAMs specific to this architecture can be found.])
|
||||
AC_MSG_RESULT([Defining \$ISA to \"$ISA\".])
|
||||
|
||||
AC_ARG_ENABLE(sconfigdir,
|
||||
[ --enable-sconfigdir=<path to module conf files> [default \$sysconfdir/security]],
|
||||
SCONFIGDIR=$enableval, SCONFIGDIR=$sysconfdir/security)
|
||||
@ -212,9 +220,15 @@ AC_SUBST(HAVE_LIBFL)
|
||||
AC_CHECK_LIB(nsl, yp_maplist, HAVE_LIBNSL=yes ; AC_DEFINE(HAVE_LIBNSL),
|
||||
HAVE_LIBNSL=no)
|
||||
AC_SUBST(HAVE_LIBNSL)
|
||||
|
||||
if test $HAVE_LIBNSL = yes ; then
|
||||
pwdblibs="$pwdblibs -lnsl"
|
||||
fi
|
||||
AC_CHECK_LIB(pwdb, pwdb_db_name, HAVE_LIBPWDB=yes ; AC_DEFINE(HAVE_LIBPWDB),
|
||||
HAVE_LIBPWDB=no)
|
||||
HAVE_LIBPWDB=no,$pwdblibs)
|
||||
AC_SUBST(HAVE_LIBPWDB)
|
||||
unset pwdblibs
|
||||
|
||||
AC_CHECK_LIB(fl, yywrap, HAVE_LIBFLEX=yes ; AC_DEFINE(HAVE_LIBFLEX),
|
||||
HAVE_LIBFLEX=no)
|
||||
AC_SUBST(HAVE_LIBFLEX)
|
||||
|
@ -34,6 +34,9 @@
|
||||
#define BUF_SIZE 1024
|
||||
#define MODULE_CHUNK 4
|
||||
#define UNKNOWN_MODULE_PATH "<*unknown module path*>"
|
||||
#ifndef _PAM_ISA
|
||||
#define _PAM_ISA "."
|
||||
#endif
|
||||
|
||||
static int _pam_assemble_line(FILE *f, char *buf, int buf_len);
|
||||
|
||||
@ -313,7 +316,7 @@ int _pam_init_handlers(pam_handle_t *pamh)
|
||||
}
|
||||
|
||||
D(("_pam_init_handlers: initializing"));
|
||||
|
||||
|
||||
/* First clean the service structure */
|
||||
|
||||
_pam_free_handlers(pamh);
|
||||
@ -358,7 +361,7 @@ int _pam_init_handlers(pam_handle_t *pamh)
|
||||
*/
|
||||
{
|
||||
struct stat test_d;
|
||||
|
||||
|
||||
/* Is there a PAM_CONFIG_D directory? */
|
||||
if ( stat(PAM_CONFIG_D, &test_d) == 0 && S_ISDIR(test_d.st_mode) ) {
|
||||
char *filename;
|
||||
@ -575,7 +578,7 @@ int _pam_add_handler(pam_handle_t *pamh
|
||||
#ifdef PAM_SHL
|
||||
const char *_sym, *_sym2;
|
||||
#endif
|
||||
char *mod_full_path=NULL;
|
||||
char *mod_full_path=NULL, *mod_full_isa_path=NULL, *isa=NULL;
|
||||
servicefn func, func2;
|
||||
int success;
|
||||
|
||||
@ -639,6 +642,30 @@ int _pam_add_handler(pam_handle_t *pamh
|
||||
dlopen(mod_path, RTLD_NOW);
|
||||
# endif /* PAM_SHL */
|
||||
D(("_pam_add_handler: dlopen'ed"));
|
||||
if (mod->dl_handle == NULL) {
|
||||
if (strstr(mod_path, "$ISA")) {
|
||||
mod_full_isa_path = malloc(strlen(mod_path) + strlen(_PAM_ISA) + 1);
|
||||
if (mod_full_isa_path == NULL) {
|
||||
D(("_pam_handler: couldn't get memory for mod_path"));
|
||||
_pam_system_log(LOG_ERR, "no memory for module path");
|
||||
success = PAM_ABORT;
|
||||
} else {
|
||||
strcpy(mod_full_isa_path, mod_path);
|
||||
isa = strstr(mod_full_isa_path, "$ISA");
|
||||
if (isa) {
|
||||
memmove(isa + strlen(_PAM_ISA), isa + 4, strlen(isa + 4) + 1);
|
||||
memmove(isa, _PAM_ISA, strlen(_PAM_ISA));
|
||||
}
|
||||
mod->dl_handle =
|
||||
# ifdef PAM_SHL
|
||||
shl_load(mod_full_isa_path, BIND_IMMEDIATE, 0L);
|
||||
# else /* PAM_SHL */
|
||||
dlopen(mod_full_isa_path, RTLD_NOW);
|
||||
# endif /* PAM_SHL */
|
||||
_pam_drop(mod_full_isa_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mod->dl_handle == NULL) {
|
||||
D(("_pam_add_handler: dlopen(%s) failed", mod_path));
|
||||
_pam_system_log(LOG_ERR, "unable to dlopen(%s)", mod_path);
|
||||
@ -782,7 +809,7 @@ int _pam_add_handler(pam_handle_t *pamh
|
||||
}
|
||||
|
||||
/* now identify this module's functions - for non-faulty modules */
|
||||
|
||||
|
||||
#ifdef PAM_DYNAMIC
|
||||
if ((mod->type == PAM_MT_DYNAMIC_MOD) &&
|
||||
# ifdef PAM_SHL
|
||||
@ -909,7 +936,7 @@ int _pam_free_handlers(pam_handle_t *pamh)
|
||||
}
|
||||
|
||||
/* Free all the handlers */
|
||||
|
||||
|
||||
_pam_free_handlers_aux(&(pamh->handlers.conf.authenticate));
|
||||
_pam_free_handlers_aux(&(pamh->handlers.conf.setcred));
|
||||
_pam_free_handlers_aux(&(pamh->handlers.conf.acct_mgmt));
|
||||
@ -949,7 +976,7 @@ void _pam_start_handlers(pam_handle_t *pamh)
|
||||
pamh->handlers.module = NULL;
|
||||
|
||||
/* initialize the .conf and .other entries */
|
||||
|
||||
|
||||
pamh->handlers.conf.authenticate = NULL;
|
||||
pamh->handlers.conf.setcred = NULL;
|
||||
pamh->handlers.conf.acct_mgmt = NULL;
|
||||
|
@ -207,12 +207,12 @@ check_logins (pam_handle_t *pamh, const char *name, int limit, int ctrl,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (++count > limit) {
|
||||
if (++count >= limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
endutent();
|
||||
if (count > limit) {
|
||||
if (count >= limit) {
|
||||
if (name) {
|
||||
_pam_log(LOG_WARNING, "Too many logins (max %d) for %s",
|
||||
limit, name);
|
||||
|
@ -123,11 +123,10 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t * pamh, int flags,
|
||||
setreuid( -1, save_euid );
|
||||
}
|
||||
|
||||
} else if (!strcmp( pwent->pw_passwd, "x" )) {
|
||||
} else if (_unix_shadowed (pwent))
|
||||
spent = _pammodutil_getspnam (pamh, uname);
|
||||
} else {
|
||||
else
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
if (!spent)
|
||||
if (on(UNIX_BROKEN_SHADOW,ctrl))
|
||||
|
@ -444,7 +444,7 @@ static int _update_passwd(pam_handle_t *pamh,
|
||||
}
|
||||
}
|
||||
|
||||
static int _update_shadow(const char *forwho, char *towhat)
|
||||
static int _update_shadow(pam_handle_t *pamh, const char *forwho, char *towhat)
|
||||
{
|
||||
struct spwd *spwdent = NULL, *stmpent = NULL;
|
||||
struct stat st;
|
||||
@ -516,6 +516,7 @@ static int _update_shadow(const char *forwho, char *towhat)
|
||||
|
||||
if (!err) {
|
||||
rename(SH_TMPFILE, "/etc/shadow");
|
||||
_log_err(LOG_NOTICE, pamh, "password changed for %s", forwho);
|
||||
return PAM_SUCCESS;
|
||||
} else {
|
||||
unlink(SH_TMPFILE);
|
||||
@ -535,7 +536,7 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho, char *fromwhat,
|
||||
if (pwd == NULL)
|
||||
return PAM_AUTHTOK_ERR;
|
||||
|
||||
if (on(UNIX_NIS, ctrl)) {
|
||||
if (on(UNIX_NIS, ctrl) && _unix_comesfromsource(pamh, forwho, 0, 1)) {
|
||||
struct timeval timeout;
|
||||
struct yppasswd yppwd;
|
||||
CLIENT *clnt;
|
||||
@ -619,13 +620,18 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho, char *fromwhat,
|
||||
}
|
||||
#endif /* def USE_LCKPWDF */
|
||||
|
||||
if (on(UNIX_SHADOW, ctrl) || (strcmp(pwd->pw_passwd, "x") == 0)) {
|
||||
retval = _update_shadow(forwho, towhat);
|
||||
if (_unix_comesfromsource (pamh, forwho, 1, 0))
|
||||
{
|
||||
if (on(UNIX_SHADOW, ctrl) || _unix_shadowed (pwd))
|
||||
{
|
||||
retval = _update_shadow (pamh, forwho, towhat);
|
||||
if (retval == PAM_SUCCESS)
|
||||
retval = _update_passwd(pamh, forwho, "x");
|
||||
} else {
|
||||
retval = _update_passwd(pamh, forwho, towhat);
|
||||
}
|
||||
if (!_unix_shadowed (pwd))
|
||||
retval = _update_passwd (pamh, forwho, "x");
|
||||
}
|
||||
else
|
||||
retval = _update_passwd (pamh, forwho, towhat);
|
||||
}
|
||||
|
||||
#ifdef USE_LCKPWDF
|
||||
ulckpwdf();
|
||||
@ -646,7 +652,7 @@ static int _unix_verify_shadow(const char *user, unsigned int ctrl)
|
||||
if (pwd == NULL)
|
||||
return PAM_AUTHINFO_UNAVAIL; /* We don't need to do the rest... */
|
||||
|
||||
if (strcmp(pwd->pw_passwd, "x") == 0) {
|
||||
if (_unix_shadowed(pwd)) {
|
||||
/* ...and shadow password file entry for this user, if shadowing
|
||||
is enabled */
|
||||
setspent();
|
||||
@ -738,7 +744,7 @@ static int _pam_unix_approve_pass(pam_handle_t * pamh
|
||||
#else
|
||||
if (strlen(pass_new) < 6)
|
||||
remark = "You must choose a longer password";
|
||||
D(("lenth check [%s]", remark));
|
||||
D(("length check [%s]", remark));
|
||||
#endif
|
||||
if (on(UNIX_REMEMBER_PASSWD, ctrl))
|
||||
if ((retval = check_old_password(user, pass_new)) != PAM_SUCCESS)
|
||||
@ -795,6 +801,30 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
|
||||
|
||||
D(("Got username of %s", user));
|
||||
|
||||
/*
|
||||
* Before we do anything else, check to make sure that the user's
|
||||
* info is in one of the databases we can modify from this module,
|
||||
* which currently is 'files' and 'nis'. We have to do this because
|
||||
* getpwnam() doesn't tell you *where* the information it gives you
|
||||
* came from, nor should it. That's our job.
|
||||
*/
|
||||
if (_unix_comesfromsource(pamh, user, 1, 1) == 0) {
|
||||
_log_err(LOG_DEBUG, pamh,
|
||||
"user \"%s\" does not exist in /etc/passwd or NIS",
|
||||
user);
|
||||
return PAM_USER_UNKNOWN;
|
||||
} else {
|
||||
struct passwd *pwd;
|
||||
_unix_getpwnam(pamh, user, 1, 1, &pwd);
|
||||
if (!_unix_shadowed(pwd) &&
|
||||
(strchr(pwd->pw_passwd, '*') != NULL)) {
|
||||
_log_err(LOG_DEBUG, pamh,
|
||||
"user \"%s\" does not have modifiable password",
|
||||
user);
|
||||
return PAM_USER_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is not an AUTH module!
|
||||
*/
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <pwd.h>
|
||||
@ -17,6 +18,8 @@
|
||||
#include <utmp.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <ctype.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include <security/_pam_macros.h>
|
||||
#include <security/pam_modules.h>
|
||||
@ -135,10 +138,6 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int argc,
|
||||
D(("PRELIM_CHECK"));
|
||||
set(UNIX__PRELIM, ctrl);
|
||||
}
|
||||
if (flags & PAM_DISALLOW_NULL_AUTHTOK) {
|
||||
D(("DISALLOW_NULL_AUTHTOK"));
|
||||
set(UNIX__NONULL, ctrl);
|
||||
}
|
||||
if (flags & PAM_SILENT) {
|
||||
D(("SILENT"));
|
||||
set(UNIX__QUIET, ctrl);
|
||||
@ -178,6 +177,11 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int argc,
|
||||
++argv; /* step to next argument */
|
||||
}
|
||||
|
||||
if (flags & PAM_DISALLOW_NULL_AUTHTOK) {
|
||||
D(("DISALLOW_NULL_AUTHTOK"));
|
||||
set(UNIX__NONULL, ctrl);
|
||||
}
|
||||
|
||||
/* auditing is a more sensitive version of debug */
|
||||
|
||||
if (on(UNIX_AUDIT, ctrl)) {
|
||||
@ -275,6 +279,165 @@ static void _cleanup_failures(pam_handle_t * pamh, void *fl, int err)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* _unix_getpwnam() searches only /etc/passwd and NIS to find user information
|
||||
*/
|
||||
static void _unix_cleanup(pam_handle_t *pamh, void *data, int error_status)
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
|
||||
int _unix_getpwnam(pam_handle_t *pamh, const char *name,
|
||||
int files, int nis, struct passwd **ret)
|
||||
{
|
||||
FILE *passwd;
|
||||
char buf[16384];
|
||||
int matched = 0, buflen;
|
||||
char *slogin, *spasswd, *suid, *sgid, *sgecos, *shome, *sshell, *p;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
if (!matched && files) {
|
||||
int userlen = strlen(name);
|
||||
passwd = fopen("/etc/passwd", "r");
|
||||
if (passwd != NULL) {
|
||||
while (fgets(buf, sizeof(buf), passwd) != NULL) {
|
||||
if ((buf[userlen] == ':') &&
|
||||
(strncmp(name, buf, userlen) == 0)) {
|
||||
p = buf + strlen(buf) - 1;
|
||||
while (isspace(*p) && (p >= buf)) {
|
||||
*p-- = '\0';
|
||||
}
|
||||
matched = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(passwd);
|
||||
}
|
||||
}
|
||||
|
||||
if (!matched && nis) {
|
||||
char *userinfo = NULL, *domain = NULL;
|
||||
int len = 0, i;
|
||||
len = yp_get_default_domain(&domain);
|
||||
if (len == YPERR_SUCCESS) {
|
||||
len = yp_bind(domain);
|
||||
}
|
||||
if (len == YPERR_SUCCESS) {
|
||||
i = yp_match(domain, "passwd.byname", name,
|
||||
strlen(name), &userinfo, &len);
|
||||
yp_unbind(domain);
|
||||
if ((i == YPERR_SUCCESS) && (len < sizeof(buf))) {
|
||||
strncpy(buf, userinfo, sizeof(buf) - 1);
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
matched = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (matched && (ret != NULL)) {
|
||||
*ret = NULL;
|
||||
|
||||
slogin = buf;
|
||||
|
||||
spasswd = strchr(slogin, ':');
|
||||
if (spasswd == NULL) {
|
||||
return matched;
|
||||
}
|
||||
*spasswd++ = '\0';
|
||||
|
||||
suid = strchr(spasswd, ':');
|
||||
if (suid == NULL) {
|
||||
return matched;
|
||||
}
|
||||
*suid++ = '\0';
|
||||
|
||||
sgid = strchr(suid, ':');
|
||||
if (sgid == NULL) {
|
||||
return matched;
|
||||
}
|
||||
*sgid++ = '\0';
|
||||
|
||||
sgecos = strchr(sgid, ':');
|
||||
if (sgecos == NULL) {
|
||||
return matched;
|
||||
}
|
||||
*sgecos++ = '\0';
|
||||
|
||||
shome = strchr(sgecos, ':');
|
||||
if (shome == NULL) {
|
||||
return matched;
|
||||
}
|
||||
*shome++ = '\0';
|
||||
|
||||
sshell = strchr(shome, ':');
|
||||
if (sshell == NULL) {
|
||||
return matched;
|
||||
}
|
||||
*sshell++ = '\0';
|
||||
|
||||
buflen = sizeof(struct passwd) +
|
||||
strlen(slogin) + 1 +
|
||||
strlen(spasswd) + 1 +
|
||||
strlen(suid) + 1 +
|
||||
strlen(sgid) + 1 +
|
||||
strlen(sgecos) + 1 +
|
||||
strlen(shome) + 1 +
|
||||
strlen(sshell) + 1;
|
||||
*ret = malloc(buflen);
|
||||
if (*ret == NULL) {
|
||||
return matched;
|
||||
}
|
||||
memset(*ret, '\0', buflen);
|
||||
|
||||
(*ret)->pw_uid = strtol(suid, &p, 0);
|
||||
if ((strlen(sgid) == 0) || (*p != '\0')) {
|
||||
free(*ret);
|
||||
*ret = NULL;
|
||||
return matched;
|
||||
}
|
||||
|
||||
(*ret)->pw_gid = strtol(sgid, &p, 0);
|
||||
if ((strlen(sgid) == 0) || (*p != '\0')) {
|
||||
free(*ret);
|
||||
*ret = NULL;
|
||||
return matched;
|
||||
}
|
||||
|
||||
p = ((char*)(*ret)) + sizeof(struct passwd);
|
||||
(*ret)->pw_name = strcpy(p, slogin);
|
||||
p += strlen(p) + 1;
|
||||
(*ret)->pw_passwd = strcpy(p, spasswd);
|
||||
p += strlen(p) + 1;
|
||||
(*ret)->pw_gecos = strcpy(p, sgecos);
|
||||
p += strlen(p) + 1;
|
||||
(*ret)->pw_dir = strcpy(p, shome);
|
||||
p += strlen(p) + 1;
|
||||
(*ret)->pw_shell = strcpy(p, sshell);
|
||||
|
||||
snprintf(buf, sizeof(buf), "_pam_unix_getpwnam_%s", name);
|
||||
|
||||
if (pam_set_data(pamh, buf,
|
||||
*ret, _unix_cleanup) != PAM_SUCCESS) {
|
||||
free(*ret);
|
||||
*ret = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return matched;
|
||||
}
|
||||
|
||||
/*
|
||||
* _unix_comsefromsource() is a quick check to see if information about a given
|
||||
* user comes from a particular source (just files and nis for now)
|
||||
*
|
||||
*/
|
||||
int _unix_comesfromsource(pam_handle_t *pamh,
|
||||
const char *name, int files, int nis)
|
||||
{
|
||||
return _unix_getpwnam(pamh, name, files, nis, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* _unix_blankpasswd() is a quick check for a blank password
|
||||
*
|
||||
@ -331,10 +494,10 @@ _unix_blankpasswd (pam_handle_t *pamh, unsigned int ctrl, const char *name)
|
||||
setreuid( save_uid, save_euid );
|
||||
else {
|
||||
if (setreuid( -1, 0 ) == -1)
|
||||
setreuid( save_uid, -1 );
|
||||
setreuid( save_uid, -1 );
|
||||
setreuid( -1, save_euid );
|
||||
}
|
||||
} else if (strcmp(pwd->pw_passwd, "x") == 0) {
|
||||
} else if (_unix_shadowed(pwd)) {
|
||||
/*
|
||||
* ...and shadow password file entry for this user,
|
||||
* if shadowing is enabled
|
||||
@ -501,7 +664,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name
|
||||
setreuid( save_uid, -1 );
|
||||
setreuid( -1, save_euid );
|
||||
}
|
||||
} else if (strcmp(pwd->pw_passwd, "x") == 0) {
|
||||
} else if (_unix_shadowed(pwd)) {
|
||||
/*
|
||||
* ...and shadow password file entry for this user,
|
||||
* if shadowing is enabled
|
||||
@ -523,7 +686,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name
|
||||
}
|
||||
|
||||
retval = PAM_SUCCESS;
|
||||
if (pwd == NULL || salt == NULL || strlen(salt) == 1) {
|
||||
if (pwd == NULL || salt == NULL || !strcmp(salt, "x") || ((salt[0] == '#') && (salt[1] == '#') && !strcmp(salt + 2, name))) {
|
||||
if (geteuid()) {
|
||||
/* we are not root perhaps this is the reason? Run helper */
|
||||
D(("running helper binary"));
|
||||
@ -850,6 +1013,21 @@ int _unix_read_password(pam_handle_t * pamh
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
int _unix_shadowed(const struct passwd *pwd)
|
||||
{
|
||||
if (pwd != NULL) {
|
||||
if (strcmp(pwd->pw_passwd, "x") == 0) {
|
||||
return 1;
|
||||
}
|
||||
if ((pwd->pw_passwd[0] == '#') &&
|
||||
(pwd->pw_passwd[1] == '#') &&
|
||||
(strcmp(pwd->pw_name, pwd->pw_passwd + 2) == 0)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ****************************************************************** *
|
||||
* Copyright (c) Jan Rêkorajski 1999.
|
||||
* Copyright (c) Andrew G. Morgan 1996-8.
|
||||
|
@ -5,6 +5,7 @@
|
||||
#ifndef _PAM_UNIX_SUPPORT_H
|
||||
#define _PAM_UNIX_SUPPORT_H
|
||||
|
||||
#include <pwd.h>
|
||||
|
||||
/*
|
||||
* here is the string to inform the user that the new passwords they
|
||||
@ -133,6 +134,11 @@ extern int _make_remark(pam_handle_t * pamh, unsigned int ctrl
|
||||
,int type, const char *text);
|
||||
extern int _set_ctrl(pam_handle_t * pamh, int flags, int *remember, int argc,
|
||||
const char **argv);
|
||||
extern int _unix_getpwnam (pam_handle_t *pamh,
|
||||
const char *name, int files, int nis,
|
||||
struct passwd **ret);
|
||||
extern int _unix_comesfromsource (pam_handle_t *pamh,
|
||||
const char *name, int files, int nis);
|
||||
extern int _unix_blankpasswd(pam_handle_t *pamh,unsigned int ctrl,
|
||||
const char *name);
|
||||
extern int _unix_verify_password(pam_handle_t * pamh, const char *name
|
||||
@ -144,6 +150,6 @@ extern int _unix_read_password(pam_handle_t * pamh
|
||||
,const char *prompt2
|
||||
,const char *data_name
|
||||
,const char **pass);
|
||||
extern int _unix_shadowed(const struct passwd *pwd);
|
||||
|
||||
#endif /* _PAM_UNIX_SUPPORT_H */
|
||||
|
||||
|
@ -57,6 +57,24 @@ static void _log_err(int err, const char *format,...)
|
||||
closelog();
|
||||
}
|
||||
|
||||
static int _unix_shadowed(const struct passwd *pwd)
|
||||
{
|
||||
char hashpass[1024];
|
||||
if (pwd != NULL) {
|
||||
if (strcmp(pwd->pw_passwd, "x") == 0) {
|
||||
return 1;
|
||||
}
|
||||
if (strlen(pwd->pw_name) < sizeof(hashpass) - 2) {
|
||||
strcpy(hashpass, "##");
|
||||
strcpy(hashpass + 2, pwd->pw_name);
|
||||
if (strcmp(pwd->pw_passwd, hashpass) == 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void su_sighandler(int sig)
|
||||
{
|
||||
if (sig > 0) {
|
||||
@ -87,7 +105,7 @@ static void setup_signals(void)
|
||||
(void) sigaction(SIGQUIT, &action, NULL);
|
||||
}
|
||||
|
||||
static int _unix_verify_password(const char *name, const char *p, int opt)
|
||||
static int _unix_verify_password(const char *name, const char *p, int nullok)
|
||||
{
|
||||
struct passwd *pwd = NULL;
|
||||
struct spwd *spwdent = NULL;
|
||||
@ -101,7 +119,7 @@ static int _unix_verify_password(const char *name, const char *p, int opt)
|
||||
pwd = getpwnam(name); /* Get password file entry... */
|
||||
endpwent();
|
||||
if (pwd != NULL) {
|
||||
if (strcmp(pwd->pw_passwd, "x") == 0) {
|
||||
if (_unix_shadowed(pwd)) {
|
||||
/*
|
||||
* ...and shadow password file entry for this user,
|
||||
* if shadowing is enabled
|
||||
@ -136,7 +154,10 @@ static int _unix_verify_password(const char *name, const char *p, int opt)
|
||||
|
||||
salt_len = strlen(salt);
|
||||
if (salt_len == 0) {
|
||||
return (opt == 0) ? UNIX_FAILED : UNIX_PASSED;
|
||||
return (nullok == 0) ? UNIX_FAILED : UNIX_PASSED;
|
||||
}
|
||||
if (p == NULL) {
|
||||
return UNIX_FAILED;
|
||||
}
|
||||
|
||||
/* the moment of truth -- do we agree with the password? */
|
||||
@ -202,7 +223,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
char pass[MAXPASS + 1];
|
||||
char option[8];
|
||||
int npass, opt;
|
||||
int npass, nullok;
|
||||
int force_failure = 0;
|
||||
int retval = UNIX_FAILED;
|
||||
char *user;
|
||||
@ -255,9 +276,9 @@ int main(int argc, char *argv[])
|
||||
} else {
|
||||
option[7] = '\0';
|
||||
if (strncmp(option, "nullok", 8) == 0)
|
||||
opt = 1;
|
||||
nullok = 1;
|
||||
else
|
||||
opt = 0;
|
||||
nullok = 0;
|
||||
}
|
||||
|
||||
/* read the password from stdin (a pipe from the pam_unix module) */
|
||||
@ -276,13 +297,13 @@ int main(int argc, char *argv[])
|
||||
if (npass == 0) {
|
||||
/* the password is NULL */
|
||||
|
||||
retval = _unix_verify_password(user, NULL, opt);
|
||||
retval = _unix_verify_password(user, NULL, nullok);
|
||||
|
||||
} else {
|
||||
/* does pass agree with the official one? */
|
||||
|
||||
pass[npass] = '\0'; /* NUL terminate */
|
||||
retval = _unix_verify_password(user, pass, opt);
|
||||
retval = _unix_verify_password(user, pass, nullok);
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user