summaryrefslogtreecommitdiffstats
path: root/libexec/mail.local
diff options
context:
space:
mode:
authorscrappy <scrappy@FreeBSD.org>1996-10-22 21:01:01 +0000
committerscrappy <scrappy@FreeBSD.org>1996-10-22 21:01:01 +0000
commitc60a33a165c15f21e7332949927393d51aaf8680 (patch)
tree3849a879190470fc42956d0018a44cdcd2de711b /libexec/mail.local
parent0e8236f24c12f83a14c1c24384443e0f37ace7f7 (diff)
downloadFreeBSD-src-c60a33a165c15f21e7332949927393d51aaf8680.zip
FreeBSD-src-c60a33a165c15f21e7332949927393d51aaf8680.tar.gz
Fixes:
>Description: /usr/libexec/mail.local runs as root. As such is can fill up a mailbox on a quota'd filesystem, and keep going... Makes quota's almost useless in an ISP environment. Closes: PR#bin/1111 Submitted by: Charles Henrich <henrich@crh.cl.msu.edu>
Diffstat (limited to 'libexec/mail.local')
-rw-r--r--libexec/mail.local/mail.local.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/libexec/mail.local/mail.local.c b/libexec/mail.local/mail.local.c
index 1809f35..733762a 100644
--- a/libexec/mail.local/mail.local.c
+++ b/libexec/mail.local/mail.local.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: mail.local.c,v 1.7 1996/09/22 21:54:07 wosch Exp $
*/
#ifndef lint
@@ -197,6 +197,7 @@ void
deliver(fd, name, nobiff)
int fd, nobiff;
char *name;
+ uid_t saveeuid;
{
struct stat fsb, sb;
struct passwd *pw;
@@ -232,7 +233,10 @@ deliver(fd, name, nobiff)
* If we created the mailbox, set the owner/group. If that fails,
* just return. Another process may have already opened it, so we
* can't unlink it. Historically, binmail set the owner/group at
+
+ saveeuid=geteuid();
* each mail delivery. We no longer do this, assuming that if the
+
* ownership or permissions were changed there was a reason.
*
* XXX
@@ -244,11 +248,28 @@ tryagain:
O_APPEND|O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR);
if (mbfd == -1) {
if (errno == EEXIST)
+
+ /* Now that the box is created and permissions are correct, we
+ close it and go back to the top so that we will come in
+ and write as the user. We dont seteuid() before the above
+ open, because we have to be root/bin to write in var/mail */
+
+ close(mbfd);
+ goto tryagain;
+
goto tryagain;
} else if (fchown(mbfd, pw->pw_uid, pw->pw_gid)) {
e_to_sys(errno);
warn("chown %u.%u: %s", pw->pw_uid, pw->pw_gid, name);
return;
+
+ /* Become the user, so quota enforcement will occur */
+
+ if(seteuid(pw->pw_uid) != 0) {
+ warn("Unable to setuid()");
+ return;
+ }
+
}
} else if (sb.st_nlink != 1 || S_ISLNK(sb.st_mode)) {
e_to_sys(errno);
@@ -256,6 +277,7 @@ tryagain:
return;
} else {
mbfd = open(path, O_APPEND|O_WRONLY, 0);
+ seteuid(saveeuid);
if (mbfd != -1 &&
(fstat(mbfd, &fsb) || fsb.st_nlink != 1 ||
S_ISLNK(fsb.st_mode) || sb.st_dev != fsb.st_dev ||
@@ -263,6 +285,8 @@ tryagain:
warn("%s: file changed after open", path);
(void)close(mbfd);
return;
+ seteuid(saveeuid);
+
}
}
@@ -283,6 +307,7 @@ tryagain:
/* Get the starting offset of the new message for biff. */
curoff = lseek(mbfd, (off_t)0, SEEK_END);
(void)snprintf(biffmsg, sizeof(biffmsg), "%s@%qd\n",
+
name, curoff);
}
@@ -302,6 +327,7 @@ tryagain:
if (nr < 0) {
e_to_sys(errno);
warn("temporary file: %s", strerror(errno));
+ seteuid(saveeuid);
err2: (void)ftruncate(mbfd, curoff);
err1: (void)close(mbfd);
return;
@@ -309,8 +335,11 @@ err1: (void)close(mbfd);
#ifndef DONT_FSYNC
/* Flush to disk, don't wait for update. */
+ seteuid(saveeuid);
if (fsync(mbfd)) {
e_to_sys(errno);
+
+ seteuid(saveeuid);
warn("%s: %s", path, strerror(errno));
goto err2;
}
OpenPOWER on IntegriCloud