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: * Merge patches from Red Hat (Bug 477000 and other - kukuk) * Fix pam_rhosts option parsing (Bug 922648 - kukuk)
This commit is contained in:
parent
328d7328e5
commit
6fb0153746
@ -117,6 +117,8 @@ BerliOS Bugs are marked with (BerliOS #XXXX).
|
||||
* Add the "broken_shadow" argument to pam_unix, for ignoring errors
|
||||
reading shadow information (from Linux distributors - kukuk)
|
||||
* 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)
|
||||
|
||||
0.77: Mon Sep 23 10:25:42 PDT 2002
|
||||
|
||||
|
@ -41,6 +41,7 @@ PIC=@PIC@
|
||||
|
||||
# Mode to install shared libraries with
|
||||
SHLIBMODE=@SHLIBMODE@
|
||||
# Mode to install man pages with
|
||||
MANMODE=@MANMODE@
|
||||
|
||||
NEED_LINK_LIB_C=@PAM_NEEDS_LIBC@
|
||||
@ -94,10 +95,12 @@ CRACKLIB_DICTPATH=@CRACKLIB_DICTPATH@
|
||||
# generic build setup
|
||||
OS=@OS@
|
||||
CC=@CC@
|
||||
CFLAGS=@CFLAGS@ $(WARNINGS) -D$(OS) $(OS_CFLAGS) $(HEADER_DIRS) @CONF_CFLAGS@
|
||||
CFLAGS=$(WARNINGS) -D$(OS) @CFLAGS@ @CPPFLAGS@ $(OS_CFLAGS) $(HEADER_DIRS) @CONF_CFLAGS@
|
||||
LDFLAGS=@LDFLAGS@
|
||||
LD=@LD@
|
||||
LD_D=@LD_D@
|
||||
LD_L=@LD_L@
|
||||
MV=@MV@
|
||||
LDCONFIG=@LDCONFIG@
|
||||
DYNTYPE=@DYNTYPE@
|
||||
USESONAME=@USESONAME@
|
||||
@ -112,6 +115,9 @@ CC_STATIC=@CC_STATIC@
|
||||
|
||||
LINKLIBS = $(NEED_LINK_LIB_C) $(LIBDL)
|
||||
|
||||
USESONAME=@USESONAME@
|
||||
SOSWITCH=@SOSWITCH@
|
||||
|
||||
ifdef DYNAMIC
|
||||
CFLAGS += $(PIC)
|
||||
endif
|
||||
|
7
Makefile
7
Makefile
@ -11,9 +11,7 @@
|
||||
|
||||
DISTNAME=Linux-PAM
|
||||
|
||||
ifeq ($(shell test \! -f Make.Rules || echo yes),yes)
|
||||
include Make.Rules
|
||||
endif
|
||||
-include Make.Rules
|
||||
|
||||
THINGSTOMAKE = libpam libpamc libpam_misc modules doc examples
|
||||
|
||||
@ -30,7 +28,7 @@ prep:
|
||||
clean:
|
||||
if [ ! -f Make.Rules ]; then touch Make.Rules ; fi
|
||||
for i in $(THINGSTOMAKE) ; do $(MAKE) -C $$i clean ; done
|
||||
rm -f security *~ *.orig *.rej Make.Rules #*#
|
||||
rm -f security *~ *.orig *.rej #*#
|
||||
|
||||
distclean: clean
|
||||
rm -f Make.Rules _pam_aconf.h
|
||||
@ -75,4 +73,3 @@ release:
|
||||
cd .. ; tar zvfc $(DISTNAME)-$(MAJOR_REL).$(MINOR_REL).tar.gz \
|
||||
--exclude CVS --exclude .cvsignore --exclude '.#*' \
|
||||
$(DISTNAME)-$(MAJOR_REL).$(MINOR_REL)/*
|
||||
|
||||
|
12
configure
vendored
12
configure
vendored
@ -1347,8 +1347,8 @@ SHLIBMODE=755 ;
|
||||
MANMODE=644 ;
|
||||
|
||||
USESONAME=yes ;
|
||||
SOSWITCH='-Xlinker -soname -Xlinker ' ;
|
||||
NEEDSONAME=no ;
|
||||
SOSWITCH="-Wl,-soname -Wl," ;
|
||||
NEEDSONAME=yes ;
|
||||
LDCONFIG=/sbin/ldconfig ;
|
||||
|
||||
ac_ext=c
|
||||
@ -6009,14 +6009,14 @@ if test "$GCC" = yes; then
|
||||
### Example: -D_POSIX_SOURCE: needed on Linux but harms Solaris.
|
||||
case $OS in
|
||||
linux)
|
||||
OS_CFLAGS="-ansi -D_POSIX_SOURCE -pedantic"
|
||||
LD_D="gcc -shared -Xlinker -x"
|
||||
OS_CFLAGS=
|
||||
LD_D="$CC -shared $LDFLAGS"
|
||||
WARNINGS="$GCC_WARNINGS"
|
||||
PIC="-fPIC"
|
||||
DYNTYPE=so
|
||||
LD=gcc
|
||||
LD_L="$LD -Xlinker -x -shared"
|
||||
RANLIB=ranlib
|
||||
LD_L="$CC -shared $LDFLAGS"
|
||||
RANLIB=:
|
||||
STRIP=strip
|
||||
CC_STATIC="-Xlinker -export-dynamic"
|
||||
;;
|
||||
|
18
configure.in
18
configure.in
@ -43,8 +43,8 @@ MANMODE=644 ; AC_SUBST(MANMODE)
|
||||
|
||||
dnl These are most likely platform specific - I think HPUX differs
|
||||
USESONAME=yes ; AC_SUBST(USESONAME)
|
||||
SOSWITCH='-Xlinker -soname -Xlinker ' ; AC_SUBST(SOSWITCH)
|
||||
NEEDSONAME=no ; AC_SUBST(NEEDSONAME)
|
||||
SOSWITCH="-Wl,-soname -Wl," ; AC_SUBST(SOSWITCH)
|
||||
NEEDSONAME=yes ; AC_SUBST(NEEDSONAME)
|
||||
LDCONFIG=/sbin/ldconfig ; AC_SUBST(LDCONFIG)
|
||||
|
||||
dnl Checks for programs.
|
||||
@ -179,7 +179,7 @@ AC_CHECK_LIB(c, lckpwdf, HAVE_LCKPWDF=yes, HAVE_LCKPWDF=no)
|
||||
AC_SUBST(HAVE_LCKPWDF)
|
||||
|
||||
dnl Checks for the existence of libdl - on BSD and Tru64 its part of libc
|
||||
AC_CHECK_LIB(dl, dlopen, LIBDL=-ldl)
|
||||
AC_CHECK_LIB(dl, dlopen, LIBDL=-ldl)
|
||||
AC_SUBST(LIBDL)
|
||||
|
||||
dnl
|
||||
@ -293,14 +293,14 @@ if test "$GCC" = yes; then
|
||||
### Example: -D_POSIX_SOURCE: needed on Linux but harms Solaris.
|
||||
case $OS in
|
||||
linux)
|
||||
OS_CFLAGS="-ansi -D_POSIX_SOURCE -pedantic"
|
||||
LD_D="gcc -shared -Xlinker -x"
|
||||
OS_CFLAGS=
|
||||
LD_D="$CC -shared $LDFLAGS"
|
||||
WARNINGS="$GCC_WARNINGS"
|
||||
PIC="-fPIC"
|
||||
DYNTYPE=so
|
||||
LD=gcc
|
||||
LD_L="$LD -Xlinker -x -shared"
|
||||
RANLIB=ranlib
|
||||
LD_L="$CC -shared $LDFLAGS"
|
||||
RANLIB=:
|
||||
STRIP=strip
|
||||
CC_STATIC="-Xlinker -export-dynamic"
|
||||
;;
|
||||
@ -310,7 +310,7 @@ if test "$GCC" = yes; then
|
||||
WARNINGS="$GCC_WARNINGS"
|
||||
PIC="-fPIC"
|
||||
DYNTYPE=so
|
||||
LD=ld
|
||||
LD=ld
|
||||
LD_L="$LD -x -shared"
|
||||
RANLIB=ranlib
|
||||
STRIP=strip
|
||||
@ -319,7 +319,7 @@ if test "$GCC" = yes; then
|
||||
aix)
|
||||
OS_CFLAGS=""
|
||||
DYNTYPE=lo
|
||||
LD=ld
|
||||
LD=ld
|
||||
LD_L=ld -bexpall -bM:SRE -bnoentry
|
||||
LD_D="$LD_L"
|
||||
RANLIB=ranlib
|
||||
|
@ -50,6 +50,8 @@ what is contained in that database.
|
||||
<tt/icase/;
|
||||
<tt/dump/;
|
||||
<tt/db=XXXX/;
|
||||
<tt/use_authtok/;
|
||||
<tt/unknown_ok/;
|
||||
|
||||
<tag><bf>Description:</bf></tag>
|
||||
|
||||
@ -59,7 +61,7 @@ fields corresponding to the username keys are the passwords, in unencrypted form
|
||||
so caution must be exercised over the access rights to the DB database itself..
|
||||
|
||||
The module will read the password from the user using the conversation mechanism. If
|
||||
you are using this module on top of another authetication module (like <tt/pam_pwdb/;)
|
||||
you are using this module on top of another authentication module (like <tt/pam_pwdb/;)
|
||||
then you should tell that module to read the entered password from the PAM_AUTHTOK field, which is set by this module.
|
||||
|
||||
<p>
|
||||
@ -85,6 +87,18 @@ use the database found on pathname XXXX. Note that Berkeley DB usually adds the
|
||||
needed filename extension for you, so you should use something like <tt>/etc/foodata</tt>
|
||||
instead of <tt>/etc/foodata.db</tt>.
|
||||
|
||||
<item> <tt/use_authtok/ -
|
||||
use the authentication token previously obtained by another module that did the
|
||||
conversation with the application. If this token can not be obtained then
|
||||
the module will try to converse again. This option can be used for stacking
|
||||
different modules that need to deal with the authentication tokens.
|
||||
|
||||
<item>
|
||||
<tt/unknown_ok/ -
|
||||
do not return error when checking for a user that is not in the database.
|
||||
This can be used to stack more than one pam_userdb module that will check a
|
||||
username/password pair in more than a database.
|
||||
|
||||
</itemize>
|
||||
|
||||
<tag><bf>Examples/suggested usage:</bf></tag>
|
||||
|
@ -268,7 +268,7 @@ that this enables.
|
||||
be used, including RADIUS, NIS, NCP (which means that Novell
|
||||
password databases can be used).
|
||||
|
||||
o pppd has a PAMified version (available from RedHat) Now it is
|
||||
o pppd has a PAMified version (available from Red Hat) Now it is
|
||||
possible to use a series of databases to authenticate ppp users.
|
||||
In addition to the normal Linux-based password databases (such
|
||||
as /etc/passwd and /etc/shadow), you can use PAM modules to
|
||||
|
@ -97,7 +97,7 @@ bootdir:
|
||||
$(LIBPAM): $(DLIBOBJECTS)
|
||||
ifeq ($(DYNAMIC_LIBPAM),yes)
|
||||
ifeq ($(USESONAME),yes)
|
||||
$(LD_L) $(SOSWITCH) $(LIBPAMNAME) -o $@ $(DLIBOBJECTS) \
|
||||
$(LD_L) $(SOSWITCH)$(LIBPAMNAME) -o $@ $(DLIBOBJECTS) \
|
||||
$(MODULES) $(LINKLIBS)
|
||||
else
|
||||
$(LD_L) -o $@ $(DLIBOBJECTS) $(MODULES) $(LINKLIBS)
|
||||
@ -112,9 +112,11 @@ endif
|
||||
|
||||
$(LIBPAMSTATIC): $(SLIBOBJECTS)
|
||||
ifeq ($(STATIC_LIBPAM),yes)
|
||||
$(AR) cr $@ $(SLIBOBJECTS) $(MODULES)
|
||||
$(AR) cru $@ $(SLIBOBJECTS) $(MODULES)
|
||||
ifdef RANLIB
|
||||
$(RANLIB) $@
|
||||
endif
|
||||
endif
|
||||
|
||||
install: all
|
||||
$(MKDIR) $(FAKEROOT)$(INCLUDED) $(FAKEROOT)$(libdir)
|
||||
|
@ -60,9 +60,9 @@ static/%.o : %.c
|
||||
$(LIBNAMED): $(DLIBOBJECTS)
|
||||
ifeq ($(DYNAMIC_LIBPAM),yes)
|
||||
ifeq ($(USESONAME),yes)
|
||||
$(LD_L) $(SOSWITCH) $(LIBNAMEDNAME) -o $@ $(DLIBOBJECTS) $(MODULES) $(LINKLIBS)
|
||||
$(LD_L) $(SOSWITCH)$(LIBNAMEDNAME) -o $@ $(DLIBOBJECTS) $(MODULES) $(LINKLIBS)
|
||||
else
|
||||
$(LD_L) -o $@ $(DLIBOBJECTS) $(MODULES)
|
||||
$(LD_L) -o $@ $(DLIBOBJECTS) $(MODULES) $(LINKLIBS)
|
||||
endif
|
||||
ifeq ($(NEEDSONAME),yes)
|
||||
rm -f $(LIBNAMEDFULL)
|
||||
@ -74,9 +74,12 @@ endif
|
||||
|
||||
$(LIBNAMEDSTATIC): $(SLIBOBJECTS)
|
||||
ifeq ($(STATIC_LIBPAM),yes)
|
||||
$(AR) rcu $@ $(SLIBOBJECTS) $(MODULES)
|
||||
ifdef RANLIB
|
||||
$(AR) rc $@ $(SLIBOBJECTS) $(MODULES)
|
||||
$(RANLIB) $@
|
||||
endif
|
||||
endif
|
||||
|
||||
install: all
|
||||
$(MKDIR) $(FAKEROOT)$(INCLUDED)
|
||||
|
@ -59,7 +59,7 @@ static/%.o : %.c
|
||||
$(LIBNAMED): $(DLIBOBJECTS)
|
||||
ifeq ($(DYNAMIC_LIBPAM),yes)
|
||||
ifeq ($(USESONAME),yes)
|
||||
$(LD_L) $(SOSWITCH) $(LIBNAMEDNAME) -o $@ $(DLIBOBJECTS) $(MODULES) $(LINKLIBS)
|
||||
$(LD_L) $(SOSWITCH)$(LIBNAMEDNAME) -o $@ $(DLIBOBJECTS) $(MODULES) $(LINKLIBS)
|
||||
else
|
||||
$(LD_L) -o $@ $(DLIBOBJECTS) $(MODULES)
|
||||
endif
|
||||
@ -73,9 +73,11 @@ endif
|
||||
|
||||
$(LIBNAMEDSTATIC): $(SLIBOBJECTS)
|
||||
ifeq ($(STATIC_LIBPAM),yes)
|
||||
$(AR) rc $@ $(SLIBOBJECTS) $(MODULES)
|
||||
$(AR) rcu $@ $(SLIBOBJECTS) $(MODULES)
|
||||
ifdef RANLIB
|
||||
$(RANLIB) $@
|
||||
endif
|
||||
endif
|
||||
|
||||
install: all
|
||||
$(MKDIR) $(FAKEROOT)$(INCLUDED)
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
include ../Make.Rules
|
||||
|
||||
MODDIRS=$(shell /bin/ls -d pam_*)
|
||||
MODDIRS=$(shell /bin/ls -d pam_*/Makefile | cut -f1 -d/)
|
||||
|
||||
all:
|
||||
@echo building the static modutil library
|
||||
|
@ -13,6 +13,8 @@
|
||||
# $(MODULE_SIMPLE_EXTRAFILES) - other files to build (no .c suffix)
|
||||
#
|
||||
|
||||
-include ../Make.Rules
|
||||
|
||||
LIBFILES = $(TITLE) $(MODULE_SIMPLE_EXTRAFILES)
|
||||
LIBSRC = $(addsuffix .c,$(LIBFILES))
|
||||
LIBOBJ = $(addsuffix .o,$(LIBFILES))
|
||||
|
@ -150,7 +150,7 @@ static int process_args(pam_handle_t *pamh
|
||||
|
||||
/* the "ARGS" variable */
|
||||
|
||||
#define ARGS_OFFSET 5 /* sizeof('ARGS='); */
|
||||
#define ARGS_OFFSET 5 /* strlen('ARGS='); */
|
||||
#define ARGS_NAME "ARGS="
|
||||
|
||||
size += ARGS_OFFSET;
|
||||
@ -174,7 +174,7 @@ static int process_args(pam_handle_t *pamh
|
||||
|
||||
/* the "SERVICE" variable */
|
||||
|
||||
#define SERVICE_OFFSET 8 /* sizeof('SERVICE='); */
|
||||
#define SERVICE_OFFSET 8 /* strlen('SERVICE='); */
|
||||
#define SERVICE_NAME "SERVICE="
|
||||
|
||||
retval = pam_get_item(pamh, PAM_SERVICE, (const void **)&tmp);
|
||||
@ -204,7 +204,7 @@ static int process_args(pam_handle_t *pamh
|
||||
|
||||
/* the "USER" variable */
|
||||
|
||||
#define USER_OFFSET 5 /* sizeof('USER='); */
|
||||
#define USER_OFFSET 5 /* strlen('USER='); */
|
||||
#define USER_NAME "USER="
|
||||
|
||||
tmp = NULL;
|
||||
@ -231,7 +231,7 @@ static int process_args(pam_handle_t *pamh
|
||||
|
||||
/* the "USER" variable */
|
||||
|
||||
#define TYPE_OFFSET 5 /* sizeof('TYPE='); */
|
||||
#define TYPE_OFFSET 5 /* strlen('TYPE='); */
|
||||
#define TYPE_NAME "TYPE="
|
||||
|
||||
size = TYPE_OFFSET+strlen(type);
|
||||
|
@ -27,6 +27,9 @@ endif
|
||||
|
||||
include ../Simple.Rules
|
||||
|
||||
#else
|
||||
#include ../dont_makefile
|
||||
#endif
|
||||
else
|
||||
|
||||
include ../dont_makefile
|
||||
|
@ -17,6 +17,9 @@ EXTRAS += -DCHKPWD_HELPER=\"$(SUPLEMENTED)/$(CHKPWD)\"
|
||||
ifeq ($(HAVE_LIBCRYPT),yes)
|
||||
EXTRALS += -lcrypt
|
||||
endif
|
||||
ifeq ($(HAVE_LIBNSL),yes)
|
||||
EXTRALS += -lnsl
|
||||
endif
|
||||
|
||||
TITLE=pam_pwdb
|
||||
CHKPWD=pwdb_chkpwd
|
||||
@ -53,7 +56,7 @@ info:
|
||||
|
||||
$(CHKPWD): pwdb_chkpwd.o md5_good.o md5_broken.o \
|
||||
md5_crypt_good.o md5_crypt_broken.o
|
||||
$(CC) -o $(CHKPWD) $^ -lpwdb
|
||||
$(CC) $(CFLAGS) -o $(CHKPWD) $^ $(LDFLAGS) -lpwdb $(EXTRALS)
|
||||
|
||||
pwdb_chkpwd.o: pwdb_chkpwd.c pam_unix_md.-c bigcrypt.-c
|
||||
|
||||
|
@ -178,7 +178,7 @@ static void set_option (struct _options *opts, const char *arg)
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(arg, "superuser=") == 0) {
|
||||
if (strncmp(arg, "superuser=", sizeof("superuser=")-1) == 0) {
|
||||
opts->superuser = arg+sizeof("superuser=")-1;
|
||||
return;
|
||||
}
|
||||
@ -293,7 +293,7 @@ __icheckhost (pam_handle_t *pamh, struct _options *opts, U32 raddr
|
||||
hp = gethostbyname(lhost);
|
||||
if (hp == NULL)
|
||||
return (0);
|
||||
|
||||
|
||||
/* Spin through ip addresses. */
|
||||
for (pp = hp->h_addr_list; *pp; ++pp)
|
||||
if (!memcmp (&raddr, *pp, sizeof (U32)))
|
||||
@ -408,7 +408,7 @@ __ivaliduser (pam_handle_t *pamh, struct _options *opts,
|
||||
user = p; /* this is the user's name */
|
||||
while (*p && !isspace(*p))
|
||||
++p; /* find end of user's name */
|
||||
} else
|
||||
} else
|
||||
user = p;
|
||||
|
||||
*p = '\0'; /* <nul> terminate username (+host?) */
|
||||
@ -480,7 +480,7 @@ pam_iruserok(pam_handle_t *pamh,
|
||||
No hosts.equiv file on system.
|
||||
} */
|
||||
}
|
||||
|
||||
|
||||
if ( opts->opt_no_rhosts )
|
||||
return 1;
|
||||
|
||||
@ -490,10 +490,10 @@ pam_iruserok(pam_handle_t *pamh,
|
||||
|
||||
pwd = _pammodutil_getpwnam(pamh, luser);
|
||||
if (pwd == NULL) {
|
||||
/*
|
||||
/*
|
||||
* luser is assumed to be valid because of an earlier check for uid = 0
|
||||
* we don't log this error twice. However, this shouldn't happen !
|
||||
* --cristiang
|
||||
* --cristiang
|
||||
*/
|
||||
return(1);
|
||||
}
|
||||
@ -652,9 +652,9 @@ pam_ruserok (pam_handle_t *pamh,
|
||||
*/
|
||||
|
||||
static int _pam_auth_rhosts (pam_handle_t *pamh,
|
||||
int flags,
|
||||
int flags,
|
||||
int argc,
|
||||
const char **argv)
|
||||
const char **argv)
|
||||
{
|
||||
int retval;
|
||||
const char *luser = NULL;
|
||||
@ -745,9 +745,9 @@ static int _pam_auth_rhosts (pam_handle_t *pamh,
|
||||
/* --- authentication management functions --- */
|
||||
|
||||
PAM_EXTERN
|
||||
int pam_sm_authenticate (pam_handle_t *pamh,
|
||||
int pam_sm_authenticate (pam_handle_t *pamh,
|
||||
int flags,
|
||||
int argc,
|
||||
int argc,
|
||||
const char **argv)
|
||||
{
|
||||
int retval;
|
||||
|
@ -18,6 +18,19 @@ include ../../Make.Rules
|
||||
#USE_CRACKLIB=-D"USE_CRACKLIB"
|
||||
#endif
|
||||
|
||||
ifeq ($(shell if [ -f /usr/lib/cracklib_dict.hwm ]; then echo yes ; fi),yes)
|
||||
CRACKLIB_DICTPATH=/usr/lib/cracklib_dict
|
||||
else
|
||||
CRACKLIB_DICTPATH=/usr/share/dict/cracklib_dict
|
||||
endif
|
||||
EXTRAS += -DCRACKLIB_DICTS=\"$(CRACKLIB_DICTPATH)\"
|
||||
|
||||
ifeq ($(HAVE_LIBCRYPT),yes)
|
||||
EXTRALS += -lcrypt
|
||||
endif
|
||||
ifeq ($(HAVE_LIBNSL),yes)
|
||||
EXTRALS += -lnsl
|
||||
endif
|
||||
# do you want to use lckpwdf?
|
||||
ifeq ($(WITH_LCKPWDF),yes)
|
||||
USE_LCKPWDF=-D"USE_LCKPWDF"
|
||||
@ -37,6 +50,8 @@ endif
|
||||
|
||||
CHKPWD=unix_chkpwd
|
||||
|
||||
BIGCRYPT=bigcrypt
|
||||
|
||||
EXTRAS += -DCHKPWD_HELPER=\"$(SUPLEMENTED)/$(CHKPWD)\"
|
||||
|
||||
LINK_PAMMODUTILS = -L../pammodutil -lpammodutil
|
||||
@ -74,7 +89,8 @@ endif
|
||||
|
||||
########################### don't edit below #######################
|
||||
|
||||
all: dirs info $(PLUS) $(LIBSHARED) $(LIBSTATIC) $(CHKPWD) register
|
||||
all: dirs info $(PLUS) $(LIBSHARED) $(LIBSTATIC) $(CHKPWD) $(BIGCRYPT) \
|
||||
register
|
||||
|
||||
dynamic/%.o : %.c
|
||||
$(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
|
||||
@ -125,7 +141,10 @@ endif
|
||||
$(CHKPWD): unix_chkpwd.o md5_good.o md5_broken.o \
|
||||
md5_crypt_good.o md5_crypt_broken.o \
|
||||
bigcrypt.o
|
||||
$(CC) -o $(CHKPWD) $^ $(LDLIBS) $(LIBCRYPT)
|
||||
$(CC) $(CFLAGS) -o $(CHKPWD) $^ $(LDLIBS) $(LIBCRYPT)
|
||||
|
||||
$(BIGCRYPT): bigcrypt_main.o bigcrypt.o
|
||||
$(CC) -o $(BIGCRYPT) $^ $(LDLIBS) $(LIBCRYPT)
|
||||
|
||||
unix_chkpwd.o: unix_chkpwd.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
|
||||
|
18
modules/pam_unix/bigcrypt_main.c
Normal file
18
modules/pam_unix/bigcrypt_main.c
Normal file
@ -0,0 +1,18 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
extern const char *bigcrypt(const char *password, const char *salt);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Usage: %s password salt\n",
|
||||
strchr(argv[0], '/') ?
|
||||
(strchr(argv[0], '/') + 1) :
|
||||
argv[0]);
|
||||
return 0;
|
||||
}
|
||||
fprintf(stdout, "%s\n", bigcrypt(argv[1], argv[2]));
|
||||
return 0;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
pam_userdb:
|
||||
Look up users in a .db database and verify their password against
|
||||
what is contained in that database.
|
||||
what is contained in that database. The database will have been
|
||||
created using db_load.
|
||||
|
||||
RECOGNIZED ARGUMENTS:
|
||||
debug write a message to syslog indicating success or
|
||||
@ -8,7 +9,9 @@ RECOGNIZED ARGUMENTS:
|
||||
|
||||
db=[path] use the [path] database for performing lookup. There
|
||||
is no default; the module will return PAM_IGNORE if
|
||||
no database is provided.
|
||||
no database is provided. Some versions of DB will
|
||||
automatically append ".db" to whatever pathname you
|
||||
supply here.
|
||||
|
||||
crypt=[mode] indicates whether encrypted or plaintext passwords
|
||||
are stored in the database. If [mode] is "crypt",
|
||||
@ -24,8 +27,28 @@ RECOGNIZED ARGUMENTS:
|
||||
dump dump all the entries in the database to the log (eek,
|
||||
don't do this by default!)
|
||||
|
||||
use_authtok use the authentication token previously obtained by
|
||||
another module that did the conversation with the
|
||||
application. If this token can not be obtained then
|
||||
the module will try to converse again. This option can
|
||||
be used for stacking different modules that need to
|
||||
deal with the authentication tokens.
|
||||
|
||||
unknown_ok do not return error when checking for a user that is
|
||||
not in the database. This can be used to stack more
|
||||
than one pam_userdb module that will check a
|
||||
username/password pair in more than a database.
|
||||
|
||||
key_only the username and password are concatenated together
|
||||
in the database hash as 'username-password' with a
|
||||
random value. if the concatenation of the username and
|
||||
password with a dash in the middle returns any result,
|
||||
the user is valid. this is useful in cases where
|
||||
the username may not be unique but the username and
|
||||
password pair are.
|
||||
|
||||
MODULE SERVICES PROVIDED:
|
||||
auth _authetication and _setcred (blank)
|
||||
auth _authentication and _setcred (blank)
|
||||
|
||||
EXAMPLE USE:
|
||||
auth sufficient pam_userdb.so icase db=/tmp/dbtest.db
|
||||
|
@ -5,8 +5,6 @@
|
||||
/* $Id */
|
||||
/* Copyright at the end of the file */
|
||||
|
||||
#define _BSD_SOURCE
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
use DB_File;
|
||||
|
||||
my $database = $ARGV[0];
|
||||
die "Use: check,pl <database>\n" unless ($database);
|
||||
die "Use: create.pl <database>\n" unless ($database);
|
||||
print "Using database: $database\n";
|
||||
|
||||
my %lusers = ();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* pam_userdb module */
|
||||
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
* Written by Cristian Gafton <gafton@redhat.com> 1996/09/10
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
#include <security/_pam_aconf.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
@ -56,39 +57,53 @@ static void _pam_log(int err, const char *format, ...)
|
||||
closelog();
|
||||
}
|
||||
|
||||
char * database = NULL;
|
||||
char * cryptmode = NULL;
|
||||
static int ctrl = 0;
|
||||
|
||||
static int _pam_parse(int argc, const char **argv)
|
||||
static int
|
||||
_pam_parse (int argc, const char **argv,
|
||||
char **database, char **cryptmode)
|
||||
{
|
||||
/* step through arguments */
|
||||
for (ctrl = 0; argc-- > 0; ++argv) {
|
||||
int ctrl;
|
||||
|
||||
/* generic options */
|
||||
*database = NULL;
|
||||
*cryptmode = NULL;
|
||||
|
||||
if (!strcmp(*argv,"debug"))
|
||||
ctrl |= PAM_DEBUG_ARG;
|
||||
else if (!strcasecmp(*argv, "icase"))
|
||||
ctrl |= PAM_ICASE_ARG;
|
||||
else if (!strcasecmp(*argv, "dump"))
|
||||
ctrl |= PAM_DUMP_ARG;
|
||||
else if (!strncasecmp(*argv,"db=", 3)) {
|
||||
database = strdup((*argv) + 3);
|
||||
if (database == NULL)
|
||||
_pam_log(LOG_ERR, "pam_parse: could not parse argument \"%s\"",
|
||||
*argv);
|
||||
} else if (!strncasecmp(*argv,"crypt=", 6)) {
|
||||
cryptmode = strdup((*argv) + 6);
|
||||
if (cryptmode == NULL)
|
||||
_pam_log(LOG_ERR, "pam_parse: could not parse argument \"%s\"",
|
||||
*argv);
|
||||
} else {
|
||||
_pam_log(LOG_ERR, "pam_parse: unknown option; %s", *argv);
|
||||
}
|
||||
}
|
||||
/* step through arguments */
|
||||
for (ctrl = 0; argc-- > 0; ++argv)
|
||||
{
|
||||
/* generic options */
|
||||
|
||||
return ctrl;
|
||||
if (!strcmp(*argv,"debug"))
|
||||
ctrl |= PAM_DEBUG_ARG;
|
||||
else if (!strcasecmp(*argv, "icase"))
|
||||
ctrl |= PAM_ICASE_ARG;
|
||||
else if (!strcasecmp(*argv, "dump"))
|
||||
ctrl |= PAM_DUMP_ARG;
|
||||
else if (!strcasecmp(*argv, "unknown_ok"))
|
||||
ctrl |= PAM_UNKNOWN_OK_ARG;
|
||||
else if (!strcasecmp(*argv, "key_only"))
|
||||
ctrl |= PAM_KEY_ONLY_ARG;
|
||||
else if (!strncasecmp(*argv,"db=", 3))
|
||||
{
|
||||
*database = strdup((*argv) + 3);
|
||||
if ((*database == NULL) || (strlen (*database) == 0))
|
||||
_pam_log(LOG_ERR,
|
||||
"pam_parse: could not parse argument \"%s\"",
|
||||
*argv);
|
||||
}
|
||||
else if (!strncasecmp(*argv,"crypt=", 6))
|
||||
{
|
||||
*cryptmode = strdup((*argv) + 6);
|
||||
if ((*cryptmode == NULL) || (strlen (*cryptmode) == 0))
|
||||
_pam_log(LOG_ERR,
|
||||
"pam_parse: could not parse argument \"%s\"",
|
||||
*argv);
|
||||
}
|
||||
else
|
||||
{
|
||||
_pam_log(LOG_ERR, "pam_parse: unknown option; %s", *argv);
|
||||
}
|
||||
}
|
||||
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
|
||||
@ -101,7 +116,9 @@ static int _pam_parse(int argc, const char **argv)
|
||||
* -1 = Password incorrect
|
||||
* -2 = System error
|
||||
*/
|
||||
static int user_lookup(const char *user, const char *pass)
|
||||
static int
|
||||
user_lookup (const char *database, const char *cryptmode,
|
||||
const char *user, const char *pass, int ctrl)
|
||||
{
|
||||
DBM *dbm;
|
||||
datum key, data;
|
||||
@ -114,7 +131,8 @@ static int user_lookup(const char *user, const char *pass)
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (ctrl &PAM_DUMP_ARG) {
|
||||
/* dump out the database contents for debugging */
|
||||
if (ctrl & PAM_DUMP_ARG) {
|
||||
_pam_log(LOG_INFO, "Database dump:");
|
||||
for (key = dbm_firstkey(dbm); key.dptr != NULL;
|
||||
key = dbm_nextkey(dbm)) {
|
||||
@ -122,14 +140,19 @@ static int user_lookup(const char *user, const char *pass)
|
||||
_pam_log(LOG_INFO, "key[len=%d] = `%s', data[len=%d] = `%s'",
|
||||
key.dsize, key.dptr, data.dsize, data.dptr);
|
||||
}
|
||||
}
|
||||
/* do some more init work */
|
||||
}
|
||||
|
||||
/* do some more init work */
|
||||
memset(&key, 0, sizeof(key));
|
||||
memset(&data, 0, sizeof(data));
|
||||
key.dptr = x_strdup(user);
|
||||
key.dsize = strlen(user);
|
||||
user = NULL;
|
||||
if (ctrl & PAM_KEY_ONLY_ARG) {
|
||||
key.dptr = malloc(strlen(user) + 1 + strlen(pass) + 1);
|
||||
sprintf(key.dptr, "%s-%s", user, pass);
|
||||
key.dsize = strlen(key.dptr);
|
||||
} else {
|
||||
key.dptr = x_strdup(user);
|
||||
key.dsize = strlen(user);
|
||||
}
|
||||
|
||||
if (key.dptr) {
|
||||
data = dbm_fetch(dbm, key);
|
||||
@ -144,7 +167,13 @@ static int user_lookup(const char *user, const char *pass)
|
||||
|
||||
if (data.dptr != NULL) {
|
||||
int compare = 0;
|
||||
|
||||
|
||||
if (ctrl & PAM_KEY_ONLY_ARG)
|
||||
{
|
||||
dbm_close (dbm);
|
||||
return 0; /* found it, data contents don't matter */
|
||||
}
|
||||
|
||||
if (strncasecmp(cryptmode, "crypt", 5) == 0) {
|
||||
|
||||
/* crypt(3) password storage */
|
||||
@ -166,7 +195,7 @@ static int user_lookup(const char *user, const char *pass)
|
||||
compare = strncasecmp (data.dptr, cryptpw, data.dsize);
|
||||
} else {
|
||||
compare = -2;
|
||||
if (ctrl & PAM_DEBUG_ARG) {
|
||||
if (ctrl & PAM_DEBUG_ARG) {
|
||||
_pam_log(LOG_INFO, "crypt() returned NULL");
|
||||
}
|
||||
};
|
||||
@ -174,20 +203,20 @@ static int user_lookup(const char *user, const char *pass)
|
||||
};
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
/* Unknown password encryption method -
|
||||
* default to plaintext password storage
|
||||
*/
|
||||
|
||||
if (strlen(pass) != data.dsize) {
|
||||
compare = 1;
|
||||
compare = 1; /* wrong password len -> wrong password */
|
||||
} else if (ctrl & PAM_ICASE_ARG) {
|
||||
compare = strncasecmp(data.dptr, pass, data.dsize);
|
||||
} else {
|
||||
compare = strncmp(data.dptr, pass, data.dsize);
|
||||
}
|
||||
|
||||
if (strncasecmp(cryptmode, "none", 4) && ctrl & PAM_DEBUG_ARG) {
|
||||
if (strncasecmp(cryptmode, "none", 4) && ctrl & PAM_DEBUG_ARG) {
|
||||
_pam_log(LOG_INFO, "invalid value for crypt parameter: %s",
|
||||
cryptmode);
|
||||
_pam_log(LOG_INFO, "defaulting to plaintext password mode");
|
||||
@ -201,13 +230,58 @@ static int user_lookup(const char *user, const char *pass)
|
||||
else
|
||||
return -1; /* wrong */
|
||||
} else {
|
||||
if (ctrl & PAM_DEBUG_ARG) {
|
||||
int saw_user = 0;
|
||||
|
||||
if (ctrl & PAM_DEBUG_ARG) {
|
||||
_pam_log(LOG_INFO, "error returned by dbm_fetch: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
dbm_close(dbm);
|
||||
|
||||
/* probably we should check dbm_error() here */
|
||||
return 1; /* not found */
|
||||
|
||||
if ((ctrl & PAM_KEY_ONLY_ARG) == 0) {
|
||||
dbm_close(dbm);
|
||||
return 1; /* not key_only, so no entry => no entry for the user */
|
||||
}
|
||||
|
||||
/* now handle the key_only case */
|
||||
for (key = dbm_firstkey(dbm);
|
||||
key.dptr != NULL;
|
||||
key = dbm_nextkey(dbm)) {
|
||||
int compare;
|
||||
/* first compare the user portion (case sensitive) */
|
||||
compare = strncmp(key.dptr, user, strlen(user));
|
||||
if (compare == 0) {
|
||||
/* assume failure */
|
||||
compare = -1;
|
||||
/* if we have the divider where we expect it to be... */
|
||||
if (key.dptr[strlen(user)] == '-') {
|
||||
saw_user = 1;
|
||||
if (key.dsize == strlen(user) + 1 + strlen(pass)) {
|
||||
if (ctrl & PAM_ICASE_ARG) {
|
||||
/* compare the password portion (case insensitive)*/
|
||||
compare = strncasecmp(key.dptr + strlen(user) + 1,
|
||||
pass,
|
||||
strlen(pass));
|
||||
} else {
|
||||
/* compare the password portion (case sensitive) */
|
||||
compare = strncmp(key.dptr + strlen(user) + 1,
|
||||
pass,
|
||||
strlen(pass));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (compare == 0) {
|
||||
dbm_close(dbm);
|
||||
return 0; /* match */
|
||||
}
|
||||
}
|
||||
}
|
||||
dbm_close(dbm);
|
||||
if (saw_user)
|
||||
return -1; /* saw the user, but password mismatch */
|
||||
else
|
||||
return 1; /* not found */
|
||||
}
|
||||
|
||||
/* NOT REACHED */
|
||||
@ -222,10 +296,17 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
|
||||
{
|
||||
const char *username;
|
||||
const char *password;
|
||||
int retval = PAM_AUTH_ERR;
|
||||
|
||||
char *database = NULL;
|
||||
char *cryptmode = NULL;
|
||||
int retval = PAM_AUTH_ERR, ctrl;
|
||||
|
||||
/* parse arguments */
|
||||
ctrl = _pam_parse(argc, argv);
|
||||
ctrl = _pam_parse(argc, argv, &database, &cryptmode);
|
||||
if ((database == NULL) || (strlen(database) == 0)) {
|
||||
if (ctrl & PAM_DEBUG_ARG)
|
||||
_pam_log(LOG_DEBUG,"can not get the database name");
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
|
||||
/* Get the username */
|
||||
retval = pam_get_user(pamh, &username, NULL);
|
||||
@ -234,32 +315,47 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
|
||||
_pam_log(LOG_DEBUG,"can not get the username");
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
|
||||
/* Converse just to be sure we have the password */
|
||||
|
||||
/* Converse just to be sure we have a password */
|
||||
retval = conversation(pamh);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
_pam_log(LOG_ERR, "could not obtain password for `%s'",
|
||||
username);
|
||||
return -2;
|
||||
return PAM_CONV_ERR;
|
||||
}
|
||||
|
||||
|
||||
/* Check if we got a password. The docs say that if we didn't have one,
|
||||
* and use_authtok was specified as an argument, that we converse with the
|
||||
* user anyway, so check for one and handle a failure for that case. If
|
||||
* use_authtok wasn't specified, then we've already asked once and needn't
|
||||
* do so again. */
|
||||
retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **) &password);
|
||||
if ((retval != PAM_SUCCESS) && ((ctrl & PAM_USE_AUTHTOK_ARG) != 0)) {
|
||||
retval = conversation(pamh);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
_pam_log(LOG_ERR, "could not obtain password for `%s'",
|
||||
username);
|
||||
return PAM_CONV_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the password */
|
||||
retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **)&password);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
_pam_log(LOG_ERR, "Could not retrive user's password");
|
||||
_pam_log(LOG_ERR, "Could not retrieve user's password");
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
if (ctrl & PAM_DEBUG_ARG)
|
||||
_pam_log(LOG_INFO, "Verify user `%s' with password `%s'",
|
||||
username, password);
|
||||
|
||||
|
||||
/* Now use the username to look up password in the database file */
|
||||
retval = user_lookup(username, password);
|
||||
retval = user_lookup(database, cryptmode, username, password, ctrl);
|
||||
switch (retval) {
|
||||
case -2:
|
||||
/* some sort of system error. The log was already printed */
|
||||
return PAM_SERVICE_ERR;
|
||||
return PAM_SERVICE_ERR;
|
||||
case -1:
|
||||
/* incorrect password */
|
||||
_pam_log(LOG_WARNING,
|
||||
@ -296,9 +392,47 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags,
|
||||
}
|
||||
|
||||
PAM_EXTERN
|
||||
int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
|
||||
int argc, const char **argv)
|
||||
int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
{
|
||||
const char *username;
|
||||
char *database = NULL;
|
||||
char *cryptmode = NULL;
|
||||
int retval = PAM_AUTH_ERR, ctrl;
|
||||
|
||||
/* parse arguments */
|
||||
ctrl = _pam_parse(argc, argv, &database, &cryptmode);
|
||||
|
||||
/* Get the username */
|
||||
retval = pam_get_user(pamh, &username, NULL);
|
||||
if ((retval != PAM_SUCCESS) || (!username)) {
|
||||
if (ctrl & PAM_DEBUG_ARG)
|
||||
_pam_log(LOG_DEBUG,"can not get the username");
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
|
||||
/* Now use the username to look up password in the database file */
|
||||
retval = user_lookup(database, cryptmode, username, "", ctrl);
|
||||
switch (retval) {
|
||||
case -2:
|
||||
/* some sort of system error. The log was already printed */
|
||||
return PAM_SERVICE_ERR;
|
||||
case -1:
|
||||
/* incorrect password, but we don't care */
|
||||
/* FALL THROUGH */
|
||||
case 0:
|
||||
/* authentication succeeded. dumbest password ever. */
|
||||
return PAM_SUCCESS;
|
||||
case 1:
|
||||
/* the user does not exist in the database */
|
||||
return PAM_USER_UNKNOWN;
|
||||
default:
|
||||
/* we don't know anything about this return value */
|
||||
_pam_log(LOG_ERR,
|
||||
"internal module error (retval = %d, user = `%s'",
|
||||
retval, username);
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
@ -311,7 +445,7 @@ struct pam_module _pam_userdb_modstruct = {
|
||||
"pam_userdb",
|
||||
pam_sm_authenticate,
|
||||
pam_sm_setcred,
|
||||
NULL,
|
||||
pam_sm_acct_mgmt,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -10,6 +10,9 @@
|
||||
#define PAM_DEBUG_ARG 0x0001
|
||||
#define PAM_ICASE_ARG 0x0002
|
||||
#define PAM_DUMP_ARG 0x0004
|
||||
#define PAM_USE_AUTHTOK_ARG 0x0008
|
||||
#define PAM_UNKNOWN_OK_ARG 0x0010
|
||||
#define PAM_KEY_ONLY_ARG 0x0020
|
||||
|
||||
/* Useful macros */
|
||||
#define x_strdup(s) ( (s) ? strdup(s):NULL )
|
||||
|
Loading…
Reference in New Issue
Block a user