*BSD News Article 18523


Return to BSD News archive

Newsgroups: comp.os.386bsd.development
Path: sserve!newshost.anu.edu.au!munnari.oz.au!news.Hawaii.Edu!ames!haven.umd.edu!darwin.sura.net!sgiblab!majipoor.cygnus.com!kithrup.com!sef
From: sef@kithrup.com (Sean Eric Fagan)
Subject: eaccess() system call
Organization: Kithrup Enterprises, Ltd.
Message-ID: <CA9zvs.82J@kithrup.com>
Date: Fri, 16 Jul 1993 21:04:25 GMT
Lines: 216

I saw a discussion about making ash handle multiple groups correctly
(in determining whether a file could be executed or not), and was
appalled, since it was, basicly, replicating code that was already in
the kernel -- sorta, since access() uses real user and group id's, but
a shell only needs to care about the effective id's.

So, I decided to write eaccess(), which is exactly like access(), only
it uses the effective id's.  When I did so, I found three more files
that were missing from the 386BSD distribution, al in /sys/kern:
syscalls.master, makesyscalls.sh, and Makefile.  I've let both the
NetBSD and interim groups know about this, so the missing files should
be in the next release.  In the meanwhile, you can get them from any
archive site that has net/2.

Anyway, for anyone who really cares, here's eaccess(), and some patches
to /bin/sh to make it use it.  The NetBSD folks don't want it, I haven't
heard back from the 4.4 folks, and I have offered it to the interim
folks :).  But, if nothing else, it can serve as an example of how to
add a system call to *bsd.

Enjoy.
*** sys.386bsd/kern/vfs_syscalls.c.~1~	Sat May 16 20:22:16 1992
--- sys.386bsd/kern/vfs_syscalls.c	Wed Jul 14 21:41:20 1993
***************
*** 969,975 ****
  /*
   * Check access permissions.
   */
! /* ARGSUSED */
  saccess(p, uap, retval)
  	struct proc *p;
  	register struct args {
--- 969,989 ----
  /*
   * Check access permissions.
   */
! 
! eaccess(p, uap, retval)
! 	struct proc *p;
! 	register struct args {
! 		char	*fname;
! 		int	fmode;
! 	} *uap;
! 	int *retval;
! {
! 	int error;
! 
! 	error = saccess1(p, uap, retval);
! 	return error;
! }
! 
  saccess(p, uap, retval)
  	struct proc *p;
  	register struct args {
***************
*** 978,994 ****
  	} *uap;
  	int *retval;
  {
  	register struct nameidata *ndp;
  	register struct ucred *cred = p->p_ucred;
  	register struct vnode *vp;
! 	int error, mode, svuid, svgid;
  	struct nameidata nd;
  
  	ndp = &nd;
- 	svuid = cred->cr_uid;
- 	svgid = cred->cr_groups[0];
- 	cred->cr_uid = p->p_cred->p_ruid;
- 	cred->cr_groups[0] = p->p_cred->p_rgid;
  	ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
  	ndp->ni_segflg = UIO_USERSPACE;
  	ndp->ni_dirp = uap->fname;
--- 992,1025 ----
  	} *uap;
  	int *retval;
  {
+ 	int error;
+ 	int svuid = p->p_ucred->cr_uid;
+ 	int svgid = p->p_ucred->cr_groups[0];
+ 
+ 	p->p_ucred->cr_uid = p->p_cred->p_ruid;
+ 	p->p_ucred->cr_groups[0] = p->p_cred->p_rgid;
+ 	error = saccess1(p, uap, retval);
+ 	p->p_ucred->cr_uid = svuid;
+ 	p->p_ucred->cr_groups[0] = svgid;
+ 	return error;
+ }
+ 
+ /* ARGSUSED */
+ saccess1(p, uap, retval)
+ 	struct proc *p;
+ 	register struct args {
+ 		char	*fname;
+ 		int	fmode;
+ 	} *uap;
+ 	int *retval;
+ {
  	register struct nameidata *ndp;
  	register struct ucred *cred = p->p_ucred;
  	register struct vnode *vp;
! 	int error, mode;
  	struct nameidata nd;
  
  	ndp = &nd;
  	ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
  	ndp->ni_segflg = UIO_USERSPACE;
  	ndp->ni_dirp = uap->fname;
***************
*** 1011,1018 ****
  	}
  	vput(vp);
  out1:
- 	cred->cr_uid = svuid;
- 	cred->cr_groups[0] = svgid;
  	return (error);
  }
  
