Subject: osetre{uid,gid} called by root return EPERM?
To: None <port-pmax@sun-lamp.cs.berkeley.edu>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: port-pmax
Date: 08/18/1994 04:53:05
It turns out Ultrix /bin/login wants to call the Ultrix
library routine setuid() and setgid() to do the obvious. The
library routines in turn call setreuid(uid, uid) and setregid(gid, gid).

NetBSD was returning EPERM for this operation even when done as root.
The fix below gets around this, but I'm not sure if it's right.
Why doesn't SunOS compatibility mode run into a similar problem?

With this, and some other minor tweaks -- partial emulation of
Ultrix's TCGETP ioctl (tcgetattr) and TIOCNMODEM ioctls; mapping
quota(), audctl() and audgen() to nullop() rather than nosys();
and  adding in osetdomain/ogetdomain support -- I get a kernel
that goes multiuser, and can run gcc.

csh and tcsh don't work yet, though.
And the clock is somehow exactly 730 days slow.


*** kern_prot.c.DIST	Wed Jun 29 03:29:00 1994
--- kern_prot.c	Thu Aug 18 04:04:04 1994
***************
*** 387,393 ****
  	return (0);
  }
  
! #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
  struct setreuid_args {
  	int	ruid;
  	int	euid;
--- 387,393 ----
  	return (0);
  }
  
! #if defined(COMPAT_43) || defined(COMPAT_SUNOS) || defined(COMPAT_ULTRIX)
  struct setreuid_args {
  	int	ruid;
  	int	euid;
***************
*** 407,413 ****
  	 * do so, but do not actually set the ruid.
  	 */
  	if (uap->ruid != (uid_t)-1 && uap->ruid != pc->p_ruid &&
! 	    uap->ruid != pc->p_svuid)
  		return (EPERM);
  	if (uap->euid == (uid_t)-1)
  		return (0);
--- 407,417 ----
  	 * do so, but do not actually set the ruid.
  	 */
  	if (uap->ruid != (uid_t)-1 && uap->ruid != pc->p_ruid &&
! 	    uap->ruid != pc->p_svuid
! #ifdef COMPAT_ULTRIX
! 	    && (suser(pc->pc_ucred, &p->p_acflag))
! #endif
! 	    )
  		return (EPERM);
  	if (uap->euid == (uid_t)-1)
  		return (0);
***************
*** 434,440 ****
  	 * do so, but do not actually set the rgid.
  	 */
  	if (uap->rgid != (gid_t)-1 && uap->rgid != pc->p_rgid &&
! 	    uap->rgid != pc->p_svgid)
  		return (EPERM);
  	if (uap->egid == (gid_t)-1)
  		return (0);
--- 438,448 ----
  	 * do so, but do not actually set the rgid.
  	 */
  	if (uap->rgid != (gid_t)-1 && uap->rgid != pc->p_rgid &&
! 	    uap->rgid != pc->p_svgid
! #ifdef COMPAT_ULTRIX
! 	    && (suser(pc->pc_ucred, &p->p_acflag))
! #endif
! 	    )
  		return (EPERM);
  	if (uap->egid == (gid_t)-1)
  		return (0);

------------------------------------------------------------------------------