From owner-freebsd-security Tue Dec 10 13:03:43 1996 Return-Path: Received: (from root@localhost) by freefall.freebsd.org (8.8.4/8.8.4) id NAA00237 for security-outgoing; Tue, 10 Dec 1996 13:03:43 -0800 (PST) Received: from scanner.worldgate.com (scanner.worldgate.com [198.161.84.3]) by freefall.freebsd.org (8.8.4/8.8.4) with ESMTP id NAA00229 for ; Tue, 10 Dec 1996 13:03:40 -0800 (PST) Received: from znep.com (uucp@localhost) by scanner.worldgate.com (8.7.5/8.7.3) with UUCP id OAA23493; Tue, 10 Dec 1996 14:03:26 -0700 (MST) Received: from localhost (marcs@localhost) by alive.ampr.ab.ca (8.7.5/8.7.3) with SMTP id OAA22782; Tue, 10 Dec 1996 14:02:46 -0700 (MST) Date: Tue, 10 Dec 1996 14:02:45 -0700 (MST) From: Marc Slemko X-Sender: marcs@alive.ampr.ab.ca To: bmk@pobox.com cc: security@freebsd.org Subject: Re: Running sendmail non-suid In-Reply-To: <199612102027.MAA14200@itchy.atlas.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk 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.