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