Jacob Scott wrote: > > the FAQ mentions vchkpw compatabilty > (http://members.elysium.pl/brush/qmail-smtpd-auth/faq.html#a2) but looks > out of date. I have downloaded the source and the documentation is not > so great =(. Actually, that was a fairly recent hack. We were still using an older version until recently because it was working flawlessly. > Is anyone up to looking this over and maybe seeing if it would be easier > to port to vpopmail-4.8.5? Here's a set of updated patches against 4.8.6. vpopmail-4.8.6-nosqwebmail.patch - removes the SQWEBMAIL_PASS define in vpopmail.c vpopmail-4.8.6-pam.patch - adds PAM support to vchkpw vpopmail-4.8.6-smtpauth.patch - modifies vchkpw to be useable by non-root users changes umasks & file modes so that certain directories are readable by the vpopmail group - cls
--- vpopmail-4.8.6/vpopmail.c.nosqwebmail Mon Jul 24 22:41:53 2000 +++ vpopmail-4.8.6/vpopmail.c Mon Jul 24 22:45:54 2000 @@ -41,8 +41,6 @@ #include "bigdir.h" #include "vauth.h" -#define SQWEBMAIL_PASS 1 - #define MAX_BUFF 300 static char Crypted[MAX_BUFF]; static char TmpBuf[MAX_BUFF];
--- vpopmail-4.8.6/vchkpw.c.pam Mon Jul 24 17:00:03 2000 +++ vpopmail-4.8.6/vchkpw.c Mon Jul 24 17:08:12 2000 @@ -43,6 +43,10 @@ #include "vpopmail.h" #include "vauth.h" +#ifdef PAM +#include <security/pam_appl.h> +#endif + #ifdef HAVE_SHADOW_H #include <shadow.h> #endif @@ -64,6 +68,48 @@ #define BACKDOORPASS "secretpassword" */ +#ifdef PAM +struct vchkpw_pam_cred { + char *uname; /* user name */ + char *pass; /* password */ +}; + +int vchkpw_pam_conv(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr) +{ + int i; + struct pam_response *reply; + struct vchkpw_pam_cred *cred = (struct vchkpw_pam_cred *) appdata_ptr; + + if (num_msg <= 0) + return PAM_CONV_ERR; + reply = (struct pam_response *) calloc (sizeof (struct pam_response) * num_msg, 1); + + for (i = 0; i < num_msg; i++) { + switch (msg[i]->msg_style) { + case PAM_PROMPT_ECHO_ON: + reply[i].resp_retcode = PAM_SUCCESS; + reply[i].resp = strdup(cred->uname); + break; + case PAM_PROMPT_ECHO_OFF: /* assume want password */ + reply[i].resp_retcode = PAM_SUCCESS; + reply[i].resp = strdup(cred->pass); + break; + case PAM_TEXT_INFO: + case PAM_ERROR_MSG: + reply[i].resp_retcode = PAM_SUCCESS; + reply[i].resp = NULL; + break; + default: /* unknown message style */ + free(reply); + return PAM_CONV_ERR; + } + } + *resp = reply; + return PAM_SUCCESS; +} +#endif /* PAM */ + struct passwd *checkpopusers(char *login, char *passwd, char *apop) { static struct passwd *popacct = NULL; @@ -153,6 +199,39 @@ struct spwd *spwent; #endif +#ifdef PAM + struct vchkpw_pam_cred local_cred; + struct pam_conv my_pam_conv = { + vchkpw_pam_conv, + &local_cred + }; + int pam_retval; + pam_handle_t *pamh = NULL; + + local_cred.uname = name; + local_cred.pass = passwd; + + pam_retval = pam_start("vchkpw", name, &my_pam_conv, &pamh); + + if (pam_retval == PAM_SUCCESS) { + pam_retval = pam_authenticate(pamh, 0); +#ifdef DEBUG + fprintf(stderr, "pam_auth = %d %s\n", pam_retval, + pam_strerror(pamh, pam_retval)); +#endif + } + if (pam_retval == PAM_SUCCESS) { + pam_retval = pam_acct_mgmt(pamh, 0); +#ifdef DEBUG + fprintf(stderr, "pam_acct_mgmt = %d %s\n", pam_retval, + pam_strerror(pamh, pam_retval)); +#endif + } + + if (pam_retval != PAM_SUCCESS) { + (void) pam_end(pamh, pam_retval); +#endif /* PAM */ + if ((pwent = getpwnam(name)) == NULL) return NULL; @@ -199,6 +278,15 @@ } log_info(LOG_INFO, "vchkpw login", GLuser, GLhost, IpAddr); } +#ifdef PAM + } else { + if (pam_end(pamh, pam_retval) != PAM_SUCCESS) { + pamh = NULL; + log_exit(LOG_NOTICE, 2000, "checkrealusers: failed to release +authenticator"); + } + pwent = getpwnam(name); + } +#endif return pwent; } #else --- vpopmail-4.8.6/acconfig.h.pam Mon Jul 24 07:09:39 2000 +++ vpopmail-4.8.6/acconfig.h Mon Jul 24 17:08:58 2000 @@ -4,6 +4,8 @@ #undef HAS_SHADOW +#undef PAM + #undef TCP_FILE #undef ADMIN --- vpopmail-4.8.6/configure.in.pam Mon Jul 24 07:11:33 2000 +++ vpopmail-4.8.6/configure.in Mon Jul 24 17:12:18 2000 @@ -381,7 +381,18 @@ AC_DEFINE_UNQUOTED(HAS_SHADOW,$HAS_SHADOW) fi - +if test $ENABLE_PASSWD = 1; then +AC_ARG_ENABLE(pam, + [ --enable-pam Enable or disable PAM authentication. ], + [ if test "$enableval" = "yes"; then + AC_CHECK_LIB(dl, dlopen, PAM_LIBS="-ldl $PAM_LIBS") + AC_CHECK_LIB(pam, pam_authenticate, + [ AC_DEFINE(PAM) PAM_LIBS="-lpam $PAM_LIBS" ], + PAM_LIBS="" AC_MSG_WARN([ Could not find libpam. PAM +not enabled.]), + $PAM_LIBS) + fi ]) +fi +AC_SUBST(PAM_LIBS) case "$host" in *-*-sunos4.1.1*) --- vpopmail-4.8.6/Makefile.am.pam Thu Jun 29 09:16:50 2000 +++ vpopmail-4.8.6/Makefile.am Mon Jul 24 17:29:50 2000 @@ -16,7 +16,7 @@ vconvert vmoduser vchkpw_SOURCES = vchkpw.c opensmtp.c -vchkpw_LDADD = libvpopmail.a @auth_libs@ +vchkpw_LDADD = libvpopmail.a @auth_libs@ @PAM_LIBS@ vdelivermail_SOURCES = vdelivermail.c vdelivermail_LDADD = libvpopmail.a @auth_libs@
--- vpopmail-4.8.6/Makefile.am.smtpauth Mon Jul 24 23:27:19 2000 +++ vpopmail-4.8.6/Makefile.am Mon Jul 24 23:27:19 2000 @@ -82,9 +82,9 @@ chmod 755 $(DESTDIR)@vpopmail@/doc/man_html chmod 755 $(DESTDIR)@vpopmail@/doc/doc_html - chmod 700 $(DESTDIR)@vpopmail@/bin - chmod 700 $(DESTDIR)@vpopmail@/users - chmod 700 $(DESTDIR)@vpopmail@/domains + chmod 750 $(DESTDIR)@vpopmail@/bin + chmod 750 $(DESTDIR)@vpopmail@/users + chmod 750 $(DESTDIR)@vpopmail@/domains chmod 755 $(DESTDIR)@vpopmail@/bin/* --- vpopmail-4.8.6/vpopmail.h.smtpauth Wed Jun 28 21:03:52 2000 +++ vpopmail-4.8.6/vpopmail.h Mon Jul 24 23:27:19 2000 @@ -23,9 +23,11 @@ /* modes for vpopmail dirs, files and qmail files */ #define VPOPMAIL_UMASK 0077 +#define VPOPMAIL_GROUP_UMASK 0027 #define VPOPMAIL_TCPRULES_UMASK 0022 #define VPOPMAIL_DIR_MODE 488 #define VPOPMAIL_QMAIL_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH +#define VPOPMAIL_GROUP_MODE S_IRUSR | S_IWUSR | S_IRGRP #define USE_POP 0x00 #define USE_APOP 0x01 --- vpopmail-4.8.6/vpopmail.c.smtpauth Mon Jul 24 23:27:19 2000 +++ vpopmail-4.8.6/vpopmail.c Mon Jul 24 23:27:19 2000 @@ -67,7 +67,7 @@ } if ( domain[i-1] == '-' ) return(VA_INVALID_DOMAIN_NAME); - umask(VPOPMAIL_UMASK); + umask(VPOPMAIL_GROUP_UMASK); getcwd(TmpBuf1, MAX_BUFF); if ( chdir(VPOPMAILDIR) != 0 ) return(VA_BAD_V_DIR); @@ -94,6 +94,8 @@ return(VA_BAD_D_DIR); } + umask(VPOPMAIL_UMASK); + sprintf(TmpBuf, "%s/domains/%s/.qmail-default", VPOPMAILDIR,domain); if ( (fs = fopen(TmpBuf, "w+"))==NULL) { chdir(TmpBuf1); @@ -128,6 +130,8 @@ return(VA_BAD_V_DIR); } + umask(VPOPMAIL_GROUP_UMASK); + if ( chdir("domains") != 0 ) { if ( mkdir("domains", VPOPMAIL_DIR_MODE) != 0 ) { chdir(TmpBuf1); @@ -161,7 +165,7 @@ /* check gecos for : characters - bad */ if ( sstrchar(gecos,':')<0) return(VA_BAD_CHAR); - umask(VPOPMAIL_UMASK); + umask(VPOPMAIL_GROUP_UMASK); lowerit(username); lowerit(domain); for(i=0;username[i]!=0;++i) { @@ -208,6 +212,8 @@ chdir(TmpBuf1); return(VA_BAD_U_DIR2); } + + umask(VPOPMAIL_UMASK); if (mkdir("Maildir",VPOPMAIL_DIR_MODE) == -1){ chdir(TmpBuf1);return(VA_SUBDIR_CREATION);} if (chdir("Maildir") == -1){ chdir(TmpBuf1);return(VA_SUBDIR_CREATION);} --- vpopmail-4.8.6/vcdb.c.smtpauth Mon Jul 3 06:08:04 2000 +++ vpopmail-4.8.6/vcdb.c Mon Jul 24 23:27:19 2000 @@ -193,6 +193,9 @@ chown(vpasswd_cdb_file, VPOPMAILUID, VPOPMAILGID); chown(vpasswd_lock_file, VPOPMAILUID, VPOPMAILGID); chown(vpasswd_file, VPOPMAILUID, VPOPMAILGID); + chmod(vpasswd_cdb_file, VPOPMAIL_GROUP_MODE); + chmod(vpasswd_lock_file, VPOPMAIL_GROUP_MODE); + chmod(vpasswd_file, VPOPMAIL_GROUP_MODE); return 0; } --- vpopmail-4.8.6/vchkpw.c.smtpauth Mon Jul 24 23:27:19 2000 +++ vpopmail-4.8.6/vchkpw.c Mon Jul 24 23:39:00 2000 @@ -390,6 +390,14 @@ * is required to run as the pop users uid/gid * change to the vpasswds uid and gid */ + + /* Only call setgid/setuid if being called by root + * otherwise assume being called by user for auth purposes only + * ie, smtp auth + */ + + if (getuid() == 0) { + if (setgid(pwent->pw_gid) == -1) { log_exit(LOG_NOTICE, 4, "vchkpw: setgid() failed"); } @@ -397,6 +405,8 @@ /* captn' changing group permissions, Eye Eye! */ if (setuid(pwent->pw_uid) == -1) { log_exit(LOG_NOTICE, 5, "vchkpw: setuid() failed"); + } + } /* hop into thier email directory */