xref: /csrg-svn/usr.bin/uucp/libuu/chkpth.c (revision 17767)
113638Ssam #ifndef lint
2*17767Sralph static char sccsid[] = "@(#)chkpth.c	5.2 (Berkeley) 01/22/85";
313638Ssam #endif
413638Ssam 
513638Ssam #include "uucp.h"
613638Ssam #include <sys/types.h>
713638Ssam #include <sys/stat.h>
813638Ssam 
913638Ssam struct userpath {
1013638Ssam 	char *us_lname;
1113638Ssam 	char *us_mname;
1213638Ssam 	char us_callback;
1313638Ssam 	char **us_path;
1413638Ssam 	struct userpath *unext;
1513638Ssam };
1613638Ssam struct userpath *Uhead = NULL;
1713638Ssam struct userpath *Mchdef = NULL, *Logdef = NULL;
1813638Ssam int Uptfirst = 1;
1913638Ssam 
2013638Ssam /*******
2113638Ssam  *	chkpth(logname, mchname, path)
2213638Ssam  *	char *path, *logname, *mchname;
2313638Ssam  *
2413638Ssam  *	chkpth  -  this routine will check the path table for the
2513638Ssam  *	machine or log name (non-null parameter) to see if the
2613638Ssam  *	input path (path)
2713638Ssam  *	starts with an acceptable prefix.
2813638Ssam  *
2913638Ssam  *	return codes:  0  |  FAIL
3013638Ssam  */
3113638Ssam 
3213638Ssam chkpth(logname, mchname, path)
3313638Ssam char *path, *logname, *mchname;
3413638Ssam {
3513638Ssam 	register struct userpath *u;
3613638Ssam 	extern char *lastpart();
3713638Ssam 	register char **p, *s;
3813638Ssam 
3913638Ssam 	/* Allow only rooted pathnames.  Security wish.  rti!trt */
4013638Ssam 	if (*path != '/')
41*17767Sralph 		return FAIL;
4213638Ssam 
4313638Ssam 	if (Uptfirst) {
4413638Ssam 		rdpth();
45*17767Sralph 		ASSERT(Uhead != NULL, "INIT USERFILE, No entrys!", CNULL, 0);
4613638Ssam 		Uptfirst = 0;
4713638Ssam 	}
4813638Ssam 	for (u = Uhead; u != NULL; ) {
4913638Ssam 		if (*logname != '\0' && strcmp(logname, u->us_lname) == SAME)
5013638Ssam 			break;
5113638Ssam 		if (*mchname != '\0' && strncmp(mchname, u->us_mname, 7) == SAME)
5213638Ssam 			break;
5313638Ssam 		u = u->unext;
5413638Ssam 	}
5513638Ssam 	if (u == NULL) {
5613638Ssam 		if (*logname == '\0')
5713638Ssam 			u = Mchdef;
5813638Ssam 		else
5913638Ssam 			u = Logdef;
6013638Ssam 		if (u == NULL)
61*17767Sralph 			return FAIL;
6213638Ssam 	}
6313638Ssam 
6413638Ssam 	/*  check for /../ in path name  */
6513638Ssam 	for (s = path; *s != '\0'; s++) {
6613638Ssam 		if (prefix("/../",s))
67*17767Sralph 			return FAIL;
6813638Ssam 	}
6913638Ssam 
7013638Ssam 	/* Check for access permission */
7113638Ssam 	for (p = u->us_path; *p != NULL; p++)
7213638Ssam 		if (prefix(*p, path))
73*17767Sralph 			return SUCCESS;
7413638Ssam 
7513638Ssam 	/* path name not valid */
76*17767Sralph 	return FAIL;
7713638Ssam }
7813638Ssam 
7913638Ssam 
8013638Ssam /***
8113638Ssam  *	rdpth()
8213638Ssam  *
8313638Ssam  *	rdpth  -  this routine will read the USERFILE and
8413638Ssam  *	construct the userpath structure pointed to by (u);
8513638Ssam  *
8613638Ssam  */
8713638Ssam 
8813638Ssam rdpth()
8913638Ssam {
9013638Ssam 	char buf[100 + 1], *pbuf[50 + 1];
9113638Ssam 	register struct userpath *u;
9213638Ssam 	register char *pc, **cp;
9313638Ssam 	FILE *uf;
9413638Ssam 
9513638Ssam 	if ((uf = fopen(USERFILE, "r")) == NULL) {
9613638Ssam 		/* can not open file */
9713638Ssam 		return;
9813638Ssam 	}
9913638Ssam 
10013638Ssam 	while (cfgets(buf, sizeof(buf), uf) != NULL) {
10113638Ssam 		int nargs, i;
10213638Ssam 
103*17767Sralph 		u = (struct userpath *)malloc(sizeof (struct userpath));
104*17767Sralph 		if (u == NULL) {
10513638Ssam 			DEBUG (1, "*** Userpath malloc failed\n", 0);
10613638Ssam 			fclose (uf);
10713638Ssam 			return;
10813638Ssam 		}
10913638Ssam 		if ((pc = calloc((unsigned)strlen(buf) + 1, sizeof (char)))
11013638Ssam 			== NULL) {
11113638Ssam 			/* can not allocate space */
11213638Ssam 			DEBUG (1, "Userpath calloc 1 failed\n", 0);
11313638Ssam 			fclose(uf);
11413638Ssam 			return;
11513638Ssam 		}
11613638Ssam 
11713638Ssam 		strcpy(pc, buf);
118*17767Sralph 		nargs = getargs(pc, pbuf, 50);
11913638Ssam 		u->us_lname = pbuf[0];
12013638Ssam 		pc = index(u->us_lname, ',');
12113638Ssam 		if (pc != NULL)
12213638Ssam 			*pc++ = '\0';
12313638Ssam 		else
12413638Ssam 			pc = u->us_lname + strlen(u->us_lname);
12513638Ssam 		u->us_mname = pc;
12613638Ssam 		if (strlen(u->us_mname) > 7)
12713638Ssam 			u->us_mname[7] = '\0';
12813638Ssam 		if (*u->us_lname == '\0' && Logdef == NULL)
12913638Ssam 			Logdef = u;
130*17767Sralph 		if (*u->us_mname == '\0' && Mchdef == NULL)
13113638Ssam 			Mchdef = u;
13213638Ssam 		i = 1;
13313638Ssam 		if (strcmp(pbuf[1], "c") == SAME) {
13413638Ssam 			u->us_callback = 1;
13513638Ssam 			i++;
13613638Ssam 		}
13713638Ssam 		else
13813638Ssam 			u->us_callback = 0;
139*17767Sralph 		cp = (char **)calloc((unsigned)(nargs-i+1), sizeof(char *));
140*17767Sralph 		if (cp == NULL) {
14113638Ssam 			/*  can not allocate space */
14213638Ssam 			DEBUG (1, "Userpath calloc 2 failed!\n", 0);
14313638Ssam 			fclose(uf);
14413638Ssam 			return;
14513638Ssam 		}
146*17767Sralph 		u->us_path = cp;
14713638Ssam 
14813638Ssam 		while (i < nargs)
14913638Ssam 			*cp++ = pbuf[i++];
15013638Ssam 		*cp = NULL;
15113638Ssam 		u->unext = Uhead;
15213638Ssam 		Uhead = u;
15313638Ssam 	}
15413638Ssam 
15513638Ssam 	fclose(uf);
15613638Ssam 	return;
15713638Ssam }
15813638Ssam 
15913638Ssam /***
16013638Ssam  *	callback(name)	check for callback
16113638Ssam  *	char *name;
16213638Ssam  *
16313638Ssam  *	return codes:
16413638Ssam  *		0  -  no call back
16513638Ssam  *		1  -  call back
16613638Ssam  */
16713638Ssam 
16813638Ssam callback(name)
16913638Ssam register char *name;
17013638Ssam {
17113638Ssam 	register struct userpath *u;
17213638Ssam 
17313638Ssam 	if (Uptfirst) {
17413638Ssam 		rdpth();
175*17767Sralph 		ASSERT(Uhead != NULL, "INIT USERFILE, No Users!", CNULL, 0);
17613638Ssam 		Uptfirst = 0;
17713638Ssam 	}
17813638Ssam 
17913638Ssam 	for (u = Uhead; u != NULL; ) {
18013638Ssam 		if (strcmp(u->us_lname, name) == SAME)
18113638Ssam 			/* found user name */
182*17767Sralph 			return u->us_callback;
18313638Ssam 		u = u->unext;
18413638Ssam 	}
18513638Ssam 
18613638Ssam 	/* userid not found */
187*17767Sralph 	return 0;
18813638Ssam }
18913638Ssam 
19013638Ssam 
19113638Ssam /***
19213638Ssam  *	chkperm(file, mopt)	check write permission of file
19313638Ssam  *	char *mopt;		none NULL - create directories
19413638Ssam  *
19513638Ssam  *	if mopt != NULL and permissions are ok,
19613638Ssam  *	a side effect of this routine is to make
19713638Ssam  *	directories up to the last part of the
19813638Ssam  *	filename (if they do not exist).
19913638Ssam  *
200*17767Sralph  *	return SUCCESS | FAIL
20113638Ssam  */
20213638Ssam 
20313638Ssam chkperm(file, mopt)
20413638Ssam char *file, *mopt;
20513638Ssam {
20613638Ssam 	struct stat s;
20713638Ssam 	int ret;
20813638Ssam 	char dir[MAXFULLNAME];
20913638Ssam 	extern char *lastpart();
21013638Ssam 
21113638Ssam 	if (stat(subfile(file), &s) == 0) {
21213638Ssam 		if ((s.st_mode & ANYWRITE) == 0)
213*17767Sralph 			return FAIL;
214*17767Sralph 		return SUCCESS;
21513638Ssam 	}
21613638Ssam 
21713638Ssam 	strcpy(dir, file);
21813638Ssam 	*lastpart(dir) = '\0';
21913638Ssam 	if ((ret = stat(subfile(dir), &s)) == -1
22013638Ssam 	  && mopt == NULL)
221*17767Sralph 		return FAIL;
22213638Ssam 
22313638Ssam 	if (ret != -1) {
22413638Ssam 		if ((s.st_mode & ANYWRITE) == 0)
225*17767Sralph 			return FAIL;
22613638Ssam 		else
227*17767Sralph 			return SUCCESS;
22813638Ssam 	}
22913638Ssam 
23013638Ssam 	/*  make directories  */
231*17767Sralph 	return mkdirs(file);
23213638Ssam }
23313638Ssam 
23413638Ssam /*
23513638Ssam  * Check for sufficient privilege to request debugging.
23613638Ssam  */
237*17767Sralph chkdebug()
23813638Ssam {
239*17767Sralph 	if (access(SYSFILE, 04) < 0) {
240*17767Sralph 		fprintf(stderr, "Sorry, you must be able to read L.sys for debugging\n");
24113638Ssam 		cleanup(1);
24213638Ssam 		exit(1);	/* Just in case */
24313638Ssam 	}
24413638Ssam }
245