]> granicus.if.org Git - linux-pam/commitdiff
Relevant BUGIDs:
authorThorsten Kukuk <kukuk@thkukuk.de>
Tue, 28 Sep 2004 13:48:45 +0000 (13:48 +0000)
committerThorsten Kukuk <kukuk@thkukuk.de>
Tue, 28 Sep 2004 13:48:45 +0000 (13:48 +0000)
Purpose of commit:

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

bugfix:

* Merge patches from Red Hat (Bug 477000 and other - kukuk)
* Fix pam_rhosts option parsing (Bug 922648 - kukuk)

23 files changed:
CHANGELOG
Make.Rules.in
Makefile
configure
configure.in
doc/modules/pam_userdb.sgml
doc/pam_source.sgml
libpam/Makefile
libpam_misc/Makefile
libpamc/Makefile
modules/Makefile
modules/Simple.Rules
modules/pam_filter/pam_filter.c
modules/pam_limits/Makefile
modules/pam_pwdb/Makefile
modules/pam_rhosts/pam_rhosts_auth.c
modules/pam_unix/Makefile
modules/pam_unix/bigcrypt_main.c [new file with mode: 0644]
modules/pam_userdb/README
modules/pam_userdb/conv.c
modules/pam_userdb/create.pl
modules/pam_userdb/pam_userdb.c
modules/pam_userdb/pam_userdb.h

index 377d80bc6b45d1737b99830d249a304bb75b6145..82b9ab91f840fee6bf7ff577107a93ee41debc8c 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -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
 
index 781bbd03920e67516a2069619dcbdb323bdded7a..722d028f675e2de7f691fae667db8f55677e918d 100644 (file)
@@ -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
index 562802d3c67e848e5bc60ab62005cabdf7f4e27d..71136952328d75b0ba5182d19b7c0b61126fc7c2 100644 (file)
--- a/Makefile
+++ b/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)/*
-
index 555f16a78976dfb95881ed4f8ddae90889cefb93..2775677941f7db90c34013adab4659419cd24727 100755 (executable)
--- a/configure
+++ b/configure
@@ -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"
                ;;
index 73734335cfda582ff802e47676ff356f3bcd7f2f..d673e3af5c0ab0c42c70c35b77bb3e92e4045758 100644 (file)
@@ -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
index bdbf80b821d09cb18c039df16726303b7ab1d634..155a2668e0f62cdc57a1248f1f54fb861df379e1 100644 (file)
@@ -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>
index 2ea9a7c9c97fa33bd19a51a2502232fe4dbd563b..8e64103274005a612760d913a1f09bbc8cb177e4 100644 (file)
@@ -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 
index 6728d63597a787a0471b0b7d12f36b9da0190d82..2a55577f741adcc60a365153601c3bb2f12c8747 100644 (file)
@@ -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)
index 88364a247c891ba474b55ad71be9b47495064e23..bb7ec27ccee805fb90ff750fe3d21df7a3d127ba 100644 (file)
@@ -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)
index 0a302534ce4bddb7a5e28f22a410526b3ac5d103..f15aadd891100602a47dc9fac12c365a6a8cbea7 100644 (file)
@@ -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)
index 938910290bf857bacf6dbf1cf9b5579c4ab61eb8..d16dedcf5c3095cf773ce0109791c6bdf94cac8d 100644 (file)
@@ -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
index 97f419a8d1a6090107324eeb18a47b94509fdcf2..c12ede3a106c9fe3cbd8d47aaf42085d5926333a 100644 (file)
@@ -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))
index e9a0494b2adcdfea5d35307113543f40297e3d8e..d3462f409cd5b2d63c115a940d39dd0230ff5864 100644 (file)
@@ -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);
index 0a481fe809bcef314fca2598b9bcf5737202101a..5aeb73ceabf24a733a4ce2b9943ec4f16a38b9bf 100644 (file)
@@ -27,6 +27,9 @@ endif
 
 include ../Simple.Rules
 
+#else
+#include ../dont_makefile
+#endif
 else
 
 include ../dont_makefile
index 2b581dcd366ec46c605710d029319c1b8d5470c3..fa0e1b026e5fc383013bef346f0f9efa6f89656d 100644 (file)
@@ -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
 
index 374318dcc777293475a3dd7505239c96f58f10a0..b41b708d4545162d5f4419e410b3c262a7345084 100644 (file)
@@ -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;
index 3fe0e8ae0bb58c927db413345b217d5c8b825d86..24ffd4b5f3c9a9f82f1404b632b14c43788d41e8 100644 (file)
@@ -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 $@
diff --git a/modules/pam_unix/bigcrypt_main.c b/modules/pam_unix/bigcrypt_main.c
new file mode 100644 (file)
index 0000000..7081907
--- /dev/null
@@ -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;
+}
index 9fa6519dd86c71d396ade1db8fe54bd3d387c6e0..fc56cfa0eb8e6d7ea2a39ec8e38e3954cdea51f6 100644 (file)
@@ -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
index 0f13d03a4fc4e5de0f1df5072e33a1fb8abb7308..de5d12f2d4574c028631c96146b8d51e3c41886c 100644 (file)
@@ -5,8 +5,6 @@
 /* $Id */
 /* Copyright at the end of the file */
 
-#define _BSD_SOURCE
-
 #include <stdlib.h>
 #include <string.h>
 
index 046b55f0821a847050c0861f9426c68ec0969c53..224204b720c176c1b8ab27c7c4102263fffda195 100644 (file)
@@ -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 = ();
index 30f1e578d2e3e739f5b1596298da32c7c0101774..a0a5b8b5aad55fdc7ad43bd43482045fbe06be93 100644 (file)
@@ -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) {
-
-          /* generic options */
-
-          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);
-          }
-     }
+  int ctrl;
+
+  *database = NULL;
+  *cryptmode = NULL;
+
+  /* step through arguments */
+  for (ctrl = 0; argc-- > 0; ++argv)
+    {
+      /* generic options */
+
+      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;
+  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,
index 911a7622351d943f6d0f21de35ce511b042775ca..a371fa9f2b291f8141f8395966d7c484cdc334a4 100644 (file)
@@ -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 )