Simon,

   For what it is worth, attached is my patchfile for my own 3.x era
work on qpopper.  I had a ton of local customizations in version 3 of
qpopper, most of which I dropped when I went to version 4 (I embraced
the server mode option -S).  One of the hacks I had in version three
was the "accesstime" option, setable via command line as "-a".  Search
the patchfile for the word "accesstime".  This feature required you to
use KEEP_TEMP_DROP.  What the pop_accesstime() subroutine did was to
compare the timestamp of the dropfile to the current time.  If the
difference was less than accesstime, then the user got the POP error
message "you just checked your mail!" and rejected the connection without
touching the mailbox.  This bit of code punished impatient users who
wanted to check their email every few seconds.

   This routine would require some work to fit into version 4, because
the "p" structure changed considerably between v3 and v4.  If you are
a C programmer and have a little time, you should be able to add
this feature to v4.  Good luck.

-----------------------------------
Jeff A. Earickson, Ph.D
Senior UNIX Sysadmin and Email Guru
Information Technology Services
Colby College, 4214 Mayflower Hill,
Waterville ME, 04901-8842
phone: 207-872-3659 (fax = 3076)
-----------------------------------

On Thu, 31 Oct 2002, Simon May wrote:

> Date: Thu, 31 Oct 2002 16:45:23 +0100
> From: Simon May <[EMAIL PROTECTED]>
> To: Subscribers of Qpopper <[EMAIL PROTECTED]>
> Subject: Re: Users popping to often
>
> I must say I was hoping that there was a way to stop the users popping to
> much
> I find when I ask users to reduce the frequency they comply with no
> problems.
> I was thinking that maybe there is a way to leave the lock files in place
> for a set time
> after the session finishes though I didn't notice the command in the docs
> and playing
> with the timeouts does not seem to do this.
>
> Simon
>
> ----- Original Message -----
> From: "Deid Reimer" <[EMAIL PROTECTED]>
>
>
>
> > I wrote a Perl script to analyse the logs and calculate traffic both
> > moved on the network and moved on our mail server.
> > Seems to work - none of our customers are currently abusing the system.
>
> > Simon May wrote:
> > > Dear All
> > > I have a number of users you are checking for mail very frequently,
> every
> > > 30s etc.
>
> > >
> > >
> >
>
# This is a patch for qpopper3.1.2 to update it to qpopper3.2.2
# 
# To apply this patch:
# STEP 1: Chdir to the source directory.
# STEP 2: Run the 'applypatch' program with this patch file as input.
#
# If you do not have 'applypatch', it is part of the 'makepatch' package
# that you can fetch from the Comprehensive Perl Archive Network:
# http://www.perl.com/CPAN/authors/Johan_Vromans/makepatch-x.y.tar.gz
# In the above URL, 'x' should be 2 or higher.
#
# To apply this patch without the use of 'applypatch':
# STEP 1: Chdir to the source directory.
# If you have a decent Bourne-type shell:
# STEP 2: Run the shell with this file as input.
# If you don't have such a shell, you may need to manually create
# the files as shown below.
# STEP 3: Run the 'patch' program with this file as input.
#
# These are the commands needed to create/delete files/directories:
#
touch 'popper/dce_pwent.c'
chmod 0600 'popper/dce_pwent.c'
touch 'popper/pop_authdce.c'
chmod 0600 'popper/pop_authdce.c'
#
# This command terminates the shell and need not be executed manually.
exit
#
#### End of Preamble ####

#### Patch data follows ####
diff -c 'qpopper3.1.2/INSTALL' 'qpopper3.2.2/INSTALL'
Index: ./INSTALL
*** ./INSTALL   Tue Oct 10 19:10:23 2000
--- ./INSTALL   Tue Nov 21 10:17:56 2000
***************
*** 191,197 ****
  
   --with-warnings          Enable additional compiler warnings.
  
!  --enable-hash-spool=1|2  Use hashed spool directory.  See 
                            HASH_SPOOL in section MACROS for more
                            information.  The default method is 2.
   
--- 191,198 ----
  
   --with-warnings          Enable additional compiler warnings.
  
!  --enable-hash-spool=1|2|3  
!                           Use hashed spool directory.  See 
                            HASH_SPOOL in section MACROS for more
                            information.  The default method is 2.
   
***************
*** 296,301 ****
--- 297,316 ----
   --disable-update-abort   Does not go into UPDATE state on abort.  Use
                            this to comply with RFC 1939.
  
+  --with-nonauth=path      Set the nonauthorized users file path.
+                           Default is /etc/pop.nonauth.
+ 
+  --with-auth=path         Set the authorized users file path.
+                           Default is  /etc/pop.authorized.
+ 
+  --with-loadlimit=load    Enable loadlimit feature.  Load is the
+                           numerical 1 minute load average, generally
+                           seen via the user command "uptime".  
+                           See LOADLIMIT in section MACROS for
+                           more information.  Default = 16.0
+                           Controllable at runtime option "-l" (see below).
+ 
+ 
  
  
  3. RUN-TIME OPTIONS (COMMAND LINE OPTIONS):
***************
*** 306,314 ****
  
  The following are the command line options you can use.
  
! popper [-b bulldir [-B] [-c] [-d] [-D drac-host] 
         [-e login_delay=nn,expire=nn] [-f config-file] [-k] [-K service]
!        [-s] [-S] [-t trace-file] [-T timeout] [-u] [-R]
  
  Note that some systems may have limitations on the length or
  number of command line arguments in inetd.conf.  (For example,
--- 321,329 ----
  
  The following are the command line options you can use.
  
! popper [-a accesstime] [-b bulldir] [-B] [-c] [-d] [-D drac-host] 
         [-e login_delay=nn,expire=nn] [-f config-file] [-k] [-K service]
!        [-l load_ave] [-s] [-S] [-t trace-file] [-T timeout] [-u] [-R]
  
  Note that some systems may have limitations on the length or
  number of command line arguments in inetd.conf.  (For example,
***************
*** 319,324 ****
--- 334,347 ----
  details, and the following section "RUN-TIME OPTIONS (CONFIG FILE)"
  for details.
  
+ -a accesstime  The minimum allowable access time between successive
+                mail checks, specified in integer seconds.  This
+                mechanism only works if KEEP_TEMP_DROP is defined,
+                because the method compares the timestamp on the
+                dropfile to the current time.  Used to keep people
+                from beating on your POP server.  A small value
+                (10 to 70 seconds) should be used.
+ 
  -b bulldir     This is the location of the bulletin 
                 directory.  The command line overrides the 
                 compiled value if it is defined.   
***************
*** 372,377 ****
--- 395,408 ----
                 KERBEROS_SERVICE define).  The default is "rcmd",
                 although the use of "pop" is popular.
  
+ -l load_ave    Refuse POP connections if the system one-minute load
+                average (as generally seen via the command "uptime")
+                is higher than the floating point number "load_ave".
+                Works on HP-UX 10.20 and 11.0 systems, and any system
+                supporting the getloadavg() call (eg, Solaris).  Used
+                to prevent POP connections from overwhelming your
+                system.
+ 
  -p 0|1|2|3     Set clear text handling options when APOP is
                 available: 0 is default (clear text passwords only
                 permitted for users not in the APOP database); 1 means
***************
*** 951,957 ****
  
  n) KEEP_TEMP_DROP -- Keep the .user.pop file.  It 
  can determine the last time a user has accessed 
! his/her mail.
  
  o) BIND43 -- BSD 4.3 is a domain name service.
  
