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