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 */

Reply via email to