--- 982,989 ----
  
  n) KEEP_TEMP_DROP -- Keep the .user.pop file.  It 
  can determine the last time a user has accessed 
! his/her mail.  Also see the runtime option "-a" for
! access_time.
  
  o) BIND43 -- BSD 4.3 is a domain name service.
  
***************
*** 1008,1023 ****
  default behavior, and obey RFC 1939.  Configure
  flag: --disable-update-abort.
  
! y) HASH_SPOOL=(1|2) -- Mail is deposited into the 
! mailspools by either (1) hashing the first 4 
! characters or (2) by using mailspools in 
! directories as in the following:  /<1st 
! letter>/<2nd letter>/file.  For example, if the
! spool directory is "/var/mail", the spool file for
! user "maida" would be:
     /var/mail/maida          HASH_SPOOL not set
     /var/mail/o/maida        HASH_SPOOL=1
     /var/mail/m/a/maida      HASH_SPOOL=2
  
  Use the --enable-hash-spool configure flag to set
  this.
--- 1040,1057 ----
  default behavior, and obey RFC 1939.  Configure
  flag: --disable-update-abort.
  
! y) HASH_SPOOL=(1|2|3) -- Mail is deposited into the
! mailspools by either (1) hashing the first 4
! characters, (2) by using mailspools in
! directories as in the following:  /<1st
! letter>/<2nd letter>/file, or (3) by just using the
! first letter of the userid as the subdirectory.
! For example, if the spool directory is "/var/mail",
! the spool file for user "maida" would be:
     /var/mail/maida          HASH_SPOOL not set
     /var/mail/o/maida        HASH_SPOOL=1
     /var/mail/m/a/maida      HASH_SPOOL=2
+    /var/mail/m/maida        HASH_SPOOL=3
  
  Use the --enable-hash-spool configure flag to set
  this.
***************
*** 1076,1081 ****
--- 1110,1123 ----
  ah) TRACE_MSG_BODY -- Define to include message bodies in
  trace information written with -t or -d run-time flag.
  
+ ac) LOADLIMIT -- Define a floating point value if you want
+ qpopper to refuse connections whenever the 1-minute load average
+ (generally seen via "uptime") goes above the chosen value.
+ This feature keeps your system from falling over if you take
+ lots of pop connections and your system load goes way up.
+ Works on any system supporting the getloadavg(3) call (eg, 
+ Solaris2 systems), and on any HPUX 10.x or 11.x system.  Coding
+ is needed to support other brands of UNIX.
  
  
  NOTES:
diff -c 'qpopper3.1.2/common/genpath.c' 'qpopper3.2.2/common/genpath.c'
Index: ./common/genpath.c
*** ./common/genpath.c  Fri Sep  8 20:28:19 2000
--- ./common/genpath.c  Tue Nov 21 10:17:56 2000
***************
*** 96,101 ****
--- 96,105 ----
   *            to open.  Eg: /usr/spool/u/s/user.
   *            Larry Schwimmer <[EMAIL PROTECTED]>
   *
+  * Method 3 - Use the first character only, so you have 26 subdirectories,
+  *            Eg, /var/spool/j/joeblow
+  *            Also, puts the dropfile in /var/spool/j/pop/.joeblow.pop
+  *
   * All these methods require that local mail delivery and client programs
   * use the same algorithm.  Only one method to a customer :-)
   */
***************
*** 200,207 ****
      return 1;
  }
  
! #endif
! #if (HASH_SPOOL == 2)
  
  int 
  genpath ( char *pszUser, char *pszDrop, int iDropLen, GNPH_WHICH iWhich,
--- 204,210 ----
      return 1;
  }
  
! #elif (HASH_SPOOL == 2) || (HASH_SPOOL == 3)
  
  int 
  genpath ( char *pszUser, char *pszDrop, int iDropLen, GNPH_WHICH iWhich,
***************
*** 224,240 ****
--- 227,255 ----
          return -1;
      }
      
+ #if (HASH_SPOOL == 3)
+     Qsprintf ( pszDrop, "%s/%c/",
+               (iWhich != GNPH_POP ? POP_MAILDIR : POP_DROP_DIR),
+               *pszUser);
+ #else
      Qsprintf ( pszDrop, "%s/%c/%c/", 
                (iWhich != GNPH_POP ? POP_MAILDIR : POP_DROP_DIR),
                *pszUser, 
                *(pszUser+1) ? *(pszUser+1) : *pszUser );
+ #endif
  
      switch ( iWhich ) {
          case GNPH_SPOOL:  /* spool file */
              strlcat ( pszDrop, pszUser, iDropLen );
              break;
          case GNPH_POP:    /* .pop file  */
+ #if (HASH_SPOOL == 3)
+             Qsprintf ( pszDrop, "%s/%c/pop/.%s.pop",
+               (iWhich != GNPH_POP ? POP_MAILDIR : POP_DROP_DIR),
+               *pszUser,pszUser);
+ #else
              Qsprintf ( pszDrop + strlen(pszDrop), POP_DROP, pszUser );
+ #endif
              break;
          case GNPH_TMP:    /* tmpxxxx    */
              strlcat ( pszDrop, POP_TMPDROP, iDropLen );
***************
*** 275,282 ****
      return 1;
  }
  
! #endif
! #if (HASH_SPOOL != 1 && HASH_SPOOL != 2)
  
  int 
  genpath ( char *pszUser, char *pszDrop, int iDropLen, GNPH_WHICH iWhich,
--- 290,296 ----
      return 1;
  }
  
