X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/4f9d7df139695e97cd1772d41940500480585df7..8838172bf0c35831f6b0f0a9763af0d04edf5468:/lib-src/movemail.c diff --git a/lib-src/movemail.c b/lib-src/movemail.c index 7f9026d89c..ae51df3d39 100644 --- a/lib-src/movemail.c +++ b/lib-src/movemail.c @@ -1,7 +1,7 @@ /* movemail foo bar -- move file foo to file bar, locking file foo the way /bin/mail respects. Copyright (C) 1986, 1992, 1993, 1994, 1996, 1999, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -60,6 +60,7 @@ along with GNU Emacs. If not, see . */ #include #include #include +#include #include #ifdef HAVE_UNISTD_H @@ -196,6 +197,9 @@ main (argc, argv) # define ARGSTR "p" #endif /* MAIL_USE_POP */ + uid_t real_gid = getgid(); + uid_t priv_gid = getegid(); + #ifdef WINDOWSNT /* Ensure all file i/o is in binary mode. */ _fmode = _O_BINARY; @@ -228,7 +232,7 @@ main (argc, argv) ) { #ifdef MAIL_USE_POP - fprintf (stderr, "Usage: movemail [-p] inbox destfile%s\n", + fprintf (stderr, "Usage: movemail [-p] [-r] inbox destfile%s\n", " [POP-password]"); #else fprintf (stderr, "Usage: movemail [-p] inbox destfile%s\n", ""); @@ -246,25 +250,6 @@ main (argc, argv) if (*outname == 0) fatal ("Destination file name is empty", 0, 0); - /* Check access to output file. */ - if (access (outname, F_OK) == 0 && access (outname, W_OK) != 0) - pfatal_with_name (outname); - - /* Also check that outname's directory is writable to the real uid. */ - { - char *buf = (char *) xmalloc (strlen (outname) + 1); - char *p; - strcpy (buf, outname); - p = buf + strlen (buf); - while (p > buf && !IS_DIRECTORY_SEP (p[-1])) - *--p = 0; - if (p == buf) - *p++ = '.'; - if (access (buf, W_OK) != 0) - pfatal_with_name (buf); - free (buf); - } - #ifdef MAIL_USE_POP if (!strncmp (inname, "po:", 3)) { @@ -276,15 +261,12 @@ main (argc, argv) exit (status); } - setuid (getuid ()); + if (setuid (getuid ()) < 0) + fatal ("Failed to drop privileges", 0, 0); + #endif /* MAIL_USE_POP */ #ifndef DISABLE_DIRECT_ACCESS - - /* Check access to input file. */ - if (access (inname, R_OK | W_OK) != 0) - pfatal_with_name (inname); - #ifndef MAIL_USE_MMDF #ifndef MAIL_USE_SYSTEM_LOCK #ifdef MAIL_USE_MAILLOCK @@ -341,6 +323,13 @@ main (argc, argv) close (desc); tem = link (tempname, lockname); + +#ifdef EPERM + if (tem < 0 && errno == EPERM) + fatal ("Unable to create hard link between %s and %s", + tempname, lockname); +#endif + unlink (tempname); if (tem >= 0) break; @@ -368,10 +357,11 @@ main (argc, argv) int lockcount = 0; int status = 0; #if defined (MAIL_USE_MAILLOCK) && defined (HAVE_TOUCHLOCK) - long touched_lock, now; + time_t touched_lock, now; #endif - setuid (getuid ()); + if (setuid (getuid ()) < 0 || setegid (real_gid) < 0) + fatal ("Failed to drop privileges", 0, 0); #ifndef MAIL_USE_MMDF #ifdef MAIL_USE_SYSTEM_LOCK @@ -397,6 +387,9 @@ main (argc, argv) if (outdesc < 0) pfatal_with_name (outname); + if (setegid (priv_gid) < 0) + fatal ("Failed to regain privileges", 0, 0); + /* This label exists so we can retry locking after a delay, if it got EAGAIN or EBUSY. */ retry_lock: @@ -490,6 +483,10 @@ main (argc, argv) pfatal_and_delete (outname); #endif + /* Prevent symlink attacks truncating other users' mailboxes */ + if (setegid (real_gid) < 0) + fatal ("Failed to drop privileges", 0, 0); + /* Check to make sure no errors before we zap the inbox. */ if (close (outdesc) != 0) pfatal_and_delete (outname); @@ -521,6 +518,10 @@ main (argc, argv) } #endif /* not MAIL_USE_SYSTEM_LOCK */ + /* End of mailbox truncation */ + if (setegid (priv_gid) < 0) + fatal ("Failed to regain privileges", 0, 0); + #ifdef MAIL_USE_MAILLOCK /* This has to occur in the child, i.e., in the process that acquired the lock! */ @@ -676,6 +677,7 @@ xmalloc (size) #include #endif #include +#include #define NOTOK (-1) #define OK 0 @@ -916,7 +918,16 @@ int mbx_delimit_begin (mbf) FILE *mbf; { - if (fputs ("\f\n0, unseen,,\n", mbf) == EOF) + time_t now; + struct tm *ltime; + char fromline[40] = "From movemail "; + + now = time (NULL); + ltime = localtime (&now); + + strcat (fromline, asctime (ltime)); + + if (fputs (fromline, mbf) == EOF) return (NOTOK); return (OK); } @@ -925,7 +936,7 @@ int mbx_delimit_end (mbf) FILE *mbf; { - if (putc ('\037', mbf) == EOF) + if (putc ('\n', mbf) == EOF) return (NOTOK); return (OK); }