Commit | Line | Data |
---|---|---|
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 | |
8 | struct userpath { | |
9 | char *us_lname; | |
10 | char *us_mname; | |
11 | char us_callback; | |
12 | char **us_path; | |
13 | }; | |
14 | struct userpath Upt[15]; | |
15 | struct userpath *Mchdef = NULL, *Logdef = NULL; | |
16 | int Nbrusers = 0; | |
17 | int 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 | ||
31 | chkpth(logname, mchname, path) | |
32 | char *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 | ||
96 | rdpth(u) | |
97 | struct 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 | ||
168 | callback(name) | |
169 | char *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 | ||
200 | chklnk(name) | |
201 | char *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 | ||
226 | chkperm(file, user, mopt) | |
227 | char *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 | } |