! #else  /* end of HASH_SPOOL methods */
  
  int 
  genpath ( char *pszUser, char *pszDrop, int iDropLen, GNPH_WHICH iWhich,
diff -c 'qpopper3.1.2/config.h.in' 'qpopper3.2.2/config.h.in'
Index: ./config.h.in
*** ./config.h.in       Thu Oct 12 12:55:59 2000
--- ./config.h.in       Tue Nov 21 10:17:56 2000
***************
*** 164,169 ****
--- 164,178 ----
  /* Define if you have the <dbm.h> header file.  */
  #undef HAVE_DBM_H
  
+ /* Define if you have the <dce/dce_error.h> header file.  */
+ #undef HAVE_DCE_DCE_ERROR_H
+ 
+ /* Define if you have the <dce/rpc.h> header file.  */
+ #undef HAVE_DCE_RPC_H
+ 
+ /* Define if you have the <dce/sec_login.h> header file.  */
+ #undef HAVE_DCE_SEC_LOGIN_H
+ 
  /* Define if you have the <dirent.h> header file.  */
  #undef HAVE_DIRENT_H
  
***************
*** 282,287 ****
--- 291,308 ----
  /* Define if you want successful authentications to be logged */
  #undef LOG_LOGIN
  
+ /* Define if you use the "not authorized to use" (/etc/pop.nonauth) file */
+ #undef NONAUTHFILE
+ 
+ /* Define if you use the "authorized" file */
+ #undef AUTHFILE
+ 
+ /* Define if you use the load-limit mechanism to prevent high machine loads */
+ #undef LOADLIMIT
+ 
+ /* Define if you use DCE */
+ #undef DCE
+ 
  /* 
   * Define if you want to automatically delete RETRd messages.
   * Caution: This could cause lost mail.  Be sure users are
***************
*** 380,392 ****
  #undef SPEC_POP_AUTH
  
  /*
!  * Define and set to 1 or 2 to use hashed spool directories.  Value
   * 1 hashes the first 4 characters; value 2 uses /<1st letter>/
   * <2nd letter>.  For example, if the spool directory is "/var/mail", 
   * the spool file for user "maida" would be:
   *     /var/mail/maida          HASH_SPOOL not set
   *     /var/mail/o/maida        HASH_SPOOL=1
   *     /var/mail/m/a/maida      HASH_SPOOL=2
   */
  #undef HASH_SPOOL
  
--- 401,414 ----
  #undef SPEC_POP_AUTH
  
  /*
!  * Define and set to 1, 2, or 3 to use hashed spool directories.  Value
   * 1 hashes the first 4 characters; value 2 uses /<1st letter>/
   * <2nd letter>.  For example, if the spool directory is "/var/mail", 
   * the spool file for user "maida" would be:
   *     /var/mail/maida          HASH_SPOOL not set
   *     /var/mail/o/maida        HASH_SPOOL=1
   *     /var/mail/m/a/maida      HASH_SPOOL=2
+  *     /var/mail/m/maida        HASH_SPOOL=3 (first letter of userid)
   */
  #undef HASH_SPOOL
  
diff -c 'qpopper3.1.2/configure.in' 'qpopper3.2.2/configure.in'
Index: ./configure.in
*** ./configure.in      Sat Nov 11 21:37:21 2000
--- ./configure.in      Tue Nov 21 10:17:56 2000
***************
*** 440,449 ****
  fi
  
  
! AC_ARG_ENABLE(hash-spool, [ --enable-hash-spool=1|2  Enable hashed spool directories 
[2] ], 
                hashspool="$enableval", hashspool="no")
  if test "$hashspool" != "no"; then
!     if test "$hashspool" = "1" -o "$hashspool" = "2" ; then 
          AC_MSG_RESULT(Using hashed spool directory method $hashspool)
          AC_DEFINE_UNQUOTED(HASH_SPOOL, $hashspool)
      else  
--- 440,449 ----
  fi
  
  
! AC_ARG_ENABLE(hash-spool, [ --enable-hash-spool=1|2|3  Enable hashed spool 
directories [2] ], 
                hashspool="$enableval", hashspool="no")
  if test "$hashspool" != "no"; then
!     if test "$hashspool" = "1" -o "$hashspool" = "2" -o "$hashspool" = "3" ; then 
          AC_MSG_RESULT(Using hashed spool directory method $hashspool)
          AC_DEFINE_UNQUOTED(HASH_SPOOL, $hashspool)
      else  
***************
*** 512,517 ****
--- 512,575 ----
      AC_DEFINE(USE_BULL_GROUPS)
  fi
  
+ dnl---location of nonauthorized users file
+ AC_ARG_WITH(nonauth, [ --with-nonauth=path      Set the nonauthorized users file 
+path [/etc/pop.nonauth]],
+       nonauth=$withval, nonauth="no")
+ if test "$nonauth" != "no" ; then
+       if test -z "$nonauth" ; then
+               AC_MSG_RESULT(Nonauthorized users file /etc/pop.nonauth enabled)
+               AC_DEFINE_UNQUOTED(NONAUTHFILE,"/etc/pop.nonauth")
+       else
+               AC_MSG_RESULT(Nonauthorized users file $nonauth enabled)
+               AC_DEFINE_UNQUOTED(NONAUTHFILE,"$nonauth")
+       fi
+ fi
+ 
+ dnl---location of authorized users file
+ AC_ARG_WITH(auth, [ --with-auth=path    Set the authorized users file path 
+[/etc/pop.authorized]],
+       auth=$withval, auth="no")
+ if test "$auth" != "no" ; then
+       if test -z "$auth" ; then
+               AC_MSG_RESULT(Authorized users file /etc/pop.authorized enabled)
+               AC_DEFINE_UNQUOTED(AUTHFILE,"/etc/pop.authorized")
+       else
+               AC_MSG_RESULT(Authorized users file $auth enabled)
+               AC_DEFINE_UNQUOTED(AUTHFILE,"$auth")
+       fi
+ fi
+ 
+ dnl--- loadlimit feature enabled
+ AC_ARG_WITH(loadlimit, [ --with-loadlimit=load    Enable loadlimit feature 
+[default=16.0]], 
+       loadlimit="$withval", loadlimit="no")
+ if test "$loadlimit" != "no"; then
+       if test -z "$loadlimit" ; then
+               AC_MSG_RESULT(Using Loadlimit feature with maximum load = 16.0)
+       AC_DEFINE_UNQUOTED(LOADLIMIT, "16.0")
+       else
+               AC_MSG_RESULT(Using Loadlimit feature with maximum load = $loadlimit)
+       AC_DEFINE_UNQUOTED(LOADLIMIT, $loadlimit)
+       fi
+ fi
+ 
+ dnl--- DCE authentication support
+ AC_ARG_WITH(DCE, [ --with-DCE               Enable DCE authentication support], 
+       DCE="$withval", DCE="no")
+ if test "$DCE" != "no"; then
+       AC_MSG_RESULT(DCE authentication support enabled)
+       AC_DEFINE(DCE)
+       SYS_NAME="`uname -sr 2>/dev/null | sed 1q`"
+       if test -z "\$SYS_NAME"; then SYS_NAME=unknown;fi
+       OS_NAME="`echo $SYS_NAME 2>/dev/null | sed -e 's/[ ].*//'`"
+       OS_VERSION="`echo $SYS_NAME 2>/dev/null | sed -e 's/.*[ ]//'`"
+       AC_MSG_RESULT(System name: $OS_NAME; System version: $OS_VERSION)
+       if test $OS_NAME = "HP-UX"; then
+               AC_MSG_RESULT(HPUX and DCE detected must use HP C compiler)
+               CC="cc"
+               AC_SUBST(CC)
+               CFLAGS="-Ae +O4 +ESlit"
+               AC_SUBST(CFLAGS)
+       fi
+ fi
  
  AC_ARG_WITH(kerberos5, [ --with-kerberos5=dir     Enable Kerberos 5 support],
             krb5_prefix=${withval},krb5_prefix="no")
***************
*** 944,949 ****
--- 1002,1010 ----
  select.h \
  shadow.h \
  security/pam_appl.h \
+ dce/rpc.h \
+ dce/sec_login.h \
+ dce/dce_error.h \
  )
  
  
***************
*** 954,959 ****
--- 1015,1021 ----
  AC_CHECK_LIB(resolv, res_init, NETWORK_LIBS="$NETWORK_LIBS -lresolv")
  AC_CHECK_LIB(mail, maillock, NETWORK_LIBS="$NETWORK_LIBS -lmail"; 
AC_DEFINE(SYS_MAILLOCK))
  AC_CHECK_LIB(krb, krb_recvauth, KERBEROS_LIBS="$KERBEROS_LIBS -lkrb")
+ AC_CHECK_LIB(dce, sec_login_setup_identity, DCE_LIBS="-ldce")
  AC_CHECK_LIB(posix4, clock_gettime, LIBS="$LIBS -lposix4"; 
AC_DEFINE(HAVE_CLOCK_GETTIME))
  
  AC_CHECK_LIB(security, set_auth_parameters, LIBS="$LIBS -lsecurity")
***************
*** 1007,1012 ****
--- 1069,1075 ----
  
  AC_SUBST(NETWORK_LIBS)
  AC_SUBST(KERBEROS_LIBS)
+ AC_SUBST(DCE_LIBS)
  AC_SUBST(DBM_LIBS)
  AC_SUBST(LIBS)
  
