Re: [Exim] Conditionalize a router on file existance; effect…

Top Page
Delete this message
Reply to this message
Author: Harald Meland
Date:  
To: exim-users
Subject: Re: [Exim] Conditionalize a router on file existance; effective uid and NFS woes
[Philip Hazel]

> On Tue, 5 Aug 2003, Harald Meland wrote:
>
>> Re-reading the latest Exim specification, I can sort of see that the
>> behaviour I'm experiencing is documented. And, indeed, the
>> behaviooral change is listed rather explicitly in Exim4.upgrade.


I've re-read it again now, and I have to disagree with myself. The
4.20 documentation states:

During delivery, the stat() function is run as root, but there is a
facility for checking the accessibility of a file by another
user. [...]

, and that is not true. Exim _tries_ to do an ad-hoc-check of the
accessibility by another user, but the check is not *really* checking
the accessibility by another user; one should use
set[e]uid(2)+access(2) for that.

In particular, the example I gave with mode 0700 NFS-mounted users'
homedirs will *not* work with the current algorithm.

> The code is still supposed to do some checking, by scanning the
> components of the path of the file, and checking the access
> permissions. Is this not sufficient for your requirement? (I
> presume it is working...)


Nope, it is not sufficient; relevant parts of -d output -- let me know
if you need even more detailed info (Note that I have slightly munged
the user's address in an attempt to avoid any spambots scouring the
archives):

  miss# /local/exim4/bin/exim -f harald.meland@??? -d -N eldrid.mageli.no.spam.please@???
  [...]
  --------> tripnote router <--------
  local_part=eldrid.mageli domain=hi.uio.no
  checking senders
  address match: subject=harald.meland@??? pattern=
  usit.uio.no in ""? no (end of list)
  address match: subject=harald.meland@??? pattern=^.+-request@
  address match: subject=harald.meland@??? pattern=^owner-.+@
  address match: subject=harald.meland@??? pattern=^.+-owner@
  address match: subject=harald.meland@??? pattern=^postmaster@
  address match: subject=harald.meland@??? pattern=^listmaster@
  address match: subject=harald.meland@??? pattern=^mailer-daemon@
  address match: subject=harald.meland@??? pattern=^root@
  address match: subject=harald.meland@??? pattern=^.+-admin@
  address match: subject=harald.meland@??? pattern=^.+=.+\..+@
  harald.meland@??? in "! : !^.+-request@ : !^owner-.+@ : !^.+-owner@ : !^postmaster@ : !^listmaster@ : !^mailer-daemon@ : !^root@ : !^.+-admin@ : !^.+=.+\..+@"? yes (end of list)
  checking require_files
  finduser used cached passwd data for eldrid
  file check: $home/tripnote
  expanded file: /hf/helene/hi-u1/eldrid/tripnote
  stat() yielded -1
  errno = 13
  tripnote router deferred: file check
  added retry item for R:eldrid.mageli.no.spam.please@???: errno=-1 0 flags=0
  post-process eldrid.mageli.no.spam.please@??? (1)
  LOG: MAIN
    == eldrid.mageli.no.spam.please@??? R=tripnote defer (-1): require_files: error for /hf/helene/hi-u1/eldrid/tripnote: Permission denied

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


The reason stat("/hf/helene/hi-u1/eldrid/tripnote") fails is this:

  miss# ls -ld ~eldrid
  drwx------  19 eldrid   hf           1024 Jul 25 16:37 /hf/helene/hi-u1/eldrid


The disk is, as mentioned, NFS (non-root) mounted. This means
root@miss has access equal to nobody@NFS-server, and hence is not
allowed to see anything at all inside this user's home directory.

>> If I'm *not* missing anything: Can anyone tell me why running as root
>> while routing is better (securitywise, the Exim4.upgrade file makes me
>> presume) than using seteuid?
>
> After many years of wondering why security people didn't like seteuid, I
> finally understood the problem a couple of years ago. The insecurity
> arises when a program behaves like this:
>
>    ... running as root
>    seteuid to something other than root
>    ... do some stuff
>    seteuid back to root
>    ... carry on

>
> During the time that the program is not running as root, any *other*
> program that is running as that euid will have access to the process,
> and could in principle modify the contents of its address space.


... or simply seteuid(2) back to root by themselves. Which is why to
do safe programming with seteuid(2), you have to do

setuid(geteuid())

before any call to external code.

I frankly can't see how the functionality I am looking to implement
(which was present in earlier Exim versions), can be done without
either

  1) using seteuid(2) or
  2) increasing the number of processes, and how much they need to
     communicate between them, involved in routing addresses.


> Then, when the program returns to being root, it might do unwanted
> things.


After the setuid(geteuid()) call, there won't be any possibility of
returning to being root, short of re-execing the Exim (setuid) binary.
--
Harald