|
|
1.1 root 1: /* ufopen.c
2: Open a file with the permissions of the invoking user.
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: #if HAVE_FCNTL_H
35: #include <fcntl.h>
36: #else
37: #if HAVE_SYS_FILE_H
38: #include <sys/file.h>
39: #endif
40: #endif
41:
42: #ifndef O_RDONLY
43: #define O_RDONLY 0
44: #define O_WRONLY 1
45: #define O_RDWR 2
46: #endif
47:
48: #ifndef O_NOCTTY
49: #define O_NOCTTY 0
50: #endif
51:
52: #ifndef FD_CLOEXEC
53: #define FD_CLOEXEC 1
54: #endif
55:
56: /* Local functions. */
57:
58: static boolean fsuser_perms P((uid_t *pieuid));
59: static boolean fsuucp_perms P((long ieuid));
60:
61: /* Switch to permissions of the invoking user. */
62:
63: static boolean
64: fsuser_perms (pieuid)
65: uid_t *pieuid;
66: {
67: uid_t ieuid, iuid;
68:
69: ieuid = geteuid ();
70: iuid = getuid ();
71: if (pieuid != NULL)
72: *pieuid = ieuid;
73:
74: #if HAVE_SETREUID
75: /* Swap the effective user id and the real user id. We can then
76: swap them back again when we want to return to the uucp user's
77: permissions. */
78: if (setreuid (ieuid, iuid) < 0)
79: {
80: ulog (LOG_ERROR, "setreuid (%ld, %ld): %s",
81: (long) ieuid, (long) iuid, strerror (errno));
82: return FALSE;
83: }
84: #else /* ! HAVE_SETREUID */
85: #if HAVE_SAVED_SETUID
86: /* Set the effective user id to the real user id. Since the
87: effective user id is saved (it's the saved setuid) we will able
88: to set back to it later. If the real user id is root we will not
89: be able to switch back and forth, so don't even try. */
90: if (iuid != 0)
91: {
92: if (setuid (iuid) < 0)
93: {
94: ulog (LOG_ERROR, "setuid (%ld): %s", (long) iuid, strerror (errno));
95: return FALSE;
96: }
97: }
98: #else /* ! HAVE_SAVED_SETUID */
99: /* There's no way to switch between real permissions and effective
100: permissions. Just try to open the file with the uucp
101: permissions. */
102: #endif /* ! HAVE_SAVED_SETUID */
103: #endif /* ! HAVE_SETREUID */
104:
105: return TRUE;
106: }
107:
108: /* Restore the uucp permissions. */
109:
110: /*ARGSUSED*/
111: static boolean
112: fsuucp_perms (ieuid)
113: long ieuid;
114: {
115: #if HAVE_SETREUID
116: /* Swap effective and real user id's back to what they were. */
117: if (! fsuser_perms ((uid_t *) NULL))
118: return FALSE;
119: #else /* ! HAVE_SETREUID */
120: #if HAVE_SAVED_SETUID
121: /* Set ourselves back to our original effective user id. */
122: if (setuid ((uid_t) ieuid) < 0)
123: {
124: ulog (LOG_ERROR, "setuid (%ld): %s", (long) ieuid, strerror (errno));
125: /* Is this error message helpful or confusing? */
126: if (errno == EPERM)
127: ulog (LOG_ERROR,
128: "Probably HAVE_SAVED_SETUID in policy.h should be set to 0");
129: return FALSE;
130: }
131: #else /* ! HAVE_SAVED_SETUID */
132: /* We didn't switch, no need to switch back. */
133: #endif /* ! HAVE_SAVED_SETUID */
134: #endif /* ! HAVE_SETREUID */
135:
136: return TRUE;
137: }
138:
139: /* Open a file with the permissions of the invoking user. Ignore the
140: fbinary argument since Unix has no distinction between text and
141: binary files. */
142:
143: /*ARGSUSED*/
144: openfile_t
145: esysdep_user_fopen (zfile, frd, fbinary)
146: const char *zfile;
147: boolean frd;
148: boolean fbinary;
149: {
150: uid_t ieuid;
151: openfile_t e;
152: const char *zerr;
153: int o = 0;
154:
155: if (! fsuser_perms (&ieuid))
156: return EFILECLOSED;
157:
158: zerr = NULL;
159:
160: #if USE_STDIO
161: e = fopen (zfile, frd ? "r" : "w");
162: if (e == NULL)
163: zerr = "fopen";
164: else
165: o = fileno (e);
166: #else
167: if (frd)
168: {
169: e = open ((char *) zfile, O_RDONLY | O_NOCTTY, 0);
170: zerr = "open";
171: }
172: else
173: {
174: e = creat ((char *) zfile, IPUBLIC_FILE_MODE);
175: zerr = "creat";
176: }
177: if (e >= 0)
178: {
179: o = e;
180: zerr = NULL;
181: }
182: #endif
183:
184: if (! fsuucp_perms ((long) ieuid))
185: {
186: if (ffileisopen (e))
187: (void) ffileclose (e);
188: return EFILECLOSED;
189: }
190:
191: if (zerr != NULL)
192: {
193: ulog (LOG_ERROR, "%s (%s): %s", zerr, zfile, strerror (errno));
194: #if ! HAVE_SETREUID
195: /* Are these error messages helpful or confusing? */
196: #if HAVE_SAVED_SETUID
197: if (errno == EACCES && getuid () == 0)
198: ulog (LOG_ERROR,
199: "The superuser may only transfer files that are readable by %s",
200: OWNER);
201: #else
202: if (errno == EACCES)
203: ulog (LOG_ERROR,
204: "You may only transfer files that are readable by %s", OWNER);
205: #endif
206: #endif /* ! HAVE_SETREUID */
207: return EFILECLOSED;
208: }
209:
210: if (fcntl (o, F_SETFD, fcntl (o, F_GETFD, 0) | FD_CLOEXEC) < 0)
211: {
212: ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno));
213: (void) ffileclose (e);
214: return EFILECLOSED;
215: }
216:
217: return e;
218: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.