|
|
1.1 ! root 1: /* indir.c ! 2: See if a file is in a directory. ! 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: #include "system.h" ! 31: ! 32: #include <errno.h> ! 33: ! 34: /* See whether a file is in a directory, and optionally check access. */ ! 35: ! 36: boolean ! 37: fsysdep_in_directory (zfile, zdir, fcheck, freadable, zuser) ! 38: const char *zfile; ! 39: const char *zdir; ! 40: boolean fcheck; ! 41: boolean freadable; ! 42: const char *zuser; ! 43: { ! 44: size_t c; ! 45: char *zcopy, *zslash; ! 46: struct stat s; ! 47: ! 48: if (*zfile != '/') ! 49: return FALSE; ! 50: c = strlen (zdir); ! 51: if (c > 0 && zdir[c - 1] == '/') ! 52: c--; ! 53: if (strncmp (zfile, zdir, c) != 0 ! 54: || (zfile[c] != '/' && zfile[c] != '\0')) ! 55: return FALSE; ! 56: if (strstr (zfile + c, "/../") != NULL) ! 57: return FALSE; ! 58: ! 59: /* If we're not checking access, get out now. */ ! 60: if (! fcheck) ! 61: return TRUE; ! 62: ! 63: zcopy = zbufcpy (zfile); ! 64: ! 65: /* Start checking directories after zdir. Otherwise, we would ! 66: require that all directories down to /usr/spool/uucppublic be ! 67: publically searchable; they probably are but it should not be a ! 68: requirement. */ ! 69: zslash = zcopy + c; ! 70: do ! 71: { ! 72: char b; ! 73: struct stat shold; ! 74: ! 75: b = *zslash; ! 76: *zslash = '\0'; ! 77: ! 78: shold = s; ! 79: if (stat (zcopy, &s) != 0) ! 80: { ! 81: if (errno != ENOENT) ! 82: { ! 83: ulog (LOG_ERROR, "stat (%s): %s", zcopy, strerror (errno)); ! 84: ubuffree (zcopy); ! 85: return FALSE; ! 86: } ! 87: ! 88: /* If this is the top directory, any problems will be caught ! 89: later when we try to open it. */ ! 90: if (zslash == zcopy + c) ! 91: { ! 92: ubuffree (zcopy); ! 93: return TRUE; ! 94: } ! 95: ! 96: /* Go back and check the last directory for read or write ! 97: access. */ ! 98: s = shold; ! 99: break; ! 100: } ! 101: ! 102: /* If this is not a directory, get out of the loop. */ ! 103: if (! S_ISDIR (s.st_mode)) ! 104: break; ! 105: ! 106: /* Make sure the directory is searchable. */ ! 107: if (! fsuser_access (&s, X_OK, zuser)) ! 108: { ! 109: ulog (LOG_ERROR, "%s: %s", zcopy, strerror (EACCES)); ! 110: ubuffree (zcopy); ! 111: return FALSE; ! 112: } ! 113: ! 114: /* If we've reached the end of the string, get out. */ ! 115: if (b == '\0') ! 116: break; ! 117: ! 118: *zslash = b; ! 119: } ! 120: while ((zslash = strchr (zslash + 1, '/')) != NULL); ! 121: ! 122: /* At this point s holds a stat on the last component of the path. ! 123: We must check it for readability or writeability. */ ! 124: if (! fsuser_access (&s, freadable ? R_OK : W_OK, zuser)) ! 125: { ! 126: ulog (LOG_ERROR, "%s: %s", zcopy, strerror (EACCES)); ! 127: ubuffree (zcopy); ! 128: return FALSE; ! 129: } ! 130: ! 131: ubuffree (zcopy); ! 132: return TRUE; ! 133: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.