summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlain Magloire <alainm@gnu.org>2001-04-24 05:09:27 +0000
committerAlain Magloire <alainm@gnu.org>2001-04-24 05:09:27 +0000
commit39dec3bccc1688d620e15a526f924cb8315f74ee (patch)
treee3528aace005926def7cc70654bdcc23b660cff9
parentdf064ef2b8140a8269106eb3c300a33a27fbdc50 (diff)
downloadmailutils-39dec3bccc1688d620e15a526f924cb8315f74ee.tar.gz
mailutils-39dec3bccc1688d620e15a526f924cb8315f74ee.tar.bz2
2001-04-23 Alain Magloire
* pop3d/*.[ch]: Rename all the pop function pop3d_xx() instead of pop3_xx() to be consistent with imap4d/*. * mailbox/mbx_pop.c (pop_user): This is sudden death; for many pop servers, it is important to let them time to remove locks or move the .user.pop files. This happen when we do BUSY_CHECK(). For example, the user does not want to read the entire file, and wants start to read a new message, closing the connection and immediately contact the server again, and we'll end up having "-ERR Mail Lock busy" or something similar. To prevent this race condition we sleep 2 seconds. 2001-04-23 Sergey Poznyakoff It is often convenient to separte log outputs from POP and SMTP servers. --with-log-facility flag which allows to specify to which log facility the loggin output should be directed. System administrators often prefere to have more information about unsuccessfull authentications. I have added more verbose logging to pop3d/user.c. Both failed attempts and possible account probes (USER immediately followed by QUIT) are logged. Made pop3d to be less verbose about its WELCOME prompt. When the symbol TERSE_MODE is defined, pop3d introduces itself just as +OK POP3 ready <apop_hash> insead of divulging its type and version. This is a bit paranoid, but it is better to be on the safe side...
-rw-r--r--ChangeLog57
-rw-r--r--acconfig.h3
-rw-r--r--configure.in11
-rw-r--r--doc/mailutils.texi2
-rw-r--r--mailbox/mapfile_stream.c3
-rw-r--r--mailbox/mbx_pop.c27
-rw-r--r--pop3d/apop.c12
-rw-r--r--pop3d/auth.c2
-rw-r--r--pop3d/capa.c2
-rw-r--r--pop3d/dele.c2
-rw-r--r--pop3d/extra.c32
-rw-r--r--pop3d/list.c2
-rw-r--r--pop3d/noop.c4
-rw-r--r--pop3d/pop3d.c119
-rw-r--r--pop3d/pop3d.h58
-rw-r--r--pop3d/signal.c5
-rw-r--r--pop3d/user.c20
17 files changed, 248 insertions, 113 deletions
diff --git a/ChangeLog b/ChangeLog
index 6f0de026b..4cc0ef9b5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,61 @@
+2001-04-23 Alain Magloire
+
+ * pop3d/*.[ch]: Rename all the pop function pop3d_xx()
+ instead of pop3_xx() to be consistent with imap4d/*.
+
+ * mailbox/mbx_pop.c (pop_user): This is sudden death; for many pop
+ servers, it is important to let them time to remove locks or move
+ the .user.pop files. This happen when we do BUSY_CHECK(). For
+ example, the user does not want to read the entire file, and wants
+ start to read a new message, closing the connection and immediately
+ contact the server again, and we'll end up having
+ "-ERR Mail Lock busy" or something similar. To prevent this race
+ condition we sleep 2 seconds.
+
+2001-04-23 Sergey Poznyakoff
+
+ It is often convenient to separte log outputs from POP and SMTP
+ servers. --with-log-facility flag which allows to specify to which
+ log facility the loggin output should be directed.
+ System administrators often prefere to have more information about
+ unsuccessfull authentications. I have added more verbose logging
+ to pop3d/user.c. Both failed attempts and possible account probes
+ (USER immediately followed by QUIT) are logged.
+ Made pop3d to be less verbose about its WELCOME prompt. When the
+ symbol TERSE_MODE is defined, pop3d introduces itself just as
+ +OK POP3 ready <apop_hash>
+ insead of divulging its type and version. This is a bit paranoid,
+ but it is better to be on the safe side...
+
+ * configure.in: ARGPINC gets assigne a relative path, due
+ to which the compilation fails if the package is configure with
+ --srdir=<path> option.
+ * configure.in: --with-log-facility new option.
+ * acconfig.h: LOG_FACILITY
+
+ * doc/mailutils.texi: Typo.
+
+ * mailbox/mapfile_stream.c: Define MAP_FAILED.
+
+ * pop3d/extra.c (pop3_abquit): new case ERR_MBOX_SYNC.
+ (pop3_signal): Syslog the reason.
+ * pop3d/pop3d.c (pop_mainloop): Syslog the hostname of
+ the user on connect.
+ (pop3_daemon): Log to many children. Lacks call to exit(), so if
+ pop3d is run as a daemon, any child after exiting from
+ pop3_mainloop tries to accept() from already closed socket
+ and issues spurious error messages.
+ (pop3_mainloop): Check if the mailbox is uptodate if not
+ and the size shrink, bail out. Do not send version number.
+ * pop3d/pop3d.h: ERR_MBOX_SYNC define. WELCOME removed.
+ * pop3d/signal (pop3_sigchld): Lacks signal() call, due to which
+ the signal handler gets cleared after first SIGCHLD and all
+ subsequent children, when finished, just hang around like zombies.
+ * pop3d/user.c: Log to LOG_FACILITY all the errors.
+
2001-04-23 Alain Magloire
- Sergey Poznyakoff pointed out that errno change depending
+ Sergey Poznyakoff pointed out that errno changes depending
if _REENTRANT is set or not. So for enable thread we take
the approach of always defining _REENTRANT.
He also noted that when in standalone the child was not exiting.
diff --git a/acconfig.h b/acconfig.h
index 4b308cbf6..ad8b738ae 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -32,3 +32,6 @@
/* Define _REENTRANT when using threads. */
#undef _REENTRANT
+
+/* Define the default loggin facility. */
+#undef LOG_FACILITY
diff --git a/configure.in b/configure.in
index ff4d08126..f6b70b474 100644
--- a/configure.in
+++ b/configure.in
@@ -42,6 +42,15 @@ AC_ARG_WITH(db2,
*) AC_MSG_ERROR(bad value ${withval} for --with-db) ;;
esac],[usedb2=no])
+AC_MSG_CHECKING(for log facility)
+log_facility="LOG_MAIL"
+AC_ARG_WITH(log-facility,
+ [ --with-log-facility=facility enable logging to the given facility],
+ AC_TRY_COMPILE([#include <syslog.h>], int lf = $withval,
+ log_facility=$withval))
+AC_DEFINE_UNQUOTED(LOG_FACILITY, $log_facility)
+AC_MSG_RESULT($log_facility)
+
dnl Check for headers
AC_HEADER_STDC
AC_HEADER_DIRENT
@@ -79,7 +88,7 @@ if test x"$ac_cv_func_argp_parse" != xyes; then
AC_REPLACE_FUNCS(strndup strnlen strchrnul)
ARGPLIBS="../argp/libargp.a"
ARGPLIB="libargp.a"
- ARGPINCS="-I../argp"
+ ARGPINCS='-I$(top_srcdir)/argp'
AC_SUBST(ARGPLIBS)
AC_SUBST(ARGPLIB)
AC_SUBST(ARGPINCS)
diff --git a/doc/mailutils.texi b/doc/mailutils.texi
index 5abb27b55..f5032409e 100644
--- a/doc/mailutils.texi
+++ b/doc/mailutils.texi
@@ -158,7 +158,7 @@ mailers.
@end group
@end example
-For example writing a simple @command{from} command that will list the
+For example writing a simple @code{from} command that will list the
@emph{From} and @emph{Subject} headers of every mail in a folder.
@example
diff --git a/mailbox/mapfile_stream.c b/mailbox/mapfile_stream.c
index 4098fd5f0..f20b8fec4 100644
--- a/mailbox/mapfile_stream.c
+++ b/mailbox/mapfile_stream.c
@@ -34,6 +34,9 @@
#ifdef _POSIX_MAPPED_FILES
#include <sys/mman.h>
+#ifndef MAP_FAILED
+# define MAP_FAILED (void*)-1
+#endif
struct _mapfile_stream
{
diff --git a/mailbox/mbx_pop.c b/mailbox/mbx_pop.c
index eceb38d76..158b075ea 100644
--- a/mailbox/mbx_pop.c
+++ b/mailbox/mbx_pop.c
@@ -24,6 +24,8 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdarg.h>
@@ -112,6 +114,7 @@ static int pop_attr_flags __P ((attribute_t, int *));
static int pop_uidl __P ((message_t, char *, size_t, size_t *));
static int pop_uid __P ((message_t, size_t *));
static int fill_buffer __P ((pop_data_t, char *, size_t));
+static int pop_sleep __P ((int));
static int pop_readline __P ((pop_data_t));
static int pop_read_ack __P ((pop_data_t));
static int pop_writeline __P ((pop_data_t, const char *, ...));
@@ -512,7 +515,18 @@ pop_open (mailbox_t mbox, int flags)
stream_setbufsiz (mbox->stream, BUFSIZ);
}
else
- stream_close (mbox->stream);
+ {
+ /* This is sudden death: for many pop servers, it is important to
+ let them time to remove locks or move the .user.pop files. This
+ happen when we do BUSY_CHECK(). For example, the user does not
+ want to read the entire file, and wants start to read a new
+ message, closing the connection and immediately contact the
+ server again, and we'll end up having "-ERR Mail Lock busy" or
+ something similar. To prevent this race condition we sleep 2
+ seconds. */
+ stream_close (mbox->stream);
+ pop_sleep (2);
+ }
mpd->state = POP_OPEN_CONNECTION;
case POP_OPEN_CONNECTION:
@@ -1739,6 +1753,17 @@ pop_retr (pop_message_t mpm, char *buffer, size_t buflen, off_t offset,
return 0;
}
+/* GRRRRR!! We can not use sleep in the library since this we'll
+ muck up any alarm() done by the user. */
+static int
+pop_sleep (int seconds)
+{
+ struct timeval tval;
+ tval.tv_sec = seconds;
+ tval.tv_usec = 0;
+ return select (1, NULL, NULL, NULL, &tval);
+}
+
/* C99 says that a conforming implementation of snprintf () should return the
number of char that would have been call but many old GNU/Linux && BSD
implementations return -1 on error. Worse QnX/Neutrino actually does not
diff --git a/pop3d/apop.c b/pop3d/apop.c
index c01e8221f..74fe4cf26 100644
--- a/pop3d/apop.c
+++ b/pop3d/apop.c
@@ -20,7 +20,7 @@
/* Check if a username exists in APOP password file
returns pointer to password if found, otherwise NULL */
char *
-pop3_apopuser (const char *user)
+pop3d_apopuser (const char *user)
{
char *password;
char buf[POP_MAXCMDLEN];
@@ -88,7 +88,7 @@ pop3_apopuser (const char *user)
if (password == NULL)
{
fclose (apop_file);
- pop3_abquit (ERR_NO_MEM);
+ pop3d_abquit (ERR_NO_MEM);
}
password[0] = '\0';
@@ -122,7 +122,7 @@ pop3_apopuser (const char *user)
}
int
-pop3_apop (const char *arg)
+pop3d_apop (const char *arg)
{
char *tmp, *user_digest, *password;
struct passwd *pw;
@@ -138,15 +138,15 @@ pop3_apop (const char *arg)
if (strlen (arg) == 0)
return ERR_BAD_ARGS;
- username = pop3_cmd (arg);
+ username = pop3d_cmd (arg);
if (strlen (username) > (POP_MAXCMDLEN - APOP_DIGEST))
{
free (username);
return ERR_BAD_ARGS;
}
- user_digest = pop3_args (arg);
+ user_digest = pop3d_args (arg);
- password = pop3_apopuser (username);
+ password = pop3d_apopuser (username);
if (password == NULL)
{
free (username);
diff --git a/pop3d/auth.c b/pop3d/auth.c
index 44d0fbe54..6e5fa1ee4 100644
--- a/pop3d/auth.c
+++ b/pop3d/auth.c
@@ -20,7 +20,7 @@
/* AUTH is not yet implemented */
int
-pop3_auth (const char *arg)
+pop3d_auth (const char *arg)
{
(void)arg;
if (state != AUTHORIZATION)
diff --git a/pop3d/capa.c b/pop3d/capa.c
index 1d3241d93..1b2100692 100644
--- a/pop3d/capa.c
+++ b/pop3d/capa.c
@@ -18,7 +18,7 @@
#include "pop3d.h"
int
-pop3_capa (const char *arg)
+pop3d_capa (const char *arg)
{
if (strlen (arg) != 0)
return ERR_BAD_ARGS;
diff --git a/pop3d/dele.c b/pop3d/dele.c
index 7efe94846..47ef5f0b0 100644
--- a/pop3d/dele.c
+++ b/pop3d/dele.c
@@ -20,7 +20,7 @@
/* DELE adds a message number to the list of messages to be deleted on QUIT */
int
-pop3_dele (const char *arg)
+pop3d_dele (const char *arg)
{
size_t num = 0;
message_t msg;
diff --git a/pop3d/extra.c b/pop3d/extra.c
index feee141ab..39f790b78 100644
--- a/pop3d/extra.c
+++ b/pop3d/extra.c
@@ -21,7 +21,7 @@
after the first space, or a zero length string if no space */
char *
-pop3_args (const char *cmd)
+pop3d_args (const char *cmd)
{
int space = -1, i = 0, len;
char *buf;
@@ -29,7 +29,7 @@ pop3_args (const char *cmd)
len = strlen (cmd) + 1;
buf = malloc (len * sizeof (char));
if (buf == NULL)
- pop3_abquit (ERR_NO_MEM);
+ pop3d_abquit (ERR_NO_MEM);
while (space < 0 && i < len)
{
@@ -58,7 +58,7 @@ pop3_args (const char *cmd)
the string, whichever occurs first */
char *
-pop3_cmd (const char *cmd)
+pop3d_cmd (const char *cmd)
{
char *buf;
int i = 0, len;
@@ -66,7 +66,7 @@ pop3_cmd (const char *cmd)
len = strlen (cmd) + 1;
buf = malloc (len * sizeof (char));
if (buf == NULL)
- pop3_abquit (ERR_NO_MEM);
+ pop3d_abquit (ERR_NO_MEM);
for (i = 0; i < len; i++)
{
@@ -84,7 +84,7 @@ pop3_cmd (const char *cmd)
being killed on a signal */
int
-pop3_abquit (int reason)
+pop3d_abquit (int reason)
{
mailbox_close (mbox);
mailbox_destroy (&mbox);
@@ -118,6 +118,11 @@ pop3_abquit (int reason)
syslog (LOG_INFO, "No socket to send to");
break;
+ case ERR_MBOX_SYNC:
+ syslog (LOG_ERR, "Mailbox was updated by other party: %s", username);
+ fprintf (ofile, "-ERR Mailbox updated by other party or corrupt\r\n");
+ break;
+
default:
fprintf (ofile, "-ERR Quitting (reason unknown)\r\n");
syslog (LOG_ERR, "Unknown quit");
@@ -133,7 +138,7 @@ pop3_abquit (int reason)
/* Prints out usage information and exits the program */
void
-pop3_usage (char *argv0)
+pop3d_usage (char *argv0)
{
printf ("Usage: %s [OPTIONS]\n", argv0);
printf ("Runs the GNU POP3 daemon.\n\n");
@@ -151,19 +156,20 @@ pop3_usage (char *argv0)
exit (0);
}
-/* Default signal handler to call the pop3_abquit() function */
+/* Default signal handler to call the pop3d_abquit() function */
void
-pop3_signal (int signo)
+pop3d_signal (int signo)
{
(void)signo;
- pop3_abquit (ERR_SIGNAL);
+ syslog (LOG_CRIT, "got signal %d", signo);
+ pop3d_abquit (ERR_SIGNAL);
}
/* Gets a line of input from the client */
char *
-pop3_readline (int fd)
+pop3d_readline (int fd)
{
fd_set rfds;
struct timeval tv;
@@ -183,17 +189,17 @@ pop3_readline (int fd)
{
available = select (fd + 1, &rfds, NULL, NULL, &tv);
if (!available)
- pop3_abquit (ERR_TIMEOUT);
+ pop3d_abquit (ERR_TIMEOUT);
}
nread = read (fd, buf, sizeof (buf) - 1);
if (nread < 1)
- pop3_abquit (ERR_DEAD_SOCK);
+ pop3d_abquit (ERR_DEAD_SOCK);
buf[nread] = '\0';
ret = realloc (ret, (total + nread + 1) * sizeof (char));
if (ret == NULL)
- pop3_abquit (ERR_NO_MEM);
+ pop3d_abquit (ERR_NO_MEM);
memcpy (ret + total, buf, nread + 1);
total += nread;
}
diff --git a/pop3d/list.c b/pop3d/list.c
index 0ddda0262..7c9a9e651 100644
--- a/pop3d/list.c
+++ b/pop3d/list.c
@@ -20,7 +20,7 @@
/* Displays the size of message number arg or all messages (if no arg) */
int
-pop3_list (const char *arg)
+pop3d_list (const char *arg)
{
size_t mesgno;
size_t size = 0;
diff --git a/pop3d/noop.c b/pop3d/noop.c
index c6a146b94..516a6e16c 100644
--- a/pop3d/noop.c
+++ b/pop3d/noop.c
@@ -1,5 +1,5 @@
/* GNU mailutils - a suite of utilities for electronic mail
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2001 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
/* Does nothing */
int
-pop3_noop (const char *arg)
+pop3d_noop (const char *arg)
{
if (strlen (arg) != 0)
return ERR_BAD_ARGS;
diff --git a/pop3d/pop3d.c b/pop3d/pop3d.c
index 08eee6170..09354b5ce 100644
--- a/pop3d/pop3d.c
+++ b/pop3d/pop3d.c
@@ -74,7 +74,7 @@ main (int argc, char **argv)
break;
case 'h':
- pop3_usage (argv[0]);
+ pop3d_usage (argv[0]);
break;
case 'i':
@@ -123,21 +123,21 @@ main (int argc, char **argv)
}
/* Set the signal handlers. */
- signal (SIGINT, pop3_signal);
- signal (SIGQUIT, pop3_signal);
- signal (SIGILL, pop3_signal);
- signal (SIGBUS, pop3_signal);
- signal (SIGFPE, pop3_signal);
- signal (SIGSEGV, pop3_signal);
- signal (SIGTERM, pop3_signal);
- signal (SIGSTOP, pop3_signal);
- signal (SIGPIPE, pop3_signal);
+ signal (SIGINT, pop3d_signal);
+ signal (SIGQUIT, pop3d_signal);
+ signal (SIGILL, pop3d_signal);
+ signal (SIGBUS, pop3d_signal);
+ signal (SIGFPE, pop3d_signal);
+ signal (SIGSEGV, pop3d_signal);
+ signal (SIGTERM, pop3d_signal);
+ signal (SIGSTOP, pop3d_signal);
+ signal (SIGPIPE, pop3d_signal);
if (timeout < 600) /* RFC 1939 says no less than 10 minutes. */
timeout = 0; /* So we'll turn it off. */
if (mode == DAEMON)
- pop3_daemon_init ();
+ pop3d_daemon_init ();
/* Change directory. */
chdir ("/");
@@ -149,10 +149,10 @@ main (int argc, char **argv)
/* Actually run the daemon. */
if (mode == DAEMON)
- pop3_daemon (maxchildren);
- /* exit() -- no way out of daemon except a signal. */
+ pop3d_daemon (maxchildren);
+ /* exit (0) -- no way out of daemon except a signal. */
else
- status = pop3_mainloop (fileno (stdin), fileno (stdout));
+ status = pop3d_mainloop (fileno (stdin), fileno (stdout));
/* Close the syslog connection and exit. */
closelog ();
@@ -161,7 +161,7 @@ main (int argc, char **argv)
/* Sets things up for daemon mode. */
void
-pop3_daemon_init (void)
+pop3d_daemon_init (void)
{
pid_t pid;
unsigned int i;
@@ -171,7 +171,7 @@ pop3_daemon_init (void)
if (pid == -1)
{
perror ("fork failed:");
- exit (-1);
+ exit (1);
}
else if (pid > 0)
exit (0); /* Parent exits. */
@@ -191,18 +191,18 @@ pop3_daemon_init (void)
/* Close inherited file descriptors. */
for (i = 0; i < MAXFD; ++i)
- close(i);
+ close (i);
#ifdef HAVE_SIGACTION
{
struct sigaction act;
- act.sa_handler = pop3_sigchld;
+ act.sa_handler = pop3d_sigchld;
sigemptyset (&act.sa_mask);
act.sa_flags = 0;
sigaction (SIGCHLD, &act, NULL);
}
#else
- signal (SIGCHLD, pop3_sigchld);
+ signal (SIGCHLD, pop3d_sigchld);
#endif
}
@@ -210,7 +210,7 @@ pop3_daemon_init (void)
executes the proper functions. Also handles the bulk of error reporting. */
int
-pop3_mainloop (int infile, int outfile)
+pop3d_mainloop (int infile, int outfile)
{
int status = OK;
char *buf, *arg, *cmd;
@@ -220,17 +220,28 @@ pop3_mainloop (int infile, int outfile)
ifile = infile;
ofile = fdopen (outfile, "w");
if (ofile == NULL)
- pop3_abquit (ERR_NO_OFILE);
+ pop3d_abquit (ERR_NO_OFILE);
state = AUTHORIZATION;
curr_time = time (NULL);
/* FIXME: Retreive hostname with getpeername() and log. */
syslog (LOG_INFO, "Incoming connection opened");
+ /* log information on the connecting client */
+ {
+ struct sockaddr_in cs;
+ int len = sizeof cs;
+ if (getpeername (infile, (struct sockaddr*)&cs, &len) < 0)
+ syslog (LOG_ERR, "can't obtain IP address of client: %s",
+ strerror (errno));
+ else
+ syslog (LOG_INFO, "connect from %s", inet_ntoa(cs.sin_addr));
+ }
+
/* Prepare the shared secret for APOP. */
local_hostname = malloc (MAXHOSTNAMELEN + 1);
if (local_hostname == NULL)
- pop3_abquit (ERR_NO_MEM);
+ pop3d_abquit (ERR_NO_MEM);
gethostname (local_hostname, MAXHOSTNAMELEN);
htbuf = gethostbyname (local_hostname);
@@ -242,52 +253,64 @@ pop3_mainloop (int infile, int outfile)
md5shared = malloc (strlen (local_hostname) + 51);
if (md5shared == NULL)
- pop3_abquit (ERR_NO_MEM);
+ pop3d_abquit (ERR_NO_MEM);
snprintf (md5shared, strlen (local_hostname) + 50, "<%u.%u@%s>", getpid (),
(int)time (NULL), local_hostname);
free (local_hostname);
- fprintf (ofile, "+OK POP3 " WELCOME " %s\r\n", md5shared);
+ fprintf (ofile, "+OK POP3 Ready %s\r\n", md5shared);
while (state != UPDATE)
{
fflush (ofile);
status = OK;
- buf = pop3_readline (ifile);
- cmd = pop3_cmd (buf);
- arg = pop3_args (buf);
+ buf = pop3d_readline (ifile);
+ cmd = pop3d_cmd (buf);
+ arg = pop3d_args (buf);
+
+ if (state == TRANSACTION && !mailbox_is_updated (mbox))
+ {
+ static size_t mailbox_size;
+ size_t newsize = 0;
+ mailbox_get_size (mbox, &newsize);
+ /* Did we shrink? */
+ if (!mailbox_size)
+ mailbox_size = newsize;
+ else (newsize < mailbox_size)
+ pop3d_abquit (ERR_MBOX_SYNC);
+ }
if (strlen (arg) > POP_MAXCMDLEN || strlen (cmd) > POP_MAXCMDLEN)
status = ERR_TOO_LONG;
else if (strlen (cmd) > 4)
status = ERR_BAD_CMD;
else if (strncasecmp (cmd, "RETR", 4) == 0)
- status = pop3_retr (arg);
+ status = pop3d_retr (arg);
else if (strncasecmp (cmd, "DELE", 4) == 0)
- status = pop3_dele (arg);
+ status = pop3d_dele (arg);
else if (strncasecmp (cmd, "USER", 4) == 0)
- status = pop3_user (arg);
+ status = pop3d_user (arg);
else if (strncasecmp (cmd, "QUIT", 4) == 0)
- status = pop3_quit (arg);
+ status = pop3d_quit (arg);
else if (strncasecmp (cmd, "APOP", 4) == 0)
- status = pop3_apop (arg);
+ status = pop3d_apop (arg);
else if (strncasecmp (cmd, "AUTH", 4) == 0)
- status = pop3_auth (arg);
+ status = pop3d_auth (arg);
else if (strncasecmp (cmd, "STAT", 4) == 0)
- status = pop3_stat (arg);
+ status = pop3d_stat (arg);
else if (strncasecmp (cmd, "LIST", 4) == 0)
- status = pop3_list (arg);
+ status = pop3d_list (arg);
else if (strncasecmp (cmd, "NOOP", 4) == 0)
- status = pop3_noop (arg);
+ status = pop3d_noop (arg);
else if (strncasecmp (cmd, "RSET", 4) == 0)
- status = pop3_rset (arg);
+ status = pop3d_rset (arg);
else if ((strncasecmp (cmd, "TOP", 3) == 0) && (strlen (cmd) == 3))
- status = pop3_top (arg);
+ status = pop3d_top (arg);
else if (strncasecmp (cmd, "UIDL", 4) == 0)
- status = pop3_uidl (arg);
+ status = pop3d_uidl (arg);
else if (strncasecmp (cmd, "CAPA", 4) == 0)
- status = pop3_capa (arg);
+ status = pop3d_capa (arg);
else
status = ERR_BAD_CMD;
@@ -326,12 +349,12 @@ pop3_mainloop (int infile, int outfile)
}
/* Runs GNU POP3 in standalone daemon mode. This opens and binds to a port
- (default 110) then executes a pop3_mainloop() upon accepting a connection.
+ (default 110) then executes a pop3d_mainloop() upon accepting a connection.
It starts maxchildren child processes to listen to and accept socket
connections. */
void
-pop3_daemon (unsigned int maxchildren)
+pop3d_daemon (unsigned int maxchildren)
{
SA server, client;
pid_t pid;
@@ -342,7 +365,7 @@ pop3_daemon (unsigned int maxchildren)
if (listenfd == -1)
{
syslog (LOG_ERR, "socket: %s", strerror(errno));
- exit (-1);
+ exit (1);
}
size = 1; /* Use size here to avoid making a new variable. */
setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &size, sizeof(size));
@@ -355,19 +378,20 @@ pop3_daemon (unsigned int maxchildren)
if (bind (listenfd, (struct sockaddr *)&server, size) == -1)
{
syslog (LOG_ERR, "bind: %s", strerror (errno));
- exit (-1);
+ exit (1);
}
if (listen (listenfd, 128) == -1)
{
syslog (LOG_ERR, "listen: %s", strerror (errno));
- exit (-1);
+ exit (1);
}
for (;;)
{
if (children > maxchildren)
{
+ syslog (LOG_ERR, "too many children");
pause ();
continue;
}
@@ -377,7 +401,7 @@ pop3_daemon (unsigned int maxchildren)
if (errno == EINTR)
continue;
syslog (LOG_ERR, "accept: %s", strerror (errno));
- exit (-1);
+ exit (1);
}
pid = fork ();
@@ -387,8 +411,7 @@ pop3_daemon (unsigned int maxchildren)
{
int status;
close (listenfd);
- /* syslog(); FIXME log the info on the connecting client. */
- status = pop3_mainloop (connfd, connfd);
+ status = pop3d_mainloop (connfd, connfd);
closelog ();
exit (status);
}
diff --git a/pop3d/pop3d.h b/pop3d/pop3d.h
index 107f16bec..739225588 100644
--- a/pop3d/pop3d.h
+++ b/pop3d/pop3d.h
@@ -26,9 +26,6 @@
/* You can edit the messages the POP server prints out here */
-/* Initial greeting */
-#define WELCOME "Welcome to " IMPL " (" PACKAGE " " VERSION ")"
-
/* A command that doesn't exist */
#define BAD_COMMAND "Invalid command"
@@ -158,6 +155,7 @@
#define ERR_NO_OFILE 14
#define ERR_TIMEOUT 15
#define ERR_UNKNOWN 16
+#define ERR_MBOX_SYNC 17
#ifndef __P
# ifdef __STDC__
@@ -179,32 +177,30 @@ extern time_t curr_time;
extern char *md5shared;
extern unsigned int children;
-extern int pop3_dele __P ((const char *arg));
-extern int pop3_list __P ((const char *arg));
-extern int pop3_noop __P ((const char *arg));
-extern int pop3_quit __P ((const char *arg));
-extern int pop3_retr __P ((const char *arg));
-extern int pop3_rset __P ((const char *arg));
-extern int pop3_stat __P ((const char *arg));
-extern int pop3_top __P ((const char *arg));
-extern int pop3_uidl __P ((const char *arg));
-extern int pop3_user __P ((const char *arg));
-extern int pop3_apop __P ((const char *arg));
-extern int pop3_auth __P ((const char *arg));
-extern int pop3_capa __P ((const char *arg));
-extern char *pop3_args __P ((const char *cmd));
-extern char *pop3_cmd __P ((const char *cmd));
-extern int pop3_mesg_exist __P ((int mesg));
-extern int pop3_abquit __P ((int reason));
-extern int pop3_lock __P ((void));
-extern int pop3_unlock __P ((void));
-extern int pop3_getsizes __P ((void));
-extern int pop3_mainloop __P ((int infile, int outfile));
-extern void pop3_daemon __P ((unsigned int maxchildren));
-extern void pop3_usage __P ((char *argv0));
-extern void pop3_signal __P ((int));
-extern void pop3_sigchld __P ((int));
-extern void pop3_daemon_init __P ((void));
-extern char *pop3_apopuser __P ((const char *user));
-extern char *pop3_readline __P ((int fd));
+extern int pop3d_dele __P ((const char *arg));
+extern int pop3d_list __P ((const char *arg));
+extern int pop3d_noop __P ((const char *arg));
+extern int pop3d_quit __P ((const char *arg));
+extern int pop3d_retr __P ((const char *arg));
+extern int pop3d_rset __P ((const char *arg));
+extern int pop3d_stat __P ((const char *arg));
+extern int pop3d_top __P ((const char *arg));
+extern int pop3d_uidl __P ((const char *arg));
+extern int pop3d_user __P ((const char *arg));
+extern int pop3d_apop __P ((const char *arg));
+extern int pop3d_auth __P ((const char *arg));
+extern int pop3d_capa __P ((const char *arg));
+extern char *pop3d_args __P ((const char *cmd));
+extern char *pop3d_cmd __P ((const char *cmd));
+extern int pop3d_abquit __P ((int reason));
+extern int pop3d_lock __P ((void));
+extern int pop3d_unlock __P ((void));
+extern int pop3d_mainloop __P ((int infile, int outfile));
+extern void pop3d_daemon __P ((unsigned int maxchildren));
+extern void pop3d_usage __P ((char *argv0));
+extern void pop3d_signal __P ((int));
+extern void pop3d_sigchld __P ((int));
+extern void pop3d_daemon_init __P ((void));
+extern char *pop3d_apopuser __P ((const char *user));
+extern char *pop3d_readline __P ((int fd));
#endif /* _POP3D_H */
diff --git a/pop3d/signal.c b/pop3d/signal.c
index 6ea0d498c..fd2e65727 100644
--- a/pop3d/signal.c
+++ b/pop3d/signal.c
@@ -29,5 +29,10 @@ pop3_sigchld (int signo)
errno = 0;
while ( (pid = waitpid(-1, &status, WNOHANG)) > 0)
--children;
+#ifndef HAVE_SIGACTION
+ /* On some system, signal implements the unreliabe sematic and
+ has to be rearm. */
+ signal (SIGCHLD, pop3_sigchld);
+#endif
errno = old_errno;
}
diff --git a/pop3d/user.c b/pop3d/user.c
index 04e228ae7..534170d5b 100644
--- a/pop3d/user.c
+++ b/pop3d/user.c
@@ -24,9 +24,8 @@ static char *_pwd;
static char *_user;
static int _perr = 0;
-#define PAM_ERROR if (_perr || (pamerror != PAM_SUCCESS)) { \
- pam_end(pamh, 0); \
- return ERR_BAD_LOGIN; }
+#define PAM_ERROR if (_perr || (pamerror != PAM_SUCCESS)) \
+ goto pam_errlab;
static int
PAM_gnupop3d_conv (int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr)
@@ -119,6 +118,7 @@ pop3_user (const char *arg)
free (cmd);
return ERR_BAD_CMD;
}
+
if ((strcasecmp (cmd, "PASS") == 0))
{
free (cmd);
@@ -145,7 +145,10 @@ pop3_user (const char *arg)
spw = getspnam ((char *)arg);
if (spw == NULL || strcmp (spw->sp_pwdp, crypt (pass, spw->sp_pwdp)))
#endif /* HAVE_SHADOW_H */
- return ERR_BAD_LOGIN;
+ {
+ syslog (LOG_INFO, "User '%s': authentication failed", arg);
+ return ERR_BAD_LOGIN;
+ }
}
#else /* !USE_LIBPAM */
_user = (char *) arg;
@@ -160,8 +163,14 @@ pop3_user (const char *arg)
PAM_ERROR;
pamerror = pam_setcred (pamh, PAM_ESTABLISH_CRED);
PAM_ERROR;
+pam_errlab:
pam_end (pamh, PAM_SUCCESS);
- openlog ("gnu-pop3d", LOG_PID, LOG_MAIL);
+ openlog ("gnu-pop3d", LOG_PID, LOG_FACILITY);
+ if (pamerror != PAM_SUCCESS)
+ {
+ syslog (LOG_INFO, "User '%s': authentication failed", _user);
+ return ERR_BAD_LOGIN;
+ }
#endif /* USE_LIBPAM */
@@ -210,6 +219,7 @@ pop3_user (const char *arg)
}
else if (strcasecmp (cmd, "QUIT") == 0)
{
+ syslog (LOG_INFO, "Possible probe of account '%s'", arg);
free (cmd);
return pop3_quit (pass);
}

Return to:

Send suggestions and report system problems to the System administrator.