Package: cucipop Severity: wishlist Attached is a patch for cucipop 1.31 to add PAM authentication support. This applies directly over the debian source package, includes needed additions to debian/{rules,dirs,conffile} as well as a /etc/pam.d/cucipop file (placed as debian/pam.d after patching)
Thanks
diff -urN cucipop-1.31/Makefile cucipop-1.31+pam/Makefile --- cucipop-1.31/Makefile Tue May 12 17:09:14 1998 +++ cucipop-1.31+pam/Makefile Thu Apr 15 16:24:31 1999 @@ -10,8 +10,8 @@ # Omit USE_DB if you don't have the -ldb2 library (Berkeley DB, v2.x) # WARNING: bulletins are not remembered to have been deleted without USE_DB -CFLAGS = -O -DUSE_DB #$(GCC_WARNINGS) -LDFLAGS = -lcrypt -ldb2 +CFLAGS = -O -DUSE_DB -DUSE_PAM #$(GCC_WARNINGS) +LDFLAGS = -lcrypt -ldb2 -lpam # If you change this, edit config.h as well CUCIPOPLIB=/var/lib/cucipop @@ -32,7 +32,7 @@ MD5_OBJ=md5/md5c.$(O) OBJS=cucipop.$(O) authenticate.$(O) atotime.$(O) locking.$(O) xcreat.$(O) \ - dbops.$(O) hsort.$(O) simplecrypt.$(O) $(MD5_OBJ) + dbops.$(O) hsort.$(O) simplecrypt.$(O) pam.$(O) $(MD5_OBJ) BINS=cucipop makevpopdb diff -urN cucipop-1.31/authenticate.c cucipop-1.31+pam/authenticate.c --- cucipop-1.31/authenticate.c Wed May 13 12:57:39 1998 +++ cucipop-1.31+pam/authenticate.c Thu Apr 15 14:29:42 1999 @@ -72,7 +72,11 @@ char*auth_logname; +#ifndef USE_PAM static auth_identity authi; /* reuse copy, only one active */ +#else +struct auth_identity authi; +#endif static void castlower(str)register char*str; /* and I'll take the low road */ { for(;*str;str++) @@ -183,6 +187,9 @@ } #ifndef PROCMAIL +#ifdef USE_PAM +extern int auth_checkpassword(const struct auth_identity*const, const char*const, const int); +#else int auth_checkpassword(pass,pw,allowemptypw)const auth_identity*const pass; const char*const pw;const int allowemptypw; { const char*rpw; @@ -197,6 +204,7 @@ return allowemptypw; /* should we allow this? */ return !strcmp(rpw,crypt(pw,rpw)); /* compare the passwords */ } +#endif /* USE_PAM */ const char*auth_getsecret(pass)const auth_identity*const pass; { return authi.usersecret; diff -urN cucipop-1.31/debian/conffiles cucipop-1.31+pam/debian/conffiles --- cucipop-1.31/debian/conffiles Thu Apr 15 16:49:54 1999 +++ cucipop-1.31+pam/debian/conffiles Thu Apr 15 16:45:58 1999 @@ -1 +1,2 @@ /etc/init.d/cucipop +/etc/pam.d/cucipop diff -urN cucipop-1.31/debian/dirs cucipop-1.31+pam/debian/dirs --- cucipop-1.31/debian/dirs Thu Apr 15 16:49:54 1999 +++ cucipop-1.31+pam/debian/dirs Thu Apr 15 16:45:44 1999 @@ -1,4 +1,5 @@ etc/init.d +etc/pam.d usr/sbin usr/doc/cucipop var/lib/cucipop/bulletins diff -urN cucipop-1.31/debian/pam.d cucipop-1.31+pam/debian/pam.d --- cucipop-1.31/debian/pam.d Wed Dec 31 19:00:00 1969 +++ cucipop-1.31+pam/debian/pam.d Thu Apr 15 16:44:26 1999 @@ -0,0 +1,6 @@ +# +# /etc/pam.d/cucipop +# + +auth required pam_unix_auth.so +account required pam_unix_acct.so diff -urN cucipop-1.31/debian/rules cucipop-1.31+pam/debian/rules --- cucipop-1.31/debian/rules Thu Apr 15 16:49:54 1999 +++ cucipop-1.31+pam/debian/rules Thu Apr 15 16:45:34 1999 @@ -33,6 +33,7 @@ dh_installdocs FEATURES README INSTALL dh_installchangelogs HISTORY install cucipop makevpopdb debian/tmp/usr/sbin/. + install -m 644 debian/pam.d debian/tmp/etc/pam.d/cucipop dh_installmanpages dh_compress chown root.mail debian/tmp/usr/sbin/cucipop* diff -urN cucipop-1.31/pam.c cucipop-1.31+pam/pam.c --- cucipop-1.31/pam.c Wed Dec 31 19:00:00 1969 +++ cucipop-1.31+pam/pam.c Thu Apr 15 16:42:32 1999 @@ -0,0 +1,167 @@ +/* + * Copyright 1999 By Ben Collins <[EMAIL PROTECTED]> + * + * Modifiable and distributable under the terms of the GPL + * + * Modifications for PAM support in cucipop + */ + +#ifdef USE_PAM + +#include <stdlib.h> +#include <stdio.h> +#include <security/pam_appl.h> +#include <pwd.h> + +#define PASSWDLEN 8 + +struct auth_identity + { + const struct passwd *pw; + char *mbox, *usersecret; + int sock; + }; +extern struct auth_identity authi; + +/* + * Static variables used to communicate between the conversation function + * and the login function + */ +static char *PAM_username; +static char *PAM_password; +static int PAM_error = 0; + +/* Safe strdup(), never tries to copy NULL -- Ben Collins */ +char * +my_strdup (char *string) +{ + if (string != NULL) + return (char *) strdup (string); + else + return NULL; +} + +/* Safe free(), never tries to free NULL, plus set's NULL after free()'ing. + * This should never double-free. -- Ben Collins */ +#define my_free(s) xmy_free((void **)&s) +void +xmy_free (void **ptr) +{ + if (*ptr != NULL) + { + free (*ptr); + *ptr = NULL; + } +} + +/* + * PAM conversation function + * Here we assume (for now, at least) that echo on means login name, and + * echo off means password. (taken from netatalk) + */ +static int +PAM_conv (int num_msg, + const struct pam_message **msg, + struct pam_response **resp, + void *appdata_ptr) +{ + int count = 0; + struct pam_response *reply; + + if (num_msg < 1) + return PAM_CONV_ERR; + + reply = (struct pam_response *) + calloc (num_msg, sizeof (struct pam_response)); + + if (!reply) + return PAM_CONV_ERR; + + for (count = 0; count < num_msg; count++) + { + char *string = NULL; + + switch (msg[count]->msg_style) + { + case PAM_PROMPT_ECHO_ON: + if ((string = my_strdup (PAM_username)) == NULL) + goto pam_fail_conv; + break; + case PAM_PROMPT_ECHO_OFF: + if ((string = my_strdup (PAM_password)) == NULL) + goto pam_fail_conv; + break; + case PAM_TEXT_INFO: + /* ignore it... */ + break; + case PAM_ERROR_MSG: + default: + goto pam_fail_conv; + } + + if (string) + { + reply[count].resp_retcode = 0; + reply[count].resp = string; + } + } + + *resp = reply; + return PAM_SUCCESS; + + pam_fail_conv: + for (count = 0; count < num_msg; count++) + { + switch (msg[count]->msg_style) + { + case PAM_PROMPT_ECHO_ON: + case PAM_PROMPT_ECHO_OFF: + if (reply[count].resp) + { + memset (reply[count].resp, 0, PASSWDLEN); + my_free (reply[count].resp); + } + break; + } + } + my_free (reply); + return PAM_CONV_ERR; +} + +static struct pam_conv PAM_conversation = +{ + &PAM_conv, + NULL +}; + +pam_handle_t *pamh = NULL; /* We need this global so we can do + pam_end() elsewhere if needed */ + +/* We ignore 'allowemptypw' since that is something PAM can handle itself */ +int +auth_checkpassword (const struct auth_identity *const pass, const char *const pw, + const int allowemptypw) +{ + int retval; + char *user; + + PAM_username = pass->pw->pw_name; + PAM_password = pw; + + retval = pam_start ("cucipop", PAM_username, &PAM_conversation, &pamh); + + if (retval == PAM_SUCCESS) + retval = pam_authenticate (pamh, 0); + + if (retval == PAM_SUCCESS) + retval = pam_acct_mgmt (pamh, 0); + + (void) pam_end (pamh, retval); + + if (retval == PAM_SUCCESS) + return (1); + else + return (0); +} + +#endif /* USE_PAM */