Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 10 Dec 1996 14:02:45 -0700 (MST)
From:      Marc Slemko <marcs@znep.com>
To:        bmk@pobox.com
Cc:        security@freebsd.org
Subject:   Re: Running sendmail non-suid
Message-ID:  <Pine.BSF.3.95.961210133528.22425A-100000@alive.ampr.ab.ca>
In-Reply-To: <199612102027.MAA14200@itchy.atlas.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 10 Dec 1996, Brant Katkansky wrote:

> > On Mon, 9 Dec 1996, Cy Schubert - ITSD Open Systems Group wrote:
> > 
> > > 
> > > First you will need to create an smtp account.
> > > 
> > > Next, chown /var/spool/mqueue, /var/mail, and /usr/sbin/sendmail to user
> > > smtp.
> > > 
> > > Run a cronjob out of root's cron every 5 minutes to process the queue.
> > 
> > You are missing something here WRT how to have sendmail bind to port 25. 
> > There are three likely ways; have it run as root long enough to bind in a
> > similar fashion to most webservers, run it from inetd, or modify the
> > kernel to let a particular non-root user bind to port 25.  If you have
> > sendmail running as a daemon using either the first or third methods, you
> > don't need to run sendmail from cron.
> 
> I don't believe that running sendmail from inetd will be a viable option -
> anticipated load is too high.  What I will likely do is run it non-suid,
> but start it as root, and give up root privelege as soon as the port is
> bound.  I'd rather not muck around in the kernel.

The kernel change is really easy.  Easier than messing with sendmail
to make it change its UID, IMHO.  In sys/netinet/in_pcb,c, note
the lines:

	if (ntohs(lport) < IPPORT_RESERVED &&
	    (error = suser(p->p_ucred, &p->p_acflag)))
		return (EACCES);

If you change to something like (uncompiled, untested):

	if (ntohs(lport) < IPPORT_RESERVED &&
	    error = suser(p->p_ucred, &p->p_acflag) && 
	    !((p->p_ucred->cr_uid == 1234) && (ntohs(lport) == 25)) )
		return (EACCES);

That says that if lport is in the reserved area, and they are not uid 0
and they are not (uid 1234 and trying to bind to port 25) don't let them. 

Then only UID 0 or 1234 will be able to bind to port 25.  It is a
hack, but for your purposes you don't have worry too much about
making a good interface to it to allow dynamic changes.  You may have
other reasons for not wanting to mess with the kernel though.

I haven't looked at it much, but the obviously place to modify sendmail to
do a setuid is right after it forks in daemon.c.  Be sure you deal
with the saved UID.  I would suspect that modifying it to setuid
right after the bind() call would cause problems because I think
sendmail may assume it can rebind to the port later on.  You would
have to check that out.

> 
> One thing I'd like to know is this: Once a process has changed it's effective
> UID to something other than root, can it ever change it's effective UID?

Yes.  It can change the euid to either the real UID or the saved UID. 
When exec is called, the effective and saved UIDs are set to the real UID. 
That means that if you fork, change the real UID to something then exec a
program, in the program execed the real, saved, and effective UIDs will
all be what you changed the real UID to. 





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.95.961210133528.22425A-100000>