#include <sys/types.h> #include <unistd.h> int getpeereid(int s,uid_t *u,gid_t *g);that returns the effective uid and effective gid of the peer connected to a UNIX-domain stream socket, recorded when the peer called connect() or listen(). This page explains why.
The rest of this page discusses several possible submission mechanisms.
Problem: A setuid program must operate in a very dangerous environment. A user is under complete control of its fds, args, environ, cwd, tty, rlimits, timers, signals, and more. Even worse, the list of controlled items varies from one vendor's UNIX to the next, so it is very difficult to write portable code that cleans up everything. (The same comments apply to setgid programs.)
Despite this problem, setuid programs are the most popular submission mechanism. They are used to submit passwords, mail messages, printer data, cron scripts, etc. They are responsible for a huge number of locally exploitable UNIX security holes.
Problem: getpeereid() is not yet portable. Here's what I've heard about OS support so far: FreeBSD supports getpeereid() starting in version 4.6. OpenBSD supports getpeereid() starting in version 3.0. Linux provides the necessary information through the SO_PEERCRED option to getsockopt(), but it doesn't support the getpeereid() interface. Solaris doesn't provide the necessary information at all.
I suggested a getpeeruid() API in a bugtraq discussion in 1998. William E. Baxter designed the getpeereid() interface and wrote getpeereid() patches for several systems.
(There are other interfaces, such as NetBSD's LOCAL_CREDS, that don't return credentials until the user writes some data. This means that an unauthorized user can chew up all available connections to the daemon, preventing anyone else from connecting.)
Some applications that can take advantage of getpeereid() when it is available (and have various problems when it is not): KDE (specifically kdesu), OpenLDAP, OpenSSH, PostgreSQL, and ucspi-ipc.
Problem: Doors are not portable. They are included in Solaris, and there is an experimental Linux implementation, but they are much too complicated to be easily included in new systems. Implementing getpeereid() is easier.
Problem 1: NFS service is difficult to implement. Typical daemon implementors are not going to want to piece together a file from NFS write requests. It would be much easier to use getpeereid().
Problem 2: NFS service requires cooperation from root. Unless a daemon runs user programs (such as local mail delivery agents), it shouldn't need root privileges.
Problem: STREAMS are not portable. They are included in SVR4-based systems, but they are much too complicated to be easily included in new systems.
Problem: Using a generic communication tool merely passes the buck. How does the mail program find the uid?