Relevant BUGIDs:

Purpose of commit:

Commit summary:
---------------

bugfix: Last part of fixes from Red Hat
This commit is contained in:
Thorsten Kukuk 2004-10-06 13:42:36 +00:00
parent b651aa8d81
commit 3f42e813b6
11 changed files with 343 additions and 40 deletions

View File

@ -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

View File

@ -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
View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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))

View File

@ -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!
*/

View File

@ -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.

View File

@ -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 */

View File

@ -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);
}
}