1/*********************************************************************** 2* * 3* This software is part of the ast package * 4* Copyright (c) 1985-2011 AT&T Intellectual Property * 5* and is licensed under the * 6* Eclipse Public License, Version 1.0 * 7* by AT&T Intellectual Property * 8* * 9* A copy of the License is available at * 10* http://www.eclipse.org/org/documents/epl-v10.html * 11* (with md5 checksum b35adb5213ca9657e911e9befb180842) * 12* * 13* Information and Software Systems Research * 14* AT&T Research * 15* Florham Park NJ * 16* * 17* Glenn Fowler <gsf@research.att.com> * 18* David Korn <dgk@research.att.com> * 19* Phong Vo <kpv@research.att.com> * 20* * 21***********************************************************************/ 22#pragma prototyped 23/* 24 * access() euid/egid implementation 25 */ 26 27#include <ast.h> 28#include <errno.h> 29#include <ls.h> 30 31#include "FEATURE/eaccess" 32 33#if _lib_eaccess 34 35NoN(eaccess) 36 37#else 38 39#if defined(__EXPORT__) 40#define extern __EXPORT__ 41#endif 42 43extern int 44eaccess(const char* path, register int flags) 45{ 46#ifdef EFF_ONLY_OK 47 return access(path, flags|EFF_ONLY_OK); 48#else 49#if _lib_euidaccess 50 return euidaccess(path, flags); 51#else 52 register int mode; 53 struct stat st; 54 55 static int init; 56 static uid_t ruid; 57 static uid_t euid; 58 static gid_t rgid; 59 static gid_t egid; 60 61 if (!init) 62 { 63 ruid = getuid(); 64 euid = geteuid(); 65 rgid = getgid(); 66 egid = getegid(); 67 init = (ruid == euid && rgid == egid) ? 1 : -1; 68 } 69 if (init > 0 || flags == F_OK) 70 return access(path, flags); 71 if (stat(path, &st)) 72 return -1; 73 mode = 0; 74 if (euid == 0) 75 { 76 if (!S_ISREG(st.st_mode) || !(flags & X_OK) || (st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))) 77 return 0; 78 goto nope; 79 } 80 else if (euid == st.st_uid) 81 { 82 if (flags & R_OK) 83 mode |= S_IRUSR; 84 if (flags & W_OK) 85 mode |= S_IWUSR; 86 if (flags & X_OK) 87 mode |= S_IXUSR; 88 } 89 else if (egid == st.st_gid) 90 { 91#if _lib_getgroups 92 setgroup: 93#endif 94 if (flags & R_OK) 95 mode |= S_IRGRP; 96 if (flags & W_OK) 97 mode |= S_IWGRP; 98 if (flags & X_OK) 99 mode |= S_IXGRP; 100 } 101 else 102 { 103#if _lib_getgroups 104 register int n; 105 106 static int ngroups = -2; 107 static gid_t* groups; 108 109 if (ngroups == -2) 110 { 111 if ((ngroups = getgroups(0, (gid_t*)0)) <= 0) 112 ngroups = NGROUPS_MAX; 113 if (!(groups = newof(0, gid_t, ngroups + 1, 0))) 114 ngroups = -1; 115 else 116 ngroups = getgroups(ngroups, groups); 117 } 118 n = ngroups; 119 while (--n >= 0) 120 if (groups[n] == st.st_gid) 121 goto setgroup; 122#endif 123 if (flags & R_OK) 124 mode |= S_IROTH; 125 if (flags & W_OK) 126 mode |= S_IWOTH; 127 if (flags & X_OK) 128 mode |= S_IXOTH; 129 } 130 if ((st.st_mode & mode) == mode) 131 return 0; 132 nope: 133 errno = EACCES; 134 return -1; 135#endif 136#endif 137} 138 139#endif 140