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

Reply via email to