Commit | Line | Data |
---|---|---|
110711f0 | 1 | #ifndef lint |
2f0181b2 | 2 | static char sccsid[] = "@(#)chkpth.c 5.4 (Berkeley) %G%"; |
110711f0 SL |
3 | #endif |
4 | ||
110711f0 | 5 | #include "uucp.h" |
110711f0 SL |
6 | #include <sys/stat.h> |
7 | ||
110711f0 SL |
8 | struct userpath { |
9 | char *us_lname; | |
10 | char *us_mname; | |
11 | char us_callback; | |
12 | char **us_path; | |
13 | struct userpath *unext; | |
14 | }; | |
15 | struct userpath *Uhead = NULL; | |
16 | struct userpath *Mchdef = NULL, *Logdef = NULL; | |
17 | int Uptfirst = 1; | |
18 | ||
2f0181b2 JB |
19 | /*LINTLIBRARY*/ |
20 | ||
21 | /* | |
22 | * this routine will check the path table for the | |
110711f0 | 23 | * machine or log name (non-null parameter) to see if the |
2f0181b2 | 24 | * input path (path) starts with an acceptable prefix. |
110711f0 SL |
25 | * |
26 | * return codes: 0 | FAIL | |
27 | */ | |
28 | ||
29 | chkpth(logname, mchname, path) | |
30 | char *path, *logname, *mchname; | |
31 | { | |
32 | register struct userpath *u; | |
33 | extern char *lastpart(); | |
34 | register char **p, *s; | |
35 | ||
36 | /* Allow only rooted pathnames. Security wish. rti!trt */ | |
1a85e9d2 RC |
37 | if (*path != '/') { |
38 | DEBUG(4, "filename doesn't begin with /\n", CNULL); | |
88db71e9 | 39 | return FAIL; |
1a85e9d2 | 40 | } |
110711f0 SL |
41 | |
42 | if (Uptfirst) { | |
43 | rdpth(); | |
88db71e9 | 44 | ASSERT(Uhead != NULL, "INIT USERFILE, No entrys!", CNULL, 0); |
110711f0 SL |
45 | Uptfirst = 0; |
46 | } | |
47 | for (u = Uhead; u != NULL; ) { | |
48 | if (*logname != '\0' && strcmp(logname, u->us_lname) == SAME) | |
49 | break; | |
2f0181b2 | 50 | if (*mchname != '\0' && strncmp(mchname, u->us_mname, MAXBASENAME) == SAME) |
110711f0 SL |
51 | break; |
52 | u = u->unext; | |
53 | } | |
54 | if (u == NULL) { | |
55 | if (*logname == '\0') | |
56 | u = Mchdef; | |
57 | else | |
58 | u = Logdef; | |
59 | if (u == NULL) | |
88db71e9 | 60 | return FAIL; |
110711f0 | 61 | } |
110711f0 SL |
62 | |
63 | /* check for /../ in path name */ | |
64 | for (s = path; *s != '\0'; s++) { | |
1a85e9d2 RC |
65 | if (prefix("/../",s)) { |
66 | DEBUG(4, "filename has /../ in it\n", CNULL); | |
88db71e9 | 67 | return FAIL; |
1a85e9d2 | 68 | } |
110711f0 SL |
69 | } |
70 | ||
71 | /* Check for access permission */ | |
72 | for (p = u->us_path; *p != NULL; p++) | |
73 | if (prefix(*p, path)) | |
88db71e9 | 74 | return SUCCESS; |
1a85e9d2 | 75 | DEBUG(4, "filename not in list\n", CNULL); |
110711f0 SL |
76 | |
77 | /* path name not valid */ | |
88db71e9 | 78 | return FAIL; |
110711f0 SL |
79 | } |
80 | ||
81 | ||
82 | /*** | |
83 | * rdpth() | |
84 | * | |
85 | * rdpth - this routine will read the USERFILE and | |
86 | * construct the userpath structure pointed to by (u); | |
87 | * | |
110711f0 SL |
88 | */ |
89 | ||
90 | rdpth() | |
91 | { | |
92 | char buf[100 + 1], *pbuf[50 + 1]; | |
93 | register struct userpath *u; | |
94 | register char *pc, **cp; | |
95 | FILE *uf; | |
96 | ||
97 | if ((uf = fopen(USERFILE, "r")) == NULL) { | |
98 | /* can not open file */ | |
99 | return; | |
100 | } | |
101 | ||
102 | while (cfgets(buf, sizeof(buf), uf) != NULL) { | |
103 | int nargs, i; | |
104 | ||
88db71e9 RC |
105 | u = (struct userpath *)malloc(sizeof (struct userpath)); |
106 | if (u == NULL) { | |
110711f0 SL |
107 | DEBUG (1, "*** Userpath malloc failed\n", 0); |
108 | fclose (uf); | |
109 | return; | |
110 | } | |
111 | if ((pc = calloc((unsigned)strlen(buf) + 1, sizeof (char))) | |
112 | == NULL) { | |
113 | /* can not allocate space */ | |
114 | DEBUG (1, "Userpath calloc 1 failed\n", 0); | |
115 | fclose(uf); | |
116 | return; | |
117 | } | |
118 | ||
119 | strcpy(pc, buf); | |
88db71e9 | 120 | nargs = getargs(pc, pbuf, 50); |
110711f0 SL |
121 | u->us_lname = pbuf[0]; |
122 | pc = index(u->us_lname, ','); | |
123 | if (pc != NULL) | |
124 | *pc++ = '\0'; | |
125 | else | |
126 | pc = u->us_lname + strlen(u->us_lname); | |
127 | u->us_mname = pc; | |
2f0181b2 JB |
128 | if (strlen(u->us_mname) > MAXBASENAME) |
129 | u->us_mname[MAXBASENAME] = '\0'; | |
110711f0 SL |
130 | if (*u->us_lname == '\0' && Logdef == NULL) |
131 | Logdef = u; | |
88db71e9 | 132 | if (*u->us_mname == '\0' && Mchdef == NULL) |
110711f0 SL |
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; | |
88db71e9 RC |
141 | cp = (char **)calloc((unsigned)(nargs-i+1), sizeof(char *)); |
142 | if (cp == NULL) { | |
110711f0 SL |
143 | /* can not allocate space */ |
144 | DEBUG (1, "Userpath calloc 2 failed!\n", 0); | |
145 | fclose(uf); | |
146 | return; | |
147 | } | |
88db71e9 | 148 | u->us_path = cp; |
110711f0 SL |
149 | |
150 | while (i < nargs) | |
151 | *cp++ = pbuf[i++]; | |
152 | *cp = NULL; | |
153 | u->unext = Uhead; | |
154 | Uhead = u; | |
155 | } | |
156 | ||
157 | fclose(uf); | |
158 | return; | |
159 | } | |
160 | ||
161 | /*** | |
162 | * callback(name) check for callback | |
163 | * char *name; | |
164 | * | |
165 | * return codes: | |
166 | * 0 - no call back | |
167 | * 1 - call back | |
168 | */ | |
169 | ||
170 | callback(name) | |
171 | register char *name; | |
172 | { | |
173 | register struct userpath *u; | |
174 | ||
175 | if (Uptfirst) { | |
176 | rdpth(); | |
88db71e9 | 177 | ASSERT(Uhead != NULL, "INIT USERFILE, No Users!", CNULL, 0); |
110711f0 SL |
178 | Uptfirst = 0; |
179 | } | |
180 | ||
181 | for (u = Uhead; u != NULL; ) { | |
182 | if (strcmp(u->us_lname, name) == SAME) | |
183 | /* found user name */ | |
88db71e9 | 184 | return u->us_callback; |
110711f0 SL |
185 | u = u->unext; |
186 | } | |
187 | ||
188 | /* userid not found */ | |
88db71e9 | 189 | return 0; |
110711f0 SL |
190 | } |
191 | ||
192 | ||
193 | /*** | |
194 | * chkperm(file, mopt) check write permission of file | |
195 | * char *mopt; none NULL - create directories | |
196 | * | |
197 | * if mopt != NULL and permissions are ok, | |
198 | * a side effect of this routine is to make | |
199 | * directories up to the last part of the | |
200 | * filename (if they do not exist). | |
201 | * | |
88db71e9 | 202 | * return SUCCESS | FAIL |
110711f0 SL |
203 | */ |
204 | ||
205 | chkperm(file, mopt) | |
206 | char *file, *mopt; | |
207 | { | |
208 | struct stat s; | |
209 | int ret; | |
210 | char dir[MAXFULLNAME]; | |
211 | extern char *lastpart(); | |
212 | ||
213 | if (stat(subfile(file), &s) == 0) { | |
1a85e9d2 RC |
214 | if ((s.st_mode & ANYWRITE) == 0) { |
215 | DEBUG(4,"file is not writable: mode %o\n", s.st_mode); | |
88db71e9 | 216 | return FAIL; |
1a85e9d2 | 217 | } |
88db71e9 | 218 | return SUCCESS; |
110711f0 SL |
219 | } |
220 | ||
221 | strcpy(dir, file); | |
222 | *lastpart(dir) = '\0'; | |
1a85e9d2 RC |
223 | if ((ret = stat(subfile(dir), &s)) == -1 && mopt == NULL) { |
224 | DEBUG(4, "can't stat directory %s\n", subfile(dir)); | |
88db71e9 | 225 | return FAIL; |
1a85e9d2 | 226 | } |
110711f0 SL |
227 | |
228 | if (ret != -1) { | |
229 | if ((s.st_mode & ANYWRITE) == 0) | |
88db71e9 | 230 | return FAIL; |
110711f0 | 231 | else |
88db71e9 | 232 | return SUCCESS; |
110711f0 SL |
233 | } |
234 | ||
235 | /* make directories */ | |
88db71e9 | 236 | return mkdirs(file); |
110711f0 SL |
237 | } |
238 | ||
239 | /* | |
240 | * Check for sufficient privilege to request debugging. | |
110711f0 | 241 | */ |
88db71e9 | 242 | chkdebug() |
110711f0 | 243 | { |
88db71e9 RC |
244 | if (access(SYSFILE, 04) < 0) { |
245 | fprintf(stderr, "Sorry, you must be able to read L.sys for debugging\n"); | |
110711f0 SL |
246 | cleanup(1); |
247 | exit(1); /* Just in case */ | |
248 | } | |
249 | } |