Blame src/lib/libast/comp/eaccess.c

Packit Service a8c26c
/***********************************************************************
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*               This software is part of the ast package               *
Packit Service a8c26c
*          Copyright (c) 1985-2011 AT&T Intellectual Property          *
Packit Service a8c26c
*                      and is licensed under the                       *
Packit Service a8c26c
*                 Eclipse Public License, Version 1.0                  *
Packit Service a8c26c
*                    by AT&T Intellectual Property                     *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*                A copy of the License is available at                 *
Packit Service a8c26c
*          http://www.eclipse.org/org/documents/epl-v10.html           *
Packit Service a8c26c
*         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*              Information and Software Systems Research               *
Packit Service a8c26c
*                            AT&T Research                             *
Packit Service a8c26c
*                           Florham Park NJ                            *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*                 Glenn Fowler <gsf@research.att.com>                  *
Packit Service a8c26c
*                  David Korn <dgk@research.att.com>                   *
Packit Service a8c26c
*                   Phong Vo <kpv@research.att.com>                    *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
***********************************************************************/
Packit Service a8c26c
#pragma prototyped
Packit Service a8c26c
/*
Packit Service a8c26c
 * access() euid/egid implementation
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
#include <ast.h>
Packit Service a8c26c
#include <errno.h>
Packit Service a8c26c
#include <ls.h>
Packit Service a8c26c
Packit Service a8c26c
#include "FEATURE/eaccess"
Packit Service a8c26c
Packit Service a8c26c
#if _lib_eaccess
Packit Service a8c26c
Packit Service a8c26c
NoN(eaccess)
Packit Service a8c26c
Packit Service a8c26c
#else
Packit Service a8c26c
Packit Service a8c26c
#if defined(__EXPORT__)
Packit Service a8c26c
#define extern	__EXPORT__
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
extern int
Packit Service a8c26c
eaccess(const char* path, register int flags)
Packit Service a8c26c
{
Packit Service a8c26c
#ifdef EFF_ONLY_OK
Packit Service a8c26c
	return access(path, flags|EFF_ONLY_OK);
Packit Service a8c26c
#else
Packit Service a8c26c
#if _lib_euidaccess
Packit Service a8c26c
	return euidaccess(path, flags);
Packit Service a8c26c
#else
Packit Service a8c26c
	register int	mode;
Packit Service a8c26c
	struct stat	st;
Packit Service a8c26c
Packit Service a8c26c
	static int	init;
Packit Service a8c26c
	static uid_t	ruid;
Packit Service a8c26c
	static uid_t	euid;
Packit Service a8c26c
	static gid_t	rgid;
Packit Service a8c26c
	static gid_t	egid;
Packit Service a8c26c
Packit Service a8c26c
	if (!init)
Packit Service a8c26c
	{
Packit Service a8c26c
		ruid = getuid();
Packit Service a8c26c
		euid = geteuid();
Packit Service a8c26c
		rgid = getgid();
Packit Service a8c26c
		egid = getegid();
Packit Service a8c26c
		init = (ruid == euid && rgid == egid) ? 1 : -1;
Packit Service a8c26c
	}
Packit Service a8c26c
	if (init > 0 || flags == F_OK)
Packit Service a8c26c
		return access(path, flags);
Packit Service a8c26c
	if (stat(path, &st))
Packit Service a8c26c
		return -1;
Packit Service a8c26c
	mode = 0;
Packit Service a8c26c
	if (euid == 0)
Packit Service a8c26c
	{
Packit Service a8c26c
		if (!S_ISREG(st.st_mode) || !(flags & X_OK) || (st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
Packit Service a8c26c
			return 0;
Packit Service a8c26c
		goto nope;
Packit Service a8c26c
	}
Packit Service a8c26c
	else if (euid == st.st_uid)
Packit Service a8c26c
	{
Packit Service a8c26c
		if (flags & R_OK)
Packit Service a8c26c
			mode |= S_IRUSR;
Packit Service a8c26c
		if (flags & W_OK)
Packit Service a8c26c
			mode |= S_IWUSR;
Packit Service a8c26c
		if (flags & X_OK)
Packit Service a8c26c
			mode |= S_IXUSR;
Packit Service a8c26c
	}
Packit Service a8c26c
	else if (egid == st.st_gid)
Packit Service a8c26c
	{
Packit Service a8c26c
#if _lib_getgroups
Packit Service a8c26c
	setgroup:
Packit Service a8c26c
#endif
Packit Service a8c26c
		if (flags & R_OK)
Packit Service a8c26c
			mode |= S_IRGRP;
Packit Service a8c26c
		if (flags & W_OK)
Packit Service a8c26c
			mode |= S_IWGRP;
Packit Service a8c26c
		if (flags & X_OK)
Packit Service a8c26c
			mode |= S_IXGRP;
Packit Service a8c26c
	}
Packit Service a8c26c
	else
Packit Service a8c26c
	{
Packit Service a8c26c
#if _lib_getgroups
Packit Service a8c26c
		register int	n;
Packit Service a8c26c
Packit Service a8c26c
		static int	ngroups = -2;
Packit Service a8c26c
		static gid_t*	groups; 
Packit Service a8c26c
Packit Service a8c26c
		if (ngroups == -2)
Packit Service a8c26c
		{
Packit Service a8c26c
			if ((ngroups = getgroups(0, (gid_t*)0)) <= 0)
Packit Service a8c26c
				ngroups = NGROUPS_MAX;
Packit Service a8c26c
			if (!(groups = newof(0, gid_t, ngroups + 1, 0)))
Packit Service a8c26c
				ngroups = -1;
Packit Service a8c26c
			else
Packit Service a8c26c
				ngroups = getgroups(ngroups, groups);
Packit Service a8c26c
		}
Packit Service a8c26c
		n = ngroups;
Packit Service a8c26c
		while (--n >= 0)
Packit Service a8c26c
			if (groups[n] == st.st_gid)
Packit Service a8c26c
				goto setgroup;
Packit Service a8c26c
#endif
Packit Service a8c26c
		if (flags & R_OK)
Packit Service a8c26c
			mode |= S_IROTH;
Packit Service a8c26c
		if (flags & W_OK)
Packit Service a8c26c
			mode |= S_IWOTH;
Packit Service a8c26c
		if (flags & X_OK)
Packit Service a8c26c
			mode |= S_IXOTH;
Packit Service a8c26c
	}
Packit Service a8c26c
	if ((st.st_mode & mode) == mode)
Packit Service a8c26c
		return 0;
Packit Service a8c26c
 nope:
Packit Service a8c26c
	errno = EACCES;
Packit Service a8c26c
	return -1;
Packit Service a8c26c
#endif
Packit Service a8c26c
#endif
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif