aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS10
-rw-r--r--driver.c23
-rw-r--r--fetchmail.c11
-rw-r--r--fetchmail.h1
4 files changed, 42 insertions, 3 deletions
diff --git a/NEWS b/NEWS
index 6f100a88..a2bb102c 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,8 @@
fetchmail-1.9 ():
+features --
+
* POP3 UID support really works now. I make rude noises at the POP3 mavens
who forced us to this with RFC1725, but thank Al Longyear <longyear@sii.com>
for fixing and verifying my slightly buggy implemntation.
@@ -17,6 +19,14 @@ fetchmail-1.9 ():
* Password is no longer displayed in verbose mode.
+* Program now tries to set itself to the ID of the local user before
+ running an MDA, and reset to root afterwards.
+
+bugs --
+
+* Default user name to deliver to is now the calling user (was the remote
+ user ID).
+
fetchmail-1.8 (Fri Oct 11 15:08:10 EDT 1996):
features --
diff --git a/driver.c b/driver.c
index 8acc54cc..6c7db786 100644
--- a/driver.c
+++ b/driver.c
@@ -692,6 +692,8 @@ struct method *proto;
/* we may want to reject this message if it's old */
if (treat_as_new || queryctl->fetchall)
{
+ int saveduid = getuid();
+
/* request a message */
(protocol->fetch)(socket, num, &len);
@@ -708,8 +710,21 @@ struct method *proto;
/* open the delivery pipe now if we're using an MDA */
if (queryctl->mda[0])
+ {
+ /*
+ * In case we're running as root, change our UID to
+ * that of the local user being delivered to, so the MDA
+ * will be able to modify that user's files. This
+ * code will fail quietly when run by non-root.
+ */
+ (void) setuid(queryctl->uid);
+
if ((mboxfd = openmailpipe(queryctl)) < 0)
+ {
+ (void) setuid(saveduid); /* see below */
goto cleanUp;
+ }
+ }
/* read the message and ship it to the output sink */
ok = gen_readmsg(socket, mboxfd,
@@ -719,9 +734,17 @@ struct method *proto;
/* close the delivery pipe, we'll reopen before next message */
if (queryctl->mda[0])
+ {
if ((ok = closemailpipe(mboxfd)) != 0 || alarmed)
goto cleanUp;
+ /*
+ * Now try to reset our UID to root. This code will fail
+ * quietly when run by non-root.
+ */
+ (void) setuid(saveduid);
+ }
+
/* tell the server we got it OK and resynchronize */
if (protocol->trail)
(protocol->trail)(socket, queryctl, num);
diff --git a/fetchmail.c b/fetchmail.c
index b21cdaef..b3a8046a 100644
--- a/fetchmail.c
+++ b/fetchmail.c
@@ -86,6 +86,7 @@ char **argv;
struct hostrec def_opts;
int parsestatus, implicitmode;
char *servername, *user, *home, *tmpdir, tmpbuf[BUFSIZ];
+ struct passwd *pw;
FILE *lockfp;
pid_t pid;
@@ -96,8 +97,6 @@ char **argv;
if ((user == (char *)NULL) || (home = getenv("HOME")) == (char *)NULL)
{
- struct passwd *pw;
-
if ((pw = getpwuid(getuid())) != NULL)
{
user = pw->pw_name;
@@ -194,7 +193,13 @@ char **argv;
/* if rc file didn't supply a localname, default appropriately */
if (!hostp->localname[0])
- strcpy(hostp->localname, hostp->remotename);
+ strcpy(hostp->localname, user);
+
+ /* check that delivery is going to a real local user */
+ if ((pw = getpwnam(user)) == (struct passwd *)NULL)
+ exit(PS_SYNTAX); /* has to be from bad rc file */
+ else
+ hostp->uid = pw->pw_uid;
/* sanity checks */
if (hostp->port < 0)
diff --git a/fetchmail.h b/fetchmail.h
index 8120af3d..9819e6ba 100644
--- a/fetchmail.h
+++ b/fetchmail.h
@@ -93,6 +93,7 @@ struct hostrec
/* internal use */
int active;
struct hostrec *next; /* next host in chain */
+ int uid; /* UID of user to deliver to */
char digest [DIGESTLEN];
};