diff -c 'qpopper3.1.2/doc/Changes' 'qpopper3.2.2/doc/Changes'
Index: ./doc/Changes
*** ./doc/Changes       Sun Nov 12 19:19:53 2000
--- ./doc/Changes       Tue Nov 21 10:17:56 2000
***************
*** 4,9 ****
--- 4,65 ----
  
  This document contains the changes since the last release.
  
+ Changes from 3.1 to 3.2
+ ---------------------------
+ 
+  1.  Configuration options fail on HPUX 11.0 when --with-pam is
+      used due to reference to -ldl library in configure.in.
+      Removed references to -ldl in configure.in.
+  2.  Compilation of popper/pop_pass.c fails on HPUX 11.0 when
+      --with-pam is used, because non-pam version of auth_user()
+      is not hidden by cpp directives.
+  3.  A third hash_spooling mechanism is added.  The first character
+      of the userid is used as a subdirectory within the spooldir
+      for the location of the mailbox.  The pop dropfile goes in
+      the "pop" subdirectory therein.  So for user "joeblow" and
+      a spool directory of "/var/mail", the mailbox is located at
+         /var/mail/j/joeblow
+      and the dropfile is located at:
+         /var/mail/j/pop/.joeblow.pop
+  4.  Configure-time options added to configure.in for features already
+      in the code, but not in the configure options.  These are:
+         --with-nonauth=path      Set the nonauthorized users file path.
+                                  Default is /etc/pop.nonauth.
+         --with-auth=path         Set the authorized users file path.
+                                  Default is  /etc/pop.authorized.
+      The appropriate defines for these were added to config.h.in.
+  5.  Added a loadlimit mechanism, to prevent qpopper connections if
+      the system load is above a system-configurable value.  Added
+      a configure option (--with-loadlimit=load), and code in popper.c
+      to enable this for systems that use getloadavg(3) (eg, Solaris)
+      and for HPUX 10.x/11.x systems.  Loadlimit feature is available 
+      as a run-time controllable feature via the "-l [load]" command-line
+      option; provided that --with-loadlimit=load is specified at
+      configure time.  The "load" number is a floating point number
+      representing the one-minute-average load above which you want to
+      refuse connections.  This feature needs code for other types of
+      UNIX.
+  6.  Changed the message for nonauthorized users to *tell* them they
+      are not authorized, instead of the usual vague message.  For use
+      with AUTHFILE and NONAUTHFILE macros.
+  7.  Fixed a bug in pop_init.c, where p->debug and p->stats were not
+      initialized before being used in the getopts loop.
+  8.  Added a timecheck in pop_pass.c to keep people from repeatedly
+      checking email.  Only works if KEEP_TEMP_DROP is defined.  Checks
+      the timestamp on the saved dropfile against the current time -- if
+      the difference in times is less than a specified number of seconds,
+      then the connection is rejected before authentication.  The minimum
+      timecheck interval is specifed via the run-time flag "-a integer",
+      where the integer is the minimum number of seconds allowed between
+      mail checks.
+      This feature required the addition of a touch_file() call in 
+      unlink_temp_drop(), to update the access times on dropfile if
+      KEEP_TEMP_DROP is defined.  This updates the timestamps on the
+      dropfile whenever the user authenticates -- even if nothing else
+      happened with his email.
+  9.  Added DCE authentication support.  Known to work on HP 10.20 and
+      11.0 systems.  May work on other DCE platforms.  Enable via
+      configuration using --with-DCE.
  
  Changes from 3.1.1 to 3.1.2
  ---------------------------
diff -c 'qpopper3.1.2/popper/Makefile.in' 'qpopper3.2.2/popper/Makefile.in'
Index: ./popper/Makefile.in
*** ./popper/Makefile.in        Wed Nov  8 19:21:24 2000
--- ./popper/Makefile.in        Tue Nov 21 10:17:56 2000
***************
*** 76,83 ****
                        pop_user.o pop_xtnd.o pop_xmit.o popper.o \
                        pop_bull.o xtnd_xlst.o pop_uidl.o mktemp.o \
                        pop_rpop.o pop_apop.o md5.o pop_auth.o pop_pope.o \
!                         pop_extend.o scram.o hmac.o base64.o pop_util.o \
!                         get_sub_opt.o msg_ptr.o drac.o pop_config.o main.o
  
  SRCS          =       pop_dele.c pop_dropcopy.c \
                        pop_get_command.c pop_get_subcommand.c pop_init.c \
--- 76,84 ----
                        pop_user.o pop_xtnd.o pop_xmit.o popper.o \
                        pop_bull.o xtnd_xlst.o pop_uidl.o mktemp.o \
                        pop_rpop.o pop_apop.o md5.o pop_auth.o pop_pope.o \
!                       pop_extend.o scram.o hmac.o base64.o pop_util.o \
!                       pop_authdce.o dce_pwent.o \
!                       get_sub_opt.o msg_ptr.o drac.o pop_config.o main.o
  
  SRCS          =       pop_dele.c pop_dropcopy.c \
                        pop_get_command.c pop_get_subcommand.c pop_init.c \
***************
*** 87,94 ****
                        pop_user.c pop_xtnd.c pop_xmit.c popper.c \
                        pop_bull.c xtnd_xlst.c pop_uidl.c mktemp.c \
                        pop_rpop.c pop_apop.c md5.c pop_auth.c pop_pope.c \
!                         pop_extend.c scram.c hmac.c base64.c pop_util.c \
!                         get_sub_opt.c msg_ptr.c drac.c pop_config.c main.c
  
  POPAUTHOBJS     =       base64.o scram.o md5.o \
                        hmac.o popauth.o
--- 88,96 ----
                        pop_user.c pop_xtnd.c pop_xmit.c popper.c \
                        pop_bull.c xtnd_xlst.c pop_uidl.c mktemp.c \
                        pop_rpop.c pop_apop.c md5.c pop_auth.c pop_pope.c \
!                       pop_extend.c scram.c hmac.c base64.c pop_util.c \
!                       pop_authdce.c dce_pwent.c \
!                       get_sub_opt.c msg_ptr.c drac.c pop_config.c main.c
  
  POPAUTHOBJS     =       base64.o scram.o md5.o \
                        hmac.o popauth.o
***************
*** 113,119 ****
  NETWORK_LIBS  =       @NETWORK_LIBS@
  KERBEROS_LIBS =       @KERBEROS_LIBS@
  DBM_LIBS      =       @DBM_LIBS@
! LIBS          =       @NETWORK_LIBS@ @KERBEROS_LIBS@ @DBM_LIBS@ @LIBS@
  AR_FLAG         =       @AR_FLAG@
  RANLIB_CMD      =       @RANLIB_CMD@
  
--- 115,122 ----
  NETWORK_LIBS  =       @NETWORK_LIBS@
  KERBEROS_LIBS =       @KERBEROS_LIBS@
  DBM_LIBS      =       @DBM_LIBS@
! DCE_LIBS    =   @DCE_LIBS@
! LIBS          =       @NETWORK_LIBS@ @KERBEROS_LIBS@ @DBM_LIBS@ @LIBS@ @DCE_LIBS@
  AR_FLAG         =       @AR_FLAG@
  RANLIB_CMD      =       @RANLIB_CMD@
  
