[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#36158: pam support for cucipop



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 <bcollins@debian.org>
+ *
+ * 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 to: