[comp.mail.sendmail] Non-root sendmail?

jc@heart-of-gold (John M Chambers) (11/11/88)

The infamous sendmail virus encourages me to, once again, ask what seems 
to me to be a straightforward question, and which will probably once again
get me no end of flames telling me what an idiot I am, but I'm going to
stick my ignorant neck out and ask it anyway:

Is there a way to run sendmail under a non-root id?  

Maybe I should clarify.  The obvious answer is "yes", since /etc/rc can
always do something like
	su mail /usr/lib/sendmail -bd -q1h
This is not a good enough answer, however, because, while I can indeed do
this on our Suns, the resulting process dies rather soon, resulting in no
sendmail daemon running at all.  Why it dies, I don't understand.

Well, I do partially understand.  Sendmail obviously must access a bunch
of files (sendmail.cf, aliases, etc.), not to mention some directories
(/usr/spool/mqueue, etc.), and these obviously must be writable by the
mail id.  OK, give me credit for enough intelligence to know all that 
without being told, as well as how to change their ownerships over to mail.
But that doesn't do the job.

I'm also rather familiar with sendmail's main competitor, uucp.  It seems
to run quite well under a mail id, and doesn't need anything setuid to root.
In fact, it's fairly conventional to make all the programs setuid to uucp,
or even better, setgid to mail, with all the files and directories being
owned by uucp/mail.  Mailboxes then end up owned by the user, with group
mail and 660 permissions, and all that, and it works just fine.  It's real
hard to do an attack like the sendmail virus on uucp.  I mean, sure, you
can fill up the /usr/spool partition.  News does that routinely.  You can
even write chain letters, if you set up a few forwarding files correctly.
But the kind of remote-execute-as-root capability that the virus was based 
on, well, it just doesn't work with uucp.

When I configure sendmail's permissions like uucp, it doesn't work 
just fine.  Does anyone know why not?  Even better, does anyone have 
instructions for installing sendmail so that it doesn't require root 
permissions (i.e., turning off system security, which is what root is 
all about) to run?

The recent virus has been something I've warned people about off and on
for years.  After all, seeing a daemon running as root that implements
network file copies and remote executes should cause a red flag to pop
up inside the skull of anyone who knows anything at all about security.
But the supposed BSD experts just respond by insulting my intelligence
for doubting the wisdom of sendmail's design.

The people who built uucp understood this all 10 years ago.  Why haven't 
the SNMP people heard about it yet?  (Oh, yes, they all know about it, but
they haven't publicised the problem and/or its solutions because they're
afraid some hacker will take advantage of the knowledge. :-)


-- 
From:	John Chambers <mitre-bedford.arpa!heart-of-gold!jc>
From	...!linus!!heart-of-gold!jc (John Chambers)
Phone	617/217-7780
[Send flames; they keep it cool in this lab :-]

louie@trantor.umd.edu (Louis A. Mamakos) (11/11/88)

sendmail runs as root for the rather obvious reason that it needs to bind
a socket to a restricted port number (25 == SMTP).  Before sendmail exec()'s
any processes, it does a setuid() to UID 1, which is daemon.  None of the
virus processes running on our system ran as root; rather they ran as
daemon.

Let's not flame sendmail for having the DEBUG command.  It actually is a
rather useful tool.  Instead of removing the DEBUG command, simply 
change the 3 lines of code that check for a particular debug flag being
set, and allowing mailing directly into programs, files and :include: lists.


Louis A. Mamakos  WA3YMH    Internet: louie@TRANTOR.UMD.EDU
University of Maryland, Computer Science Center - Systems Programming

gl8f@bessel.acc.Virginia.EDU (Greg Lindahl) (11/12/88)

In article <3031@haven.umd.edu> louie@trantor.umd.edu (Louis A. Mamakos) writes:
>sendmail runs as root for the rather obvious reason that it needs to bind
>a socket to a restricted port number (25 == SMTP).  Before sendmail exec()'s
>any processes, it does a setuid() to UID 1, which is daemon.  None of the
>virus processes running on our system ran as root; rather they ran as
>daemon.
>

Is there any reason why sendmail has to run as the same "daemon" which
owns the files generated by the "at" command? This is unfortunate,
because anyone who can break sendmail and get a suid daemon shell can
(according to a friend of mine) then generate an "at" command and go
edit the command file to have root execute the command. This allows
you to generate a root suid shell.

Shouldn't we be glad that our friendly virus didn't know this :-) Why
are these daemons the same?

-- greg

----------
Greg Lindahl                                    internet:  gl8f@virginia.edu
University of Virginia Department of Astronomy    bitnet:  gl8f@virginia.bitnet
"grad students don't need disclaimers; the department doen't care what I think"

badri@valhalla.ee.rochester.edu (Badri Lokanathan) (11/12/88)

In article <164@heart-of-gold>, jc@heart-of-gold (John M Chambers) writes:
> 
> Is there a way to run sendmail under a non-root id?  
> 
It may not be possible for the following reason: there is no way currently
for any other id to concatenate a new message to /usr/spool/mail/fubar,
where fubar typically has rw to owner only. If permissions were not so, then
other users could peek into fubar's mail.
>
> I'm also rather familiar with sendmail's main competitor, uucp.  It seems
> to run quite well under a mail id, and doesn't need anything setuid to root.
> In fact, it's fairly conventional to make all the programs setuid to uucp,
> or even better, setgid to mail, with all the files and directories being
> owned by uucp/mail.  Mailboxes then end up owned by the user, with group
> mail and 660 permissions, and all that, and it works just fine.
>
Which system are you talking about? If it is BSD, the final delivery of mail
is always done by a suid program and not directly by UUCP, since quite
obviously there is no way for a program running as user "uucp" to write
to file that is owned by the user.

(The postal van may be out of bounds but you can always mug the postman :-)

However what you say gives me an idea. What if sendmail were made set-gid
"mail" (but not set-uid) and all mail related files, including
/usr/spool/mail/foo were made rw by group "mail", but no user is a member
of group "mail"? This would mean, of course, that /usr/spool/mail must
always contain a mbox for each user (since a rw file owned by user can
only be created by the user or root,) but that is a minor hassle. Maybe a
few hacks to make sure that /usr/spool/mail/fubar never gets deleted by any
program.
-- 
"We will fight for the right to be free {) badri@ee.rochester.edu
 We will build our own society         //\\ {ames,cmcl2,columbia,cornell,
 And we will sing, we will sing       ///\\\ garp,harvard,ll-xn,rutgers}!
 We will sing our own song."  -UB40    _||_   rochester!ur-valhalla!badri

lyndon@nexus.ca (Lyndon Nerenberg) (11/12/88)

In article <164@heart-of-gold>, jc@heart-of-gold (John M Chambers) writes:
>Is there a way to run sendmail under a non-root id?  
>
>Maybe I should clarify.  The obvious answer is "yes", since /etc/rc can
>always do something like
>	su mail /usr/lib/sendmail -bd -q1h
>This is not a good enough answer, however, because, while I can indeed do
>this on our Suns, the resulting process dies rather soon, resulting in no
>sendmail daemon running at all.  Why it dies, I don't understand.

When sendmail runs as the SMTP listener it must bind itself to a
priveledged port. This requires it run as the superuser.

You might consider writing a seperate process to deal with the
SMTP socket that hands off incoming messages to sendmail,
which could (probably) run setgid and not setuid. I say probably
becuase sendmail was written to run as the superuser, and would
require some hacking to function in a setgid environment.

The fact of the matter is sendmail needs a complete re-write.

--lyndon

matt@oddjob.uchicago.edu (Matt Crawford) (11/12/88)

) John M Chambers:
) > Is there a way to run sendmail under a non-root id?  

Badri Lokanathan:
) It may not be possible for the following reason: there is no way currently
) for any other id to concatenate a new message to /usr/spool/mail/fubar,

Sendmail doesn't *do* that, /bin/mail does.

louie@trantor.umd.edu (Louis A. Mamakos) (11/12/88)