--- 1042,1047 ----
*** sys.386bsd/kern/syscalls.master.~1~	Tue Jul 13 19:48:26 1993
--- sys.386bsd/kern/syscalls.master	Wed Jul 14 14:49:21 1993
***************
*** 114,120 ****
  78	STD	3 mincore
  79	STD	2 getgroups
  80	STD	2 setgroups
! 81	STD	0 getpgrp
  82	STD	2 setpgid
  83	STD	3 setitimer
  84	COMPAT	0 wait
--- 114,120 ----
  78	STD	3 mincore
  79	STD	2 getgroups
  80	STD	2 setgroups
! 81	STD	1 getpgrp
  82	STD	2 setpgid
  83	STD	3 setitimer
  84	COMPAT	0 wait
*** lib/libc/sys/Makefile.inc.~1~	Wed Feb 12 23:42:44 1992
--- lib/libc/sys/Makefile.inc	Wed Jul 14 17:29:42 1993
***************
*** 11,17 ****
  # modules with default implementations on all architectures:
  ASM=	accept.o access.o acct.o adjtime.o async_daemon.o bind.o chdir.o \
  	chflags.o chmod.o chown.o chroot.o close.o connect.o dup.o dup2.o \
! 	execve.o fchdir.o fchflags.o fchmod.o fchown.o fcntl.o flock.o \
  	fstat.o fstatfs.o fsync.o ftruncate.o getdirentries.o \
  	getdtablesize.o getegid.o geteuid.o getfh.o getfsstat.o getgid.o \
  	getgroups.o gethostid.o gethostname.o getitimer.o getkerninfo.o \
--- 11,17 ----
  # modules with default implementations on all architectures:
  ASM=	accept.o access.o acct.o adjtime.o async_daemon.o bind.o chdir.o \
  	chflags.o chmod.o chown.o chroot.o close.o connect.o dup.o dup2.o \
! 	eaccess.o execve.o fchdir.o fchflags.o fchmod.o fchown.o fcntl.o flock.o \
  	fstat.o fstatfs.o fsync.o ftruncate.o getdirentries.o \
  	getdtablesize.o getegid.o geteuid.o getfh.o getfsstat.o getgid.o \
  	getgroups.o gethostid.o gethostname.o getitimer.o getkerninfo.o \
*** bin/sh/exec.c.~1~	Mon Apr 15 17:22:50 1991
--- bin/sh/exec.c	Wed Jul 14 22:52:49 1993
***************
*** 66,71 ****
--- 66,72 ----
  #include "mystring.h"
  #include <sys/types.h>
  #include <sys/stat.h>
+ #include <unistd.h>
  #include <fcntl.h>
  #include <errno.h>
  
***************
*** 459,464 ****
--- 460,473 ----
  			TRACE(("searchexec \"%s\": no change\n", name));
  			goto success;
  		}
+ #if 1
+ 		while (eaccess(fullname, X_OK) < 0) {
+ 			if (errno != ENOENT && errno != ENOTDIR)
+ 				e = errno;
+ 			goto loop;
+ 		}
+ 		e = EACCES;
+ #else
  		while (stat(fullname, &statb) < 0) {
  #ifdef SYSV
  			if (errno == EINTR)
***************
*** 471,476 ****
--- 480,486 ----
  		e = EACCES;	/* if we fail, this will be the error */
  		if ((statb.st_mode & S_IFMT) != S_IFREG)
  			goto loop;
+ #endif
  		if (pathopt) {		/* this is a %func directory */
  			stalloc(strlen(fullname) + 1);
  			readcmdfile(fullname);
***************
*** 479,484 ****
--- 489,495 ----
  			stunalloc(fullname);
  			goto success;
  		}
+ #if 0
  		if (statb.st_uid == geteuid()) {
  			if ((statb.st_mode & 0100) == 0)
  				goto loop;
***************
*** 489,494 ****
--- 500,506 ----
  			if ((statb.st_mode & 01) == 0)
  				goto loop;
  		}
+ #endif
  		TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
  		INTOFF;
  		cmdp = cmdlookup(name, 1);