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: