Prevent hardlink attack on mbox sticky mail directory. fixes: bug #988
[exim.git] / src / src / transports / appendfile.c
index f31232a0f496ffd45632b637dffb884b62cd11c0..984f2d7d64f7c25d63e2db4783c6cdd44e4e1eac 100644 (file)
@@ -1,10 +1,10 @@
-/* $Cambridge: exim/src/src/transports/appendfile.c,v 1.21 2007/01/22 16:29:55 ph10 Exp $ */
+/* $Cambridge: exim/src/src/transports/appendfile.c,v 1.25 2010/05/26 12:26:01 nm4 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2007 */
+/* Copyright (c) University of Cambridge 1995 - 2009 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 
@@ -1806,6 +1806,18 @@ if (!isdirectory)
         goto RETURN;
         }
 
+      /* Just in case this is a sticky-bit mail directory, we don't want
+      users to be able to create hard links to other users' files. */
+
+      if (statbuf.st_nlink != 1)
+        {
+        addr->basic_errno = ERRNO_NOTREGULAR;
+        addr->message = string_sprintf("mailbox %s%s has too many links (%d)",
+          filename, islink? " (symlink)" : "", statbuf.st_nlink);
+        goto RETURN;
+
+        }
+
       /* If symlinks are permitted (not recommended), the lstat() above will
       have found the symlink. Its ownership has just been checked; go round
       the loop again, using stat() instead of lstat(). That will never yield a
@@ -2451,6 +2463,8 @@ else
         addr->message = string_sprintf ("failed to open %s (%d tr%s)",
           filename, i, (i == 1)? "y" : "ies");
         addr->basic_errno = errno;
+        if (errno == errno_quota || errno == ENOSPC)
+          addr->user_message = US"mailbox is full";
         return FALSE;
         }
 
@@ -2903,6 +2917,7 @@ if (yield != OK)
     #else
     addr->message = string_sprintf("mailbox is full");
     #endif  /* EDQUOT */
+    addr->user_message = US"mailbox is full";
     DEBUG(D_transport) debug_printf("System quota exceeded for %s%s%s\n",
       dataname,
       isdirectory? US"" : US": time since file read = ",