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