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