diff -c /dev/null 'qpopper3.2.2/popper/dce_pwent.c'
Index: ./popper/dce_pwent.c
*** ./popper/dce_pwent.c        Wed Dec 31 19:00:00 1969
--- ./popper/dce_pwent.c        Tue Nov 21 10:17:56 2000
***************
*** 0 ****
--- 1,271 ----
+ /*
+  *  Contributed by Jeff Earickson, Colby College, Waterville, ME
+  *  ([EMAIL PROTECTED])
+  *
+  *  The code below basically comes from the examples supplied on
+  *  the OSF DCE 1.0.3 manpages for the sec_login routines, with
+  *  enough additional polishing to make the routine work correctly.
+  *
+  *  This code is known to work on HP 700 and 800 series systems
+  *  running HP-UX 9.X and 10.X, with either HP's version 1.2.1 of DCE.
+  *  (aka, OSF DCE 1.0.3) or with HP's version 1.4 of DCE (aka, OSF
+  *  DCE 1.1).
+  *
+  *  Use at your own risk!!!  (But I would like to hear about bugs.)
+ */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #ifdef DCE
+ 
+ #include <stdio.h>
+ /* #include <string.h> */
+ #include <signal.h>
+ #include <setjmp.h>
+ #include <pwd.h>
+ #include "popper.h"
+ #include <dce/rpc.h>
+ #include <dce/sec_login.h>
+ #include <dce/dce_error.h> /* required to call dce_error_inq_text routine   */
+ 
+ /* global variables */
+ static int                error_stat;
+ static unsigned char      error_string[dce_c_error_string_len];
+ jmp_buf                   dcejump;        /* stack for setjmp/longjmp herein */
+ sec_login_handle_t        login_context;    /* DCE login context */
+ 
+ void dcetimeout()
+ {
+     error_status_t        status;
+ 
+     sec_login_purge_context( &login_context, &status );
+     longjmp( dcejump, 1 );
+ }
+ 
+ int dce_auth_time(p, errormsg, timeout)
+ /* returns 1 ("true") if user is a valid DCE principal, 0 otherwise */
+ /* cleans up and exits if DCE times out */
+ POP *p;
+ char *errormsg;
+ int timeout;
+ {
+     int retcode;
+ 
+     /* prepare to catch the signal for DCE timeout */
+     (void) signal(SIGALRM, dcetimeout);
+ 
+     /* now set the DCE timeout alarm */
+     alarm(timeout);
+ 
+     DEBUG_LOG1 ( p, "dce_auth_time: signal alarm set for %d sec\n", timeout);
+ 
+     /* set retcode to failure if alarm went off */
+     /* before the dce_pwent() call finished */
+     /* time to die... */
+     if(setjmp(dcejump))
+     {
+         DEBUG_LOG0 (p, "dce_auth_time: returning from longjmp\n" );
+         pop_msg(p,POP_FAILURE, HERE,
+             "[AUTH] DCE Authentication Timeout for %s", p->user );
+         closelog();
+         exit(-1);
+     }
+     else
+     {
+         DEBUG_LOG0 (p, "dce_auth_time: before dce_pwent\n" );
+         retcode = dce_pwent(p, errormsg);
+         DEBUG_LOG0 (p, "dce_auth_time: after dce_pwent\n" );
+     }
+ 
+     /* turn off the alarm and reset SIGALRM */
+     alarm(0);
+     (void) signal(SIGALRM,SIG_DFL);
+ 
+     DEBUG_LOG0 (p, "dce_auth_time: signal and alarm turned off\n" );
+ 
+     return retcode;
+ }
+ 
+ int dce_pwent(p, errormsg)
+ /* returns 1 ("true") if user is a valid DCE principal, 0 otherwise */
+ POP *p;
+ char *errormsg;
+ {
+     struct passwd        *pwd;
+     sec_passwd_rec_t      password_rec;
+     boolean32             reset_passwd;
+     sec_login_auth_src_t  auth_src;
+     error_status_t        status;
+     unsigned32            nbytes;
+     char                 *tmppass;
+ 
+     /* create the local context of the DCE principal necessary   */
+     /* to perform authenticated network operations. The network  */
+     /* identity set up by this operation cannot be used until it */
+     /* is validated via sec_login_validate_identity(). */
+     if ( sec_login_setup_identity((unsigned_char_p_t) p->user,
+         sec_login_no_flags, &login_context,&status))
+     {
+         if ( check( p, status, "sec_login_setup_identity(1):")) 
+         {
+             strcpy( errormsg, (const char *) error_string );
+             return( 0 );
+         }
+ 
+         /* note that contents of passwd are trashed after DCE */
+         /* so we need to make a local copy of it for use here */
+         /* malloc space for passwd structure */
+         nbytes = strlen( p->pop_parm[1] ) + 1;
+         if ( (tmppass = (char *) malloc(nbytes)) == NULL )
+         {
+             strcpy( errormsg,p->user );
+             strcat( errormsg,": malloc for tmppass failed." );
+             return(0);
+         }
+         strcpy( tmppass,p->pop_parm[1] );
+ 
+         password_rec.key.tagged_union.plain = (idl_char *) tmppass;
+         password_rec.key.key_type = sec_passwd_plain;
+         password_rec.pepper = NULL;
+         password_rec.version_number = sec_passwd_c_version_none;
+ 
+         /* validate the login context with the password */
+         if (sec_login_validate_identity( login_context, &password_rec,
+             &reset_passwd,&auth_src,&status))
+         {
+             if ( check( p, status, "sec_login_validate_identity(1):")) 
+             {
+                 strcpy( errormsg, (const char *) error_string );
+                 return(0);
+             }
+ 
+             /* Certify that the DCE Security Server used to set      */
+             /* up and validate a login context is legitimate.  Makes */
+             /* sure that we didn't get spoofed by another DCE server.*/
+             if ( !sec_login_certify_identity( login_context, &status))
+             {
+                 /* fprintf(stderr,"Whoa! Bogus authentication server!\n"); */
+                 (void) check( p, status, "sec_login_certify_identity(1):"); 
+                 strcpy( errormsg, (const char *) error_string );
+                 return(0);
+             }
+             if ( check( p, status, "sec_login_certify_identity(2):")) 
+             {
+                 strcpy( errormsg,(const char *) error_string );
+                 return(0);
+             }
+ 
+             /* sets the network credentials to those specified */
+             /* by the now validated login context. */
+             sec_login_set_context( login_context, &status );
+             if ( check( p, status, "sec_login_set_context:")) 
+             {
+                 strcpy( errormsg,(const char *) error_string );
+                 return(0);
+             }
+ 
+             /* oops, your credentials were no good. Possibly   */
+             /* caused by clock times out of adjustment between */
+             /* DCE client and DCE security server...           */
+             if ( auth_src != sec_login_auth_src_network )
+             {
+                 /* fprintf(stderr,"You have no network credentials\n"); */
+                 strcpy( errormsg, p->user );
+                 strcat( errormsg, " has no network credentials." );
+                 return(0);
+             }
+             /* check if the password has aged and is no good */
+             if ( reset_passwd )
+             {
+                 /* fprintf(stderr,"Your DCE password needs resetting\n"); */
+                 strcpy( errormsg, p->user );
+                 strcat( errormsg, " has an invalid password." );
+                 return(0);
+             }
+ 
+ #ifdef UNNEEDED
+             /* malloc space for passwd structure */
+             nbytes = sizeof(struct passwd);
+             if ( (pwd = (struct passwd *) malloc(nbytes)) == NULL )
+             {
+                 /* fprintf(stderr,"malloc for passwd struct failed\n"); */
+                 strcpy(errormsg, p->user);
+                 strcat(errormsg, ": malloc for passwd struct failed.");
+                 return(0);
+             }
+ 
+             /* we should be a valid user by this point.  Pull the */
+             /* user's password structure from the DCE security    */
+             /* server just to make sure.  If we get it with no    */
+             /* problems, then we really are legitimate...         */
+             sec_login_get_pwent(login_context,(sec_login_passwd_t) pwd,&status);
+             free(pwd);
+             if ( check(p,status,"sec_login_get_pwent:") ) 
+             {
+                 strcpy( errormsg,(const char *) error_string );
+                 return(0);
+             }
+ #endif /* UNNEEDED */
+ 
+             /************************************************************/
+             /* if we get to here, then the pwent above properly fetched */
+             /* the password structure from the DCE registry, so the user*/
+             /*  must be valid.  We don't really care what the user's    */
+             /* registry password is, just that the user could be        */
+             /* validated.  In fact, if we tried to compare the local    */
+             /* password to the DCE entry at this point, the operation   */
+             /* would fail if the hidden password feature is turned on,  */
+             /* because the password field would contain an asterisk.    */
+             /*   Also go ahead and destroy the user's DCE login context */
+             /* before we leave here (and don't bother checking the      */
+             /* status), in order to clean up credentials files in       */
+             /* /opt/dcelocal/var/security/creds.  By doing this, we are */
+             /* assuming that the user will not need DCE authentication  */
+             /* later in the program, only local authentication.  If this*/
+             /* is not true, then the login_context will have to be      */
+             /* returned to the calling program, and the context purged  */
+             /* somewhere later in the program.                          */
+             /************************************************************/
+             sec_login_purge_context( &login_context , &status );
+             errormsg = NULL;
+             return(1);
+         }
+         else
+         {
+             if ( check( p, status, "sec_login_validate_identity(2):")) 
+             {
+                 strcpy( errormsg, (const char *) error_string );
+                 return(0);
+             }
+             sec_login_purge_context( &login_context, &status );
+             if ( check( p, status, "sec_login_purge_context:"))
+             {
+                 strcpy( errormsg, (const char *) error_string );
+                 return(0);
+             }
+         }
+         free(tmppass);
+     }
+     if ( check( p, status, "sec_login_setup_identity(2):") )
+     {
+         strcpy( errormsg, (const char *) error_string );
+         return(0);
+     }
+     return(0);
+ }
+ 
+ int check(p,input_status, comment) 
+ /* returns 0 for DCE "ok" status, 1 otherwise */
+ POP *p;
+ error_status_t input_status;
+ char *comment;
+ { 
+     if ( input_status == rpc_s_ok ) return(0);
+     dce_error_inq_text( input_status, error_string, &error_stat ); 
+     DEBUG_LOG2 ( p, "DCE: %s %s",comment,error_string);
+     return(1);
+ }
+ 
+ #endif /* DCE */
diff -c /dev/null 'qpopper3.2.2/popper/pop_authdce.c'
Index: ./popper/pop_authdce.c
*** ./popper/pop_authdce.c      Wed Dec 31 19:00:00 1969
--- ./popper/pop_authdce.c      Tue Nov 21 10:17:56 2000
***************
*** 0 ****
--- 1,92 ----
+ /*
+  *  DCE Authentication mechanism for Qpopper
+  *  Contributed by Jeff Earickson, Colby College, Waterville, ME
+  *  ([EMAIL PROTECTED])
+  *
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #ifdef DCE
+ 
+ #include <pwd.h>
+ #include <crypt.h>
+ #ifdef SYSV
+ #include <string.h>
+ #else
+ #include <strings.h>
+ #endif
+ #include <stdio.h>
+ 
+ #define DCE_TIMEOUT 60  /* timeout on DCE authentication after this secs */
+ #define PASSWD_OVERRIDE "/opt/dcelocal/etc/passwd_override"
+ 
+ int use_dce_passwd;
+ 
+ #include "popper.h"
+ 
+ char *crypt();
+ 
+ int auth_user_dce (p)
+ POP *p;
+ {
+     FILE *fd;
+     struct passwd *pw;
+     char errormsg[MAXMSGLINELEN];
+ 
+     DEBUG_LOG1 ( p, "Looking in %s.", PASSWD_OVERRIDE);
+ 
+     /* first look in the passwd_override file */
+     if ((fd = fopen(PASSWD_OVERRIDE, "r")) == NULL )
+     {
+         return (pop_msg( p, POP_FAILURE, HERE,
+             "DCE: Cannot open %s.", PASSWD_OVERRIDE));
+     }
+ 
+     use_dce_passwd = 0;
+ 
+     /* Look for the user in password_override file */
+     while(( pw = fgetpwent(fd)) != NULL )
+     {
+         if ( strcmp(p->user, pw->pw_name) == 0 ) break;
+     }
+ 
+     /* if the password structure is NULL then we hit EOF */
+     /* if the password field is not 13 characters long,  */
+     /* then it is not an encrypted password field, so    */
+     /* close the file and move on */
+     if ( pw == NULL || strlen(pw->pw_passwd) != 13 )
+     {
+         fclose(fd);
+     }
+     /* the password field is good so spend the CPU cycles */
+     /* to encrypt it and see if the entered pw is valid.. */
+     else
+     {
+         if ( strcmp( crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd) == 0 )
+         {
+             use_dce_passwd = 1;
+             fclose(fd);
+             return(POP_SUCCESS);
+         }
+         else
+         {
+             fclose(fd);
+         }
+     }
+ 
+     DEBUG_LOG0 ( p, "Consulting DCE Registry." );
+ 
+     /* then go ask the DCE registry */
+     if ( dce_auth_time(p, errormsg, DCE_TIMEOUT) == 1 )
+     {
+         use_dce_passwd = 1;
+         return(POP_SUCCESS);
+     }
+ 
+     /* if we get to here then everything failed */
+     return(pop_msg(p, POP_FAILURE, HERE, "DCE: \"%s\"",errormsg));
+ }
+ #endif /* DCE */
diff -c 'qpopper3.1.2/popper/pop_init.c' 'qpopper3.2.2/popper/pop_init.c'
Index: ./popper/pop_init.c
*** ./popper/pop_init.c Sat Sep 30 23:54:41 2000
--- ./popper/pop_init.c Tue Nov 21 10:17:56 2000
***************
*** 431,436 ****
--- 431,438 ----
       * Note that we zeroed the block above, so we really only need to
       * set any desired non-zero/non-NULL values.
       */
