1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2010 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 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 35 NoN(eaccess) 36 37 #else 38 39 #if defined(__EXPORT__) 40 #define extern __EXPORT__ 41 #endif 42 43 extern int 44 eaccess(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