From 5dbeed06ae0b0f168158920c59dcfb0cc822dee6 Mon Sep 17 00:00:00 2001 From: Charl Botha Date: Sun, 16 Aug 2009 19:57:51 +0000 Subject: Added note about contrib directory. --- README | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/README b/README index 532f230..d5c82f9 100644 --- a/README +++ b/README @@ -37,10 +37,18 @@ username:crypted_passwd[34] in the case of MD5 crypted passwords. The latter is thanks to Warwick Duncan . pam_pwdfile also handles bigcrypt passwords. -Warwick has also written a utility for managing the password files that -pam_pwdfile uses. Please see: http://eclipse.che.uct.ac.za/chpwdfile/ +NOTES: +----- -Note that we still expect users to have accounts in the usual place, as we +* Also have a look at the files in the contrib subdirectory. + Especially if you're having trouble building paw_pwdfile, the + Makefile.standalone could be your new friend. + +* Warwick has also written a utility for managing the password files that +pam_pwdfile uses. The website has disappeared, but I've mirrored the +source code here: http://cpbotha.net/files/mirror/chpwdfile-0.24.tar.gz + +* Note that we still expect users to have accounts in the usual place, as we make use of the pam_pwdb.so module for the account service. This module is just so that one can have multiple sets of passwords for different services, e.g. with our /etc/imap.passwd. It is however possible with certain -- cgit v1.2.3 From 0148de59cdcea4013d694fc04db3174ce06c60b1 Mon Sep 17 00:00:00 2001 From: Timo Weingärtner Date: Thu, 25 Apr 2013 14:22:49 +0200 Subject: rework Makefile for standalone building if this is ever integrated into pam it will be autotools anyways use ?= and += to better work with distribution's build systems --- Makefile | 122 ++++++++------------------------------- contrib/Makefile.standalone | 47 --------------- contrib/Makefile.standalone-0.95 | 26 --------- 3 files changed, 25 insertions(+), 170 deletions(-) delete mode 100644 contrib/Makefile.standalone delete mode 100644 contrib/Makefile.standalone-0.95 diff --git a/Makefile b/Makefile index da956d3..364cee0 100644 --- a/Makefile +++ b/Makefile @@ -1,112 +1,40 @@ -# $Id: Makefile,v 1.5 2002-06-09 21:01:46 cpbotha Exp $ -# -# This Makefile controls a build process of $(TITLE) module for -# Linux-PAM. You should not modify this Makefile (unless you know -# what you are doing!). -# +PAM_LIB_DIR ?= $(DESTDIR)/lib/security +INSTALL ?= install +CFLAGS ?= -O2 -g -Wall -Wformat-security -include ../../Make.Rules +CFLAGS += -fPIC +LDFLAGS += -Wl,-x -shared -ifeq ($(HAVE_LIBCRYPT),yes) - EXTRALS += -lcrypt -endif - -TITLE=pam_pwdfile -CFLAGS += -D_BSD_SOURCE - -md5_good.o: md5.c - $(CC) $(CFLAGS) $(CPPFLAGS) -DHIGHFIRST -D'MD5Name(x)=Good##x' \ - $(TARGET_ARCH) -c $< -o $@ - -md5_broken.o: md5.c - $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Broken##x' \ - $(TARGET_ARCH) -c $< -o $@ - -md5_crypt_good.o: md5_crypt.c - $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Good##x' \ - $(TARGET_ARCH) -c $< -o $@ - -md5_crypt_broken.o: md5_crypt.c - $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Broken##x' \ - $(TARGET_ARCH) -c $< -o $@ - -##### The following mostly from Simple.Rules -##### * modifications to first 5 definitions - -LIBFILES = $(TITLE) bigcrypt -LIBSRC = $(addsuffix .c,$(LIBFILES)) md5.c md5_crypt.c -LIBOBJ = $(addsuffix .o,$(LIBFILES)) -LIBOBJD = $(addprefix dynamic/,$(LIBOBJ)) md5_good.o md5_broken.o md5_crypt_good.o md5_crypt_broken.o -LIBOBJS = $(addprefix static/,$(LIBOBJ)) md5_good.o md5_broken.o md5_crypt_good.o md5_crypt_broken.o - -ifdef DYNAMIC +TITLE = pam_pwdfile LIBSHARED = $(TITLE).so -endif - -ifdef STATIC -LIBSTATIC = lib$(TITLE).o -endif - -####################### don't edit below ####################### +LDLIBS = -lcrypt -lpam +LIBOBJ = $(TITLE).o md5_good.o md5_broken.o md5_crypt_good.o md5_crypt_broken.o bigcrypt.o +CPPFLAGS_MD5_GOOD = -D'MD5Name(x)=Good\#\#x' +CPPFLAGS_MD5_BROKEN = -DHIGHFIRST -D'MD5Name(x)=Broken\#\#x' -all: dirs $(LIBSHARED) $(LIBSTATIC) register -dynamic/%.o : %.c - $(CC) $(CFLAGS) $(DYNAMIC) $(TARGET_ARCH) -c $< -o $@ +all: $(LIBSHARED) -static/%.o : %.c - $(CC) $(CFLAGS) $(STATIC) $(TARGET_ARCH) -c $< -o $@ +$(LIBSHARED): $(LIBOBJ) + $(CC) $(LDFLAGS) $(LIBOBJ) $(LDLIBS) -o $@ -dirs: -ifdef DYNAMIC - $(MKDIR) ./dynamic -endif -ifdef STATIC - $(MKDIR) ./static -endif -register: -ifdef STATIC - ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) ) -endif - -ifdef DYNAMIC -$(LIBOBJD): $(LIBSRC) -endif +md5_good.o: md5.c + $(CC) -c $(CPPFLAGS) $(CPPFLAGS_MD5_GOOD) $(CFLAGS) $< -o $@ -ifdef DYNAMIC -$(LIBSHARED): $(LIBOBJD) - $(LD_D) -o $@ $(LIBOBJD) $(EXTRALS) $(NEED_LINK_LIB_C) -endif +md5_broken.o: md5.c + $(CC) -c $(CPPFLAGS) $(CPPFLAGS_MD5_BROKEN) $(CFLAGS) $< -o $@ -ifdef STATIC -$(LIBOBJS): $(LIBSRC) -endif +md5_crypt_good.o: md5_crypt.c + $(CC) -c $(CPPFLAGS) $(CPPFLAGS_MD5_GOOD) $(CFLAGS) $< -o $@ -ifdef STATIC -$(LIBSTATIC): $(LIBOBJS) - $(LD) -r -o $@ $(LIBOBJS) $(EXTRALS) -endif +md5_crypt_broken.o: md5_crypt.c + $(CC) -c $(CPPFLAGS) $(CPPFLAGS_MD5_BROKEN) $(CFLAGS) $< -o $@ -install: all - $(MKDIR) $(FAKEROOT)$(SECUREDIR) -ifdef DYNAMIC - $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR) -endif - $(MODULE_SIMPLE_INSTALL) -remove: - rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so - $(MODULE_SIMPLE_REMOVE) +install: $(LIBSHARED) + $(INSTALL) -m 0755 -d $(PAM_LIB_DIR) + $(INSTALL) -m 0755 $(LIBSHARED) $(PAM_LIB_DIR) clean: - rm -f $(LIBOBJD) $(LIBOBJS) core *~ - $(MODULE_SIMPLE_CLEAN) - rm -f *.a *.o *.so *.bak - rm -rf dynamic static - $(MODULE_SIMPLE_EXTRACLEAN) - -.c.o: - $(CC) $(CFLAGS) -c $< - - + $(RM) *.o *.so diff --git a/contrib/Makefile.standalone b/contrib/Makefile.standalone deleted file mode 100644 index 857eaff..0000000 --- a/contrib/Makefile.standalone +++ /dev/null @@ -1,47 +0,0 @@ -PAM_LIB_DIR = /lib/security -CC = gcc -LD = ld -INSTALL = /usr/bin/install -CFLAGS = -fPIC -O2 -c -g -Wall -Wformat-security -LDFLAGS = -x --shared -PAMLIB = -lpam -CRYPTLIB = -lcrypt -CPPFLAGS = - -all: pam_pwdfile.so - -pam_pwdfile.so: pam_pwdfile.o bigcrypt.o md5_good.o md5_crypt_good.o md5_broken.o md5_crypt_broken.o - $(LD) $(LDFLAGS) -o pam_pwdfile.so pam_pwdfile.o md5_good.o md5_crypt_good.o md5_broken.o md5_crypt_broken.o bigcrypt.o $(PAMLIB) $(CRYPTLIB) - -pam_pwdfile.o: pam_pwdfile.c - $(CC) $(CFLAGS) pam_pwdfile.c - -bigcrypt.o: bigcrypt.c - $(CC) $(CFLAGS) bigcrypt.c - - -md5_good.o: md5.c - $(CC) $(CFLAGS) $(CPPFLAGS) -DHIGHFIRST -D'MD5Name(x)=Good##x' -c $< -o $@ - -md5_broken.o: md5.c - $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Broken##x' \ - -c $< -o $@ - -md5_crypt_good.o: md5_crypt.c - $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Good##x' \ - -c $< -o $@ - -md5_crypt_broken.o: md5_crypt.c - $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Broken##x' \ - -c $< -o $@ - - -install: pam_pwdfile.so - $(INSTALL) -m 0755 -d $(PAM_LIB_DIR) - $(INSTALL) -m 0755 pam_pwdfile.so $(PAM_LIB_DIR) - -clean: - rm -f pam_pwdfile.o pam_pwdfile.so - -spotless: - rm -f pam_pwdfile.so pam_pwdfile.o *~ core diff --git a/contrib/Makefile.standalone-0.95 b/contrib/Makefile.standalone-0.95 deleted file mode 100644 index 136f04a..0000000 --- a/contrib/Makefile.standalone-0.95 +++ /dev/null @@ -1,26 +0,0 @@ -PAM_LIB_DIR = /lib/security -CC = gcc -LD = ld -INSTALL = /usr/bin/install -CFLAGS = -fPIC -O2 -c -g -Wall -Wformat-security -LDFLAGS = -x --shared -PAMLIB = -lpam -CRYPTLIB = -lcrypt - -all: pam_pwdfile.so - -pam_pwdfile.so: pam_pwdfile.o - $(LD) $(LDFLAGS) -o pam_pwdfile.so pam_pwdfile.o $(PAMLIB) $(CRYPTLIB) - -pam_pwdfile.o: pam_pwdfile.c - $(CC) $(CFLAGS) pam_pwdfile.c - -install: pam_pwdfile.so - $(INSTALL) -m 0755 -d $(PAM_LIB_DIR) - $(INSTALL) -m 0755 pam_pwdfile.so $(PAM_LIB_DIR) - -clean: - rm -f pam_pwdfile.o pam_pwdfile.so - -spotless: - rm -f pam_pwdfile.so pam_pwdfile.o *~ core -- cgit v1.2.3 From fbce1a480fda4c97b21c87fb39096d23db6eedfb Mon Sep 17 00:00:00 2001 From: Timo Weingärtner Date: Thu, 25 Apr 2013 14:27:07 +0200 Subject: apply visibility patch by Peter Palfrader --- Makefile | 2 +- pam_pwdfile.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 364cee0..06e1637 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ PAM_LIB_DIR ?= $(DESTDIR)/lib/security INSTALL ?= install CFLAGS ?= -O2 -g -Wall -Wformat-security -CFLAGS += -fPIC +CFLAGS += -fPIC -fvisibility=hidden LDFLAGS += -Wl,-x -shared TITLE = pam_pwdfile diff --git a/pam_pwdfile.c b/pam_pwdfile.c index 2d020a9..c8cae75 100644 --- a/pam_pwdfile.c +++ b/pam_pwdfile.c @@ -222,6 +222,7 @@ static int fgetpwnam(FILE *stream, const char *name, char *password) { } /* expected hook for auth service */ +__attribute__((visibility("default"))) PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { int retval, pcnt, pwdfilename_found; @@ -408,6 +409,7 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, } /* another expected hook */ +__attribute__((visibility("default"))) PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) { -- cgit v1.2.3 From 629c03d7775e1f4b5c0fdee358c6773f70e91961 Mon Sep 17 00:00:00 2001 From: Timo Weingärtner Date: Fri, 26 Apr 2013 12:57:56 +0200 Subject: add debug module option and use pam_syslog also: * remove some unnessesary comments * add vim settings for unusual indentation --- bigcrypt.c | 5 ----- pam_pwdfile.c | 71 ++++++++++++++++++++--------------------------------------- 2 files changed, 24 insertions(+), 52 deletions(-) diff --git a/bigcrypt.c b/bigcrypt.c index b1568d6..28d042a 100644 --- a/bigcrypt.c +++ b/bigcrypt.c @@ -25,7 +25,6 @@ */ #include -#include char *crypt(const char *key, const char *salt); char *bigcrypt(const char *key, const char *salt); @@ -51,8 +50,6 @@ char *bigcrypt(const char *key, const char *salt) char *cipher_ptr, *plaintext_ptr, *tmp_ptr, *salt_ptr; char keybuf[KEYBUF_SIZE + 1]; - D(("called with key='%s', salt='%s'.", key, salt)); - /* reset arrays */ memset(keybuf, 0, KEYBUF_SIZE + 1); memset(dec_c2_cryptbuf, 0, CBUF_SIZE); @@ -111,9 +108,7 @@ char *bigcrypt(const char *key, const char *salt) salt_ptr = cipher_ptr - ESEGMENT_SIZE; } } - D(("key=|%s|, salt=|%s|\nbuf=|%s|\n", key, salt, dec_c2_cryptbuf)); /* this is the terminated encrypted password */ - return dec_c2_cryptbuf; } diff --git a/pam_pwdfile.c b/pam_pwdfile.c index c8cae75..d8c9e69 100644 --- a/pam_pwdfile.c +++ b/pam_pwdfile.c @@ -44,7 +44,6 @@ #include #include -#include #include #include #include @@ -54,11 +53,13 @@ #include #include #include +#include #include #define PAM_SM_AUTH #include +#include #include "md5.h" extern char *crypt(const char *key, const char *salt); @@ -72,27 +73,10 @@ extern char *bigcrypt(const char *key, const char *salt); #define CRYPTED_MD5PWD_LEN 34 #define CRYPTED_BCPWD_LEN 178 -#ifdef DEBUG -# define D(a) a; -#else -# define D(a) {} -#endif - /* prototypes */ int converse(pam_handle_t *, int, struct pam_message **, struct pam_response **); int _set_auth_tok(pam_handle_t *, int, int, const char **); -/* logging function ripped from pam_listfile.c */ -static void _pam_log(int err, const char *format, ...) { - va_list args; - - va_start(args, format); - openlog("pam_pwdfile", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - static int lock_fd(int fd) { int delay; @@ -235,6 +219,7 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int use_flock = 0; int use_delay = 1; int temp_result = 0; + int debug = 0; /* we require the pwdfile switch and argument to be present, else we don't work */ /* pcnt is the parameter counter variable for iterating through argv */ @@ -264,48 +249,45 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, } else if (strcmp(argv[pcnt],NODELAY_PARAM)==0) { /* no delay on authentication failure */ use_delay = 0; + } else if (strcmp(argv[pcnt], "debug") == 0) { + debug = 1; } } while (++pcnt < argc); #ifdef HAVE_PAM_FAIL_DELAY if (use_delay) { - D(("setting delay")); - (void) pam_fail_delay(pamh, 2000000); /* 2 sec delay for on failure */ + if (debug) pam_syslog(pamh, LOG_DEBUG, "setting fail delay"); + (void) pam_fail_delay(pamh, 2000000); /* 2 sec */ } #endif - /* for some or other reason, the password file wasn't specified */ if (!pwdfilename_found) { - _pam_log(LOG_ERR,"password file name not specified"); + pam_syslog(pamh, LOG_ERR, "password file name not specified"); return PAM_AUTHINFO_UNAVAIL; } - /* DEBUG */ - D(_pam_log(LOG_ERR, "password filename extracted")); + if (debug) pam_syslog(pamh, LOG_DEBUG, "password filename extracted"); /* now try to open the password file */ if ((pwdfile=fopen(pwdfilename,"r"))==NULL) { - _pam_log(LOG_ERR,"couldn't open password file %s",pwdfilename); + pam_syslog(pamh, LOG_ALERT, "couldn't open password file %s", pwdfilename); return PAM_AUTHINFO_UNAVAIL; } - /* set a lock on the password file */ if (use_flock && lock_fd(fileno(pwdfile)) == -1) { - _pam_log(LOG_ERR,"couldn't lock password file %s",pwdfilename); + pam_syslog(pamh, LOG_ALERT, "couldn't lock password file %s", pwdfilename); return PAM_AUTHINFO_UNAVAIL; } /* get user name */ if ((retval = pam_get_user(pamh,&name,"login: ")) != PAM_SUCCESS) { - _pam_log(LOG_ERR, "username not found"); + pam_syslog(pamh, LOG_ERR, "username not found"); fclose(pwdfile); return retval; } - - /* DEBUG */ - D(_pam_log(LOG_ERR,"username is %s", name)); + if (debug) pam_syslog(pamh, LOG_DEBUG, "username is %s", name); /* get password - code from pam_unix_auth.c */ pam_get_item(pamh, PAM_AUTHTOK, (void *)&password); @@ -319,38 +301,34 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, pam_get_item(pamh, PAM_AUTHTOK, (void *)&password); if ((retval = pam_get_item(pamh, PAM_AUTHTOK, (void *)&password)) != PAM_SUCCESS) { - _pam_log(LOG_ERR, "auth token not found"); + pam_syslog(pamh, LOG_ERR, "auth token not found"); fclose(pwdfile); return retval; } - /* DEBUG */ - D(_pam_log(LOG_ERR,"got password from user", password)); - /* now crypt password and compare to the user entry in the password file */ /* first make sure password is long enough -- may I do this? */ if (strlen(password)<2 || password==NULL) { - _pam_log(LOG_ERR,"password too short or NULL"); + pam_syslog(pamh, LOG_ERR, "password too short or NULL"); fclose(pwdfile); return PAM_AUTH_ERR; } /* get the crypted password corresponding to this user */ if (!fgetpwnam(pwdfile, name, stored_crypted_password)) { - _pam_log(LOG_ERR,"user not found in password database"); + pam_syslog(pamh, LOG_ERR, "user not found in password database"); fclose(pwdfile); return PAM_AUTHINFO_UNAVAIL; } - /* DEBUG */ - D(_pam_log(LOG_ERR,"got crypted password == '%s'", stored_crypted_password)); + if (debug) pam_syslog(pamh, LOG_DEBUG, "got crypted password == '%s'", stored_crypted_password); temp_result = 0; /* Extract the salt and set the passwd length, depending on MD5 or DES */ if (strncmp(stored_crypted_password, "$1$", 3) == 0) { - D(_pam_log(LOG_ERR,"password hash type is 'md5'")); + if (debug) pam_syslog(pamh, LOG_ERR, "password hash type is 'md5'"); /* get out the salt into "salt" */ strncpy(salt, stored_crypted_password, 11); salt[11] = '\0'; @@ -376,10 +354,10 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, stored_crypted_password[CRYPTED_BCPWD_LEN] = '\0'; if (strlen(stored_crypted_password) <= CRYPTED_DESPWD_LEN) { - D(_pam_log(LOG_ERR,"password hash type is 'crypt'")); + if (debug) pam_syslog(pamh, LOG_DEBUG, "password hash type is 'crypt'"); crypted_password = crypt(password, salt); } else { - D(_pam_log(LOG_ERR,"password hash type is 'bigcrypt'")); + if (debug) pam_syslog(pamh, LOG_DEBUG, "password hash type is 'bigcrypt'"); crypted_password = bigcrypt(password, salt); } @@ -389,19 +367,17 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, } } - /* DEBUG */ - D(_pam_log(LOG_ERR,"user password crypted is '%s'", crypted_password)); + if (debug) pam_syslog(pamh, LOG_DEBUG, "user password crypted is '%s'", crypted_password); /* if things don't match up, complain */ if (!temp_result) { - _pam_log(LOG_ERR,"wrong password for user %s",name); + pam_syslog(pamh, LOG_NOTICE, "wrong password for user %s", name); fclose(pwdfile); return PAM_AUTH_ERR; } - /* DEBUG */ - D(_pam_log(LOG_ERR,"passwords match")); + if (debug) pam_syslog(pamh, LOG_DEBUG, "passwords match"); /* we've gotten here, i.e. authentication was sucessful! */ fclose(pwdfile); @@ -427,3 +403,4 @@ struct pam_module _pam_listfile_modstruct = { NULL, }; #endif +/* vim:set ts=8 sw=4: */ -- cgit v1.2.3 From 64707e82165bb32db5763b38bf550b538bcd4eec Mon Sep 17 00:00:00 2001 From: Timo Weingärtner Date: Sat, 27 Apr 2013 18:07:22 +0200 Subject: make Brokencrypt_md5 also broken on little-endian otherwise broken hashes from big-endian systems won't work also remove ASM_MD5 #ifndef's, we don't have assembler code here --- md5.c | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/md5.c b/md5.c index 0fb1a78..94f1e2a 100644 --- a/md5.c +++ b/md5.c @@ -19,29 +19,17 @@ */ #include +#include #include "md5.h" #ifndef HIGHFIRST #define byteReverse(buf, len) /* Nothing */ #else -static void byteReverse(unsigned char *buf, unsigned longs); - -#ifndef ASM_MD5 -/* - * Note: this code is harmless on little-endian machines. - */ -static void byteReverse(unsigned char *buf, unsigned longs) -{ - uint32 t; - do { - t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | - ((unsigned) buf[1] << 8 | buf[0]); - *(uint32 *) buf = t; - buf += 4; - } while (--longs); +static void byteReverse(unsigned char *buf, unsigned longs) { + for (; longs; --longs, buf +=4) + *((uint32 *) buf) = bswap_32(*((uint32 *) buf)); } #endif -#endif /* * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious @@ -151,8 +139,6 @@ void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx) memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ } -#ifndef ASM_MD5 - /* The four core functions - F1 is optimized somewhat */ /* #define F1(x, y, z) (x & y | ~x & z) */ @@ -252,5 +238,3 @@ void MD5Name(MD5Transform)(uint32 buf[4], uint32 const in[16]) buf[2] += c; buf[3] += d; } - -#endif -- cgit v1.2.3 From 86c95423b2908869ee42f9f40896a0bb0b773cf4 Mon Sep 17 00:00:00 2001 From: Timo Weingärtner Date: Sat, 27 Apr 2013 23:55:20 +0200 Subject: rework argument parsing * don't copy pwdfile argument, we don't need to modify it * replace sizeof() with strlen() as that is easier to understand and the compiler can also optimize it away * expand DEFINE's so we can get rid of the comments --- pam_pwdfile.c | 48 +++++++++++++----------------------------------- 1 file changed, 13 insertions(+), 35 deletions(-) diff --git a/pam_pwdfile.c b/pam_pwdfile.c index d8c9e69..21e37d9 100644 --- a/pam_pwdfile.c +++ b/pam_pwdfile.c @@ -65,10 +65,6 @@ extern char *crypt(const char *key, const char *salt); extern char *bigcrypt(const char *key, const char *salt); -#define PWDF_PARAM "pwdfile" -#define FLOCK_PARAM "flock" -#define NODELAY_PARAM "nodelay" -#define PWDFN_LEN 256 #define CRYPTED_DESPWD_LEN 13 #define CRYPTED_MD5PWD_LEN 34 #define CRYPTED_BCPWD_LEN 178 @@ -209,10 +205,10 @@ static int fgetpwnam(FILE *stream, const char *name, char *password) { __attribute__((visibility("default"))) PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { - int retval, pcnt, pwdfilename_found; + int retval, i; const char *name; char *password; - char pwdfilename[PWDFN_LEN]; + char const * pwdfilename = NULL; char salt[12], stored_crypted_password[CRYPTED_BCPWD_LEN+1]; char *crypted_password; FILE *pwdfile; @@ -222,38 +218,20 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int debug = 0; /* we require the pwdfile switch and argument to be present, else we don't work */ - /* pcnt is the parameter counter variable for iterating through argv */ - pcnt = pwdfilename_found = 0; - do { - /* see if the current parameter looks like "pwdfile" */ - if (strcmp(argv[pcnt],PWDF_PARAM)==0) { - /* if argv is long enough, grab the subsequent parameter */ - if (pcnt+1 < argc) { - /* make sure we can't overflow */ - strncpy(pwdfilename,argv[++pcnt],PWDFN_LEN); - /* indicate that we've found it */ - pwdfilename_found = 1; - } - /* also check for "pwdfile=blah" */ - } else if (strncmp(argv[pcnt],PWDF_PARAM "=",sizeof(PWDF_PARAM "=")-1)==0) { - /* make sure we can't overflow */ - strncpy(pwdfilename,argv[pcnt]+sizeof(PWDF_PARAM),PWDFN_LEN); - /* indicate that we've found it */ - pwdfilename_found = 1; - } else if (strcmp(argv[pcnt],FLOCK_PARAM)==0) { - /* we have a "flock" parameter */ + for (i = 0; i < argc; ++i) { + if (!strcmp(argv[i], "pwdfile") && i + 1 < argc) + pwdfilename = argv[++i]; + else if (!strncmp(argv[i], "pwdfile=", strlen("pwdfile="))) + pwdfilename = argv[i] + strlen("pwdfile="); + else if (!strcmp(argv[i], "flock")) use_flock = 1; - } else if (strcmp(argv[pcnt],"no" FLOCK_PARAM)==0) { - /* or a "noflock" parameter */ + else if (!strcmp(argv[i], "noflock")) use_flock = 0; - } else if (strcmp(argv[pcnt],NODELAY_PARAM)==0) { - /* no delay on authentication failure */ + else if (!strcmp(argv[i], "nodelay")) use_delay = 0; - } else if (strcmp(argv[pcnt], "debug") == 0) { + else if (!strcmp(argv[i], "debug")) debug = 1; - } - - } while (++pcnt < argc); + } #ifdef HAVE_PAM_FAIL_DELAY if (use_delay) { @@ -262,7 +240,7 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, } #endif - if (!pwdfilename_found) { + if (!pwdfilename) { pam_syslog(pamh, LOG_ERR, "password file name not specified"); return PAM_AUTHINFO_UNAVAIL; } -- cgit v1.2.3 From 0437f4656f1d5a541b4ab951c457fae19f8deee4 Mon Sep 17 00:00:00 2001 From: Timo Weingärtner Date: Sun, 28 Apr 2013 17:15:15 +0200 Subject: use pam_get_authtok this also gets it right with use_first_pass also use the default prompt for the username --- pam_pwdfile.c | 87 +++-------------------------------------------------------- 1 file changed, 3 insertions(+), 84 deletions(-) diff --git a/pam_pwdfile.c b/pam_pwdfile.c index 21e37d9..cd4d941 100644 --- a/pam_pwdfile.c +++ b/pam_pwdfile.c @@ -69,10 +69,6 @@ extern char *bigcrypt(const char *key, const char *salt); #define CRYPTED_MD5PWD_LEN 34 #define CRYPTED_BCPWD_LEN 178 -/* prototypes */ -int converse(pam_handle_t *, int, struct pam_message **, struct pam_response **); -int _set_auth_tok(pam_handle_t *, int, int, const char **); - static int lock_fd(int fd) { int delay; @@ -90,72 +86,6 @@ static int lock_fd(int fd) { return -1; } -/* this function ripped from pam_unix/support.c */ -int converse( pam_handle_t *pamh, - int nargs, - struct pam_message **message, - struct pam_response **response ) { - int retval; - struct pam_conv *conv; - - retval = pam_get_item( pamh, PAM_CONV, (const void **) &conv ) ; - if ( retval == PAM_SUCCESS ) { - retval = conv->conv( nargs, - ( const struct pam_message ** ) message, - response, - conv->appdata_ptr ); - } - return retval; -} - -/* this function ripped from pam_unix/support.c */ -int _set_auth_tok( pam_handle_t *pamh, - int flags, int argc, - const char **argv ) { - int retval; - char *p; - - struct pam_message msg[1],*pmsg[1]; - struct pam_response *resp; - - /* set up conversation call */ - - pmsg[0] = &msg[0]; - msg[0].msg_style = PAM_PROMPT_ECHO_OFF; - msg[0].msg = "Password: "; - resp = NULL; - - if ( ( retval = converse( pamh, 1 , pmsg, &resp ) ) != PAM_SUCCESS ) - return retval; - - if ( resp ) - { - if ( ( flags & PAM_DISALLOW_NULL_AUTHTOK ) && - resp[0].resp == NULL ) - { - free( resp ); - return PAM_AUTH_ERR; - } - - p = resp[ 0 ].resp; - - /* This could be a memory leak. If resp[0].resp - is malloc()ed, then it has to be free()ed! - -- alex - */ - - resp[ 0 ].resp = NULL; - - } - else - return PAM_CONV_ERR; - - free( resp ); - pam_set_item( pamh, PAM_AUTHTOK, p ); - return PAM_SUCCESS; -} - - /* puts the crypted password corresponding to user "name" in password, * from a file with lines consisting of: name:crypted_password * if unsucessful, returns 0 @@ -207,7 +137,7 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { int retval, i; const char *name; - char *password; + char const * password; char const * pwdfilename = NULL; char salt[12], stored_crypted_password[CRYPTED_BCPWD_LEN+1]; char *crypted_password; @@ -259,7 +189,7 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, } /* get user name */ - if ((retval = pam_get_user(pamh,&name,"login: ")) != PAM_SUCCESS) { + if ((retval = pam_get_user(pamh, &name, NULL)) != PAM_SUCCESS) { pam_syslog(pamh, LOG_ERR, "username not found"); fclose(pwdfile); return retval; @@ -267,18 +197,7 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, if (debug) pam_syslog(pamh, LOG_DEBUG, "username is %s", name); - /* get password - code from pam_unix_auth.c */ - pam_get_item(pamh, PAM_AUTHTOK, (void *)&password); - if (!password) { - retval = _set_auth_tok(pamh, flags, argc, argv); - if (retval!=PAM_SUCCESS) { - fclose(pwdfile); - return retval; - } - } - pam_get_item(pamh, PAM_AUTHTOK, (void *)&password); - - if ((retval = pam_get_item(pamh, PAM_AUTHTOK, (void *)&password)) != PAM_SUCCESS) { + if ((retval = pam_get_authtok(pamh, PAM_AUTHTOK, &password, NULL)) != PAM_SUCCESS) { pam_syslog(pamh, LOG_ERR, "auth token not found"); fclose(pwdfile); return retval; -- cgit v1.2.3 From 138c589dd4cdf68659bfa643e5659fa1200f6081 Mon Sep 17 00:00:00 2001 From: Timo Weingärtner Date: Mon, 29 Apr 2013 13:06:26 +0200 Subject: rework pwdfile reading * drop rewind(), we read the file just once * use getline() to get rid of the fixed-size buffer * let strsep() also handle the newline * stop at the first line containing the user instead of using the last --- pam_pwdfile.c | 60 +++++++++++++++++++++++++---------------------------------- 1 file changed, 25 insertions(+), 35 deletions(-) diff --git a/pam_pwdfile.c b/pam_pwdfile.c index cd4d941..80cd893 100644 --- a/pam_pwdfile.c +++ b/pam_pwdfile.c @@ -91,43 +91,33 @@ static int lock_fd(int fd) { * if unsucessful, returns 0 */ static int fgetpwnam(FILE *stream, const char *name, char *password) { - char tempLine[256], *tpointer, *curname, *curpass, *fgr; - int loopdone, pwdfound; - int len; + char * linebuf = NULL; + size_t linebuflen; + int pwdfound = 0; - /* go to beginning of file */ - rewind(stream); - /* some control variables */ - loopdone = pwdfound = 0; - /* fgets should do this, but we make sure */ - tempLine[255] = '\0'; /* iterate through lines in file, until end of file */ - do { - /* get the current line */ - fgr = fgets(tempLine,255,stream); - /* if it's valid, go on */ - if ( fgr != NULL) { - /* first get the username out */ - tpointer = tempLine; - curname = strsep(&tpointer,":"); - /* check to see if it's the right one */ - if (strcmp(curname,name)==0) { - /* at least we know our loop is done */ - loopdone = 1; - /* remove possible trailing newline */ - len = strlen(tpointer); - if (tpointer[len - 1] == '\n') - tpointer[len - 1] = '\0'; - /* get the password and put it in its place */ - curpass = strsep(&tpointer,":"); - if (curpass != NULL) { - /* we use bigcrypt pwd len, as this is just a safe maximum */ - strncpy(password,curpass,CRYPTED_BCPWD_LEN+1); - pwdfound = 1; - } /* if (curpass... */ - } /* if (strcmp(curname... */ - } /* if (tempLine... */ - } while (fgr != NULL); + while (getline(&linebuf, &linebuflen, stream) > 0) { + /* strsep changes its argument, make a copy */ + char * nexttok = linebuf; + + /* first field: username */ + char * curtok = strsep(&nexttok, ":"); + + /* skip non-matchin usernames */ + if (strcmp(curtok, name)) + continue; + + /* second field: password (until next colon or newline) */ + curtok = strsep(&nexttok, ":\n"); + + if (curtok) { + /* we use bigcrypt pwd len, as this is just a safe maximum */ + strncpy(password, curtok, CRYPTED_BCPWD_LEN + 1); + pwdfound = 1; + break; + } + } + free(linebuf); /* allocated by getline */ return pwdfound; } -- cgit v1.2.3 From 88dd2b1a22cd06fc401a8ddadd41114cebe159d5 Mon Sep 17 00:00:00 2001 From: Timo Weingärtner Date: Fri, 10 May 2013 21:27:56 +0200 Subject: include proper headers for crypt() this also prepares for crypt_r() --- bigcrypt.c | 5 +++-- bigcrypt.h | 1 + pam_pwdfile.c | 15 +++++++++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 bigcrypt.h diff --git a/bigcrypt.c b/bigcrypt.c index 28d042a..c1486fa 100644 --- a/bigcrypt.c +++ b/bigcrypt.c @@ -24,10 +24,11 @@ * Andy Phillips */ +#define _XOPEN_SOURCE +#include #include -char *crypt(const char *key, const char *salt); -char *bigcrypt(const char *key, const char *salt); +#include "bigcrypt.h" /* * Max cleartext password length in segments of 8 characters this diff --git a/bigcrypt.h b/bigcrypt.h new file mode 100644 index 0000000..a66a96e --- /dev/null +++ b/bigcrypt.h @@ -0,0 +1 @@ +extern char *bigcrypt(const char *key, const char *salt); diff --git a/pam_pwdfile.c b/pam_pwdfile.c index 80cd893..34ce78d 100644 --- a/pam_pwdfile.c +++ b/pam_pwdfile.c @@ -42,6 +42,18 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifdef USE_CRYPT_R +#define _GNU_SOURCE +#include +#else +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 +#endif +#ifndef _BSD_SOURCE +#define _BSD_SOURCE +#endif +#endif + #include #include #include @@ -62,8 +74,7 @@ #include #include "md5.h" -extern char *crypt(const char *key, const char *salt); -extern char *bigcrypt(const char *key, const char *salt); +#include "bigcrypt.h" #define CRYPTED_DESPWD_LEN 13 #define CRYPTED_MD5PWD_LEN 34 -- cgit v1.2.3 From ce9367b3202477b3cc914cabfe0cb2a856f3a51d Mon Sep 17 00:00:00 2001 From: Timo Weingärtner Date: Fri, 10 May 2013 21:30:05 +0200 Subject: major overhaul * merge fgetpwnam into pam_sm_authenticate * handle empty password field * fix a fd and memory leak if pwdfile opening succeeds but locking fails * use crypt_r (enabled via USE_CRYPT_R) * rely on crypt() to handle newer crypt variants (including "good" md5 crypt) * make bigcrypt and broken md5 crypt optional * add some const's --- Makefile | 10 +--- pam_pwdfile.c | 185 +++++++++++++++++++++------------------------------------- 2 files changed, 70 insertions(+), 125 deletions(-) diff --git a/Makefile b/Makefile index 06e1637..5b60784 100644 --- a/Makefile +++ b/Makefile @@ -2,14 +2,14 @@ PAM_LIB_DIR ?= $(DESTDIR)/lib/security INSTALL ?= install CFLAGS ?= -O2 -g -Wall -Wformat-security +CPPFLAGS += -DUSE_CRYPT_R CFLAGS += -fPIC -fvisibility=hidden LDFLAGS += -Wl,-x -shared TITLE = pam_pwdfile LIBSHARED = $(TITLE).so LDLIBS = -lcrypt -lpam -LIBOBJ = $(TITLE).o md5_good.o md5_broken.o md5_crypt_good.o md5_crypt_broken.o bigcrypt.o -CPPFLAGS_MD5_GOOD = -D'MD5Name(x)=Good\#\#x' +LIBOBJ = $(TITLE).o md5_broken.o md5_crypt_broken.o bigcrypt.o CPPFLAGS_MD5_BROKEN = -DHIGHFIRST -D'MD5Name(x)=Broken\#\#x' @@ -19,15 +19,9 @@ $(LIBSHARED): $(LIBOBJ) $(CC) $(LDFLAGS) $(LIBOBJ) $(LDLIBS) -o $@ -md5_good.o: md5.c - $(CC) -c $(CPPFLAGS) $(CPPFLAGS_MD5_GOOD) $(CFLAGS) $< -o $@ - md5_broken.o: md5.c $(CC) -c $(CPPFLAGS) $(CPPFLAGS_MD5_BROKEN) $(CFLAGS) $< -o $@ -md5_crypt_good.o: md5_crypt.c - $(CC) -c $(CPPFLAGS) $(CPPFLAGS_MD5_GOOD) $(CFLAGS) $< -o $@ - md5_crypt_broken.o: md5_crypt.c $(CC) -c $(CPPFLAGS) $(CPPFLAGS_MD5_BROKEN) $(CFLAGS) $< -o $@ diff --git a/pam_pwdfile.c b/pam_pwdfile.c index 34ce78d..4e8805d 100644 --- a/pam_pwdfile.c +++ b/pam_pwdfile.c @@ -76,10 +76,6 @@ #include "md5.h" #include "bigcrypt.h" -#define CRYPTED_DESPWD_LEN 13 -#define CRYPTED_MD5PWD_LEN 34 -#define CRYPTED_BCPWD_LEN 178 - static int lock_fd(int fd) { int delay; @@ -97,56 +93,26 @@ static int lock_fd(int fd) { return -1; } -/* puts the crypted password corresponding to user "name" in password, - * from a file with lines consisting of: name:crypted_password - * if unsucessful, returns 0 - */ -static int fgetpwnam(FILE *stream, const char *name, char *password) { - char * linebuf = NULL; - size_t linebuflen; - int pwdfound = 0; - - /* iterate through lines in file, until end of file */ - while (getline(&linebuf, &linebuflen, stream) > 0) { - /* strsep changes its argument, make a copy */ - char * nexttok = linebuf; - - /* first field: username */ - char * curtok = strsep(&nexttok, ":"); - - /* skip non-matchin usernames */ - if (strcmp(curtok, name)) - continue; - - /* second field: password (until next colon or newline) */ - curtok = strsep(&nexttok, ":\n"); - - if (curtok) { - /* we use bigcrypt pwd len, as this is just a safe maximum */ - strncpy(password, curtok, CRYPTED_BCPWD_LEN + 1); - pwdfound = 1; - break; - } - } - free(linebuf); /* allocated by getline */ - return pwdfound; -} - /* expected hook for auth service */ __attribute__((visibility("default"))) PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { - int retval, i; + int i; const char *name; char const * password; char const * pwdfilename = NULL; - char salt[12], stored_crypted_password[CRYPTED_BCPWD_LEN+1]; - char *crypted_password; + char const * stored_crypted_password = NULL; + char const * crypted_password; FILE *pwdfile; int use_flock = 0; int use_delay = 1; - int temp_result = 0; + int legacy_crypt = 0; int debug = 0; + char * linebuf = NULL; + size_t linebuflen; +#ifdef USE_CRYPT_R + struct crypt_data crypt_buf; +#endif /* we require the pwdfile switch and argument to be present, else we don't work */ for (i = 0; i < argc; ++i) { @@ -162,6 +128,8 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, use_delay = 0; else if (!strcmp(argv[i], "debug")) debug = 1; + else if (!strcmp(argv[i], "legacy_crypt")) + legacy_crypt = 1; } #ifdef HAVE_PAM_FAIL_DELAY @@ -176,109 +144,92 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, return PAM_AUTHINFO_UNAVAIL; } - if (debug) pam_syslog(pamh, LOG_DEBUG, "password filename extracted"); + if (pam_get_user(pamh, &name, NULL) != PAM_SUCCESS) { + pam_syslog(pamh, LOG_ERR, "couldn't get username from PAM stack"); + return PAM_AUTH_ERR; + } + if (debug) pam_syslog(pamh, LOG_DEBUG, "username is %s", name); - /* now try to open the password file */ - if ((pwdfile=fopen(pwdfilename,"r"))==NULL) { + if (!(pwdfile = fopen(pwdfilename, "r"))) { pam_syslog(pamh, LOG_ALERT, "couldn't open password file %s", pwdfilename); return PAM_AUTHINFO_UNAVAIL; } if (use_flock && lock_fd(fileno(pwdfile)) == -1) { pam_syslog(pamh, LOG_ALERT, "couldn't lock password file %s", pwdfilename); + fclose(pwdfile); return PAM_AUTHINFO_UNAVAIL; } - /* get user name */ - if ((retval = pam_get_user(pamh, &name, NULL)) != PAM_SUCCESS) { - pam_syslog(pamh, LOG_ERR, "username not found"); - fclose(pwdfile); - return retval; + /* get the crypted password corresponding to this user out of pwdfile */ + while (getline(&linebuf, &linebuflen, pwdfile) > 0) { + /* strsep changes its argument, make a copy */ + char * nexttok = linebuf; + + /* first field: username */ + char * curtok = strsep(&nexttok, ":"); + + /* skip non-matching usernames */ + if (strcmp(curtok, name)) + continue; + + /* second field: password (until next colon or newline) */ + if ((curtok = strsep(&nexttok, ":\n"))) { + stored_crypted_password = curtok; + break; + } } + fclose(pwdfile); + /* we keep linebuf (allocated by getline), stored_crypted_password is pointing into it */ + + if (!stored_crypted_password) + if (debug) pam_syslog(pamh, LOG_ERR, "user not found in password database"); - if (debug) pam_syslog(pamh, LOG_DEBUG, "username is %s", name); - - if ((retval = pam_get_authtok(pamh, PAM_AUTHTOK, &password, NULL)) != PAM_SUCCESS) { - pam_syslog(pamh, LOG_ERR, "auth token not found"); - fclose(pwdfile); - return retval; + if (stored_crypted_password && !strlen(stored_crypted_password)) { + if (debug) pam_syslog(pamh, LOG_DEBUG, "user has empty password field"); + free(linebuf); + return flags & PAM_DISALLOW_NULL_AUTHTOK ? PAM_AUTH_ERR : PAM_SUCCESS; } - /* now crypt password and compare to the user entry in the password file */ - /* first make sure password is long enough -- may I do this? */ - if (strlen(password)<2 || password==NULL) { - pam_syslog(pamh, LOG_ERR, "password too short or NULL"); - fclose(pwdfile); + if (pam_get_authtok(pamh, PAM_AUTHTOK, &password, NULL) != PAM_SUCCESS) { + pam_syslog(pamh, LOG_ERR, "couldn't get password from PAM stack"); + free(linebuf); return PAM_AUTH_ERR; } - /* get the crypted password corresponding to this user */ - if (!fgetpwnam(pwdfile, name, stored_crypted_password)) { - pam_syslog(pamh, LOG_ERR, "user not found in password database"); - fclose(pwdfile); - return PAM_AUTHINFO_UNAVAIL; + if (!stored_crypted_password) { + free(linebuf); + return PAM_USER_UNKNOWN; } if (debug) pam_syslog(pamh, LOG_DEBUG, "got crypted password == '%s'", stored_crypted_password); +#ifdef USE_CRYPT_R + crypt_buf.initialized = 0; + if (!(crypted_password = crypt_r(password, stored_crypted_password, &crypt_buf))) { +#else + if (!(crypted_password = crypt(password, stored_crypted_password))) { +#endif + pam_syslog(pamh, LOG_ERR, "crypt() failed"); + free(linebuf); + return PAM_AUTH_ERR; + } - temp_result = 0; - - /* Extract the salt and set the passwd length, depending on MD5 or DES */ - if (strncmp(stored_crypted_password, "$1$", 3) == 0) { - if (debug) pam_syslog(pamh, LOG_ERR, "password hash type is 'md5'"); - /* get out the salt into "salt" */ - strncpy(salt, stored_crypted_password, 11); - salt[11] = '\0'; - stored_crypted_password[CRYPTED_MD5PWD_LEN] = '\0'; - /* try both md5 crypts */ - crypted_password = Goodcrypt_md5(password, salt); - if (strcmp(crypted_password, stored_crypted_password) == 0) - { - temp_result = 1; - } + if (legacy_crypt && strcmp(crypted_password, stored_crypted_password)) { + if (!strncmp(stored_crypted_password, "$1$", 3)) + crypted_password = Brokencrypt_md5(password, stored_crypted_password); else - { - crypted_password = Brokencrypt_md5(password, salt); - if (strcmp(crypted_password, stored_crypted_password) == 0) - { - temp_result = 1; - } - } - } else { - /* get the salt out into "salt" */ - strncpy(salt, stored_crypted_password, 2); - salt[2] = '\0'; - stored_crypted_password[CRYPTED_BCPWD_LEN] = '\0'; - - if (strlen(stored_crypted_password) <= CRYPTED_DESPWD_LEN) { - if (debug) pam_syslog(pamh, LOG_DEBUG, "password hash type is 'crypt'"); - crypted_password = crypt(password, salt); - } else { - if (debug) pam_syslog(pamh, LOG_DEBUG, "password hash type is 'bigcrypt'"); - crypted_password = bigcrypt(password, salt); - } - - if (strcmp(crypted_password, stored_crypted_password) == 0) - { - temp_result = 1; - } + crypted_password = bigcrypt(password, stored_crypted_password); } - - if (debug) pam_syslog(pamh, LOG_DEBUG, "user password crypted is '%s'", crypted_password); - - /* if things don't match up, complain */ - if (!temp_result) - { + + if (strcmp(crypted_password, stored_crypted_password)) { pam_syslog(pamh, LOG_NOTICE, "wrong password for user %s", name); - fclose(pwdfile); + free(linebuf); return PAM_AUTH_ERR; } if (debug) pam_syslog(pamh, LOG_DEBUG, "passwords match"); - - /* we've gotten here, i.e. authentication was sucessful! */ - fclose(pwdfile); + free(linebuf); return PAM_SUCCESS; } -- cgit v1.2.3 From be53f76279d158aa3e5fb2960f9ae4da52201857 Mon Sep 17 00:00:00 2001 From: Timo Weingärtner Date: Sat, 11 May 2013 01:43:50 +0200 Subject: replace self-defined uint32 with uint32_t from stdint.h unsigned int is not guaranteed to have 32 bits --- md5.c | 22 +++++++++++----------- md5.h | 10 +++++----- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/md5.c b/md5.c index 94f1e2a..2bc558e 100644 --- a/md5.c +++ b/md5.c @@ -27,7 +27,7 @@ #else static void byteReverse(unsigned char *buf, unsigned longs) { for (; longs; --longs, buf +=4) - *((uint32 *) buf) = bswap_32(*((uint32 *) buf)); + *((uint32_t *) buf) = bswap_32(*((uint32_t *) buf)); } #endif @@ -52,12 +52,12 @@ void MD5Name(MD5Init)(struct MD5Context *ctx) */ void MD5Name(MD5Update)(struct MD5Context *ctx, unsigned const char *buf, unsigned len) { - uint32 t; + uint32_t t; /* Update bitcount */ t = ctx->bits[0]; - if ((ctx->bits[0] = t + ((uint32) len << 3)) < t) + if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) ctx->bits[1]++; /* Carry from low to high */ ctx->bits[1] += len >> 29; @@ -75,7 +75,7 @@ void MD5Name(MD5Update)(struct MD5Context *ctx, unsigned const char *buf, unsign } memcpy(p, buf, t); byteReverse(ctx->in, 16); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); + MD5Name(MD5Transform)(ctx->buf, (uint32_t *) ctx->in); buf += t; len -= t; } @@ -84,7 +84,7 @@ void MD5Name(MD5Update)(struct MD5Context *ctx, unsigned const char *buf, unsign while (len >= 64) { memcpy(ctx->in, buf, 64); byteReverse(ctx->in, 16); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); + MD5Name(MD5Transform)(ctx->buf, (uint32_t *) ctx->in); buf += 64; len -= 64; } @@ -119,7 +119,7 @@ void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx) /* Two lots of padding: Pad the first block to 64 bytes */ memset(p, 0, count); byteReverse(ctx->in, 16); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); + MD5Name(MD5Transform)(ctx->buf, (uint32_t *) ctx->in); /* Now fill the next block with 56 bytes */ memset(ctx->in, 0, 56); @@ -130,10 +130,10 @@ void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx) byteReverse(ctx->in, 14); /* Append length in bits and transform */ - ((uint32 *) ctx->in)[14] = ctx->bits[0]; - ((uint32 *) ctx->in)[15] = ctx->bits[1]; + ((uint32_t *) ctx->in)[14] = ctx->bits[0]; + ((uint32_t *) ctx->in)[15] = ctx->bits[1]; - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); + MD5Name(MD5Transform)(ctx->buf, (uint32_t *) ctx->in); byteReverse((unsigned char *) ctx->buf, 4); memcpy(digest, ctx->buf, 16); memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ @@ -156,9 +156,9 @@ void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx) * reflect the addition of 16 longwords of new data. MD5Update blocks * the data and converts bytes into longwords for this routine. */ -void MD5Name(MD5Transform)(uint32 buf[4], uint32 const in[16]) +void MD5Name(MD5Transform)(uint32_t buf[4], uint32_t const in[16]) { - register uint32 a, b, c, d; + register uint32_t a, b, c, d; a = buf[0]; b = buf[1]; diff --git a/md5.h b/md5.h index 103f168..b48edea 100644 --- a/md5.h +++ b/md5.h @@ -2,22 +2,22 @@ #ifndef MD5_H #define MD5_H -typedef unsigned int uint32; +#include struct MD5Context { - uint32 buf[4]; - uint32 bits[2]; + uint32_t buf[4]; + uint32_t bits[2]; unsigned char in[64]; }; void GoodMD5Init(struct MD5Context *); void GoodMD5Update(struct MD5Context *, unsigned const char *, unsigned); void GoodMD5Final(unsigned char digest[16], struct MD5Context *); -void GoodMD5Transform(uint32 buf[4], uint32 const in[16]); +void GoodMD5Transform(uint32_t buf[4], uint32_t const in[16]); void BrokenMD5Init(struct MD5Context *); void BrokenMD5Update(struct MD5Context *, unsigned const char *, unsigned); void BrokenMD5Final(unsigned char digest[16], struct MD5Context *); -void BrokenMD5Transform(uint32 buf[4], uint32 const in[16]); +void BrokenMD5Transform(uint32_t buf[4], uint32_t const in[16]); char *Goodcrypt_md5(const char *pw, const char *salt); char *Brokencrypt_md5(const char *pw, const char *salt); -- cgit v1.2.3 From 495461432ca4034d49ee37cb398c6bd253d6f66d Mon Sep 17 00:00:00 2001 From: Timo Weingärtner Date: Sat, 11 May 2013 19:34:44 +0200 Subject: md5.c: fix compiler warnings --- md5.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/md5.c b/md5.c index 2bc558e..3565e55 100644 --- a/md5.c +++ b/md5.c @@ -130,13 +130,12 @@ void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx) byteReverse(ctx->in, 14); /* Append length in bits and transform */ - ((uint32_t *) ctx->in)[14] = ctx->bits[0]; - ((uint32_t *) ctx->in)[15] = ctx->bits[1]; + memcpy(ctx->in + 56, ctx->bits, 8); MD5Name(MD5Transform)(ctx->buf, (uint32_t *) ctx->in); byteReverse((unsigned char *) ctx->buf, 4); memcpy(digest, ctx->buf, 16); - memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ + memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ } /* The four core functions - F1 is optimized somewhat */ -- cgit v1.2.3 From caea065f12f3d358948cd0ca760ebd7c27cb6c80 Mon Sep 17 00:00:00 2001 From: Timo Weingärtner Date: Tue, 14 May 2013 20:08:06 +0200 Subject: overhaul bigcrypt.c * drop unnessesary variables * rename variables and define's to be more desciptive * rotate pointer updates to front of loop * don't copy key there was no point in using crypt_r() here, we return our result in a static buffer ourselves --- bigcrypt.c | 93 ++++++++++++++++++-------------------------------------------- 1 file changed, 26 insertions(+), 67 deletions(-) diff --git a/bigcrypt.c b/bigcrypt.c index c1486fa..18024dc 100644 --- a/bigcrypt.c +++ b/bigcrypt.c @@ -24,7 +24,7 @@ * Andy Phillips */ -#define _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 #include #include @@ -36,80 +36,39 @@ * password). */ -#define MAX_PASS_LEN 16 +#define MAX_SEGMENTS 16 #define SEGMENT_SIZE 8 #define SALT_SIZE 2 -#define KEYBUF_SIZE ((MAX_PASS_LEN*SEGMENT_SIZE)+SALT_SIZE) #define ESEGMENT_SIZE 11 -#define CBUF_SIZE ((MAX_PASS_LEN*ESEGMENT_SIZE)+SALT_SIZE+1) -char *bigcrypt(const char *key, const char *salt) -{ - static char dec_c2_cryptbuf[CBUF_SIZE]; /* static storage area */ +char *bigcrypt(char const * key, char const * salt) { + static char outbuf[MAX_SEGMENTS * ESEGMENT_SIZE + SALT_SIZE + 1]; /* static storage area */ - unsigned long int keylen, n_seg, j; - char *cipher_ptr, *plaintext_ptr, *tmp_ptr, *salt_ptr; - char keybuf[KEYBUF_SIZE + 1]; + unsigned char n_seg, seg; + char * outptr; - /* reset arrays */ - memset(keybuf, 0, KEYBUF_SIZE + 1); - memset(dec_c2_cryptbuf, 0, CBUF_SIZE); + /* ensure NUL-termination */ + memset(outbuf, 0, sizeof(outbuf)); - /* fill KEYBUF_SIZE with key */ - strncpy(keybuf, key, KEYBUF_SIZE); - - /* deal with case that we are doing a password check for a - conventially encrypted password: the salt will be - SALT_SIZE+ESEGMENT_SIZE long. */ - if (strlen(salt) == (SALT_SIZE + ESEGMENT_SIZE)) - keybuf[SEGMENT_SIZE] = '\0'; /* terminate password early(?) */ - - keylen = strlen(keybuf); - - if (!keylen) { + if (strlen(salt) == (SALT_SIZE + ESEGMENT_SIZE)) /* conventional crypt */ n_seg = 1; - } else { - /* work out how many segments */ - n_seg = 1 + ((keylen - 1) / SEGMENT_SIZE); - } - - if (n_seg > MAX_PASS_LEN) - n_seg = MAX_PASS_LEN; /* truncate at max length */ - - /* set up some pointers */ - cipher_ptr = dec_c2_cryptbuf; - plaintext_ptr = keybuf; - - /* do the first block with supplied salt */ - tmp_ptr = crypt(plaintext_ptr, salt); /* libc crypt() */ - - /* and place in the static area */ - strncpy(cipher_ptr, tmp_ptr, 13); - cipher_ptr += ESEGMENT_SIZE + SALT_SIZE; - plaintext_ptr += SEGMENT_SIZE; /* first block of SEGMENT_SIZE */ - - /* change the salt (1st 2 chars of previous block) - this was found - by dowsing */ - - salt_ptr = cipher_ptr - ESEGMENT_SIZE; - - /* so far this is identical to "return crypt(key, salt);", if - there is more than one block encrypt them... */ - - if (n_seg > 1) { - for (j = 2; j <= n_seg; j++) { - - tmp_ptr = crypt(plaintext_ptr, salt_ptr); - - /* skip the salt for seg!=0 */ - strncpy(cipher_ptr, (tmp_ptr + SALT_SIZE), ESEGMENT_SIZE); - - cipher_ptr += ESEGMENT_SIZE; - plaintext_ptr += SEGMENT_SIZE; - salt_ptr = cipher_ptr - ESEGMENT_SIZE; - } + else if (key[0] == '\0') + n_seg = 1; + else + n_seg = (strnlen(key, MAX_SEGMENTS * SEGMENT_SIZE) + SEGMENT_SIZE - 1) / SEGMENT_SIZE; + + /* first block is special and just traditional crypt() */ + outptr = outbuf; + strncpy(outptr, crypt(key, salt), SALT_SIZE + ESEGMENT_SIZE); + + for (seg = 1, outptr += SALT_SIZE; seg < n_seg; ++seg) { + /* subsequent blocks use the previous output block for salt input */ + salt = outptr; + key += SEGMENT_SIZE; + outptr += ESEGMENT_SIZE; + /* and omit the salt on output */ + strncpy(outptr, crypt(key, salt) + SALT_SIZE, ESEGMENT_SIZE); } - /* this is the terminated encrypted password */ - return dec_c2_cryptbuf; + return outbuf; } -- cgit v1.2.3 From e493c1467bbaebfbaf2a9a6b1da3398b76232ce5 Mon Sep 17 00:00:00 2001 From: Timo Weingärtner Date: Tue, 14 May 2013 20:22:36 +0200 Subject: remove CVS $Id line and static version number --- INSTALL | 1 - README | 3 --- changelog | 1 - contrib/README.txt | 2 -- md5.c | 2 -- md5_crypt.c | 2 -- pam_pwdfile.c | 4 ---- 7 files changed, 15 deletions(-) diff --git a/INSTALL b/INSTALL index 97ed833..5fe4680 100644 --- a/INSTALL +++ b/INSTALL @@ -1,5 +1,4 @@ INSTALL for pam_pwdfile PAM module - Charl P. Botha -$Id: INSTALL,v 1.4 2001-04-17 21:18:15 cpbotha Exp $ --------------------------------------------------------------------------- This file is the quick and dirty on how to get pam_pwdfile compiled on your diff --git a/README b/README index d5c82f9..4f07913 100644 --- a/README +++ b/README @@ -1,9 +1,6 @@ README for pam_pwdfile PAM module - Charl P. Botha -$Id: README,v 1.12 2003-12-20 19:21:19 cpbotha Exp $ --------------------------------------------------------------------------- -This is version 0.99 of pam_pwdfile. - This pam module can be used for the authentication service only, in cases where one wants to use a different set of passwords than those in the main system password database. E.g. in our case we have an imap server running, diff --git a/changelog b/changelog index e545376..9936e81 100644 --- a/changelog +++ b/changelog @@ -1,5 +1,4 @@ changelog for pam_pwdfile PAM module - Charl P. Botha -$Id: changelog,v 1.20 2003-12-20 19:30:57 cpbotha Exp $ --------------------------------------------------------------------------- 0.99 : Sat Dec 20 20:30:37 CET 2003 diff --git a/contrib/README.txt b/contrib/README.txt index a8c8462..1c0f886 100644 --- a/contrib/README.txt +++ b/contrib/README.txt @@ -1,5 +1,3 @@ -$Id: README.txt,v 1.3 2003-07-07 15:09:41 cpbotha Exp $ - * Makefile.standalone-0.95 and pam-pwdfile.spec were contributed by Jason F. McBrayer . You can use these for building RPMs of pam_pwdfile; you should also be able to use the Makefile to build diff --git a/md5.c b/md5.c index 3565e55..542ff80 100644 --- a/md5.c +++ b/md5.c @@ -1,6 +1,4 @@ /* - * $Id: md5.c,v 1.1 2002-05-11 14:42:35 cpbotha Exp $ - * * This code implements the MD5 message-digest algorithm. * The algorithm is due to Ron Rivest. This code was * written by Colin Plumb in 1993, no copyright is claimed. diff --git a/md5_crypt.c b/md5_crypt.c index 7871b45..639b1d3 100644 --- a/md5_crypt.c +++ b/md5_crypt.c @@ -1,6 +1,4 @@ /* - * $Id: md5_crypt.c,v 1.1 2002-05-11 14:42:35 cpbotha Exp $ - * * ---------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): * wrote this file. As long as you retain this notice you diff --git a/pam_pwdfile.c b/pam_pwdfile.c index 4e8805d..9b96fe3 100644 --- a/pam_pwdfile.c +++ b/pam_pwdfile.c @@ -1,13 +1,9 @@ /* pam_pwdfile.c copyright 1999-2003 by Charl P. Botha * - * $Id: pam_pwdfile.c,v 1.18 2003-12-20 19:21:19 cpbotha Exp $ - * * pam authentication module that can be pointed at any username/crypted * text file so that pam using application can use an alternate set of * passwords than specified in system password database * - * version 0.99 - * * Copyright (c) Charl P. Botha, 1999-2003. All rights reserved * * Redistribution and use in source and binary forms, with or without -- cgit v1.2.3 From da52bf9630a077d90e1338d818a3e179367058c4 Mon Sep 17 00:00:00 2001 From: Timo Weingärtner Date: Mon, 27 May 2013 21:08:02 +0200 Subject: separate DESTDIR and PAM_LIB_DIR --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 5b60784..6905e9a 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -PAM_LIB_DIR ?= $(DESTDIR)/lib/security +PAM_LIB_DIR ?= /lib/security INSTALL ?= install CFLAGS ?= -O2 -g -Wall -Wformat-security @@ -27,8 +27,8 @@ md5_crypt_broken.o: md5_crypt.c install: $(LIBSHARED) - $(INSTALL) -m 0755 -d $(PAM_LIB_DIR) - $(INSTALL) -m 0755 $(LIBSHARED) $(PAM_LIB_DIR) + $(INSTALL) -m 0755 -d $(DESTDIR)$(PAM_LIB_DIR) + $(INSTALL) -m 0755 $(LIBSHARED) $(DESTDIR)$(PAM_LIB_DIR) clean: $(RM) *.o *.so -- cgit v1.2.3 From 201e799f7a2fcba3af2c9214f25545460ef9b08a Mon Sep 17 00:00:00 2001 From: Timo Weingärtner Date: Mon, 27 May 2013 21:10:18 +0200 Subject: rework documentation remove stuff in contrib, it is outdated or explained in the service's documentation --- INSTALL | 45 ++--------- README | 91 +++++++++------------- contrib/README.txt | 13 ---- contrib/pam-pwdfile.spec | 44 ----------- ...arwick_duncan-cyrus_without_system_accounts.txt | 49 ------------ 5 files changed, 45 insertions(+), 197 deletions(-) delete mode 100644 contrib/README.txt delete mode 100644 contrib/pam-pwdfile.spec delete mode 100644 contrib/warwick_duncan-cyrus_without_system_accounts.txt diff --git a/INSTALL b/INSTALL index 5fe4680..80846dd 100644 --- a/INSTALL +++ b/INSTALL @@ -1,38 +1,7 @@ -INSTALL for pam_pwdfile PAM module - Charl P. Botha ---------------------------------------------------------------------------- - -This file is the quick and dirty on how to get pam_pwdfile compiled on your -system. As per usual, I can not be held responsible for the results of the -application of this information. - -1. Get the Linux PAM source code tarball. Currently, this is at: -http://www.us.kernel.org/pub/linux/libs/pam/pre/library/Linux-PAM-0.75.tar.bz2 - -2. Extract the tarball somewhere convenient: -bunzip2 -c Linux-PAM-0.75.tar.bz2 | tar -xvf - - -3. Prepare pam_pwdfile -cd Linux-PAM-0.75/modules -tar -xzvf /where/you/put/it/pam_pwdfile-x.y.tar.gz -cd .. -(x.y represents the pam_pwdfile version, e.g. 0.7) - -4. Prepare Linux-PAM -rm default.defs -ln -s defs/whatever.defs default.defs (on my system whatever == debian) - -5. in Linux-PAM-0.75/ do: - make all - NOTE: if you only need pam_pwdfile and some of the other modules are - causing you problems during compilation, go and delete them (i.e. - delete the whole module dir, e.g. rm -rf modules/pam_pwdb) and then - restart make all in the top level directory. - -6. When you're done, there should be a pam_pwdfile.so in modules/pam_pwdfile; - copy this into your pam modules directory. (this is /lib/security/ on my - debian 2.2. system) - -7. You should now be operational. See the README for more info. - -Remember that pam_pwdfile is packaged as a .deb and is part of the official -Debian distribution. +* install needed packages (if not installed already): + * make + * C compiler (e.g. gcc or clang) + * libc development headers (package libc6-dev on Debian, glibc-headers on Hat) + * PAM development headers (package libpam-dev on Debian, pam-devel on Hat) +* make +* make install diff --git a/README b/README index 4f07913..568cf5a 100644 --- a/README +++ b/README @@ -1,53 +1,38 @@ -README for pam_pwdfile PAM module - Charl P. Botha ---------------------------------------------------------------------------- - -This pam module can be used for the authentication service only, in cases -where one wants to use a different set of passwords than those in the main -system password database. E.g. in our case we have an imap server running, -and prefer to keep the imap passwords different from the system passwords -for security reasons. - -The /etc/pam.d/imap looks like this (e.g.) -#%PAM-1.0 -auth required /lib/security/pam_pwdfile.so pwdfile /etc/imap.passwd -account required /lib/security/pam_pwdb.so - -At the moment the only parameters that pam_pwdfile.so parses for is -"pwdfile", followed by the name of the ASCII password database, as in the -above example. Also, thanks to Jacob Schroeder , -pam_pwdfile now supports password file locking. Adding a "flock" parameter -activates this feature: pam_pwdfile uses and honours flock() file locking on -the specified password file. Specifying "noflock" or no flock-type -parameter at all deactivates this feature. - -Example: -auth required /lib/security/pam_pwdfile.so pwdfile /etc/blah.passwd flock - -Like other PAM modules, pam_pwdfile causes a 2 second delay when an -incorrect password is supplied. This is too discourage brute force testing; -however, this behaviour can be disabled with a "nodelay" parameter. Thanks -to Ethan Benson for this patch. - -The ASCII password file is simply a list of lines, each looking like this: -username:crypted_passwd[13] in the case of vanilla crypted passwords and -username:crypted_passwd[34] in the case of MD5 crypted passwords. The -latter is thanks to Warwick Duncan . pam_pwdfile -also handles bigcrypt passwords. - -NOTES: ------ - -* Also have a look at the files in the contrib subdirectory. - Especially if you're having trouble building paw_pwdfile, the - Makefile.standalone could be your new friend. - -* Warwick has also written a utility for managing the password files that -pam_pwdfile uses. The website has disappeared, but I've mirrored the -source code here: http://cpbotha.net/files/mirror/chpwdfile-0.24.tar.gz - -* Note that we still expect users to have accounts in the usual place, as we -make use of the pam_pwdb.so module for the account service. This module is -just so that one can have multiple sets of passwords for different services, -e.g. with our /etc/imap.passwd. It is however possible with certain -applications patched for pam (Cyrus IMAP server e.g.) that one does not need -the users to exist in the system database. +This pam module provides the authentication service using an own set of user/password pairs. + +CONFIGURATION +============= + +simple PAM config +----------------- + +Just add/change the config file for service to contain the line: + +auth required pam_pwdfile.so pwdfile=/path/to/passwd_file + +If your service does more with PAM than auth there will be a fallback to the service "other". +If that is not what you want, you can use pam_permit.so or pam_deny.so for that: + +account required pam_permit.so +session required pam_permit.so +password required pam_deny.so + + +options +------- + +* pwdfile= +* debug: produce a bit of debug output +* nodelay: don't tell the PAM stack to cause a delay on auth failure +* flock: use a shared (read) advisory lock on pwdfile, you should better move new versions into place instead +* legacy_crypt: turns on bigcrypt and "broken md5_crypt", you will only need that if you use password hashes from another system that uses those algorithms + + +PASSWORD FILE +============= + +The password file basically looks like passwd(5): one line for each user with two or more colon-separated fields. +First field contains the username, the second the crypt()ed password. +Other field are optional. + +crypt()ed passwords in various formats can be generated with mkpasswd from the whois package. diff --git a/contrib/README.txt b/contrib/README.txt deleted file mode 100644 index 1c0f886..0000000 --- a/contrib/README.txt +++ /dev/null @@ -1,13 +0,0 @@ -* Makefile.standalone-0.95 and pam-pwdfile.spec were contributed by Jason F. - McBrayer . You can use these for building RPMs of - pam_pwdfile; you should also be able to use the Makefile to build - pam_pwdfile on other platforms _without_ the Linux-PAM hierarchy. - -* warwick_duncan-cyrus_without_system_accounts.txt is a short explanation by - Warwick Duncan on how to get Cyrus IMAPD + pam_pwdfile to work WITHOUT - having to create system accounts for IMAPD users. - -* Makefile.standalone was contributed by Gerald Richter and should be more - up to date than Makefile.standalone-0.95. The primary difference is that - Gerald's Makefile also takes into account the new md5 code. - diff --git a/contrib/pam-pwdfile.spec b/contrib/pam-pwdfile.spec deleted file mode 100644 index cbcd88a..0000000 --- a/contrib/pam-pwdfile.spec +++ /dev/null @@ -1,44 +0,0 @@ -%define nam pam-pwdfile -%define ver 0.95 -%define prefix /usr -%define docdir %{prefix}/doc/%{nam}-%{ver} - -%define installer /usr/bin/install - -Summary: A PAM module that allows users to authenticate on htpasswd-type files separate from /etc/passwd. -Name: pam-pwdfile -Version: %{ver} -Release: 1 -Copyright: LGPL -Group: System Environment/Base -Source0: %{nam}-%{ver}.tar.gz -Source1: pam-pwdfile-Makefile.standalone -URL: http://cpbotha.net/pam_pwdfile.html -Distribution: Xeran Internal Packages -Vendor: Xeran Technologies -Packager: Jason F. McBrayer -BuildRoot: /var/tmp/%{nam}-%{ver}-root -BuildPrereq: pam -Requires: pam - -%description -This pam module can be used for the authentication service only, in cases -where one wants to use a different set of passwords than those in the main -system password database. E.g. in our case we have an imap server running, -and prefer to keep the imap passwords different from the system passwords -for security reasons. - -%prep -%setup -cp $RPM_SOURCE_DIR/pam-pwdfile-Makefile.standalone $RPM_BUILD_DIR/%{nam}-%{ver}/Makefile.standalone - -%build -make -f Makefile.standalone - -%install -make -f Makefile.standalone PAM_LIB_DIR="$RPM_BUILD_ROOT/lib/security" install - -%files -%attr(0755, root, root) /lib/security/pam_pwdfile.so -%attr(-, root, root) %doc README -%attr(-, root, root) %doc changelog diff --git a/contrib/warwick_duncan-cyrus_without_system_accounts.txt b/contrib/warwick_duncan-cyrus_without_system_accounts.txt deleted file mode 100644 index 0144af1..0000000 --- a/contrib/warwick_duncan-cyrus_without_system_accounts.txt +++ /dev/null @@ -1,49 +0,0 @@ -On Tue, Jan 14, 2003 at 01:06:02AM +0100, Charl P. Botha wrote: -[...] -> ----- Forwarded message from Darren Gibbons ----- -[...] -> It is however possible with certain applications patched for pam -> (Cyrus IMAP server e.g.) that one does not need the users to -> exist in the system database. -[...] - -I've got it working with cyrus 2.0 and 2.1, so I'll give some pointers -on both. When I say `cyrus x' I mean cyrus imapd version x and -whichever version of sasl you need with it. - -Cyrus 2.0 ---------- - -- sasl must be configured with `--with-pam --enable-plain'; it doesn't - hurt to add `--disable cram --disable-digest' -- imapd must be configured with `--with-auth=unix' (sounds like you got - that right) -- in imapd.conf you need the line - sasl_pwcheck_method: PAM -- in /etc/pam.d/imap (on FreeBSD I believe you use /etc/pam.conf, but - the idea is similar) you need - auth required pam_pwdfile.so pwdfile /path/to/passwordfile - account required pam_permit.so -- make sure your password file is readable by user cyrus - -The idea of all this is to use the SASL PLAIN mechanism to get the -password in plaintext and then get SASL to leave the authentication to -PAM, which will use pam_pwdfile. - -Cyrus 2.1 ---------- - -- same as above, but different ;) in the details -- sasl must be configured with `--with-pam --with-saslauthd - --enable-plain' and I disable the rest (checkapop, digest, otp, krb4, - etc.) -- imapd should be configured with `--with-auth=unix' -- in imapd.conf you need the line - sasl_pwcheck_method: saslauthd -- start up saslauthd with `saslauthd -a pam' -- you need the /etc/pam.d/imap as above, as well as (an identical) - /etc/pam.d/sieve if you use timsieved - -I think that about covers it. One tricky bit with SASL is to get the -right mechanisms advertised; I do this by only compiling in support for -PLAIN and LOGIN. If the rest don't exist they can't cause problems. -- cgit v1.2.3