+     p->debug               = 0;
+     p->stats               = 0;
      p->msgs_deleted        = 0;
      p->last_msg            = 0;
      p->bytes_deleted       = 0;
***************
*** 444,449 ****
--- 446,452 ----
      p->kerberos            = FALSE;
      p->AllowClearText      = ClearTextDefault;
      p->check_lock_refresh  = 5000; /* just a wild guess */
+     p->min_access_time     = 0;
  
  #ifdef  KERBEROS
      p->kerberos_service    = KERBEROS_SERVICE;
***************
*** 467,472 ****
--- 470,478 ----
      expire                 = 0;
  #endif /* AUTO_DELETE */
  
+ #ifdef LOADLIMIT
+     p->loadlimit      = (double) LOADLIMIT;
+ #endif /* LOADLIMIT */
  
      StackInit ( & ( p->InProcess ) );
      
***************
*** 487,495 ****
      /*  
       * Process command line arguments 
       */
!     while ( ( c = getopt ( argcount, argmessage, "b:BcdD:e:f:kK:L:p:RsSt:T:u") ) != 
EOF )
          switch ( c ) {
  
          /* Bulletins requested */
          case 'b':
              p->bulldir = optarg;
--- 493,510 ----
      /*  
       * Process command line arguments 
       */
!     while ( ( c = getopt ( argcount, argmessage, "a:b:BcdD:e:f:kK:l:L:p:RsSt:T:u") ) 
!= EOF )
          switch ( c ) {
  
+ #ifdef KEEP_TEMP_DROP
+         /* minimum access time */
+         case 'a':
+             p->min_access_time = atoi(optarg);
+             DEBUG_LOG1 ( p, "minimum access time = %s seconds",
+                          p->min_access_time );
+             break;
+ #endif /* KEEP_TEMP_DROP */
+ 
          /* Bulletins requested */
          case 'b':
              p->bulldir = optarg;
***************
*** 569,574 ****
--- 584,598 ----
                           p->kerberos_service );
              break;
  #endif  /* KERBEROS */
+ 
+ #ifdef LOADLIMIT
+         /*  Define the max on-minute load average for connections */
+         case 'l':
+             p->loadlimit = atof(optarg);
+             DEBUG_LOG1 ( p, "Max one-minute load average = %f",
+                          p->loadlimit );
+             break;
+ #endif /* LOADLIMIT */
  
          /*  Touch the mail lock every this many messages (crude)  */
          case 'L':
diff -c 'qpopper3.1.2/popper/pop_pass.c' 'qpopper3.2.2/popper/pop_pass.c'
Index: ./popper/pop_pass.c
*** ./popper/pop_pass.c Sun Nov 12 19:18:07 2000
--- ./popper/pop_pass.c Tue Nov 21 12:40:39 2000
***************
*** 125,132 ****
--- 125,140 ----
  #  define   CHECK_SP_MAX    TRUE
  #endif /* DONT_CHECK_SP_MAX */
  
+ #ifdef KEEP_TEMP_DROP
+ #include "genpath.h"
+ #endif /* KEEP_TEMP_DROP */
+ 
  #define SLEEP_SECONDS 10
  
+ #ifdef DCE
+ extern int use_dce_passwd;
+ #endif
+ 
  /* This error message is vague on purpose to help improve
     security at the inconvience of administrators and users */
  
***************
*** 676,682 ****
  
  
  /*----------------------------------------------- POPSCO or HPUX */
! #    if defined(POPSCO) || defined(HPUX)
  
  #      ifdef POPSCO
  #        include <sys/security.h>
--- 684,690 ----
  
  
  /*----------------------------------------------- POPSCO or HPUX */
! #  if !defined(USE_PAM) && (defined(POPSCO) || defined(HPUX))
  
  #      ifdef POPSCO
  #        include <sys/security.h>
***************
*** 1117,1122 ****
--- 1125,1177 ----
  
  #endif  /* SPEC_POP_AUTH */
  
+ #ifdef KEEP_TEMP_DROP
+ int pop_accesstime(p)
+ POP *p;
+ /* check time since last POP access, as measured by */
+ /* the timestamp on the POP_DROP file.  Returns one */
+ /* if enough time has passed (or no drop file) or   */
+ /* or zero if minimum time has not elapsed... */
+ {
+     struct stat buf;
+     time_t now, diff;
+ 
+     /* if the min_access_time is defined as zero */
+     /* then it was not set by the user, return   */
+     if ( p->min_access_time == 0 ) return(1);
+ 
+       /* figure out what the dropfile is */
+     if ( genpath ( p->user, 
+                    p->temp_drop, 
+                    sizeof(p->temp_drop),
+                    GNPH_POP,
+                    (p->debug ? p->trace : NULL),
+                    p->debug ) < 0 )
+         return ( pop_msg ( p, POP_FAILURE, HERE,
+                            "[SYS/TEMP] Unable to get temporary drop name" ) );
+ 
+     DEBUG_LOG1 ( p, "accesstime: Temporary maildrop is '%s'", p->temp_drop );
+ 
+     /* if no pop_drop file then go on */
+     if ( stat(p->temp_drop,&buf) != 0 )
+     {
+       return(1);
+     }
+     
+     /* get the current time */
+     now = time(NULL);
+ 
+     /* difference in times in seconds */
+       /* since last access time */
+     diff = (now - buf.st_atime);
+ 
+     DEBUG_LOG3 ( p, "Last access of %s was %d seconds, min access time is %d",
+         p->temp_drop, diff, p->min_access_time );
+ 
+     return(( diff < p->min_access_time ) ? 0 : 1 );
+ }
+ 
+ #endif /* KEEP_TEMP_DROP */
  
  /* 
   *  pass:   Obtain the user password from a POP client
***************
*** 1161,1167 ****
          DEBUG_LOG2 ( p, "User %.128s in nonauthfile %.256s",
                       p->user, NONAUTHFILE );
          sleep  ( SLEEP_SECONDS );
!         return ( pop_msg ( p, POP_FAILURE, HERE, ERRMSG_PW, p->user ) );
      }
  #endif /* NONAUTHFILE */
  
--- 1216,1224 ----
          DEBUG_LOG2 ( p, "User %.128s in nonauthfile %.256s",
                       p->user, NONAUTHFILE );
          sleep  ( SLEEP_SECONDS );
!         return ( pop_msg ( p, POP_FAILURE, HERE,
!                           "[AUTH] %s not authorized to use POP",
!                           p->user ) );
      }
  #endif /* NONAUTHFILE */
  