In article <1572@valhalla.ee.rochester.edu> badri@valhalla.ee.rochester.edu (Badri Lokanathan) writes:
>In article <164@heart-of-gold>, jc@heart-of-gold (John M Chambers) writes:
>> 
>> Is there a way to run sendmail under a non-root id?  
>> 
>It may not be possible for the following reason: there is no way currently
>for any other id to concatenate a new message to /usr/spool/mail/fubar,
>where fubar typically has rw to owner only. If permissions were not so, then
>other users could peek into fubar's mail.

Funny thing is, sendmail doesn't deliver mail to the user's mailbox.  It
invokes '/bin/mail -d' to actually concatinate the mail to the end of the
user's mailbox.  Look at the defintion of the the local mailer in the
sendmail configuration file /usr/lib/sendmail.cf if you want to see how
it is invoked.

By invoking /bin/mail, sendmail doesn't have to know about which flavor
of mailbox locking you happen to be using on that system (link to lock file,
flock, etc).


Louis A. Mamakos  WA3YMH    Internet: louie@TRANTOR.UMD.EDU
University of Maryland, Computer Science Center - Systems Programming

tytso@athena.mit.edu (Theodore Y. Tso) (11/12/88)

In article <756@hudson.acc.virginia.edu> gl8f@bessel.acc.Virginia.EDU (Greg Lindahl) writes:
>Is there any reason why sendmail has to run as the same "daemon" which
>owns the files generated by the "at" command? This is unfortunate,
>because anyone who can break sendmail and get a suid daemon shell can
>(according to a friend of mine) then generate an "at" command and go
>edit the command file to have root execute the command. This allows
>you to generate a root suid shell.
>
>Shouldn't we be glad that our friendly virus didn't know this :-) Why
>are these daemons the same?

On machines that I care about :-), /usr/spool/at gets owned by root and
the at, atq, and atrm commands are setuid root.  The reason?
It's precisely as you mentioned --- being able to fake out "at" is
equivelent to having root access.

On to a more interesting sendmail question:  why is it that when
sendmail invokes a pipe to a program, if it can resolve the sender of
the mail message to a local user, it runs the program as that user?
That seems to me to be completely wrong, since there's absolutely no
authentication over an SMTP port --- this could be an easy way to
breach security, even if the DEBUG command isn't there.  For example,
the user may have been careless in a .forward or in the aliases file.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Theodore Ts'o				mit-eddie!mit-athena!tytso
3 Ames St., Cambridge, MA 02139		tytso@athena.mit.edu
			If it's for real, it isn't!

badri@valhalla.ee.rochester.edu (Badri Lokanathan) (11/12/88)

In article <735@tank.uchicago.edu>, matt@oddjob.uchicago.edu (Matt Crawford) writes:
> Badri Lokanathan:
> ) It may not be possible for the following reason: there is no way currently
> ) for any other id to concatenate a new message to /usr/spool/mail/fubar,
> 
> Sendmail doesn't *do* that, /bin/mail does.

True. I stand corrected. However I delved into the Installation and
Operation Guide (by Eric Allman) and found this interesting tidbit:
-------------------------------------------------------------------------------
	.
	.
4.7.1. To suid or not to suid?
		Sendmail can safely be made setuid to root. At the point where
       it is about to exec(2) a mailer, it checks to see if the userid
       is zero; if so, it resets the userid and groupid to a default
       (set by the u and g options.) This can be overridden by
       setting the S flag to the mailer for mailers that are trusted
       and must be called as root. However this will cause mail
       processing to be accounted (using sa(8)) to root rather than to
       the user sending mail.

4.7.2. Temporary file modes
		The mode of all temporary files that sendmail creates
	is determined by the "F" option. Reasonable values for this option
	are 0600 and 0644. If the more permissive mode is selected, it
	will not be necessary to run sendmail as root at all (even
	when running the queue).
	.
	.

5.3.6. Building mailer descriptions
	.
	.
	If the mailer must be called as root, the "S" flag should be
	given; this will not reset the userid before calling the
	mailer (sendmail must be running setuid to root for this to
	work.)
	.
	.
