Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!seismo!rutgers!princeton!allegra!ulysses!sfmag!sfsup!mpl
From: mpl@sfsup.UUCP
Newsgroups: comp.unix.questions
Subject: Re: access(2) question
Message-ID: <1598@sfsup.UUCP>
Date: Mon, 6-Jul-87 17:14:00 EDT
Article-I.D.: sfsup.1598
Posted: Mon Jul  6 17:14:00 1987
Date-Received: Wed, 8-Jul-87 03:10:36 EDT
References: <530@applix.UUCP> <1341@xanth.UUCP> <1027@killer.UUCP> <348@ems.UUCP>
Organization: AT&T-IS, Summit N.J. USA
Lines: 37
Summary: great, except it doesn't work!

In article <348@ems.UUCP>, mark@ems.UUCP writes:
> 	After all the discussion about an access call that uses EFFECTIVE
	[text deleted]
> 	if (geteuid() == buf.st_uid)
> 		tempmode = (buf.st_mode & 0x01c0) >> 6;
	first of all, why not say
 		tempmode = (buf.st_mode >> 6 & 07);
	rather than making the reader guess that 0x01c0 is 7 <<'ed 6 times

> 	if (getegid() == buf.st_gid)
> 		tempmode |= (buf.st_mode & 0x038) >> 3;
> 	tempmode |= buf.st_mode & 0x07;
	secondly, these bits shouldn't be or'ed in.  In other words, a
	file which is owned by me and mode 066 can be read or written by
	anyone BUT me.  This is *not* the behavior this code exhibits.
	A (hopefully correct) solution is:

access(path, amode)
char	*path;
int	amode;
{
	struct	stat	buf;
	int	shifter;	/* how many bits to shift right */

	if (stat(path, &buf))
		return -1;
	if (geteuid() == buf.st_uid)
		shifter = 6;
	else if (getegid() == buf.st_gid)
		shifter = 3;
	else
		shifter = 0;
	amode &= 07;	/* mask off only the bits of interest */
	if ((amode & (buf.st_mode >> shifter)) != amode)
		return -1;
	return 0;
}