***************
*** 1173,1179 ****
          DEBUG_LOG2 ( p, "User %.128s not in authfile %.256s",
                       p->user, AUTHFILE );
          sleep  ( SLEEP_SECONDS );
!         return ( pop_msg ( p, POP_FAILURE, HERE, ERRMSG_PW, p->user ) );
      }
  #endif /* AUTHFILE */
  
--- 1230,1238 ----
          DEBUG_LOG2 ( p, "User %.128s not in authfile %.256s",
                       p->user, AUTHFILE );
          sleep  ( SLEEP_SECONDS );
!         return ( pop_msg ( p, POP_FAILURE, HERE,
!                           "[AUTH] %s not authorized to use POP",
!                           p->user ) );
      }
  #endif /* AUTHFILE */
  
***************
*** 1279,1293 ****
--- 1338,1371 ----
      }
  #endif /* CHECK_SHELL */
  
+ #ifdef KEEP_TEMP_DROP
+       /*
+       /* if user has accessed pop within MIN_ACCESS_TIME
+       /* as defined by mtime on their POP_DROP file then
+       /* deny access...
+       */
+       if(!pop_accesstime(p))
+       {
+               return(pop_msg(p, POP_FAILURE, HERE,
+                       "[AUTH] %s: you just checked your mail!",p->user));
+       }
+ #endif /* KEEP_TEMP_DROP */
+ 
+ #ifdef DCE
+     if (auth_user_dce(p) != POP_SUCCESS
+ #else
      if ( ( p->kerberos ? auth_user_kerberos ( p, pwp ) 
                         : auth_user          ( p, pwp ) 
           ) != POP_SUCCESS 
+ #endif /* DCE */
         ) {
          pop_log ( p, POP_PRIORITY, HERE,
                   "[AUTH] Failed attempted login to %s from host (%s) %s",
                    p->user, p->client, p->ipaddr );
          free   ( pw.pw_dir );
+ #ifndef DCE
          sleep  ( SLEEP_SECONDS );
+ #endif /* DCE */
          return ( POP_FAILURE );
      }
  
***************
*** 1369,1377 ****
--- 1447,1470 ----
       */
  
  #ifdef LOG_LOGIN
+ #if defined(DCE)
+     if(use_dce_passwd == 1)
+     {
+         pop_log( p, POP_PRIORITY, HERE,
+              "(v%s) %s DCE authenticated from %s (%s)",
+               VERSION, p->user, p->client, p->ipaddr );
+     }
+     else
+     {
+         pop_log( p, POP_PRIORITY, HERE,
+               "(v%s) %s authenticated from %s (%s)",
+               VERSION, p->user, p->client, p->ipaddr );
+     }
+ #else
      pop_log ( p, POP_PRIORITY, HERE,
                "(v%s) POP login by user \"%s\" at (%s) %s",
                VERSION, p->user, p->client, p->ipaddr );
+ #endif /* DCE */
  #endif /* LOG_LOGIN */
  
  #ifdef DRAC_AUTH
diff -c 'qpopper3.1.2/popper/pop_updt.c' 'qpopper3.2.2/popper/pop_updt.c'
Index: ./popper/pop_updt.c
*** ./popper/pop_updt.c Thu Aug 17 21:27:26 2000
--- ./popper/pop_updt.c Tue Nov 21 10:17:57 2000
***************
*** 112,117 ****
--- 112,120 ----
  unlink_temp_drop ( POP *p, char *filename, const char *fn, size_t ln )
  {
  #ifdef  KEEP_TEMP_DROP
+     /* update the access time, no matter what */
+     /* this shows the last time user checked mail */
+     touch_file ( filename, p->trace );
      DEBUG_LOG3 ( p, "KEEP_TEMP_DROP set [%s:%lu]; temp drop (%s) not unlinked",
                   fn, ln, filename );
  #else   /* not KEEP_TEMP_DROP */
diff -c 'qpopper3.1.2/popper/popper.c' 'qpopper3.2.2/popper/popper.c'
Index: ./popper/popper.c
*** ./popper/popper.c   Mon Aug 21 18:58:47 2000
--- ./popper/popper.c   Tue Nov 21 10:17:57 2000
***************
*** 77,82 ****
--- 77,92 ----
  #  endif
  #endif /* SPEC_POP_AUTH */
  
+ #if defined(LOADLIMIT)
+ #if defined(SOLARIS2)
+ #include <sys/loadavg.h>
+ #endif /* SOLARIS2 */
+ #if defined(HPUX)
+ #include <sys/param.h>
+ #include <sys/pstat.h>
+ #endif /* HPUX */
+ #endif /* LOADLIMIT */
+ 
  #include "popper.h"
  #include "misc.h"
  
***************
*** 152,159 ****
      if ( pop_init ( &p, argc, argv ) != POP_SUCCESS )
          EXIT ( 1 );
  
  /*  
!  * Tell the user that we are listenting 
   */
      { /* local env */
      char                myname [ 128 ];
--- 162,181 ----
      if ( pop_init ( &p, argc, argv ) != POP_SUCCESS )
          EXIT ( 1 );
  
+ #if defined(LOADLIMIT)
+     /* if the system load too high, die now */
+     if(system_load(&p) != 0)
+     {
+         pop_msg( &p,POP_FAILURE, HERE,
+             "Sorry, POP server load too high (%g), try later...",
+             p.loadlimit);
+         closelog();
+         exit(-1);
+     }
+ #endif /* LOADLIMIT */
+ 
  /*  
!  * Tell the user that we are listening 
   */
      { /* local env */
      char                myname [ 128 ];
***************
*** 299,304 ****
--- 321,363 ----
      closelog();
      return ( 0 );
  }
+ 
+ #if defined(LOADLIMIT)
+ int system_load(p)
+ POP *p;
+ /* is the one-minute system load higher than we want? */
+ {
+     double one_min_load_avg;
+ 
+ #if defined(SOLARIS2)
+     /* specific to Solaris */
+     double loadavg[3];
+ 
+     if(getloadavg(loadavg, 3) == -1)
+     {
+         perror("getloadavg");
+         exit(1);
+     }
+     one_min_load_avg = loadavg[LOADAVG_1MIN];
+ #endif /* SOLARIS2 */
+ 
+ #if defined(HPUX)
+     /* components specific to an HP 10.x or 11.x system */
+     struct pst_dynamic psd;
+ 
+     if(pstat_getdynamic(&psd, sizeof(psd),(size_t)1, 0) == -1)
+     {
+         perror("pstat_dynamic");
+         exit(1);
+     }
+     one_min_load_avg = psd.psd_avg_1_min;
+ #endif /* HPUX */
+ 
+     DEBUG_LOG2 (p, "Checking load limit, load = %g, limit = %g",
+                 one_min_load_avg, p->loadlimit);
+     return(( one_min_load_avg > p->loadlimit ) ? 1 : 0 );
+ }
+ #endif /* LOADLIMIT */
  
  jmp_buf env;
  
diff -c 'qpopper3.1.2/popper/popper.h' 'qpopper3.2.2/popper/popper.h'
Index: ./popper/popper.h
*** ./popper/popper.h   Fri Sep 29 18:39:53 2000
--- ./popper/popper.h   Tue Nov 21 10:17:57 2000
***************
*** 528,533 ****
--- 528,537 ----
  #endif /* DRAC_AUTH */
  
      BOOL                user_opts;              /* process ~/.qpopper-options ? */
+     int                 min_access_time;        /* min time between accesses */
+ #ifdef LOADLIMIT
+     double              loadlimit;              /* max allowed load limit */
+ #endif /* LOADLIMIT */
  };
  
  typedef enum { HANGUP,  /* SIGHUP */ 
diff -c 'qpopper3.1.2/popper/version.h' 'qpopper3.2.2/popper/version.h'
Index: ./popper/version.h
*** ./popper/version.h  Sun Nov 12 19:18:47 2000
--- ./popper/version.h  Tue Nov 21 10:24:32 2000
***************
*** 13,21 ****
   *  Current version of Qpopper
   */
  
! #define VERS_NUM          "3.1.2"
  
! #ifdef KERBEROS
  #  ifdef KRB4
  #    define VERS_SUF1     "-krb-IV"
  #  endif /* KRB4 */
--- 13,23 ----
   *  Current version of Qpopper
   */
  
! #define VERS_NUM          "3.2.2"
  
! #ifdef DCE
! #define VERS_SUF1         "-DCE"
! #elif KERBEROS
  #  ifdef KRB4
  #    define VERS_SUF1     "-krb-IV"
  #  endif /* KRB4 */
#### End of Patch data ####

#### ApplyPatch data follows ####
# Data version        : 1.0
# Date generated      : Tue Nov 21 12:43:10 2000
# Generated by        : makepatch 2.00
# Recurse directories : Yes
# p 'INSTALL' 52085 974819876 0100400
# p 'common/genpath.c' 13975 974819876 0100400
# p 'config.h.in' 14095 974819876 0100400
# p 'configure.in' 34453 974819876 0100400
# p 'doc/Changes' 886 974819876 0100600
# p 'popper/Makefile.in' 4343 974819876 0100400
# c 'popper/dce_pwent.c' 0 974819876 0100600
# c 'popper/pop_authdce.c' 0 974819876 0100600
# p 'popper/pop_init.c' 28732 974819876 0100400
# p 'popper/pop_pass.c' 40378 974828439 0100600
# p 'popper/pop_updt.c' 27843 974819877 0100400
# p 'popper/popper.c' 15787 974819877 0100400
# p 'popper/popper.h' 28113 974819877 0100400
# p 'popper/version.h' 826 974820272 0100600
#### End of ApplyPatch data ####

#### End of Patch kit [created: Tue Nov 21 12:43:10 2000] ####
#### Checksum: 1463 49814 44334 ####

Reply via email to