From: Theodore Tso Date: Tue, 9 Aug 1994 02:03:38 +0000 (+0000) Subject: Initial commit of John Brezak's changes. This updates the Berkeley popper X-Git-Tag: krb5-1.0-beta4.2~48 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=ed607cdf24fa69900c56dc59f87828b067daa0d2;p=krb5.git Initial commit of John Brezak's changes. This updates the Berkeley popper from version 1.7 to 1.831beta; it also adds autoconf support. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@4070 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/appl/popper/Makefile.in b/src/appl/popper/Makefile.in new file mode 100644 index 000000000..93f4b8375 --- /dev/null +++ b/src/appl/popper/Makefile.in @@ -0,0 +1,80 @@ +# +# Compile options: +# -DMMDF : Use for MMDF style mail drops +# -DKPOP_SERVICE : define the name of service (defaults to kpop) +# -DPOP_PVT_PASSWD : use a private passwd file for users of the POP mail service +# -DMAILDIR : Set to site specific other than default. +# +CFLAGS = -g -DMAILDIR=\"/usr/spool/pop\" -DKERBEROS -DKRB5 -DDEBUG $(DEFS) $(LOCALINCLUDE) +LDFLAGS = -g + +KRB5MANROOT = $(KRB5ROOT)/man +ADMIN_BINDIR = $(KRB5ROOT)/admin +SERVER_BINDIR = $(KRB5ROOT)/sbin +CLIENT_BINDIR = $(KRB5ROOT)/bin +SERVER_MANSUFFIX = 8 +ADMIN_MANDIR = $(KRB5MANROOT)/man$(SERVER_MANSUFFIX) +SERVER_MANDIR = $(KRB5MANROOT)/man$(SERVER_MANSUFFIX) +SERVER_MANDIR = $(KRB5MANROOT)/man8 +CLIENT_MANDIR = $(KRB5MANROOT)/man1 +FILE_MANDIR = $(KRB5MANROOT)/man5 +KRB5_LIBDIR = $(KRB5ROOT)/lib +KRB5_INCDIR = $(KRB5ROOT)/include +KRB5_INCSUBDIRS = \ + $(KRB5_INCDIR)/krb5 \ + $(KRB5_INCDIR)/asn.1 \ + $(KRB5_INCDIR)/kerberosIV + +SRCTOP = $(srcdir)/$(BUILDTOP) +TOPLIBD = $(BUILDTOP)/lib +ISODELIB=$(TOPLIBD)/libisode.a +COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a +DBMLIB= + +all:: + +KLIB = $(TOPLIBD)/libkrb5.a $(TOPLIBD)/libcrypto.a $(ISODELIB) $(COMERRLIB) $(DBMLIB) + +OBJS = pop_dele.o pop_dropcopy.o pop_dropinfo.o \ + pop_get_command.o pop_get_subcommand.o pop_init.o \ + pop_last.o pop_list.o pop_log.o pop_lower.o \ + pop_msg.o pop_parse.o pop_pass.o pop_quit.o \ + pop_rset.o pop_send.o pop_stat.o pop_updt.o \ + pop_user.o pop_xtnd.o pop_xmit.o popper.o + +popper: $(OBJS) + $(CC) $(CFLAGS) -o popper $(OBJS) $(KLIB) $(LIBS) + +all:: popper + +$(OBJS): popper.h +pop_dele.o: $(srcdir)/pop_dele.c +pop_dropcopy.o: $(srcdir)/pop_dropcopy.c +pop_dropinfo.o: $(srcdir)/pop_dropinfo.c +pop_enter.o: $(srcdir)/pop_enter.c +pop_get_command.o: $(srcdir)/pop_get_command.c +pop_get_subcommand.o: $(srcdir)/pop_get_subcommand.c +pop_init.o: $(srcdir)/pop_init.c +pop_last.o: $(srcdir)/pop_last.c +pop_list.o: $(srcdir)/pop_list.c +pop_log.o: $(srcdir)/pop_log.c +pop_lower.o: $(srcdir)/pop_lower.c +pop_msg.o: $(srcdir)/pop_msg.c +pop_parse.o: $(srcdir)/pop_parse.c +pop_pass.o: $(srcdir)/pop_pass.c +pop_quit.o: $(srcdir)/pop_quit.c +pop_rset.o: $(srcdir)/pop_rset.c +pop_send.o: $(srcdir)/pop_send.c +pop_stat.o: $(srcdir)/pop_stat.c +pop_updt.o: $(srcdir)/pop_updt.c +pop_user.o: $(srcdir)/pop_user.c +pop_xmit.o: $(srcdir)/pop_xmit.c +pop_xtnd.o: $(srcdir)/pop_xtnd.c +popper.o: $(srcdir)/popper.c + +clean:: + $(RM) popper + +install:: + $(INSTALL_PROGRAM) popper ${DESTDIR}$(SERVER_BINDIR)/popper + $(INSTALL_DATA) popper.M ${DESTDIR}$(SERVER_MANDIR)/popper.$(SERVER_MANSUFFIX) diff --git a/src/appl/popper/README b/src/appl/popper/README index 43084cce5..0735fdd56 100644 --- a/src/appl/popper/README +++ b/src/appl/popper/README @@ -1,4 +1,4 @@ -@(#)README 1.6 7/13/90 +@(#)@(#)README 2.6 2.6 4/2/91 The Post Office Protocol Server: Installation Guide @@ -21,10 +21,10 @@ capable of performing Unix system administration. How to Obtain the Server -The POP server is available via anonymous ftp from lilac.Berkeley.EDU -(128.32.136.12). It is in two files in the pub directory: a compressed -tar file popper.tar.Z and a Macintosh StuffIt archive in BinHex format -called MacPOP.sit.hqx. +The POP server is available via anonymous ftp from ftp.CC.Berkeley.EDU +(128.32.136.9, 128.32.206.12). It is in two files in the pub directory: +a compressed tar file popper-version.tar.Z and a Macintosh StuffIt archive +in BinHex format called MacPOP.sit.hqx. Contents of the Distribution @@ -121,6 +121,30 @@ debugging which is logged at priority "debug". The default log file is systems with 4.2 syslogging all messages are logged to the local log file, usually /usr/spool/mqueue/syslog. +Problems + +If the filesystem which holds the /usr/spool/mail fills up users will +experience difficulties. The filesystem must have enough space to hold +(approximately) two copies of the largest mail box. Popper (v1.81 and +above) is designed to be robust in the face of this problem, but you may +end up with a situation where some of the user's mail is in + + /usr/spool/mail/.userid.pop + +and some of the mail is in + + /usr/spool/mail/userid + +If this happens the System Administrator should clear enough disk space +so that the filesystem has at least as much free disk as both mailboxes +hold and probably a little more. Then the user should initiate a POP +session, and do nothing but quit. If the POP session ends without an +error the user can then use POP or another mail program to clean up his/her +mailbox. + +Alternatively, the System Administrator can combine the two files (but +popper will do this for you if there is enough disk space). + Debugging @@ -129,7 +153,8 @@ is specified after its invocation in the inetd.conf file. Care should be exercised in using this option since it generates considerable output in the syslog file. Alternatively, the "-t " option will place debugging information into file "" using fprintf -instead of syslog. +instead of syslog. (To enable debugging, you must edit the Makefile +to add -DDEBUG to the compiler options.) For SunOS version 3.5, the popper program is launched by inetd from /etc/servers. This file does not allow you to specify command line @@ -227,6 +252,26 @@ Connection closed by foreign host. Release Notes +1.83 Make sure that everything we do as root is non-destructive. + +1.82 Make the /usr/spool/mail/.userid.pop file owned by the user rather + than owned by root. + +1.81 There were two versions of 1.7 floating around, 1.7b4 and 1.7b5. + The difference is that 1.7b5 attempted to save disk space on + /usr/spool/mail by deleting the users permanent maildrop after + making the temporary copy. Unfortunately, if compiled with + -DDEBUG, this version could easily wipe out a users' mail file. + This is now fixed. + + This version also fixes a security hole for systems that have + /usr/spool/mail writeable by all users. + + With this version we go to all new SCCS IDs for all files. This + is unfortunate, and we hope it is not too much of a problem. + + Thanks to Steve Dorner of UIUC for pointing out the major problem. + 1.7 Extensive re-write of the maildrop processing code contributed by Viktor Dukhovni that greatly reduces the possibility that the maildrop can be corrupted as the result of @@ -293,6 +338,24 @@ Release Notes 1.1 Several bugs fixed. +1.0 Original version. + + +Limitations + ++ The POP server copies the user's entire maildrop to /tmp and + then operates on that copy. If the maildrop is particularly + large, or inadequate space is available in /tmp, then the + server will refuse to continue and terminate the connection. + ++ Simultaneous modification of a single maildrop can result in + confusing results. For example, manipulating messages in a + maildrop using the Unix /usr/ucb/mail command while a copy of + it is being processed by the POP server can cause the changes + made by one program to be lost when the other terminates. This + problem is being worked on and will be fixed in a later + release. + Credits diff --git a/src/appl/popper/Release.Notes b/src/appl/popper/Release.Notes new file mode 100644 index 000000000..c0b313ecd --- /dev/null +++ b/src/appl/popper/Release.Notes @@ -0,0 +1,45 @@ +Release Notes: + +popper-1.831beta is no longer beta 30 July 91 + Removed popper-1.7.tar.Z + +popper-1.831beta.tar.Z 03 April 91 + Changed mkstemp to mktemp for Ultrix. Sigh. + +popper-1.83beta.tar.Z 02 April 91 + + This version makes certain that while running as root we do nothing + at all destructive. + +popper-1.82beta.tar.Z 27 March 91 + + This version fixes problems on Encore MultiMax and some Sun releases + which wouldn't allow a user to ftruncate() a file from an open + file descripter unless the user owns the file. Now the user + owns the /usr/spool/mail/.userid.pop file. Thanks to Ben Levy + of FTP Software and Henry Holtzman of Apple. + +popper-1.81beta.tar.Z 20 March 91 + + This version of popper is supposed to fix three problems reported + with various versions of popper (all called 1.7 or 1.7something). + + 1) Dropped network connections meant lost mail files. Some 1.7 + versions also risked corrupting mail files. + + 2) Some versions of 1.7 created temporary drop files with world + read and write permissions. + + 3) Some versions of 1.7 were not careful about opening the temporary + drop file. + +popper-1.7.tar.Z 09 September 90 (updated 20 March 91) + + This version will exhibit the first problem listed above if it is + compiled with -DDEBUG and run without the "-d" (debug) flag. + + If it is compiled without -DDEBUG it will exhibit only the second + and third bug listed above. + +Cliff Frost poptest@nettlesome.berkeley.edu +UC Berkeley diff --git a/src/appl/popper/configure.in b/src/appl/popper/configure.in new file mode 100644 index 000000000..f9eab3f27 --- /dev/null +++ b/src/appl/popper/configure.in @@ -0,0 +1,23 @@ +AC_INIT(popper.c) +WITH_CCOPTS +AC_FUNC_CHECK(vsprintf,AC_DEFINE(HAS_VSPRINTF)) +CONFIG_RULES +AC_SET_BUILDTOP +AC_HAVE_LIBRARY(socket) +AC_HAVE_LIBRARY(nsl) +AC_HAVE_LIBRARY(BSD) +AC_HAVE_LIBRARY(ndbm) + +AC_HEADER_CHECK(flock.h,[echo found flock.h for non-posix locks], +AC_COMPILE_CHECK([POSIX file locking -- structs and flags], +[#include +#include ], +[struct flock f; 1+F_SETLK;], +AC_DEFINE(POSIX_FILE_LOCKS))) + +AC_HEADER_CHECK(unistd.h,AC_DEFINE(HAS_UNISTD_H)) +AC_HEADER_CHECK(paths.h,AC_DEFINE(HAS_PATHS_H)) + +KRB_INCLUDE +WITH_KRB5ROOT +AC_OUTPUT(Makefile,[EXTRA_RULES]) diff --git a/src/appl/popper/mh-6.8.patch b/src/appl/popper/mh-6.8.patch new file mode 100644 index 000000000..10a4def6a --- /dev/null +++ b/src/appl/popper/mh-6.8.patch @@ -0,0 +1,292 @@ +*** ./zotnet/mts/client.c.orig Fri Jul 8 21:56:54 1994 +--- ./zotnet/mts/client.c Fri Jul 8 22:44:04 1994 +*************** +*** 26,31 **** +--- 26,46 ---- + #include + #endif + ++ #if defined(KPOP) && defined(K5POP) ++ #error "You cannot define both KPOP and K5POP" ++ #endif ++ #ifdef K5POP ++ #include ++ #include ++ #include ++ #include ++ #include ++ ++ static krb5_error_code retval; ++ static krb5_ccache ccdef; ++ static krb5_principal kclient = NULL, kserver = NULL; ++ #endif ++ + #ifdef KPOP + #include + #include +*************** +*** 75,80 **** +--- 90,98 ---- + static struct addrent *he, *hz; + static struct addrent hosts[MAXHOSTS]; + ++ #ifdef K5POP ++ static char *kservice; /* "pop" if using kpop */ ++ #endif + #ifdef KPOP + char krb_realm[REALM_SZ]; + char *PrincipalHostname(); +*************** +*** 109,115 **** + register struct netent *np; + #endif + register struct servent *sp; +! #ifdef KPOP + char *cp; + + if (cp = index (kservice = service, '/')) { /* "pop/kpop" */ +--- 127,133 ---- + register struct netent *np; + #endif + register struct servent *sp; +! #if defined(KPOP) || defined(K5POP) + char *cp; + + if (cp = index (kservice = service, '/')) { /* "pop/kpop" */ +*************** +*** 118,129 **** + } + else + kservice = NULL; /* not using KERBEROS */ +! #endif /* KPOP */ + + + if ((sp = getservbyname (service, protocol)) == NULL) { + #ifdef HESIOD +! if ((sp = hes_getservbyname (service, protocol)) == NULL) { + (void) sprintf (response, "%s/%s: unknown service", + protocol, service); + return NOTOK; +--- 136,147 ---- + } + else + kservice = NULL; /* not using KERBEROS */ +! #endif /* KPOP || K5POP */ + + + if ((sp = getservbyname (service, protocol)) == NULL) { + #ifdef HESIOD +! if ((sp = (struct servent *) hes_getservbyname (service, protocol)) == NULL) { + (void) sprintf (response, "%s/%s: unknown service", + protocol, service); + return NOTOK; +*************** +*** 206,214 **** + register struct addrent *ap; + struct sockaddr_in in_socket; + register struct sockaddr_in *isock = &in_socket; +! #ifdef KPOP + int rem; +! #endif /* KPOP */ + + for (ap = nets; ap < ne; ap++) + if (ap -> a_addrtype == hp -> h_addrtype && inet (hp, ap -> a_net)) +--- 224,232 ---- + register struct addrent *ap; + struct sockaddr_in in_socket; + register struct sockaddr_in *isock = &in_socket; +! #if defined(KPOP) || defined(K5POP) + int rem; +! #endif /* KPOP || K5POP */ + + for (ap = nets; ap < ne; ap++) + if (ap -> a_addrtype == hp -> h_addrtype && inet (hp, ap -> a_net)) +*************** +*** 252,257 **** +--- 270,328 ---- + return NOTOK; + } + ++ #ifdef K5POP ++ if (kservice) { /* "pop" */ ++ krb5_error *err_ret = NULL; ++ ++ krb5_init_ets(); ++ ++ if (retval = krb5_cc_default(&ccdef)) { ++ sprintf(response, "Post office refused connection: krb5_cc_default: %s", ++ error_message(retval)); ++ close(sd); ++ return OOPS2; ++ } ++ if (retval = krb5_cc_get_principal(ccdef, &kclient)) { ++ sprintf(response, "Post office refused connection: krb5_cc_get_principal: %s", ++ error_message(retval)); ++ close(sd); ++ return OOPS2; ++ } ++ ++ if (retval = krb5_sname_to_principal(hp->h_name, kservice, ++ KRB5_NT_SRV_HST, ++ &kserver)) { ++ sprintf(response, "Post office refused connection: krb5_sname_to_principal: %s", ++ error_message(retval)); ++ close(sd); ++ return OOPS2; ++ } ++ ++ retval = krb5_sendauth((krb5_pointer) &sd, "KPOPV1.0", kclient, kserver, ++ AP_OPTS_MUTUAL_REQUIRED, ++ 0, /* no checksum */ ++ 0, /* no creds, use ccache instead */ ++ ccdef, ++ 0, /* don't need seq # */ ++ 0, /* don't need a subsession key */ ++ &err_ret, ++ 0); /* don't need reply */ ++ krb5_free_principal(kserver); ++ if (retval) { ++ if (err_ret && err_ret->text.length) { ++ sprintf(response, "Post office refused connection: %s [server says '%*s'] ", ++ error_message(retval), ++ err_ret->text.length, ++ err_ret->text.data); ++ krb5_free_error(err_ret); ++ } else ++ sprintf(response, "Post office refused connection: %s", ++ error_message(retval)); ++ close(sd); ++ return OOPS2; ++ } ++ } ++ #endif /* K5POP */ + #ifdef KPOP + if (kservice) { /* "pop" */ + ticket = (KTEXT)malloc( sizeof(KTEXT_ST) ); +*************** +*** 298,307 **** + : "unknown error"); + return NOTOK; + } +! #ifdef KPOP + if (kservice) /* "pop" */ + return(sd); +! #endif /* KPOP */ + if (!rproto) + return sd; + +--- 369,378 ---- + : "unknown error"); + return NOTOK; + } +! #if defined(KPOP) || defined(K5POP) + if (kservice) /* "pop" */ + return(sd); +! #endif /* KPOP || K5POP */ + if (!rproto) + return sd; + +*** ./uip/popsbr.c.orig Fri Jul 8 21:59:08 1994 +--- ./uip/popsbr.c Fri Jul 8 22:28:00 1994 +*************** +*** 144,153 **** + #endif /* APOP */ + + #ifndef NNTP +! #ifndef KPOP + if ((fd1 = client (host, "tcp", POPSERVICE, rpop, response)) == NOTOK) + #else /* KPOP */ + (void) sprintf (buffer, "%s/%s", POPSERVICE, "kpop"); + if ((fd1 = client (host, "tcp", buffer, rpop, response)) == NOTOK) + #endif + #else /* NNTP */ +--- 144,158 ---- + #endif /* APOP */ + + #ifndef NNTP +! #if !defined(KPOP) && !defined(K5POP) + if ((fd1 = client (host, "tcp", POPSERVICE, rpop, response)) == NOTOK) + #else /* KPOP */ ++ #ifdef K5POP ++ (void) sprintf (buffer, "%s/%s", POPSERVICE, "k5pop"); ++ #endif ++ #ifdef KPOP + (void) sprintf (buffer, "%s/%s", POPSERVICE, "kpop"); ++ #endif + if ((fd1 = client (host, "tcp", buffer, rpop, response)) == NOTOK) + #endif + #else /* NNTP */ +*************** +*** 177,183 **** + fprintf (stderr, "<--- %s\n", response); + #ifndef NNTP + if (*response == '+') { +! #ifndef KPOP + #ifdef APOP + if (apop < 0) { + char *cp = pop_auth (user, pass); +--- 182,188 ---- + fprintf (stderr, "<--- %s\n", response); + #ifndef NNTP + if (*response == '+') { +! #if !defined(KPOP) && !defined(K5POP) + #ifdef APOP + if (apop < 0) { + char *cp = pop_auth (user, pass); +*************** +*** 191,197 **** + && command ("%s %s", rpop ? "RPOP" : (pophack++, "PASS"), + pass) != NOTOK) + return OK; +! #else /* KPOP */ + if (command ("USER %s", user) != NOTOK + && command ("PASS %s", pass) != NOTOK) + return OK; +--- 196,202 ---- + && command ("%s %s", rpop ? "RPOP" : (pophack++, "PASS"), + pass) != NOTOK) + return OK; +! #else /* KPOP || K5POP */ + if (command ("USER %s", user) != NOTOK + && command ("PASS %s", pass) != NOTOK) + return OK; +*** ./uip/inc.c.orig Fri Jul 8 22:02:16 1994 +--- ./uip/inc.c Fri Jul 8 22:02:35 1994 +*************** +*** 19,27 **** + #ifdef POP + #include "../h/dropsbr.h" + #endif +- #ifdef KPOP +- #include +- #endif + #ifdef HESIOD + #include + #endif +--- 19,24 ---- +*** ./conf/makefiles/uip.orig Fri Jul 8 22:17:19 1994 +--- ./conf/makefiles/uip Fri Jul 8 22:35:23 1994 +*************** +*** 84,89 **** +--- 84,92 ---- + @BEGIN: KPOP + KRBLIB = -lkrb -ldes + @END: KPOP ++ @BEGIN: K5POP ++ KRBLIB = -lkrb5 -lcrypto -lisode -lcom_err ++ @END: K5POP + @BEGIN: BPOP + PSHLIB = popsbr.o + PSHLLIBS= popsbr.c +*** ./conf/mhconfig.c.orig Fri Jul 8 22:14:14 1994 +--- ./conf/mhconfig.c Fri Jul 8 22:19:37 1994 +*************** +*** 138,143 **** +--- 138,144 ---- + "APOP", 0, /* authenticated pop */ + "BSD43", 0, /* sgid ttys */ + "KPOP", 0, /* KERBEROS pop */ ++ "K5POP", 0, /* KERBEROS5 pop */ + "HESIOD", 0, + "MIME", 0, /* multi-media extensions */ + "MPOP", 0, /* mobile pop */ diff --git a/src/appl/popper/pop_dele.c b/src/appl/popper/pop_dele.c index e148d71e8..1c4d0bc95 100644 --- a/src/appl/popper/pop_dele.c +++ b/src/appl/popper/pop_dele.c @@ -6,7 +6,7 @@ #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_dele.c 1.5 7/13/90"; +static char SccsId[] = "@(#)pop_dele.c 2.1 3/18/91"; #endif not lint #include diff --git a/src/appl/popper/pop_dropcopy.c b/src/appl/popper/pop_dropcopy.c index feaf698ab..0acb16d67 100644 --- a/src/appl/popper/pop_dropcopy.c +++ b/src/appl/popper/pop_dropcopy.c @@ -6,44 +6,49 @@ #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_dropcopy.c 1.2 7/13/90"; +static char SccsId[] = "@(#)pop_dropcopy.c 2.6 4/3/91"; #endif not lint #include #include +#ifdef HAS_UNISTD_H +#include +#endif +#ifdef POSIX_FILE_LOCKS +#include +#endif #include #include #include #include +#include #include "popper.h" -extern int errno; -extern int sys_nerr; -extern char *sys_errlist[]; - -#define LOCK_RETRY 3 -#define LOCK_WAIT 5 - /* * dropcopy: Make a temporary copy of the user's mail drop and * save a stream pointer for it. */ -pop_dropcopy(p) +pop_dropcopy(p,pwp) POP * p; +struct passwd * pwp; { int mfd; /* File descriptor for the user's maildrop */ int dfd; /* File descriptor for the SERVER maildrop */ + FILE *tf; /* The temp file */ + char *template; /* Temp name holder */ char buffer[BUFSIZ]; /* Read buffer */ - long offset; /* Old/New boundary */ + off_t offset; /* Old/New boundary */ int nchar; /* Bytes written/read */ - int locked; /* if drop is loced */ - int retry = 0; /* times to retry lock */ + struct stat mybuf; /* For lstat() */ +#ifdef POSIX_FILE_LOCKS + struct flock lock_arg; +#endif /* Create a temporary maildrop into which to copy the updated maildrop */ - (void)sprintf(p->temp_drop,POP_DROP,p->user); + (void)sprintf(p->temp_drop,"%s/.%s.temp",MAILDIR,p->user); #ifdef DEBUG if(p->debug) @@ -51,45 +56,88 @@ POP * p; p->temp_drop); #endif DEBUG - /* Open for append, this solves the crash recovery problem */ - if ((dfd = open(p->temp_drop,O_RDWR|O_APPEND|O_CREAT,0666)) == -1){ - pop_log(p,POP_ERROR, - "%s: (%s) unable to create temporary maildrop: %s", - p->client, p->temp_drop, - (errno < sys_nerr) ? sys_errlist[errno] : "") ; - return (POP_FAILURE); + /* Here we work to make sure the user doesn't cause us to remove or + * write over existing files by limiting how much work we do while + * running as root. + */ + + /* First create a unique file. Would prefer mkstemp, but Ultrix...*/ + template = tempnam(MAILDIR, "tmpXXXXXX"); + if ( (tf=fopen(template,"w+")) == NULL ) { /* failure, bail out */ + pop_log(p,POP_PRIORITY, + "Unable to create temporary temporary maildrop '%s': %s",template, + strerror(errno)) ; + return pop_msg(p,POP_FAILURE, + "System error, can't create temporary file."); } - /* Lock the temporary maildrop. Try a few times if it doesn't succeed. */ + /* Now give this file to the user */ +#ifndef KERBEROS + (void) chown(template,pwp->pw_uid, pwp->pw_gid); +#endif + (void) chmod(template,0600); + + /* Now link this file to the temporary maildrop. If this fails it + * is probably because the temporary maildrop already exists. If so, + * this is ok. We can just go on our way, because by the time we try + * to write into the file we will be running as the user. + */ + (void) link(template,p->temp_drop); + (void) fclose(tf); + (void) unlink(template); + free(template); - locked = 1; - while(locked) { - if ( flock (dfd, LOCK_EX|LOCK_NB) == -1 ) - switch(errno) { - case EWOULDBLOCK: - if(retry++ < LOCK_RETRY) { - sleep(LOCK_WAIT); - continue; - } - pop_log(p, POP_PRIORITY, "%s: (%s) maildrop locked", - p->client, p->temp_drop); - return pop_msg(p,POP_FAILURE, - "Maildrop for %s is busy. Please try again in a few moments.", - p->user); - /* NOTREACHED */ - - default: - pop_log(p, POP_PRIORITY, "%s: (%s) flock: %s", p->client, - p->temp_drop, - (errno < sys_nerr) ? sys_errlist[errno] : ""); - return pop_msg(p,POP_FAILURE,"flock: '%s': %s", p->temp_drop, - (errno < sys_nerr) ? sys_errlist[errno] : ""); - /* NOTREACHED */ - } - else - locked = 0; +#ifndef KERBEROS + /* Now we run as the user. */ + (void) setuid(pwp->pw_uid); + (void) setgid(pwp->pw_gid); +#endif + +#ifdef DEBUG + if(p->debug)pop_log(p,POP_DEBUG,"uid = %d, gid = %d",getuid(),getgid()); +#endif DEBUG + + /* Open for append, this solves the crash recovery problem */ + if ((dfd = open(p->temp_drop,O_RDWR|O_APPEND|O_CREAT,0600)) == -1){ + pop_log(p,POP_PRIORITY, + "Unable to open temporary maildrop '%s': %s",p->temp_drop, + strerror(errno)) ; + return pop_msg(p,POP_FAILURE, + "System error, can't open temporary file, do you own it?"); } + /* Lock the temporary maildrop */ +#ifdef POSIX_FILE_LOCKS + lock_arg.l_type = F_WRLCK; + lock_arg.l_whence = 0; + lock_arg.l_start = 0; + lock_arg.l_len = 0; + if ( fcntl (dfd, F_SETLK, &lock_arg) == -1) + switch(errno) { + case EAGAIN: + case EACCES: + return pop_msg(p,POP_FAILURE, + "Maildrop lock busy! Is another session active?"); + /* NOTREACHED */ + default: + return pop_msg(p,POP_FAILURE,"fcntl(F_SETLK|F_WRLCK): '%s': %s", p->temp_drop, + strerror(errno)); + /* NOTREACHED */ + } +#else + if ( flock (dfd, LOCK_EX|LOCK_NB) == -1 ) + switch(errno) { + case EWOULDBLOCK: + return pop_msg(p,POP_FAILURE, + "Maildrop lock busy! Is another session active?"); + /* NOTREACHED */ + default: + return pop_msg(p,POP_FAILURE,"flock: '%s': %s", p->temp_drop, + strerror(errno)); + /* NOTREACHED */ + } +#endif + /* May have grown or shrunk between open and lock! */ offset = lseek(dfd,0,L_XTND); @@ -97,14 +145,23 @@ POP * p; if ((mfd = open(p->drop_name,O_RDWR)) > 0) { /* Lock the maildrop */ +#ifdef POSIX_FILE_LOCKS + lock_arg.l_type = F_WRLCK; + lock_arg.l_whence = 0; + lock_arg.l_start = 0; + lock_arg.l_len = 0; + if (fcntl (mfd, F_SETLKW, &lock_arg) == -1) { + (void)close(mfd) ; + return pop_msg(p,POP_FAILURE, "fcntl(F_SETLW|F_WRLCK): '%s': %s", p->temp_drop, + strerror(errno)); + } +#else if (flock (mfd,LOCK_EX) == -1) { (void)close(mfd) ; - pop_log(p, POP_PRIORITY, "%s: (%s) flock: %s", p->client, - p->drop_name,(errno < sys_nerr) ? sys_errlist[errno] : ""); return pop_msg(p,POP_FAILURE, "flock: '%s': %s", p->temp_drop, - (errno < sys_nerr) ? sys_errlist[errno] : ""); + strerror(errno)); } - +#endif /* Copy the actual mail drop into the temporary mail drop */ while ( (nchar=read(mfd,buffer,BUFSIZ)) > 0 ) if ( nchar != write(dfd,buffer,nchar) ) { @@ -118,11 +175,11 @@ POP * p; see the new mail until the error goes away. Should let them process the current backlog, in case the error is a quota problem requiring deletions! */ - (void)ftruncate(dfd,(int)offset) ; + (void)ftruncate(dfd,offset) ; } else { /* Mail transferred! Zero the mail drop NOW, that we do not have to do gymnastics to figure out what's new - and what is old later */ + and what is old later */ (void)ftruncate(mfd,0) ; } @@ -133,18 +190,11 @@ POP * p; /* Acquire a stream pointer for the temporary maildrop */ if ( (p->drop = fdopen(dfd,"a+")) == NULL ) { (void)close(dfd) ; - pop_log(p, POP_PRIORITY, "%s: (%s) fdopen: %s", p->client, - p->temp_drop, (errno < sys_nerr) ? sys_errlist[errno] : ""); return pop_msg(p,POP_FAILURE,"Cannot assign stream for %s", p->temp_drop); } rewind (p->drop); -#ifdef DEBUG - if (!p->debug) - unlink (p->temp_drop); -#endif DEBUG - return(POP_SUCCESS); } diff --git a/src/appl/popper/pop_dropinfo.c b/src/appl/popper/pop_dropinfo.c index 021082020..827f282e6 100644 --- a/src/appl/popper/pop_dropinfo.c +++ b/src/appl/popper/pop_dropinfo.c @@ -4,13 +4,9 @@ * specifies the terms and conditions for redistribution. */ -/* - * compatibility with mail files stored with mh (tom) - */ - #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_dropinfo.c 1.4 8/16/90"; +static char SccsId[] = "@(#)pop_dropinfo.c 2.1 3/18/91"; #endif not lint #include @@ -21,10 +17,6 @@ static char SccsId[] = "@(#)pop_dropinfo.c 1.4 8/16/90"; #include #include "popper.h" -extern int errno; -extern int sys_nerr; -extern char *sys_errlist[]; - /* * dropinfo: Extract information about the POP maildrop and store * it for use by the other POP routines. @@ -55,7 +47,6 @@ POP * p; if (p->mlp == NULL){ (void)fclose (p->drop); p->msg_count = 0; - pop_log(p, POP_ERROR, "%s: (%s) no memory.", p->client, p->user); return pop_msg (p,POP_FAILURE, "Can't build message list for '%s': Out of memory", p->user); } @@ -69,6 +60,7 @@ POP * p; fgets(buffer,MAXMSGLINELEN,p->drop);) { nchar = strlen(buffer); +#ifdef MMDF if((strncmp(buffer,"\001\001\001\001",4) == 0) && (end == 0)) { end = 1; continue; @@ -76,14 +68,15 @@ POP * p; if (is_msg_boundary(buffer)) { end = 0; +#else + if (strncmp(buffer,"From ",5) == 0) { +#endif if (++msg_num > p->msg_count) { p->mlp=(MsgInfoList *) realloc(p->mlp, (p->msg_count+=ALLOC_MSGS)*sizeof(MsgInfoList)); if (p->mlp == NULL){ (void)fclose (p->drop); p->msg_count = 0; - pop_log(p, POP_ERROR, "%s: (%s) no memory.", - p->client, p->user); return pop_msg (p,POP_FAILURE, "Can't build message list for '%s': Out of memory", p->user); @@ -107,7 +100,7 @@ POP * p; if(p->debug) pop_log(p,POP_DEBUG, "Msg %d being added to list", mp->number); #endif DEBUG - } + } mp->length += nchar; p->drop_size += nchar; mp->lines++; @@ -126,5 +119,3 @@ POP * p; return(POP_SUCCESS); } - - diff --git a/src/appl/popper/pop_enter.c b/src/appl/popper/pop_enter.c index 11e5b5f00..c78656b63 100644 --- a/src/appl/popper/pop_enter.c +++ b/src/appl/popper/pop_enter.c @@ -19,8 +19,6 @@ char *Zsignature = "Your friendly neighborhood post office."; void notify_recipient(); -#define POP_MAILDIR "/usr/spool/pop" - char buffer[BUFSIZ]; char xtmpfile[512]; /* tmp file */ int newmail; /* fd for temp message */ @@ -94,7 +92,7 @@ open_drop(name) { char dropfile[512]; - sprintf(dropfile, "%s/%s", POP_MAILDIR, name); + sprintf(dropfile, "%s/%s", MAILDIR, name); if ((maildrop = open(dropfile, O_RDWR|O_CREAT,0600)) == -1) { fprintf(stderr, "unable to open \"%s\": %s.\n", diff --git a/src/appl/popper/pop_get_command.c b/src/appl/popper/pop_get_command.c index fe5d22e87..ba13a42e3 100644 --- a/src/appl/popper/pop_get_command.c +++ b/src/appl/popper/pop_get_command.c @@ -6,7 +6,7 @@ #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_get_command.c 1.9 8/16/90"; +static char SccsId[] = "@(#)pop_get_command.c 2.1 3/18/91"; #endif not lint #include diff --git a/src/appl/popper/pop_get_subcommand.c b/src/appl/popper/pop_get_subcommand.c index c77af80f0..b79c9aeaa 100644 --- a/src/appl/popper/pop_get_subcommand.c +++ b/src/appl/popper/pop_get_subcommand.c @@ -6,7 +6,7 @@ #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_get_subcommand.c 1.5 7/13/90"; +static char SccsId[] = "@(#)pop_get_subcommand.c 2.1 3/18/91"; #endif not lint #include diff --git a/src/appl/popper/pop_init.c b/src/appl/popper/pop_init.c index 5eba83cd2..a7e25e492 100644 --- a/src/appl/popper/pop_init.c +++ b/src/appl/popper/pop_init.c @@ -4,13 +4,9 @@ * specifies the terms and conditions for redistribution. */ -/* - * added kerberos authentication (tom coppeto, 1/15/91) - */ - #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_init.c 1.12 8/16/90"; +static char SccsId[] = "@(#)pop_init.c 2.1 2.1 3/18/91"; #endif not lint #include @@ -20,9 +16,13 @@ static char SccsId[] = "@(#)pop_init.c 1.12 8/16/90"; #include #include #include -#include #include "popper.h" +#ifndef lint +static char whatId[] = "@(#)POP3 Mail daemon - popper " VERSION; +static char rcsId[] = "$Id$"; +#endif + #ifdef KERBEROS #ifdef KRB4 #ifdef KRB5 @@ -41,9 +41,6 @@ char *client_name; #endif /* KRB5 */ #endif /* KERBEROS */ -extern int errno; -int sp = 0; /* Socket pointer */ - /* we use this later */ /* * init: Start a Post Office Protocol session */ @@ -57,15 +54,16 @@ char ** argmessage; struct sockaddr_in cs; /* Communication parameters */ struct hostent * ch; /* Client host information */ int errflag = 0; - int standalone = 0; int c; int len; extern char * optarg; int options = 0; + int sp = 0; /* Socket pointer */ char * trace_file_name; + int standalone = 0; /* Initialize the POP parameter block */ - memset ((char *)p, 0,(int)sizeof(POP)); + bzero ((char *)p,(int)sizeof(POP)); /* Save my name in a global variable */ p->myname = argmessage[0]; @@ -81,7 +79,7 @@ char ** argmessage; #endif /* Process command line arguments */ - while ((c = getopt(argcount,argmessage,"dst:")) != EOF) + while ((c = getopt(argcount,argmessage,"dt:s")) != EOF) switch (c) { /* Debugging requested */ @@ -94,16 +92,19 @@ char ** argmessage; case 't': p->debug++; if ((p->trace = fopen(optarg,"a+")) == NULL) { - pop_log(p,POP_ERROR, + pop_log(p,POP_PRIORITY, "Unable to open trace file \"%s\", err = %d", optarg,errno); exit(-1); } trace_file_name = optarg; break; + + /* Standalone operation */ case 's': standalone++; break; + /* Unknown option received */ default: errflag++; @@ -129,13 +130,16 @@ char ** argmessage; sin.sin_addr.s_addr = 0; #ifdef KERBEROS - if (!(spr = getservbyname("kpop", "tcp"))) { - syslog(LOG_ERR, "kpop/tcp: unknown service"); +#ifndef KPOP_SERVICE +#define KPOP_SERVICE "kpop" +#endif + if (!(spr = getservbyname(KPOP_SERVICE, "tcp"))) { + syslog(LOG_ERR, "%s/tcp: unknown service", KPOP_SERVICE); exit(3); } #else if (!(spr = getservbyname("pop", "tcp"))) { - syslog(LOG_ERR, "kpop/tcp: unknown service"); + syslog(LOG_ERR, "pop/tcp: unknown service"); exit(3); } #endif @@ -161,7 +165,7 @@ char ** argmessage; /* Get the address and socket of the client to whom I am speaking */ len = sizeof(cs); if (getpeername(sp,(struct sockaddr *)&cs,&len) < 0){ - pop_log(p,POP_ERROR, + pop_log(p,POP_PRIORITY, "Unable to obtain socket and address of client, err = %d",errno); exit(-1); } @@ -177,26 +181,23 @@ char ** argmessage; ch = gethostbyaddr((char *) &cs.sin_addr, sizeof(cs.sin_addr), AF_INET); if (ch == NULL){ pop_log(p,POP_PRIORITY, - "%s: unable to get canonical name of client, err = %d", - p->ipaddr, errno); + "Unable to get canonical name of client, err = %d",errno); p->client = p->ipaddr; } /* Save the cannonical name of the client host in the POP parameter block */ else { -#ifndef BIND43HACK +#ifndef BIND43 p->client = ch->h_name; #else - /* - * There's no reason for this. In any case, reset res options. - */ - # include # include /* Distrust distant nameservers */ +#if (__RES < 19931104) extern struct state _res; +#endif struct hostent * ch_again; char * * addrp; @@ -206,8 +207,8 @@ char ** argmessage; /* See if the name obtained for the client's IP address returns an address */ if ((ch_again = gethostbyname(ch->h_name)) == NULL) { - pop_log(p,POP_PRIORITY, - "%s: resolves to an unknown host name \"%s\".", + pop_log(p,POP_PRIORITY, + "Client at \"%s\" resolves to an unknown host name \"%s\"", p->ipaddr,ch->h_name); p->client = p->ipaddr; } @@ -219,41 +220,35 @@ char ** argmessage; /* Look for the client's IP address in the list returned for its name */ for (addrp=ch_again->h_addr_list; *addrp; ++addrp) - if (memcmp(*addrp,&(cs.sin_addr),sizeof(cs.sin_addr)) == 0) break; + if (bcmp(*addrp,&(cs.sin_addr),sizeof(cs.sin_addr)) == 0) break; if (!*addrp) { pop_log (p,POP_PRIORITY, - "%s: not listed for its host name \"%s\".", - p->ipaddr,ch->h_name); + "Client address \"%s\" not listed for its host name \"%s\"", + p->ipaddr,ch->h_name); p->client = p->ipaddr; } } - /* restore bind state */ - _res.options |= RES_DEFNAMES; - -#endif /* BIND43HACK */ +#endif BIND43 } - fcntl(sp, F_SETFL, SO_KEEPALIVE); - /* Create input file stream for TCP/IP communication */ if ((p->input = fdopen(sp,"r")) == NULL){ - pop_log(p,POP_ERROR, - "%s: unable to open communication stream for input, err = %d", - p->client, errno); + pop_log(p,POP_PRIORITY, + "Unable to open communication stream for input, err = %d",errno); exit (-1); } /* Create output file stream for TCP/IP communication */ if ((p->output = fdopen(sp,"w")) == NULL){ - pop_log(p,POP_ERROR, - "%s: unable to open communication stream for output, err = %d", - p->client, errno); + pop_log(p,POP_PRIORITY, + "Unable to open communication stream for output, err = %d",errno); exit (-1); } - pop_log(p,POP_INFO, - "%s: (v%s) Servicing request at %s\n", p->client, VERSION, p->ipaddr); + pop_log(p,POP_PRIORITY, + "(v%s) Servicing request from \"%s\" at %s\n", + VERSION,p->client,p->ipaddr); #ifdef DEBUG if (p->trace) @@ -263,12 +258,10 @@ char ** argmessage; else if (p->debug) pop_log(p,POP_PRIORITY,"Debugging turned on"); #endif DEBUG - + return(authenticate(p, &cs)); } - - authenticate(p, addr) POP *p; struct sockaddr_in *addr; @@ -301,14 +294,20 @@ authenticate(p, addr) #endif /* DEBUG */ strcpy(p->user, kdata.pname); +#endif + +#ifdef KRB5 + krb5_error_code retval; + krb5_principal server; + int sock = 0; krb5_init_ets(); - if (retval = krb5_sname_to_principal(p->myhost, "pop", KRB5_NT_SRV_HOST, + if (retval = krb5_sname_to_principal(p->myhost, "pop", KRB5_NT_SRV_HST, &server)) { pop_msg(p, POP_FAILURE, - "server mis-configured, can't get principal--%s", - error_message(retval)); + "server '%s' mis-configured, can't get principal--%s", + p->myhost, error_message(retval)); pop_log(p, POP_WARNING, "%s: mis-configured, can't get principal--%s", p->client, error_message(retval)); exit(-1); @@ -343,6 +342,14 @@ authenticate(p, addr) pop_log(p, POP_DEBUG, "%s (%s): ok", client_name, inet_ntoa(addr->sin_addr)); #endif /* DEBUG */ + if (retval= krb5_aname_to_localname(ext_client, sizeof(p->user), p->user)) { + pop_msg(p, POP_FAILURE, "unable to convert aname(%s) to localname --%s", + client_name, + error_message(retval)); + pop_log(p, POP_DEBUG, "unable to convert aname to localname (%s)", + client_name); + exit(-1); + } #endif /* KRB5 */ #endif /* KERBEROS */ diff --git a/src/appl/popper/pop_last.c b/src/appl/popper/pop_last.c index 6298b7615..53b3b8d1e 100644 --- a/src/appl/popper/pop_last.c +++ b/src/appl/popper/pop_last.c @@ -6,7 +6,7 @@ #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_last.c 1.5 7/13/90"; +static char SccsId[] = "@(#)pop_last.c 2.1 3/18/91"; #endif not lint #include diff --git a/src/appl/popper/pop_list.c b/src/appl/popper/pop_list.c index a79f5d168..ac5aecb8a 100644 --- a/src/appl/popper/pop_list.c +++ b/src/appl/popper/pop_list.c @@ -6,7 +6,7 @@ #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_list.c 1.5 7/13/90"; +static char SccsId[] = "@(#)pop_list.c 2.1 3/18/91"; #endif not lint #include diff --git a/src/appl/popper/pop_log.c b/src/appl/popper/pop_log.c index a64716111..76fdecb93 100644 --- a/src/appl/popper/pop_log.c +++ b/src/appl/popper/pop_log.c @@ -6,7 +6,7 @@ #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_log.c 1.7 7/13/90"; +static char SccsId[] = "@(#)pop_log.c 2.1 3/18/91"; #endif not lint #include @@ -34,12 +34,12 @@ va_dcl format = va_arg(ap,char *); va_end(ap); -#ifdef HAVE_VSPRINTF +#ifdef HAS_VSPRINTF vsprintf(msgbuf,format,ap); #else (void)sprintf (msgbuf,format,((int *)ap)[0],((int *)ap)[1],((int *)ap)[2], ((int *)ap)[3],((int *)ap)[4],((int *)ap)[5]); -#endif HAVE_VSPRINTF +#endif /* HAS_VSPRINTF */ if (p->debug && p->trace) { (void)fprintf(p->trace,"%s\n",msgbuf); diff --git a/src/appl/popper/pop_lower.c b/src/appl/popper/pop_lower.c index 45fb4e4da..62054ed47 100644 --- a/src/appl/popper/pop_lower.c +++ b/src/appl/popper/pop_lower.c @@ -6,7 +6,7 @@ #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_lower.c 1.6 7/13/90"; +static char SccsId[] = "@(#)pop_lower.c 2.1 3/18/91"; #endif not lint #include diff --git a/src/appl/popper/pop_msg.c b/src/appl/popper/pop_msg.c index 366c5155c..839cb39bf 100644 --- a/src/appl/popper/pop_msg.c +++ b/src/appl/popper/pop_msg.c @@ -6,7 +6,7 @@ #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_msg.c 1.7 7/13/90"; +static char SccsId[] = "@(#)pop_msg.c 2.1 3/18/91"; #endif not lint #include @@ -49,12 +49,12 @@ va_dcl /* Append the message (formatted, if necessary) */ if (format) -#ifdef HAVE_VSPRINTF +#ifdef HAS_VSPRINTF vsprintf(mp,format,ap); #else (void)sprintf(mp,format,((int *)ap)[0],((int *)ap)[1],((int *)ap)[2], ((int *)ap)[3],((int *)ap)[4]); -#endif HAVE_VSPRINTF +#endif /* HAS_VSPRINTF */ /* Log the message if debugging is turned on */ #ifdef DEBUG @@ -62,6 +62,10 @@ va_dcl pop_log(p,POP_DEBUG,"%s",message); #endif DEBUG + /* Log the message if a failure occurred */ + if (stat != POP_SUCCESS) + pop_log(p,POP_PRIORITY,"%s",message); + /* Append the */ (void)strcat(message, "\r\n"); diff --git a/src/appl/popper/pop_parse.c b/src/appl/popper/pop_parse.c index 05b42a40c..20f67d618 100644 --- a/src/appl/popper/pop_parse.c +++ b/src/appl/popper/pop_parse.c @@ -6,7 +6,7 @@ #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_parse.c 1.5 7/13/90"; +static char SccsId[] = "@(#)pop_parse.c 2.1 3/18/91"; #endif not lint #include diff --git a/src/appl/popper/pop_pass.c b/src/appl/popper/pop_pass.c index 5c05acb03..b2cc3b2b6 100644 --- a/src/appl/popper/pop_pass.c +++ b/src/appl/popper/pop_pass.c @@ -4,21 +4,15 @@ * specifies the terms and conditions for redistribution. */ -/* - * authorization rules for use with kerberos (tom) - * password server using kerberos (jon) - */ - #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_pass.c 1.7 7/13/90"; +static char SccsId[] = "@(#)pop_pass.c 2.3 4/2/91"; #endif not lint #include #include #include #include -#include #include "popper.h" #ifdef KERBEROS @@ -39,7 +33,9 @@ extern char *client_name; #endif /* KRB5 */ #endif /* KERBEROS */ -#ifndef KERBEROS_PASSWD_HACK +#ifdef POP_PASSFILE +struct passwd * our_getpwnam(); +#endif /* * pass: Obtain the user password from a POP client @@ -63,7 +59,6 @@ POP * p; char *crypt(); #endif /* KERBEROS */ - #ifdef KERBEROS #ifdef KRB4 if ((status = krb_get_lrealm(lrealm,1)) == KFAILURE) { @@ -90,6 +85,7 @@ POP * p; #endif /* KRB4 */ #ifdef KRB5 +#ifdef NO_CROSSREALM if (retval = krb5_get_default_realm(&lrealm)) { pop_log(p, POP_WARNING, "%s: (%s) %s", p->client, client_name, error_message(retval)); @@ -105,7 +101,7 @@ POP * p; "Kerberos realm \"%*s\" not accepted.", tmpdata->length, tmpdata->data)); } - +#endif /* only accept one-component names, i.e. realm and name only */ if (krb5_princ_size(ext_client) > 1) { pop_log(p, POP_WARNING, "%s: (%s) instance not accepted.", @@ -134,51 +130,45 @@ POP * p; #endif /* KRB5 */ /* Build the name of the user's maildrop */ - (void)sprintf(p->drop_name,"%s/%s",POP_MAILDIR,p->user); + (void)sprintf(p->drop_name,"%s/%s",MAILDIR,p->user); /* Make a temporary copy of the user's maildrop */ - if (pop_dropcopy(p) != POP_SUCCESS) return (POP_FAILURE); + if (pop_dropcopy(p, NULL) != POP_SUCCESS) return (POP_FAILURE); #else /* KERBEROS */ /* Look for the user in the password file */ +#ifdef POP_PASSFILE + our_setpwent(POP_PASSFILE); + + if ((pw = our_getpwnam(p->user)) == NULL) +#else if ((pw = getpwnam(p->user)) == NULL) +#endif return (pop_msg(p,POP_FAILURE, "Password supplied for \"%s\" is incorrect.",p->user)); - + /* We don't accept connections from users with null passwords */ if (pw->pw_passwd == NULL) return (pop_msg(p,POP_FAILURE, "Password supplied for \"%s\" is incorrect.",p->user)); - + /* Compare the supplied password with the password file entry */ if (strcmp (crypt (p->pop_parm[1], pw->pw_passwd), pw->pw_passwd) != 0) return (pop_msg(p,POP_FAILURE, "Password supplied for \"%s\" is incorrect.",p->user)); /* Build the name of the user's maildrop */ - (void)sprintf(p->drop_name,"%s/%s",POP_MAILDIR,p->user); + (void)sprintf(p->drop_name,"%s/%s",MAILDIR,p->user); /* Make a temporary copy of the user's maildrop */ - if (pop_dropcopy(p) != POP_SUCCESS) return (POP_FAILURE); - -#ifndef KERBEROS_PASSWD_HACK - /* Set the group and user id */ - (void)setgid(pw->pw_gid); - (void)setuid(pw->pw_uid); -#endif /* KERBEROS_PASSWD_HACK */ - -#ifdef DEBUG - if(p->debug)pop_log(p,POP_DEBUG,"uid = %d, gid = %d",getuid(),getgid()); -#endif DEBUG + /* and set the group and user id */ + if (pop_dropcopy(p,pw) != POP_SUCCESS) return (POP_FAILURE); #endif /* KERBEROS */ /* Get information about the maildrop */ - if (pop_dropinfo(p) != POP_SUCCESS) { - pop_log(p, POP_PRIORITY, "dropinfo failure"); - return(POP_FAILURE); - } + if (pop_dropinfo(p) != POP_SUCCESS) return(POP_FAILURE); /* Initialize the last-message-accessed number */ p->last_msg = 0; @@ -189,189 +179,69 @@ POP * p; p->user,p->msg_count,p->drop_size)); } - - - - -#else /* KERBEROS_PASSWD_HACK */ - - - -#ifdef KRB4 +#ifdef POP_PASSFILE /* - * Check to see if the user is in the passwd file, if not get a kerberos - * ticket with the password + * I'm getting myself deeper and deeper */ +static char *pwfile = "/etc/passwd"; - -#include -#include -#include - -int pop_pass (p) -POP * p; +our_setpwent(file) + char *file; { - register struct passwd * pw; - char *crypt(); - - setpwfile(POP_PASSFILE); - - /* Look for the user in the password file */ - pw = getpwnam(p->user); - - /* Compare the supplied password with the password file entry */ - if (pw && pw->pw_passwd) { - if (strcmp (crypt (p->pop_parm[1], pw->pw_passwd), pw->pw_passwd) != 0) - return (pop_msg(p,POP_FAILURE, - "Password supplied for \"%s\" is incorrect.",p->user)); - } - else { - if(verify_passwd_hack_hack_hack(p) != POP_SUCCESS) - return(POP_FAILURE); + if(file) + { + pwfile = (char *) malloc(strlen(file) + 1); + if(pwfile) + strcpy(pwfile, file); + else + return(-1); + return(0); } - - /* Build the name of the user's maildrop */ - (void)sprintf(p->drop_name,"%s/%s",POP_MAILDIR,p->user); - - /* Make a temporary copy of the user's maildrop */ - if (pop_dropcopy(p) != POP_SUCCESS) return (POP_FAILURE); - - -#ifndef KERBEROS_PASSWD_HACK - /* Set the group and user id */ - (void)setgid(pw->pw_gid); - (void)setuid(pw->pw_uid); -#endif /* KERBEROS_PASSWD_HACK */ - -#ifdef DEBUG - if(p->debug)pop_log(p,POP_DEBUG,"uid = %d, gid = %d",getuid(),getgid()); -#endif DEBUG - - /* Get information about the maildrop */ - if (pop_dropinfo(p) != POP_SUCCESS) { - pop_log(p, POP_PRIORITY, "dropinfo failure"); - return(POP_FAILURE); - } - - /* Initialize the last-message-accessed number */ - p->last_msg = 0; - - /* Authorization completed successfully */ - return (pop_msg (p,POP_SUCCESS, - "%s has %d message(s) (%d octets).", - p->user,p->msg_count,p->drop_size)); + return(-1); } - -/* for Ultrix and friends ... */ -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif - -#ifndef MAXPATHLEN -#define MAXPATHLEN 1024 -#endif - - -int verify_passwd_hack_hack_hack(p) - POP *p; +struct passwd * +our_getpwnam(user) + char *user; { - char lrealm[REALM_SZ]; - int status, fd; - KTEXT_ST ticket; - AUTH_DAT kdata; - char savehost[MAXHOSTNAMELEN]; - char tkt_file_name[MAXPATHLEN]; - struct sockaddr_in sin; - int len; - - extern int errno; - extern int sp; - - /* Be sure ticket file is correct and exists */ - - sprintf(tkt_file_name, "/tmp/tkt_pop.%s.%d", p->user, getpid()); - if (setenv("KRBTKFILE", tkt_file_name, 1 /* overwrite = yes */)) - return(pop_msg(p,POP_FAILURE, "Could not set ticket file name.")); - - if ((fd = open(tkt_file_name, O_RDWR|O_CREAT, 0600)) == -1) { - close(fd); - pop_log(p, POP_ERROR, "%s: could not create ticket file, \"%s\": %s", - p->user, tkt_file_name, sys_errlist[errno]); - return(pop_msg(p,POP_FAILURE,"POP server error: %s while creating %s.", - sys_errlist[errno], tkt_file_name)); - } - close(fd); - - /* - * Get an initial ticket using the given name/password and then use it. - * This hack will allow us to stop maintaining a separate pop passwd - * on eagle. We can cut over to real Kerberos POP clients at any point. - */ - - if ((status = krb_get_lrealm(lrealm,1)) == KFAILURE) { - pop_log(p,POP_ERROR, "%s (%s): error getting local realm: \"%s\".", - p->user, p->client, krb_err_txt[status]); - return(pop_msg(p,POP_FAILURE, "POP server error: \"%s\".", - krb_err_txt[status])); - } - - status = krb_get_pw_in_tkt(p->user, "", lrealm, "krbtgt", lrealm, - 2 /* 10 minute lifetime */, p->pop_parm[1]); - if (status != KSUCCESS) { - pop_log(p,POP_WARNING, "%s (%s): error getting tgt: %s", - p->user, p->client, krb_err_txt[status]); - return(pop_msg(p,POP_FAILURE, - "Kerberos authentication error: \"%s\".", - krb_err_txt[status])); - } - - /* - * Now use the ticket for something useful, to make sure - * it is valid. - */ - - (void) strncpy(savehost, krb_get_phost(p->myhost), sizeof(savehost)); - savehost[sizeof(savehost)-1] = 0; - - status = krb_mk_req(&ticket, "pop", savehost, lrealm, 0); - if (status == KDC_PR_UNKNOWN) { - pop_log(p, POP_ERROR, "%s (%s): %s", p->user, p->client, - krb_err_txt[status]); - return(pop_msg(p,POP_FAILURE, - "POP server configuration error: \"%s\".", - krb_err_txt[status])); - } + FILE *fp; + char buf[BUFSIZ]; + register char *c; + register char *d; + static struct passwd p; + + if(!(fp = fopen(pwfile, "r"))) + return(NULL); + + bzero(&p, sizeof(p)); + while(fgets(buf, sizeof(buf), fp)) + { + if(!(c = (char *) index(buf, ':'))) + continue; + + *c++ = '\0'; + if(strcmp(buf, user)) + continue; - if (status != KSUCCESS) { - dest_tkt(); - pop_log(p, POP_ERROR, "%s (%s): krb_mk_req error: %s", p->user, - p->client, krb_err_txt[status]); - return(pop_msg(p,POP_FAILURE, - "Kerberos authentication error (while getting ticket) \"%s\".", - krb_err_txt[status])); - } - - len = sizeof(sin); - getsockname(sp, &sin, &len); - if ((status = krb_rd_req(&ticket, "pop", savehost, sin.sin_addr.s_addr, - &kdata, "")) - != KSUCCESS) { - dest_tkt(); - pop_log(p, POP_WARNING, "%s (%s): krb_rd_req error: %s", p->user, - p->client, krb_err_txt[status]); - return(pop_msg(p,POP_FAILURE, - "Kerberos authentication error: \"%s\".", - krb_err_txt[status])); + p.pw_name = strdup(buf); + +#ifdef hpux + if (!(d = (char *) index(c, ':'))) + return(&p); +#else + if(!((d = (char *) index(c, ':')) && (c = (char *) index(++d, ':')) && + (d = (char *) index(++c, ':')))) + return(&p); +#endif + *d = '\0'; + + p.pw_passwd = strdup(c); + return(&p); } - dest_tkt(); - return(POP_SUCCESS); + + return(NULL); } -#endif -#ifdef KRB5 - #error: no passwd_hack source for V5. -#endif -#endif /* KERBEROS_PASSWD_HACK */ +#endif /* POP_PASSFILE */ diff --git a/src/appl/popper/pop_quit.c b/src/appl/popper/pop_quit.c index 2cfe9016a..212044db2 100644 --- a/src/appl/popper/pop_quit.c +++ b/src/appl/popper/pop_quit.c @@ -6,7 +6,7 @@ #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_quit.c 1.5 7/13/90"; +static char SccsId[] = "@(#)pop_quit.c 2.1 3/18/91"; #endif not lint #include diff --git a/src/appl/popper/pop_rset.c b/src/appl/popper/pop_rset.c index 2c97527c6..cf85385eb 100644 --- a/src/appl/popper/pop_rset.c +++ b/src/appl/popper/pop_rset.c @@ -6,7 +6,7 @@ #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_rset.c 1.5 7/13/90"; +static char SccsId[] = "@(#)pop_rset.c 2.1 3/18/91"; #endif not lint #include diff --git a/src/appl/popper/pop_send.c b/src/appl/popper/pop_send.c index 2de7ffa0b..c356a610c 100644 --- a/src/appl/popper/pop_send.c +++ b/src/appl/popper/pop_send.c @@ -4,13 +4,9 @@ * specifies the terms and conditions for redistribution. */ -/* - * mh compatibility (tom) - */ - #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_send.c 1.7 7/13/90"; +static char SccsId[] = "@(#)pop_send.c 2.1 3/18/91"; #endif not lint #include @@ -78,7 +74,11 @@ POP * p; /* Send the message body */ while (fgets(buffer,MAXMSGLINELEN,p->drop)) { /* Look for the start of the next message */ +#ifdef MMDF if (is_msg_boundary(buffer)) break; +#else + if (strncmp(buffer,"From ",5) == 0) break; +#endif /* Decrement the lines sent (for a TOP command) */ if (msg_lines >= 0 && msg_lines-- == 0) break; pop_sendline(p,buffer); diff --git a/src/appl/popper/pop_stat.c b/src/appl/popper/pop_stat.c index 20f94427e..d23935727 100644 --- a/src/appl/popper/pop_stat.c +++ b/src/appl/popper/pop_stat.c @@ -6,7 +6,7 @@ #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_stat.c 1.5 7/13/90"; +static char SccsId[] = "@(#)pop_stat.c 2.2 3/18/91"; #endif not lint #include @@ -20,6 +20,9 @@ static char SccsId[] = "@(#)pop_stat.c 1.5 7/13/90"; int pop_stat (p) POP * p; { +#ifdef DEBUG + if (p->debug) pop_log(p,POP_DEBUG,"%d message(s) (%d octets).",p->msg_count-p->msgs_deleted,p->drop_size-p->bytes_deleted); +#endif DEBUG return (pop_msg (p,POP_SUCCESS, "%u %u",p->msg_count-p->msgs_deleted,p->drop_size-p->bytes_deleted)); } diff --git a/src/appl/popper/pop_updt.c b/src/appl/popper/pop_updt.c index ebedb0fc9..38cbdaf28 100644 --- a/src/appl/popper/pop_updt.c +++ b/src/appl/popper/pop_updt.c @@ -4,27 +4,27 @@ * specifies the terms and conditions for redistribution. */ -/* - * code for mh compatibility (tom) - */ - #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_updt.c 1.9 8/16/90"; +static char SccsId[] = "@(#)pop_updt.c 2.3 3/20/91"; #endif not lint #include #include +#ifdef HAS_UNISTD_H +#include +#endif +#ifdef POSIX_FILE_LOCKS +#include +#endif #include #include #include #include #include "popper.h" -extern int errno; - static char standard_error[] = - "Error updating primary drop. Mailbox unchanged."; + "Error error updating primary drop. Mailbox unchanged"; /* * updt: Apply changes to a user's POP maildrop @@ -45,11 +45,14 @@ POP * p; counter */ register int status_written; /* Status header field written */ - int nchar; /* Bytes read/written */ + int nchar; /* Bytes read/written */ + + off_t offset; /* New mail offset */ - long offset; /* New mail offset */ - int begun; /* Sanity check */ +#ifdef POSIX_FILE_LOCKS + struct flock lock_arg; +#endif #ifdef DEBUG if (p->debug) { @@ -72,18 +75,29 @@ POP * p; #endif DEBUG /* Open the user's real maildrop */ - if (((mfd = open(p->drop_name,O_RDWR|O_CREAT,0666)) == -1 ) || - ((md = fdopen(mfd,"r+")) == NULL)) { - return pop_msg(p,POP_FAILURE,"%s %s", - p->drop_name, sys_errlist[errno]); + if ((mfd = open(p->drop_name,O_RDWR|O_CREAT,0600)) == -1 || + (md = fdopen(mfd,"r+")) == NULL) { + return pop_msg(p,POP_FAILURE,standard_error); } /* Lock the user's real mail drop */ +#ifdef POSIX_FILE_LOCKS + lock_arg.l_type = F_WRLCK; + lock_arg.l_whence = 0; + lock_arg.l_start = 0; + lock_arg.l_len = 0; + if ( fcntl(mfd, F_SETLKW, &lock_arg) == -1) { + (void)fclose(md) ; + return pop_msg(p,POP_FAILURE, "lockf: '%s': %s", p->temp_drop, + strerror(errno)); + } +#else if ( flock(mfd,LOCK_EX) == -1 ) { (void)fclose(md) ; return pop_msg(p,POP_FAILURE, "flock: '%s': %s", p->temp_drop, - (errno < sys_nerr) ? sys_errlist[errno] : ""); + strerror(errno)); } +#endif /* Go to the right places */ offset = lseek((int)fileno(p->drop),0,L_XTND) ; @@ -97,7 +111,7 @@ POP * p; } if ( nchar != 0 ) { (void)fclose(md) ; - (void)ftruncate((int)fileno(p->drop),(int)offset) ; + (void)ftruncate((int)fileno(p->drop),offset) ; (void)fclose(p->drop) ; return pop_msg(p,POP_FAILURE,standard_error); } @@ -116,11 +130,11 @@ POP * p; pop_log(p,POP_DEBUG,"Creating new maildrop \"%s\" from \"%s\"", p->drop_name,p->temp_drop); #endif DEBUG - + for (msg_num = 0; msg_num < p->msg_count; ++msg_num) { int doing_body; - + /* Get a pointer to the message information list */ mp = &p->mlp[msg_num]; @@ -132,14 +146,13 @@ POP * p; #endif DEBUG continue; } - + (void)fseek(p->drop,mp->offset,0); #ifdef DEBUG if(p->debug) pop_log(p,POP_DEBUG,"Copying message %d.",mp->number); #endif DEBUG - begun = 0; for(status_written = doing_body = 0 ; @@ -147,6 +160,7 @@ POP * p; if (doing_body == 0) { /* Header */ +#ifdef MMDF /* panic, I'm tired and can't think contorted. */ if(is_msg_boundary(buffer) && begun) { pop_log(p, POP_ERROR, @@ -158,7 +172,7 @@ POP * p; } begun = 1; - +#endif /* Update the message status */ if (strncasecmp(buffer,"Status:",7) == 0) { if (mp->retr_flag) @@ -171,32 +185,31 @@ POP * p; /* A blank line signals the end of the header. */ if (*buffer == '\n') { doing_body = 1; - -#ifndef NOSTATUS if (status_written == 0) { if (mp->retr_flag) (void)fputs("Status: RO\n\n",md); else (void)fputs("Status: U\n\n",md); } - else -#endif /* NOSTATUS */ - (void)fputs ("\n", md); + else (void)fputs ("\n", md); continue; } /* Save another header line */ (void)fputs (buffer, md); - } - else { /* Body */ + } + else { /* Body */ +#ifdef MMDF if (strncmp(buffer,"\001\001\001\001",4) == 0) { (void)fputs (buffer, md); break; } - if(is_msg_boundary(buffer)) - break; + if (is_msg_boundary(buffer)) break; +#else + if (strncmp(buffer,"From ",5) == 0) break; +#endif (void)fputs (buffer, md); - } - } + } + } } /* flush and check for errors now! The new mail will writen @@ -233,9 +246,7 @@ POP * p; return(pop_quit(p)); } - - - +#ifdef MMDF is_msg_boundary(line) char *line; { @@ -251,8 +262,12 @@ is_msg_boundary(line) if(*line++ != ' ') return(0); - - if(strlen(line) < 28) + + /* + * check the line length but some timestamps do not include time zone + */ + + if(strlen(line) < 24) return(0); /* Tue */ @@ -285,4 +300,4 @@ is_msg_boundary(line) return(1); } - +#endif diff --git a/src/appl/popper/pop_user.c b/src/appl/popper/pop_user.c index dee41edd6..6559e6a98 100644 --- a/src/appl/popper/pop_user.c +++ b/src/appl/popper/pop_user.c @@ -6,7 +6,7 @@ #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_user.c 1.5 7/13/90"; +static char SccsId[] = "@(#)pop_user.c 2.1 3/18/91"; #endif not lint #include @@ -14,6 +14,24 @@ static char SccsId[] = "@(#)pop_user.c 1.5 7/13/90"; #include #include "popper.h" +#ifdef KERBEROS +#ifdef KRB4 +#ifdef KRB5 + #error you can only use one of KRB4, KRB5 +#endif +#include +extern AUTH_DAT kdata; +#endif /* KRB4 */ +#ifdef KRB5 +#include +#include +#include +#include +extern krb5_principal ext_client; +extern char *client_name; +#endif /* KRB5 */ +#endif /* KERBEROS */ + /* * user: Prompt for the user name at the start of a POP session */ @@ -24,6 +42,24 @@ POP * p; #ifndef KERBEROS /* Save the user name */ (void)strcpy(p->user, p->pop_parm[1]); + +#else /* KERBEROS */ + + if(strcmp(p->pop_parm[1], p->user)) + { +#ifdef KRB4 + pop_log(p, POP_WARNING, "%s: auth failed: %s.%s@@%s vs %s", + p->client, kdata.pname, kdata.pinst, kdata.prealm, + p->pop_parm[1]); +#else + pop_log(p, POP_WARNING, "%s: auth failed: %s vs %s", + p->client, p->user, p->pop_parm[1]); +#endif + return(pop_msg(p,POP_FAILURE, + "Wrong username supplied (%s vs. %s).\n", p->user, + p->pop_parm[1])); + } + #endif /* KERBEROS */ /* Tell the user that the password is required */ diff --git a/src/appl/popper/pop_xmit.c b/src/appl/popper/pop_xmit.c index 4096f3023..21cbe61dd 100644 --- a/src/appl/popper/pop_xmit.c +++ b/src/appl/popper/pop_xmit.c @@ -6,15 +6,22 @@ #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_xmit.c 1.5 7/13/90"; +static char SccsId[] = "@(#)pop_xmit.c 2.1 3/18/91"; #endif not lint #include #include #include #include +#ifdef HAS_PATHS_H +#include +#endif #include "popper.h" +#ifndef _PATH_SENDMAIL +#define _PATH_SENDMAIL "/usr/lib/sendmail" +#endif + /* * xmit: POP XTND function to receive a message from * a client and send it in the mail @@ -26,13 +33,13 @@ POP * p; FILE * tmp; /* File descriptor for temporary file */ char buffer[MAXLINELEN]; /* Read buffer */ - char temp_xmit[MAXDROPLEN]; /* Name of the temporary + char * temp_xmit; /* Name of the temporary filedrop */ union wait stat; int id, pid; /* Create a temporary file into which to copy the user's message */ - (void)mktemp((char *)strcpy(temp_xmit,POP_TMPXMIT)); + temp_xmit = tempnam(NULL, "xmitXXXXXX"); #ifdef DEBUG if(p->debug) pop_log(p,POP_DEBUG, @@ -65,7 +72,7 @@ POP * p; (void)fclose (tmp); #ifdef DEBUG - if(p->debug)pop_log(p,POP_DEBUG,"Forking for \"%s\"",MAIL_COMMAND); + if(p->debug)pop_log(p,POP_DEBUG,"Forking for \"%s\"",_PATH_SENDMAIL); #endif DEBUG /* Send the message */ switch (pid = fork()) { @@ -74,14 +81,14 @@ POP * p; (void)fclose (p->output); (void)close(0); if (open(temp_xmit,O_RDONLY,0) < 0) (void)_exit(1); - (void)execl (MAIL_COMMAND,"send-mail","-t","-oem",NULLCP); + (void)execl (_PATH_SENDMAIL,"send-mail","-t","-oem",NULLCP); (void)_exit(1); case -1: #ifdef DEBUG if (!p->debug) (void)unlink (temp_xmit); #endif DEBUG return (pop_msg(p,POP_FAILURE, - "Unable to execute \"%s\"",MAIL_COMMAND)); + "Unable to execute \"%s\"",_PATH_SENDMAIL)); default: while((id = wait(&stat)) >=0 && id != pid); if (!p->debug) (void)unlink (temp_xmit); @@ -89,5 +96,5 @@ POP * p; return (pop_msg(p,POP_FAILURE,"Unable to send message")); return (pop_msg (p,POP_SUCCESS,"Message sent successfully")); } - + free(temp_xmit); } diff --git a/src/appl/popper/pop_xtnd.c b/src/appl/popper/pop_xtnd.c index 29aaed8f7..cb3b07e3b 100644 --- a/src/appl/popper/pop_xtnd.c +++ b/src/appl/popper/pop_xtnd.c @@ -6,7 +6,7 @@ #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)pop_xtnd.c 1.5 7/13/90"; +static char SccsId[] = "@(#)pop_xtnd.c 2.1 3/18/91"; #endif not lint #include diff --git a/src/appl/popper/popper.M b/src/appl/popper/popper.M index bfd3b1d72..390809ac4 100644 --- a/src/appl/popper/popper.M +++ b/src/appl/popper/popper.M @@ -8,11 +8,13 @@ .\" software without specific prior written permission. This software .\" is provided ``as is'' without express or implied warranty. .\" -.\" @(#)popper.8 1.3 (CCS) 9/15/90 Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n +.\" @(#)@(#)popper.8 2.3 2.3 (CCS) 4/2/91 Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n .\" -.TH popper 8 "Kerberos Version 5.0" "MIT Project Athena" +.TH popper 8 "August 1990" +.UC 6 +.ad .SH NAME -popper \- Kerberized Berkeley pop 3 server +popper \- pop 3 server .SH SYNOPSIS .B /usr/etc/popper [ -d ] @@ -24,29 +26,7 @@ variety of Unix computers to manage electronic mail for Macintosh and MS-DOS computers. The server was developed at the University of California at Berkeley and conforms fully to the specifications in RFC 1081 and RFC 1082. The Berkeley server also has extensions to -send electronic mail on behalf of a client. - -This Kerberized version of popper works like just like the Berkeley -POP server, except -that it expects the client to do a Kerberos authentication at the very -beginning (using krb5_sendauth). After the successful Kerberos -exchange, the protocol reverts back to standard POP protocol, except -that the username must match the Kerberos principal used in the initial -authentication, and the password command is ignored, since the user has -already authenticated using Kerberos. -.PP -The kerberized version of popper is invoked out of -.IR inetd(8), -using a -line in /etc/inetd.conf like this: -.PP -kpop stream tcp nowait root /usr/etc/popper popper -.PP -Since a Kerberos authentication is required at the beginning, the port -used by the Kerberized POP protocol is different from the standard -Berkeley POP -protocol. This port is kpop, and it is traditionally 1109 (where the -official Berkely port is 110 for version 3 and 109 for version 2). +send electronic mail on behalf of a client. .PP The .B \-d @@ -56,26 +36,31 @@ information is saved using syslog(8). The flag turns on debugging and saves the trace information in .I trace\-file using fprintf(s). -.\" .SH HOW TO OBTAIN THE SERVER -.\" .PP -.\" The POP server is available via anonymous ftp from lilac.Berkeley.EDU -.\" (128.32.136.12). It is in two files in the pub directory: a compressed -.\" tar file popper.tar.Z and a Macintosh StuffIt archive in BinHex format -.\" called MacPOP.sit.hqx. -.\" +.SH HOW TO OBTAIN THE SERVER +.PP +The POP server is available via anonymous ftp from ftp.CC.Berkeley.EDU +(128.32.136.9, 128.32.206.12). It is in two files in the pub directory: +a compressed +tar file popper.tar.Z and a Macintosh StuffIt archive in BinHex format +called MacPOP.sit.hqx. .SH THE POP TRANSACTION CYCLE .PP -The Kerberized Berkeley POP server is a single program (called popper) that is -launched by inetd when it gets a service request on the KPOP TCP port. +The Berkeley POP server is a single program (called popper) that is +launched by inetd when it gets a service request on the POP TCP port. +(The official port number specified in RFC 1081 for POP version 3 is +port 110. However, some POP3 clients attempt to contact the server at +port 109, the POP version 2 port. Unless you are running both POP2 and +POP3 servers, you can simply define both ports for use by the POP3 +server. This is explained in the installation instructions later on.) The popper program initializes and verifies that the peer IP address is registered in the local domain, logging a warning message when a connection is made to a client whose IP address does not have a canonical name. For systems using BSD 4.3 bind, it also checks to see if a cannonical name lookup for the client returns the same peer IP address, logging a warning message if it does not. The the server -enters the authorization state, during which the client sends the -password command with a dummy password, since authentication is done -with Kerberos credentials. No other exchanges are allowed during this +enters the authorization state, during which the client must correctly +identify itself by providing a valid Unix userid and password on the +server's host machine. No other exchanges are allowed during this state (other than a request to quit.) If authentication fails, a warning message is logged and the session ends. Once the user is identified, popper changes its user and group ids to match that of the @@ -106,18 +91,18 @@ be exercised in using this option since it generates considerable output in the syslog file. Alternatively, the "-t " option will place debugging information into file "" using fprintf instead of syslog. -.\" .PP -.\" For SunOS version 3.5, the popper program is launched by inetd from -.\" /etc/servers. This file does not allow you to specify command line -.\" arguments. Therefore, if you want to enable debugging, you can specify -.\" a shell script in /etc/servers to be launched instead of popper and in -.\" this script call popper with the desired arguments. +.PP +For SunOS version 3.5, the popper program is launched by inetd from +/etc/servers. This file does not allow you to specify command line +arguments. Therefore, if you want to enable debugging, you can specify +a shell script in /etc/servers to be launched instead of popper and in +this script call popper with the desired arguments. .PP You can confirm that the POP server is running on Unix by telneting to -port 1109. For example: +port 110 (or 109 if you set it up that way). For example: .PP .nf -%telnet myhost 1109 +%telnet myhost 110 Trying... Connected to myhost.berkeley.edu. Escape character is '^]'. @@ -142,6 +127,19 @@ in response to a TOP or RETR command. Encased all debugging code in #ifdef DEBUG constructs. This code can be included by specifying the DEGUG compiler flag. Note: You still need to use the -d or -t option to obtain debugging output. +.SH LIMITATIONS +The POP server copies the user's entire maildrop to /tmp and +then operates on that copy. If the maildrop is particularly +large, or inadequate space is available in /tmp, then the +server will refuse to continue and terminate the connection. +.PP +Simultaneous modification of a single maildrop can result in +confusing results. For example, manipulating messages in a +maildrop using the Unix /usr/ucb/mail command while a copy of +it is being processed by the POP server can cause the changes +made by one program to be lost when the other terminates. This +problem is being worked on and will be fixed in a later +release. .SH FILES .nf /usr/spool/mail mail files @@ -154,5 +152,4 @@ RFC1081, RFC1082 .SH AUTHORS Bob Campbell, Edward Moy, Austin Shelton, Marshall T Rose, and cast of -thousands at Rand, UDel, UCI, and elsewhere. -Kerberos authentication added by Tom Coppeto - MIT Network Services. +thousands at Rand, UDel, UCI, and elsewhere diff --git a/src/appl/popper/popper.c b/src/appl/popper/popper.c index be94f9312..e05020667 100644 --- a/src/appl/popper/popper.c +++ b/src/appl/popper/popper.c @@ -6,7 +6,7 @@ #ifndef lint static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; -static char SccsId[] = "@(#)popper.c 1.7 7/13/90"; +static char SccsId[] = "@(#)popper.c 2.1 3/18/91"; #endif not lint #include @@ -42,7 +42,7 @@ char ** argv; #else /* !KERBEROS */ "UCB Pop server (version %s) at %s starting.", #endif /* KERBEROS */ - VERSION,p.myhost); + VERSION,p.myhost); /* State loop. The POP server is always in a particular state in which a specific suite of commands can be executed. The following @@ -60,6 +60,7 @@ char ** argv; else { /* Search for the command in the command/state table */ if ((s = pop_get_command(&p,message)) == NULL) continue; + /* Call the function associated with this command in the current state */ if (s->function) p.CurrentState = s->result[(*s->function)(&p)]; @@ -72,13 +73,12 @@ char ** argv; } } - /* Say goodbye to the client */ pop_msg(&p,POP_SUCCESS,"Pop server at %s signing off.",p.myhost); /* Log the end of activity */ - pop_log(&p,POP_DEBUG, - "%s: (v%s) Ending request from \"%s\".\n",p.ipaddr,VERSION,p.client); + pop_log(&p,POP_PRIORITY, + "(v%s) Ending request from \"%s\" at %s\n",VERSION,p.user,p.ipaddr); /* Stop logging */ closelog(); diff --git a/src/appl/popper/popper.h b/src/appl/popper/popper.h index 5c9db41eb..0c93f77cd 100644 --- a/src/appl/popper/popper.h +++ b/src/appl/popper/popper.h @@ -4,7 +4,7 @@ * specifies the terms and conditions for redistribution. * * static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; - * static char SccsId[] = "@(#)popper.h 1.10 7/13/90"; + * static char SccsId[] = "@(#)popper.h 2.2 4/2/91"; * */ @@ -26,14 +26,13 @@ #define MAXHOSTNAMELEN 256 #define MAXUSERNAMELEN 65 -#define MAXDROPLEN 296 /* was 65: kerberos name + max path size - tom */ +#define MAXDROPLEN 64 #define MAXLINELEN 1024 #define MAXMSGLINELEN 1024 #define MAXCMDLEN 4 #define MAXPARMCOUNT 5 #define MAXPARMLEN 10 #define ALLOC_MSGS 20 -#define MAIL_COMMAND "/usr/lib/sendmail" #define POP_FACILITY LOG_LOCAL0 #define POP_ERROR LOG_ERR @@ -42,10 +41,25 @@ #define POP_INFO LOG_INFO #define POP_DEBUG LOG_DEBUG #define POP_LOGOPTS 0 -#define POP_MAILDIR "/usr/spool/pop" + +#ifdef POP_PVT_PASSWD +#ifndef POP_PASSFILE #define POP_PASSFILE "/usr/spool/pop/POP" -#define POP_DROP "/usr/spool/pop/.%s.temp" -#define POP_TMPXMIT "/tmp/xmitXXXXXX" +#endif /* POP_PASSFILE */ +#endif + +#ifndef MAILDIR +#ifdef BSD +#if BSD < 199103 +#define MAILDIR "/usr/spool/mail" +#else +#define MAILDIR "/var/mail" +#endif +#else +#define MAILDIR "/usr/mail" +#endif +#endif + #define POP_OK "+OK" #define POP_ERR "-ERR" #define POP_SUCCESS 1 @@ -53,9 +67,6 @@ #define POP_TERMINATE '.' extern int errno; -extern int sys_nerr; -extern char * sys_errlist[]; -extern char * sys_siglist[]; #define pop_command pop_parm[0] /* POP command is first token */ #define pop_subcommand pop_parm[1] /* POP XTND subcommand is the diff --git a/src/appl/popper/version.h b/src/appl/popper/version.h index 4512cb4a5..a0cdea438 100644 --- a/src/appl/popper/version.h +++ b/src/appl/popper/version.h @@ -4,12 +4,19 @@ * specifies the terms and conditions for redistribution. * * static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; - * static char SccsId[] = "@(#)version.h 1.11 9/15/90"; + * static char SccsId[] = "@(#)version.h 2.6 4/3/91"; * */ /* * Current version of this POP implementation */ - -#define VERSION "1.7" +#ifdef KERBEROS +#ifdef KRB5 +#define VERSION "1.831beta Kerberos5" +#else +#define VERSION "1.831beta KerberosIV" +#endif +#else +#define VERSION "1.831beta" +#endif