diff -ruN cucipop-1.31.orig/Makefile cucipop-1.31/Makefile
--- cucipop-1.31.orig/Makefile	Wed May 13 07:09:14 1998
+++ cucipop-1.31/Makefile	Sat May  8 20:54:25 1999
@@ -1,6 +1,6 @@
 #$Id: Makefile,v 1.18 1998/05/12 21:09:14 srb Exp $
 
-BASENAME= /usr
+BASENAME= ${ROOT_DIR}/usr
 
 GCC_WARNINGS = -O2 -pedantic -Wreturn-type -Wunused -Wformat \
  -Wpointer-arith -Wconversion -Waggregate-return \
@@ -10,21 +10,25 @@
 # 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	= -g -O #-DUSE_DB #$(GCC_WARNINGS)
+LDFLAGS = -lcrypt -lpam -lpam_misc -ldl #-ldb2
 
 # If you change this, edit config.h as well
-CUCIPOPLIB=/var/lib/cucipop
+CUCIPOPLIB=${ROOT_DIR}/var/lib/cucipop
 CUCIPOPBULLETINS=$(CUCIPOPLIB)/bulletins
 
 O=o
 
 BINDIR=$(BASENAME)/sbin
 MANDIR=$(BASENAME)/man/man8
+PAMDIR=$(ROOT_DIR)/etc/pam.d
+RCDIR=$(ROOT_DIR)/etc/rc.d/init.d
 
 INSTALL=install -o root -m
 BINPERM=02755 -s -g mail
 REGPERM=0644
+PAMPERM=0644
+RCPERM=0755
 
 #
 # When compiling without APOP support, the md5 library can be omitted.
@@ -32,11 +36,13 @@
 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_authentication.${O} \
+        $(MD5_OBJ)
 
 BINS=cucipop makevpopdb
-
 MANS=cucipop.8 makevpopdb.8
+PAMS=pam.d/cucipop
+RCS=rc.d/cucipop
 
 all: $(BINS)
 
@@ -47,7 +53,8 @@
 	$(CC) $(CFLAGS) makevpopdb.$(O) simplecrypt.$(O) \
 	 -o $@ $(LDFLAGS) $(LIBS)
 
-cucipop.$(O): config.h patchlevel.h cucipop.h atotime.h authenticate.h
+cucipop.$(O): config.h patchlevel.h cucipop.h atotime.h authenticate.h \
+              pam_authentication.h
 cucipop.$(O): cucipop.h hsort.h
 
 authenticate.$(O): config.h cucipop.h authenticate.h sdb.h
@@ -64,20 +71,22 @@
 
 makevpopdb.$(O): sdb.h
 
+pam_authenticate.$(O): pam_authenticate.h
+
 $(MD5_OBJ): md5/md5c.c md5/md5.h
 	cd md5; $(CC) $(CFLAGS) -c md5c.c
 
-install: $(BINS) $(MANS)
+install: $(BINS) $(MANS) $(PAMS) $(RCS)
 	$(INSTALL) $(BINPERM) $(BINS) $(BINDIR)
 	$(INSTALL) $(REGPERM) $(MANS) $(MANDIR)
-	mkdir $(CUCIPOPLIB) 2>/dev/null; exit 0
-	mkdir $(CUCIPOPBULLETINS) 2>/dev/null; exit 0
-	@for a in $(BINS); do ls -l $(BINDIR)/$$a; done
-	@for a in $(MANS); do ls -l $(MANDIR)/$$a; done
+	$(INSTALL) $(PAMPERM) $(PAMS) $(PAMDIR)
+	$(INSTALL) $(RCPERM) $(RCS) $(RCDIR)
 
 deinstall:
 	cd $(BINDIR) && $(RM) $(BINS)
 	cd $(MANDIR) && $(RM) $(MANS)
+	cd $(PAMDIR) && $(RM) $(PAMS)
+	cd $(RCDIR)  && $(RM) $(RCS)
 
 clean:
 	rm -f *.$(O) md5/*.$(O) $(BINS) *core*
diff -ruN cucipop-1.31.orig/config.h cucipop-1.31/config.h
--- cucipop-1.31.orig/config.h	Wed May 13 07:09:14 1998
+++ cucipop-1.31/config.h	Sat May  8 20:40:55 1999
@@ -1,5 +1,8 @@
 /*$Id: config.h,v 1.20 1998/05/12 21:09:14 srb Exp $*/
 
+#ifndef CUCIPOP_CONFIG_H
+#define CUCIPOP_CONFIG_H
+
 #define USEdot_lock	/**/
 /*#define USEfcntl_lock /**/	    /* to test which combinations make sense */
 /*#define USElockf	/**/	      /* run the lockingtest program part of */
