|
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
|