|
|
1.1 ! root 1: /* uacces.c ! 2: Check access to a file by user name. ! 3: ! 4: Copyright (C) 1992 Ian Lance Taylor ! 5: ! 6: This file is part of the Taylor UUCP package. ! 7: ! 8: This program is free software; you can redistribute it and/or ! 9: modify it under the terms of the GNU General Public License as ! 10: published by the Free Software Foundation; either version 2 of the ! 11: License, or (at your option) any later version. ! 12: ! 13: This program is distributed in the hope that it will be useful, but ! 14: WITHOUT ANY WARRANTY; without even the implied warranty of ! 15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 16: General Public License for more details. ! 17: ! 18: You should have received a copy of the GNU General Public License ! 19: along with this program; if not, write to the Free Software ! 20: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 21: ! 22: The author of the program may be contacted at [email protected] or ! 23: c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. ! 24: */ ! 25: ! 26: #include "uucp.h" ! 27: ! 28: #include "uudefs.h" ! 29: #include "sysdep.h" ! 30: ! 31: #include <pwd.h> ! 32: #include <errno.h> ! 33: ! 34: #if HAVE_GETGRENT ! 35: #include <grp.h> ! 36: #if GETGRENT_DECLARATION_OK ! 37: #ifndef getgrent ! 38: extern struct group *getgrent (); ! 39: #endif ! 40: #endif ! 41: #endif /* HAVE_GETGRENT */ ! 42: ! 43: #if GETPWNAM_DECLARATION_OK ! 44: #ifndef getpwnam ! 45: extern struct passwd *getpwnam (); ! 46: #endif ! 47: #endif ! 48: ! 49: /* Do access(2) on a stat structure, except that the user name is ! 50: provided. If the user name in zuser is NULL, require the file to ! 51: be accessible to the world. Return TRUE if access is permitted, ! 52: FALSE otherwise. This does not log an error message. */ ! 53: ! 54: boolean ! 55: fsuser_access (q, imode, zuser) ! 56: const struct stat *q; ! 57: int imode; ! 58: const char *zuser; ! 59: { ! 60: static char *zuser_hold; ! 61: static uid_t iuid_hold; ! 62: static gid_t igid_hold; ! 63: static int cgroups_hold; ! 64: static gid_t *paigroups_hold; ! 65: int ir, iw, ix, iand; ! 66: ! 67: if (imode == F_OK) ! 68: return TRUE; ! 69: ! 70: if (zuser != NULL) ! 71: { ! 72: /* We keep static variables around for the last user we did, to ! 73: avoid looking up a user multiple times. */ ! 74: if (zuser_hold == NULL || strcmp (zuser_hold, zuser) != 0) ! 75: { ! 76: struct passwd *qpwd; ! 77: ! 78: if (zuser_hold != NULL) ! 79: { ! 80: ubuffree (zuser_hold); ! 81: zuser_hold = NULL; ! 82: cgroups_hold = 0; ! 83: xfree ((pointer) paigroups_hold); ! 84: paigroups_hold = NULL; ! 85: } ! 86: ! 87: qpwd = getpwnam ((char *) zuser); ! 88: if (qpwd == NULL) ! 89: { ! 90: /* Check this as a remote request. */ ! 91: zuser = NULL; ! 92: } ! 93: else ! 94: { ! 95: #if HAVE_GETGRENT ! 96: struct group *qg; ! 97: #endif ! 98: ! 99: zuser_hold = zbufcpy (zuser); ! 100: ! 101: iuid_hold = qpwd->pw_uid; ! 102: igid_hold = qpwd->pw_gid; ! 103: ! 104: #if HAVE_GETGRENT ! 105: /* Get the list of groups for this user. This is ! 106: definitely more appropriate for BSD than for System ! 107: V. It may just be a waste of time, and perhaps it ! 108: should be configurable. */ ! 109: setgrent (); ! 110: while ((qg = getgrent ()) != NULL) ! 111: { ! 112: const char **pz; ! 113: ! 114: if (qg->gr_gid == igid_hold) ! 115: continue; ! 116: for (pz = (const char **) qg->gr_mem; *pz != NULL; pz++) ! 117: { ! 118: if ((*pz)[0] == *zuser ! 119: && strcmp (*pz, zuser) == 0) ! 120: { ! 121: paigroups_hold = ((gid_t *) ! 122: (xrealloc ! 123: ((pointer) paigroups_hold, ! 124: ((cgroups_hold + 1) ! 125: * sizeof (gid_t))))); ! 126: paigroups_hold[cgroups_hold] = qg->gr_gid; ! 127: ++cgroups_hold; ! 128: break; ! 129: } ! 130: } ! 131: } ! 132: endgrent (); ! 133: #endif ! 134: } ! 135: } ! 136: } ! 137: ! 138: ! 139: /* Now do the actual access check. */ ! 140: ! 141: if (zuser != NULL) ! 142: { ! 143: /* The superuser can do anything. */ ! 144: if (iuid_hold == 0) ! 145: return TRUE; ! 146: ! 147: /* If this is the uid we're running under, there's no point to ! 148: checking access further, because when we actually try the ! 149: operation the system will do the checking for us. */ ! 150: if (iuid_hold == geteuid ()) ! 151: return TRUE; ! 152: } ! 153: ! 154: ir = S_IROTH; ! 155: iw = S_IWOTH; ! 156: ix = S_IXOTH; ! 157: ! 158: if (zuser != NULL) ! 159: { ! 160: if (iuid_hold == q->st_uid) ! 161: { ! 162: ir = S_IRUSR; ! 163: iw = S_IWUSR; ! 164: ix = S_IXUSR; ! 165: } ! 166: else ! 167: { ! 168: boolean fgroup; ! 169: ! 170: fgroup = FALSE; ! 171: if (igid_hold == q->st_gid) ! 172: fgroup = TRUE; ! 173: else ! 174: { ! 175: int i; ! 176: ! 177: for (i = 0; i < cgroups_hold; i++) ! 178: { ! 179: if (paigroups_hold[i] == q->st_gid) ! 180: { ! 181: fgroup = TRUE; ! 182: break; ! 183: } ! 184: } ! 185: } ! 186: ! 187: if (fgroup) ! 188: { ! 189: ir = S_IRGRP; ! 190: iw = S_IWGRP; ! 191: ix = S_IXGRP; ! 192: } ! 193: } ! 194: } ! 195: ! 196: iand = 0; ! 197: if ((imode & R_OK) != 0) ! 198: iand |= ir; ! 199: if ((imode & W_OK) != 0) ! 200: iand |= iw; ! 201: if ((imode & X_OK) != 0) ! 202: iand |= ix; ! 203: ! 204: return (q->st_mode & iand) == iand; ! 205: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.