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