Sophie

Sophie

distrib > Mandriva > 2007.1 > x86_64 > media > main-updates-src > by-pkgid > 62ea43af7ec497e7a578db1ca6717d17 > files > 14

postfix-2.3.8-1.1mdv2007.1.src.rpm

This patch is suitable for Postfix 2.0 and later. It presents the
least invasive change that eliminates the problem. Future Postfix
releases may adopt a different strategy.

The solution introduces the following change: when the target of
mail delivery is a symlink, the parent directory of that symlink
must now be writable by root only (in addition to the already
existing requirement that the symlink itself is owned by root).
This change will break legitimate configurations that deliver mail
to a symbolic link in a directory with less restrictive permissions.

*** src/util/safe_open.c.orig	Sun Jun  4 19:04:49 2006
--- src/util/safe_open.c	Mon Aug  4 16:47:18 2008
***************
*** 83,88 ****
--- 83,89 ----
  #include <msg.h>
  #include <vstream.h>
  #include <vstring.h>
+ #include <stringops.h>
  #include <safe_open.h>
  
  /* safe_open_exist - open existing file */
***************
*** 138,150 ****
       * for symlinks owned by root. NEVER, NEVER, make exceptions for symlinks
       * owned by a non-root user. This would open a security hole when
       * delivering mail to a world-writable mailbox directory.
       */
      else if (lstat(path, &lstat_st) < 0) {
  	vstring_sprintf(why, "file status changed unexpectedly: %m");
  	errno = EPERM;
      } else if (S_ISLNK(lstat_st.st_mode)) {
! 	if (lstat_st.st_uid == 0)
! 	    return (fp);
  	vstring_sprintf(why, "file is a symbolic link");
  	errno = EPERM;
      } else if (fstat_st->st_dev != lstat_st.st_dev
--- 139,167 ----
       * for symlinks owned by root. NEVER, NEVER, make exceptions for symlinks
       * owned by a non-root user. This would open a security hole when
       * delivering mail to a world-writable mailbox directory.
+      * 
+      * Sebastian Krahmer of SuSE brought to my attention that some systems have
+      * changed their semantics of link(symlink, newpath), such that the
+      * result is a hardlink to the symlink. For this reason, we now also
+      * require that the symlink's parent directory is writable only by root.
       */
      else if (lstat(path, &lstat_st) < 0) {
  	vstring_sprintf(why, "file status changed unexpectedly: %m");
  	errno = EPERM;
      } else if (S_ISLNK(lstat_st.st_mode)) {
! 	if (lstat_st.st_uid == 0) {
! 	    VSTRING *parent_buf = vstring_alloc(100);
! 	    const char *parent_path = sane_dirname(parent_buf, path);
! 	    struct stat parent_st;
! 	    int     parent_ok;
! 
! 	    parent_ok = (stat(parent_path, &parent_st) == 0	/* not lstat */
! 			 && parent_st.st_uid == 0
! 			 && (parent_st.st_mode & (S_IWGRP | S_IWOTH)) == 0);
! 	    vstring_free(parent_buf);
! 	    if (parent_ok)
! 		return (fp);
! 	}
  	vstring_sprintf(why, "file is a symbolic link");
  	errno = EPERM;
      } else if (fstat_st->st_dev != lstat_st.st_dev