-------------------------------------------------------------------------------
These were the only references to setuid that I found in the
documentation (other than rebuilding the aliases database and another
reference to the S flag in appendix C with the ironic statement that a
safe environment ran sendmail as root!) No reference to socket 25
being a restricted port.
-- 
"We will fight for the right to be free {) badri@ee.rochester.edu
 We will build our own society         //\\ {ames,cmcl2,columbia,cornell,
 And we will sing, we will sing       ///\\\ garp,harvard,ll-xn,rutgers}!
 We will sing our own song."  -UB40    _||_   rochester!ur-valhalla!badri

honey@mailrus.cc.umich.edu (peter honeyman) (11/13/88)

In article <7902@bloom-beacon.MIT.EDU> tytso@athena.mit.edu (Theodore Y. Tso) writes:
>On to a more interesting sendmail question:  why is it that when
>sendmail invokes a pipe to a program, if it can resolve the sender of
>the mail message to a local user, it runs the program as that user?
>That seems to me to be completely wrong, since there's absolutely no
>authentication over an SMTP port --- this could be an easy way to
>breach security, even if the DEBUG command isn't there.  For example,
>the user may have been careless in a .forward or in the aliases file.

as to your question, i have no idea, of course, as i understand very
little about the hows and whys of sendmail, especially the latter, and
my understanding diminishes with each passing day.

that said, i wonder if that's why sendmail refuses to talk to itself.
does anyone have another theory as to why this might be?

	peter

ps:  i use "smtp talk to myself" all the time.  on my subnet, only one
machine, citi, does uucp, the rest of the machines smtp their uucp
requests to that machine.  (i didn't want to hack uucp to share
/usr/spool/uucp, although it's not that hard.)  the smtp queue *is*
shared, and (by coincidence) citi also runs that queue.  so citi
delivers to itself all the time.

honey@mailrus.cc.umich.edu (peter honeyman) (11/13/88)

Badri Lokanathan writes:
>4.7.2. Temporary file modes
>		The mode of all temporary files that sendmail creates
>	is determined by the "F" option. Reasonable values for this option
>	are 0600 and 0644. If the more permissive mode is selected, it
>	will not be necessary to run sendmail as root at all (even
>	when running the queue).

we run 0660 here.

the trouble with sendmail is ... hey, books could be written about
that.  certainly one problem with sendmail is that it is the smtp
speaker and listener.  around these parts, smtp mail is handled by
/usr/lib/mail/smtp and /usr/lib/mail/in.smtpd.

	peter

rayan@ai.toronto.edu (Rayan Zachariassen) (11/14/88)

Sendmail refuses to talk to itself in the (mistaken) belief that doing so is
necessarily a symptom of an imminent infinite loop.  It wants to be nice
and save your behind.

Sendmail needs root permissions so that:

1. it can read random user's .forward files
2. it can create [qdlx]f* files in a particular "secure" directory
3. it can execute "mailers" which require root permissions to do their work
4. it can read /dev/kmem to grab load averages, used to decide when to run

Every one of these points can be compromised, but you won't end up with a
normal sendmail.  It is hard to make a mailer run non-root unless you
use a different model of the environment (e.g. "protected ~/.forward files will
be ignored", or use a completely different scheme with the same functionality).

# why is it that when sendmail invokes a pipe to a program, if it can resolve
# the sender of the mail message to a local user, it runs the program as that
# user?

Because it is cheap security in the normal case (Sendmail always has to
route the sender address anyway, in order to verify From: and Sender:
headers), and someone overlooked the interaction of this mechanism with SMTP.

There have been two efforts going on to get rid of Sendmail, neither are
yet widely/publically available (so don't ask unless you want to put some
work in):

Smail 3.x:	This is sort of "Sendmail without the rulesets", or as one
		of the authors put it "A 100% solution for 90% of the sites,
		a 90% solution for 9% of the sites, a 9% solution for 1%
		of the sites, etc.".  From what I've seen, this will be a
		a good product.  Its configuration feels MMDF-like to someone
		who hasn't used MMDF (me); although apart from that it
		isn't like MMDF at all.

ZMailer:	This is my solution to the Sendmail problem, it is intended
		to be "A 100% solution for 100% of the sites".  That doesn't
		imply complexity, on the contrary.  At UofT, the version running
		on internal servers and the one running on a gateway differ
		only in their databases; the configuration file is identical.
		The configuration file has a different feel than anything
		else I know (superficially reminiscent of Upas I suppose),
		it is a /bin/sh-superset language.

MMDF is an alternative to Sendmail if you have predictable address
manipulation needs.

SliME and Upas are other solutions to the mail problem, perhaps some
sweet guy can be coaxed to comment on them?

Also, quoting one of the Smail3.x authors, "The complexity of sendmail.cf
is highly overrated"... it is.  Sendmail has problems in its basic design
that makes it unsuitable (i.e. it isn't flexible enough) for real situations.
For a while though, it was the only game in town for our purposes.

rayan

Sendmail's old hat! ZMailer's where its at!

ccdan@ucdavis.ucdavis.edu (Dan Dorough) (11/16/88)

In article <164@heart-of-gold> jc@heart-of-gold (John M Chambers) writes:
> Is there a way to run sendmail under a non-root id?  

i run sendmail under uid 1 (daemon) on some of our systems
here.  these systems include all of our 11/70s (2.9bsd) and
some of our isolated VAXen (4.3bsd, not on any TCP/IP network).
i am sure that it would be possible to run sendmail under
uid 1 on systems with TCP/IP, i just haven't had the desire
to.  with source, sendmail could easily be modified to
start up, obtain required resources, and then permanently
setuid(1).

when running non-super, several things are important.
  1) the spooling directory must be owned by the uid
     and/or gid that sendmail runs under.  sendmail must
     have permission to create and delete spooling files.
     i do this by running setgid to 1 and letting the
     group permissions on the spooling directory be "rwx".
  2) people who have turned off search ("x") permission
     on their login directories will not be able to
     use .forward files.
  3) load average checking won't work for systems that
     get load average through /dev/kmem.  (2.9bsd has
     a separate system call.)
  4) all mailers you call must be prepared to do their
     own setuid()ing, since sendmail will never start
     them as uid 0.  /bin/mail on my systems already runs
     setuid to 0, and the other mailers likewise do not
     depend on being started as 0.