@@ -15,6 +18,8 @@
 #define LAST_HACK	/**/		   /* uncomment to enable dummy LAST */
 							 /* violates RFC1939 */
 
+#define PAM
+
 /* to change the MAILSPOOLDIR, edit authenticate.c */
 
 /************************************************************************
@@ -87,3 +92,5 @@
 #define CUCIPOP_LIB	"/var/lib/cucipop"
 #define STATE_DB	"state.db"
 #define BULLETINS_PATH	CUCIPOP_LIB"/bulletins"
+
+#endif
diff -ruN cucipop-1.31.orig/cucipop.c cucipop-1.31/cucipop.c
--- cucipop-1.31.orig/cucipop.c	Thu May 14 02:57:39 1998
+++ cucipop-1.31/cucipop.c	Sat May  8 20:40:55 1999
@@ -48,6 +48,10 @@
 #include "md5/md5.h"
 #endif
 
+#ifdef PAM
+#include "pam_authentication.h"
+#endif
+
 #define MD5_DIGLEN	16
 #define BIN2HEXLEN	(MD5_DIGLEN*2)
 #define Signal(sig,fn)	signal(sig,(void(*)())(fn))
@@ -241,15 +245,23 @@
   return setuid(auth_whatuid(pass))?(auth_identity*)0:pass;
 }
 
+#ifdef PAM
+static const auth_identity*checkpw(pam_handle_t *pamh, const char*pw)
+#else
 static const auth_identity*checkpw(const char*pw)
+#endif
 { const auth_identity*pass;int valid=0;
   if(!(pass=auth_finduser(user,fileno(sockin)))||auth_whatuid(pass)<LOWEST_UID)
      goto ret0;
+#ifdef PAM
+  if(do_pam_authentication(pamh, user, pw))
+#else
   ;{ char*secret;
      if((secret=(char*)auth_getsecret(pass))&&*secret)
 	valid=!strcmp(pw,secret),wipestring(secret);
    }
   if(!valid&&!auth_checkpassword(pass,pw,0))
+#endif
 ret0:
      return 0;
   return transmogrify(pass);
@@ -615,7 +627,17 @@
 { unsigned loginattempts=0,quiet=0,debug=0;short port=POP3_PORT;
   unsigned douser=1,douidl=1,doapop=1,dotop=1,autodel=0,sabotage=0;
   static const char tdotnl[]=".\r\n";time_t agecutoff=-AGETOLERANCE;
+#ifdef PAM
+  pam_handle_t *pamh=NULL;
+#endif
+  
   openlog(cucipopn,LOG_PID,LOG_FACILITY);sockin=stdin;sockout=stdout;
+
+#ifdef PAM
+  if((pam_retval=pam_start(SERVICE_NAME, user, &conv_struct, &pamh))
+    !=PAM_SUCCESS)
+    return do_pam_end(pamh, EX_PAM_ERROR);
+#endif
   if(!(msgs=malloc(GROWSTEP*sizeof*msgs)))
      outofmem();
   msgs_max=GROWSTEP;
@@ -694,12 +716,24 @@
 		  auth_mailboxname(auth_finduid(getuid(),0)),virtualhostdb,
 		  virtualuser,cplib,bulletins_path,MAXBULLETINS-1,cplib,
 		  statedbfile);
+#ifdef PAM
+		 return do_pam_end(pamh, EXIT_SUCCESS);
+#else
 		 return EXIT_SUCCESS;
+#endif
 usg:	      default:printusg();
+#ifdef PAM
+		 return do_pam_end(pamh, EX_USAGE);
+#else
 		 return EX_USAGE;
+#endif
 	      case HELP1:case HELP2:printusg();
 		 fprintf(stderr,XUSAGE,POP3_PORT);
-		 return EX_USAGE;
+#ifdef PAM
+		 return  do_pam_end(pamh, EX_USAGE);
+#else
+		 return  EX_USAGE;
+#endif
 	      case EXPIRE:Qnext_arg();agecutoff=atosec(chp,&chp);
 		 continue;
 	      case PORT:Qnext_arg();port=strtol(chp,(char**)&chp,10);
@@ -722,11 +756,19 @@
 	if(bind(serverfd,(struct sockaddr*)&peername,sizeof peername))
 	 { syslog(LOG_CRIT,"unable to bind socket %d",POP3_PORT);
 	   fprintf(stderr,"%s: Can't bind socket %d\n",cucipopn,POP3_PORT);
+#ifdef PAM
+	   return do_pam_end(pamh, EX_OSFILE);
+#else
 	   return EX_OSFILE;
+#endif
 	 }
 	fclose(stderr);
 	if(fork()>0)
+#ifdef PAM
+	   return do_pam_end(pamh, EXIT_SUCCESS);
+#else
 	   return EXIT_SUCCESS;
+#endif
 	setsid();listen(serverfd,LISTEN_BACKLOG);
 	sprintf(linebuf,PIDFILE,cucipopn);
 	;{ FILE*pidf;
@@ -784,7 +826,11 @@
      readcommand(0);
      if(!arg1&&cmpbuf("quit"))
       { fprintf(sockout,"+OK Not really your day, is it?\r\n");
+#ifdef PAM
+	return do_pam_end(pamh, EXIT_SUCCESS);
+#else
 	return EXIT_SUCCESS;
+#endif
       }					  /* still allow for trailing spaces */
      if(douser&&(!arg2||!*arg2)&&cmpbuf("user"))
 	if(!*user)
