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