i've run sendmail for a few years this way, and have had
no troubles with it.

--dan dorough, ucdavis systems programmer, ccdan@ucdavis.edu

allbery@ncoast.UUCP (Brandon S. Allbery) (11/19/88)

As quoted from <3031@haven.umd.edu> by louie@trantor.umd.edu (Louis A. Mamakos):
+---------------
| sendmail runs as root for the rather obvious reason that it needs to bind
| a socket to a restricted port number (25 == SMTP).  Before sendmail exec()'s
| any processes, it does a setuid() to UID 1, which is daemon.  None of the
| virus processes running on our system ran as root; rather they ran as
| daemon.
+---------------

Is it possible to run sendmail on a UUCP-only system without any setuid, but
instead setgid mail like the System III/V mailer?  What kinds of changes
would it take?  (Note that ncoast will most probably NEVER run any kind of
networking, so there's no reason for us to keep a setuid-root mailer.)

++Brandon
-- 
Brandon S. Allbery, comp.sources.misc moderator and one admin of ncoast PA UN*X
uunet!hal.cwru.edu!ncoast!allbery  <PREFERRED!>	    ncoast!allbery@hal.cwru.edu
allberyb@skybridge.sdi.cwru.edu	      <ALSO>		   allbery@uunet.uu.net
comp.sources.misc is moving off ncoast -- please do NOT send submissions direct
      Send comp.sources.misc submissions to comp-sources-misc@<backbone>.

jc@minya.UUCP (John Chambers) (11/20/88)

> obviously there is no way for a program running as user "uucp" to write
> to file that is owned by the user.
> 
> However what you say gives me an idea. What if sendmail were made set-gid
> "mail" (but not set-uid) and all mail related files, including
> /usr/spool/mail/foo were made rw by group "mail", but no user is a member
> of group "mail"? 

You just contradicted yourself! (;-)  This is how uucp runs here.  Actually,
it is setuid also, to uucp.  So are uuxqt and uusched.  Mail files are owned
by the user, are group mail and have 660 permissions.


>		This would mean, of course, that /usr/spool/mail must
> always contain a mbox for each user (since a rw file owned by user can
> only be created by the user or root,) but that is a minor hassle. Maybe a
> few hacks to make sure that /usr/spool/mail/fubar never gets deleted by any
> program.

That happens here, though it isn't necessary.  This is a Sys/V, and the
command "chown root temp" just worked for me.  Of course, temp's setuid
and setgid bits got turned off by the chown, for obvious reasons.  If
your systems doesn't allow mere users to use chown, then you'll need
some hack for creating a mailbox for new users.  Perhaps a program that
does nothing but create a mailbox, and is setuid-root.  That oughta be
simple enough that it can be verified.

Most versions of uucp mail will leave a mailbox there if it has permissions
other than 600.

-- 
John Chambers <{adelie,ima,maynard,mit-eddie}!minya!{jc,root}> (617/484-6393)

[Any errors in the above are due to failures in the logic of the keyboard,
not in the fingers that did the typing.]

jc@minya.UUCP (John Chambers) (11/20/88)

> Is it possible to run sendmail on a UUCP-only system without any setuid, but
> instead setgid mail like the System III/V mailer?  What kinds of changes
> would it take?  (Note that ncoast will most probably NEVER run any kind of
> networking, so there's no reason for us to keep a setuid-root mailer.)
> 
Actually, it's rather common to make uucp's critical programs (uucico, uuxqt,
rmail, uusched, uuetc.) both setuid-mail and setgid-mail.  If you do this,
then you "protect" innocent administrators (including yourself) from all 
the ways that these programs can inadvertently end up being run with uid=root.
This includes all the various things triggered by cron (which must run as
root), any of which may call mail which may call uucico and/or uuxqt...

I've seen the same problems with news, which keeps stumbling across files
owned by root (and thus unwritable by news), until I change rnews, expire,
etc. to be setuid-news and setgid-news.

In both cases, using both setuid and setgid makes certain that the programs
will always run with the restricted permissions and can't be tricked by
some hacker into running as you and sending out all your secret files to
some interested party.

Of course, there are rumored to be versions of Sys/V which "remembers" old
ids (specifically, root, when run from cron) and provide some way of getting
back the old id even though it differs from getuid() and geteuid().  Such
systems probably provide a way of getting to root even with setuid-mail.
(I hope I'm wrong.)

-- 
John Chambers <{adelie,ima,maynard,mit-eddie}!minya!{jc,root}> (617/484-6393)

[Any errors in the above are due to failures in the logic of the keyboard,
not in the fingers that did the typing.]

guy@auspex.UUCP (Guy Harris) (11/23/88)

>Of course, there are rumored to be versions of Sys/V which "remembers" old
>ids (specifically, root, when run from cron) and provide some way of getting
>back the old id even though it differs from getuid() and geteuid().

Every version of System V since at least System V Release 2 will, when
you run a set-UID program, remember both the "real" UID (generally the
one in effect when the program was "exec"ed) and the UID to which the
program is set-UID, and will permit you to use the "setuid()" call to
switch the effective UID back and forth between them an arbitrary number
of times - with one exception: if the effective UID is "root",
"setuid()" will set the real, effective, and "save set-user" UIDs to the
specified UID.

Except for the latter glitch, this is a win; it allows a set-UID program
to do privileged operations, then do operations with the credentials of
the user (without having to muck with "access()").  The intent behind
the aforementioned glitch is presumably to allow programs such as
"login" or "su" to set all the IDs.  SunOS also supports the saved
set-user ID notion; since it has "setreuid", it permits even set-UID
"root" programs to set the effective UID back and forth.  Systems that
have "setreuid", including SunOS, also generally permit you to exchange
the real and effective UIDs; this provides another way for programs to
switch back and forth.