Build pam_fshadow even if fgetpwent is not defined.

* configure.ac: Only check if fgetpwent is defined,
don't disable the module if it is not.
* pam_fshadow/pam_fshadow.c [!HAVE_FGETPWENT] (fgetpwent): Provide a
replacement.
This commit is contained in:
Sergey Poznyakoff 2014-12-05 07:49:41 +02:00
parent e094d80820
commit 399768dde3
2 changed files with 64 additions and 16 deletions

View file

@ -63,10 +63,8 @@ AC_CHECK_HEADERS(security/pam_appl.h security/pam_modules.h,
:,
AC_MSG_ERROR([Required PAM header files not found]))
AC_CHECK_HEADERS(fcntl.h syslog.h unistd.h crypt.h security/_pam_aconf.h \
security/pam_misc.h security/pam_ext.h termios.h)
AC_CHECK_HEADER(shadow.h,
[],
[build_fshadow=no])
security/pam_misc.h security/pam_ext.h termios.h \
shadow.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
@ -79,19 +77,10 @@ AC_CHECK_MEMBERS([struct spwd.sp_expire], , ,
[ #include <shadow.h> ])
dnl Checks for library functions.
AC_CHECK_FUNCS(strerror tcgetattr)
AC_CHECK_FUNCS(strerror tcgetattr fgetpwent)
PM_ENABLE(fshadow,[
AC_CHECK_FUNC(fgetpwent,
[build_fshadow=yes],
[if $build_fshadow = yes; then
AC_MSG_ERROR([cannot build requested pam_fgetpwent, because the fgetpwent function is not available])
else
build_fshadow=no
fi])
])
PM_ENABLE(fshadow)
PM_ENABLE(log)
PM_ENABLE(regex)
PM_ENABLE(groupmember)

View file

@ -36,6 +36,65 @@ extern char *crypt(const char *, const char *);
#include <security/pam_modules.h>
#if !HAVE_FGETPWENT
static struct passwd *
fgetpwent(FILE *fp)
{
static char *buffer;
static size_t buflen;
static struct passwd pwbuf;
size_t pos = 0;
int c;
size_t off[6];
int i = 0;
while ((c = fgetc(fp)) != EOF) {
if (pos == buflen) {
char *nb;
size_t ns;
if (buflen == 0)
ns = 128;
else {
ns = ns * 2;
if (ns < buflen) {
errno = ENOMEM;
return NULL;
}
}
nb = realloc(buffer, ns);
if (!nb)
return NULL;
buffer = nb;
buflen = ns;
}
if (c == '\n') {
buffer[pos++] = 0;
break;
}
if (c == ':') {
buffer[pos++] = 0;
if (i < sizeof(off)/sizeof(off[0]))
off[i++] = pos;
} else
buffer[pos++] = c;
}
if (pos == 0)
return NULL;
pwbuf.pw_name = buffer;
pwbuf.pw_passwd = buffer + off[0];
pwbuf.pw_uid = strtoul(buffer + off[1], NULL, 10);
pwbuf.pw_gid = strtoul(buffer + off[2], NULL, 10);
pwbuf.pw_gecos = buffer + off[3];
pwbuf.pw_dir = buffer + off[4];
pwbuf.pw_shell = buffer + off[5];
return &pwbuf;
}
#endif
#define CNTL_AUTHTOK 0x0010
#define CNTL_PASSWD 0x0020
#define CNTL_SHADOW 0x0040
@ -251,7 +310,7 @@ verify_user_acct(const char *confdir, const char *username, char **pwd)
if (fp) {
struct passwd *pw;
while ((pw = fgetpwent (fp)) != NULL) {
while ((pw = fgetpwent(fp)) != NULL) {
if (strcmp (pw->pw_name, username) == 0)
break;
}