Hi, The attached file is my patchfile to 3.1.2. Among the several additional features is the "with-loadlimit" feature, which is what you want/need. The folks at Qualcomm seem comatose about picking up and adding the features included in this patch. I sent it in long ago.... ** Jeff A. Earickson, Ph.D PHONE: 207-872-3659 ** Senior UNIX Sysadmin, Information Technology EMAIL: [EMAIL PROTECTED] ** Colby College, 4214 Mayflower Hill, FAX: 207-872-3555 ** Waterville ME, 04901-8842 ----------------------------------------------------------------------------
# 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 ####
