Research V7 release
[unix-history] / usr / src / cmd / uucp / chkpth.c
CommitLineData
b7b37452
N
1#include "uucp.h"
2#include <sys/types.h>
3#include <sys/stat.h>
4
5
6#define DFLTNAME "default"
7#define MAXUSERS 20
8struct userpath {
9 char *us_lname;
10 char *us_mname;
11 char us_callback;
12 char **us_path;
13};
14struct userpath Upt[15];
15struct userpath *Mchdef = NULL, *Logdef = NULL;
16int Nbrusers = 0;
17int Uptfirst = 1;
18
19/*******
20 * chkpth(logname, mchname, path)
21 * char *path, *logname, *mchname;
22 *
23 * chkpth - this routine will check the path table for the
24 * machine or log name (non-null parameter) to see if the
25 * input path (path)
26 * starts with an acceptable prefix.
27 *
28 * return codes: 0 | FAIL
29 */
30
31chkpth(logname, mchname, path)
32char *path, *logname, *mchname;
33{
34 struct userpath *u;
35 extern char *lastpart();
36 char **p, *s;
37 char c;
38 int ret, i;
39
40 if (prefix(THISDIR, path))
41 return(FAIL);
42 if (Uptfirst) {
43 ret = rdpth(Upt);
44 ASSERT(ret == 0, "INIT USERFILE %d", Nbrusers);
45 Uptfirst = 0;
46 }
47 for (u = Upt, i = 0; i < Nbrusers; i++, u++) {
48 if (*logname != '\0' && strcmp(logname, u->us_lname) == SAME)
49 break;
50 if (*mchname != '\0' && strcmp(mchname, u->us_mname) == SAME)
51 break;
52
53 }
54 if (i >= Nbrusers) {
55 if (*logname == '\0')
56 u = Mchdef;
57 else
58 u = Logdef;
59 if (u == NULL)
60 return(FAIL);
61 }
62 /* found user name */
63 p = u->us_path;
64 /* check for /../ in path name */
65 for (s = path; *s != '\0'; s++) {
66 if (*s == '/' && prefix("../", (++s)))
67 return(FAIL);
68 }
69
70 if (chklnk(path) > LINKLEVEL)
71 return(FAIL);
72 for (p = u->us_path; *p != NULL; p++)
73 if (prefix(*p, path))
74 return(0);
75
76 if (prefix(Spool, path)) {
77 if ((c = *lastpart(path)) == DATAPRE
78 || c == XQTPRE)
79 return(0);
80 }
81 /* path name not valid */
82 return(FAIL);
83}
84
85
86/***
87 * rdpth(u)
88 * struct userpath *u;
89 *
90 * rdpth - this routine will read the USFILE and
91 * construct the userpath structure pointed to by (u);
92 *
93 * return codes: 0 | FAIL
94 */
95
96rdpth(u)
97struct userpath *u;
98{
99 char buf[BUFSIZ + 1], *pbuf[BUFSIZ + 1], *pc, **cp;
100 extern char *calloc(), *index();
101 FILE *uf;
102
103 if ((uf = fopen(USERFILE, "r")) == NULL) {
104 /* can not open file */
105 return(FAIL);
106 }
107
108 while (fgets(buf, BUFSIZ, uf) != NULL) {
109 int nargs, i;
110 if (++Nbrusers > MAXUSERS) {
111 fclose(uf);
112 return(FAIL);
113 }
114 if ((pc = calloc(strlen(buf) + 1, sizeof (char)))
115 == NULL) {
116 /* can not allocate space */
117 fclose(uf);
118 return(FAIL);
119 }
120
121 strcpy(pc, buf);
122 nargs = getargs(pc, pbuf);
123 u->us_lname = pbuf[0];
124 pc = index(u->us_lname, ',');
125 if (pc != NULL)
126 *pc++ = '\0';
127 else
128 pc = u + strlen(u->us_lname);
129 u->us_mname = pc;
130 if (*u->us_lname == '\0')
131 Logdef = u;
132 else if (*u->us_mname == '\0')
133 Mchdef = u;
134 i = 1;
135 if (strcmp(pbuf[1], "c") == SAME) {
136 u->us_callback = 1;
137 i++;
138 }
139 else
140 u->us_callback = 0;
141 if ((cp = u->us_path =
142 calloc(nargs - i + 1, sizeof (char *))) == NULL) {
143 /* can not allocate space */
144 fclose(uf);
145 return(FAIL);
146 }
147
148 while (i < nargs)
149 *cp++ = pbuf[i++];
150 *cp = NULL;
151 u++;
152 }
153
154 fclose(uf);
155 return(0);
156}
157
158
159/***
160 * callback(name) check for callback
161 * char *name;
162 *
163 * return codes:
164 * 0 - no call back
165 * 1 - call back
166 */
167
168callback(name)
169char *name;
170{
171 struct userpath *u;
172 int ret, i;
173
174 if (Uptfirst) {
175 ret = rdpth(Upt);
176 ASSERT(ret == 0, "INIT USERFILE %d", Nbrusers);
177 Uptfirst = 0;
178 }
179
180 for (u = Upt, i = 0; i < Nbrusers; u++, i++) {
181 if (strcmp(u->us_lname, name) != SAME)
182 continue;
183
184 /* found user name */
185 return(u->us_callback);
186 }
187
188 /* userid not found */
189 return(0);
190}
191
192
193/***
194 * chklnk(name) get number of links
195 * char *name;
196 *
197 * return codes: 0 - stat failed or directory | number of links
198 */
199
200chklnk(name)
201char *name;
202{
203 struct stat s;
204
205 if (stat(name, &s) == -1)
206 return(0);
207 if ((s.st_mode & S_IFMT) == S_IFDIR)
208 return(0);
209 return(s.st_nlinks);
210}
211
212
213/***
214 * chkperm(file, user, mopt) check write permission of file
215 * char *file, *user;
216 * char *mopt; none NULL - create directories
217 *
218 * if mopt != NULL and permissions are ok,
219 * a side effect of this routine is to make
220 * directories up to the last part of the
221 * filename (if they do not exist).
222 *
223 * return 0 | FAIL
224 */
225
226chkperm(file, user, mopt)
227char *file, *user, *mopt;
228{
229 struct stat s;
230 int ret, bits;
231 char dir[MAXFULLNAME];
232 extern char *lastpart();
233
234 if (stat(file, &s) != -1)
235 return(0);
236
237 strcpy(dir, file);
238 *lastpart(dir) = '\0';
239 if ((ret = stat(dir, &s)) == -1
240 && mopt == NULL)
241 return(FAIL);
242
243 bits = (geteuid() == 0) ? 02 : 0200;
244 if (ret != -1) {
245 if ((s.st_mode & bits) == 0)
246 return(FAIL);
247 else
248 return(0);
249 }
250
251 /* make directories */
252 return(mkdirs(file));
253}