|
|
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.