@@ -800,7 +846,11 @@
       { if(*user)
 	 { if(arg2)
 	      arg2[-1]=' ';	   /* put back a literal space in the passwd */
+#ifdef PAM
+	   if(arg1&&*arg1&&(pass=checkpw(pamh, arg1)))
+#else
 	   if(arg1&&*arg1&&(pass=checkpw(arg1)))
+#endif
 	    { wipestring(arg1);
 	      goto okpass;
 	    }
@@ -820,8 +870,10 @@
 	      if(pass=checkchallenge(arg2))
 okpass:	       { free(timestamp);
 		 hostnduser=strlen(host)+strlen(Vuser);
-		 if(openmailbox(pass,agecutoff))
+		 if(openmailbox(pass,agecutoff)){
 		    fprintf(sockout,"+OK Congratulations!\r\n");
+                    syslog(LOG_DEBUG,"Opened %s's mailbox",Vuser);
+                 }
 		 else
 		  { syslog(LOG_ALERT,"Error opening %s's mailbox",Vuser);
 		    fail("Error opening your mailbox");terminate(EX_NOINPUT);
@@ -1084,5 +1136,9 @@
   if(!si.lastabort)
      si.lastabort=tsessionstart;
   blocksignals();putstate(Vuser,&si);closedb();exitappdb();
+#ifdef PAM
+  return do_pam_end(pamh, EXIT_SUCCESS);
+#else
   return EXIT_SUCCESS;
+#endif
 }
diff -ruN cucipop-1.31.orig/pam.d/cucipop cucipop-1.31/pam.d/cucipop
--- cucipop-1.31.orig/pam.d/cucipop	Thu Jan  1 10:00:00 1970
+++ cucipop-1.31/pam.d/cucipop	Sat May  8 20:41:53 1999
@@ -0,0 +1,7 @@
+#%PAM-1.0
+auth       required     /lib/security/pam_pwdb.so shadow
+auth       required     /lib/security/pam_nologin.so
+account    required     /lib/security/pam_pwdb.so
+password   required     /lib/security/pam_cracklib.so
+password   required     /lib/security/pam_pwdb.so shadow nullok use_authtok
+session    required     /lib/security/pam_pwdb.so
diff -ruN cucipop-1.31.orig/pam_authentication.c cucipop-1.31/pam_authentication.c
--- cucipop-1.31.orig/pam_authentication.c	Thu Jan  1 10:00:00 1970
+++ cucipop-1.31/pam_authentication.c	Sat May  8 20:40:55 1999
@@ -0,0 +1,65 @@
+/* pam_authenticaton                                     November 1998
+ * Horms                                         horms@zipworld.com.au
+ * Zip World                               http://www.zipworld.com.au/
+ *
+ * Wrapper around pam authentication functions
+ *
+ * Taken from Linux-PAM Application Developers' Guide
+ * by Andrew G. Morgan <morgan@parc.power.net>
+ */
+
+#include "pam_authentication.h"
+
+int cucipop_conv(
+  int num_msg,
+  const struct pam_message **msgm,
+  struct pam_response **response,
+  void *appdata_ptr
+){
+  char *pass;
+
+  if((*response=(struct pam_response *)malloc(sizeof(struct pam_response)))
+    ==NULL)
+    return(PAM_CONV_ERR);
+
+  (*response)->resp_retcode=0;
+
+  if((char *)appdata_ptr==NULL)
+    pass=NULL;
+  else if((pass=strdup((char *)appdata_ptr))==NULL)
+    return(PAM_CONV_ERR);
+
+  (*response)->resp=pass;
+  return(PAM_SUCCESS);
+}
+
+int do_pam_authentication(
+  pam_handle_t *pamh, 
+  const char *user,
+  const char *pass
+){
+    extern struct pam_conv conv_struct;  
+
+    conv_struct.appdata_ptr=(void *)pass;
+    pam_retval = pam_set_item(pamh, PAM_CONV, (void *) &conv_struct);
+
+    if (pam_retval == PAM_SUCCESS) 
+        pam_retval = pam_set_item(pamh, PAM_USER, user);
+
+    if (pam_retval == PAM_SUCCESS)
+        pam_retval = pam_authenticate(pamh, 0);    /* is user really user? */
+
+    if (pam_retval == PAM_SUCCESS)
+        pam_retval = pam_acct_mgmt(pamh, 0);       /* permitted access? */
+
+    return ( pam_retval == PAM_SUCCESS ? 0:1 );       /* indicate success */
+}
+
+int do_pam_end(pam_handle_t *pamh, int defult_return){
+    if (pam_end(pamh,pam_retval) != PAM_SUCCESS) {     /* close Linux-PAM */
+        pamh = NULL;
+        return(EX_PAM_ERROR);
+    }
+    return(defult_return);
+}
+
diff -ruN cucipop-1.31.orig/pam_authentication.h cucipop-1.31/pam_authentication.h
--- cucipop-1.31.orig/pam_authentication.h	Thu Jan  1 10:00:00 1970
+++ cucipop-1.31/pam_authentication.h	Sat May  8 20:40:55 1999
@@ -0,0 +1,38 @@
+/* pam_authenticaton                                     November 1998
+ * Horms                                         horms@zipworld.com.au
+ * Zip World                               http://www.zipworld.com.au/
+ *
+ * Wrapper around pam authentication functions
+ *
+ * Taken from Linux-PAM Application Developers' Guide
+ * by Andrew G. Morgan <morgan@parc.power.net>
+ */
+
+#ifndef DO_PAM
+#define DO_PAM
+
+#include <security/pam_appl.h>
+#include <security/pam_misc.h>
+#include <stdio.h>
+
+#define SERVICE_NAME "cucipop"
+#define EX_PAM_ERROR -1
+
+
+int do_pam_authentication(
+  pam_handle_t *pamh,
+  const char *user,
+  const char *pass
+);
+int cucipop_conv(
+  int num_msg,
+  const struct pam_message **msgm,
+  struct pam_response **response,
+  void *appdata_ptr
+);
+int do_pam_end(pam_handle_t *pamh, int defult_return);
+
+static struct pam_conv conv_struct =  { cucipop_conv, NULL }; 
+static int pam_retval;
+
+#endif
diff -ruN cucipop-1.31.orig/rc.d/cucipop cucipop-1.31/rc.d/cucipop
--- cucipop-1.31.orig/rc.d/cucipop	Thu Jan  1 10:00:00 1970
+++ cucipop-1.31/rc.d/cucipop	Sat May  8 20:45:17 1999
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# skeleton      Example file to build /etc/init.d scripts.
+#
+# Version:      @(#) /etc/init.d/cucipop  20-Nov-1998
+#
+# Author:       Horms <horms@zipworld.com.au>
+#
+# Adapted from: Tomasz Kłoczko, <kloczek@rudy.mif.pg.gda.pl>
+#               Michele Marziani <marziani@fe.infn.it>
+#
+# cucipop:
+# chkconfig: 2345 81 29
+# description: Cubic Circle's POP3 daemon has support for just about \
+# everything including APOP, UIDL, flexible authenication mechanisms \
+# including hooks for RADIUS and shadow. It can also be used as a \
+# standalone daemon for heavy POP traffic systems. It's fast and it's \
+# small. Please read the README for registration information. This one \
+# has Shadowsupport by default.
+# processname: cucipop
+
+# Source function library.
+. /etc/rc.d/init.d/functions
+
+# See how we were called.
+case "$1" in
+  start)
+        echo -n "Starting cucipop services: "
+	daemon /usr/sbin/cucipop
+	touch /var/lock/subsys/cucipop
+	echo
+	;;
+  status)
+        status cucipop
+	;;
+  restart|reload)
+        $0 stop
+	$0 start
+        ;;
+  stop)
+        echo -n "Shutting down cucipop services: "
+	killproc cucipop
+	rm -f /var/lock/subsys/cucipop
+	echo
+	;;
+  *)
+	echo "Usage: cucipop {start|stop|status|restart|reload}"
+	exit 1
+esac
+
+exit 0
+
