xref: /csrg-svn/usr.bin/uucp/libuu/chkpth.c (revision 23588)
113638Ssam #ifndef lint
2*23588Sbloom static char sccsid[] = "@(#)chkpth.c	5.4 (Berkeley) 06/19/85";
313638Ssam #endif
413638Ssam 
513638Ssam #include "uucp.h"
613638Ssam #include <sys/stat.h>
713638Ssam 
813638Ssam struct userpath {
913638Ssam 	char *us_lname;
1013638Ssam 	char *us_mname;
1113638Ssam 	char us_callback;
1213638Ssam 	char **us_path;
1313638Ssam 	struct userpath *unext;
1413638Ssam };
1513638Ssam struct userpath *Uhead = NULL;
1613638Ssam struct userpath *Mchdef = NULL, *Logdef = NULL;
1713638Ssam int Uptfirst = 1;
1813638Ssam 
19*23588Sbloom /*LINTLIBRARY*/
20*23588Sbloom 
21*23588Sbloom /*
22*23588Sbloom  *	this routine will check the path table for the
2313638Ssam  *	machine or log name (non-null parameter) to see if the
24*23588Sbloom  *	input path (path) starts with an acceptable prefix.
2513638Ssam  *
2613638Ssam  *	return codes:  0  |  FAIL
2713638Ssam  */
2813638Ssam 
2913638Ssam chkpth(logname, mchname, path)
3013638Ssam char *path, *logname, *mchname;
3113638Ssam {
3213638Ssam 	register struct userpath *u;
3313638Ssam 	extern char *lastpart();
3413638Ssam 	register char **p, *s;
3513638Ssam 
3613638Ssam 	/* Allow only rooted pathnames.  Security wish.  rti!trt */
3718616Sralph 	if (*path != '/') {
3818616Sralph 		DEBUG(4, "filename doesn't begin with /\n", CNULL);
3917767Sralph 		return FAIL;
4018616Sralph 	}
4113638Ssam 
4213638Ssam 	if (Uptfirst) {
4313638Ssam 		rdpth();
4417767Sralph 		ASSERT(Uhead != NULL, "INIT USERFILE, No entrys!", CNULL, 0);
4513638Ssam 		Uptfirst = 0;
4613638Ssam 	}
4713638Ssam 	for (u = Uhead; u != NULL; ) {
4813638Ssam 		if (*logname != '\0' && strcmp(logname, u->us_lname) == SAME)
4913638Ssam 			break;
50*23588Sbloom 		if (*mchname != '\0' && strncmp(mchname, u->us_mname, MAXBASENAME) == SAME)
5113638Ssam 			break;
5213638Ssam 		u = u->unext;
5313638Ssam 	}
5413638Ssam 	if (u == NULL) {
5513638Ssam 		if (*logname == '\0')
5613638Ssam 			u = Mchdef;
5713638Ssam 		else
5813638Ssam 			u = Logdef;
5913638Ssam 		if (u == NULL)
6017767Sralph 			return FAIL;
6113638Ssam 	}
6213638Ssam 
6313638Ssam 	/*  check for /../ in path name  */
6413638Ssam 	for (s = path; *s != '\0'; s++) {
6518616Sralph 		if (prefix("/../",s)) {
6618616Sralph 			DEBUG(4, "filename has /../ in it\n", CNULL);
6717767Sralph 			return FAIL;
6818616Sralph 		}
6913638Ssam 	}
7013638Ssam 
7113638Ssam 	/* Check for access permission */
7213638Ssam 	for (p = u->us_path; *p != NULL; p++)
7313638Ssam 		if (prefix(*p, path))
7417767Sralph 			return SUCCESS;
7518616Sralph 	DEBUG(4, "filename not in list\n", CNULL);
7613638Ssam 
7713638Ssam 	/* path name not valid */
7817767Sralph 	return FAIL;
7913638Ssam }
8013638Ssam 
8113638Ssam 
8213638Ssam /***
8313638Ssam  *	rdpth()
8413638Ssam  *
8513638Ssam  *	rdpth  -  this routine will read the USERFILE and
8613638Ssam  *	construct the userpath structure pointed to by (u);
8713638Ssam  *
8813638Ssam  */
8913638Ssam 
9013638Ssam rdpth()
9113638Ssam {
9213638Ssam 	char buf[100 + 1], *pbuf[50 + 1];
9313638Ssam 	register struct userpath *u;
9413638Ssam 	register char *pc, **cp;
9513638Ssam 	FILE *uf;
9613638Ssam 
9713638Ssam 	if ((uf = fopen(USERFILE, "r")) == NULL) {
9813638Ssam 		/* can not open file */
9913638Ssam 		return;
10013638Ssam 	}
10113638Ssam 
10213638Ssam 	while (cfgets(buf, sizeof(buf), uf) != NULL) {
10313638Ssam 		int nargs, i;
10413638Ssam 
10517767Sralph 		u = (struct userpath *)malloc(sizeof (struct userpath));
10617767Sralph 		if (u == NULL) {
10713638Ssam 			DEBUG (1, "*** Userpath malloc failed\n", 0);
10813638Ssam 			fclose (uf);
10913638Ssam 			return;
11013638Ssam 		}
11113638Ssam 		if ((pc = calloc((unsigned)strlen(buf) + 1, sizeof (char)))
11213638Ssam 			== NULL) {
11313638Ssam 			/* can not allocate space */
11413638Ssam 			DEBUG (1, "Userpath calloc 1 failed\n", 0);
11513638Ssam 			fclose(uf);
11613638Ssam 			return;
11713638Ssam 		}
11813638Ssam 
11913638Ssam 		strcpy(pc, buf);
12017767Sralph 		nargs = getargs(pc, pbuf, 50);
12113638Ssam 		u->us_lname = pbuf[0];
12213638Ssam 		pc = index(u->us_lname, ',');
12313638Ssam 		if (pc != NULL)
12413638Ssam 			*pc++ = '\0';
12513638Ssam 		else
12613638Ssam 			pc = u->us_lname + strlen(u->us_lname);
12713638Ssam 		u->us_mname = pc;
128*23588Sbloom 		if (strlen(u->us_mname) > MAXBASENAME)
129*23588Sbloom 			u->us_mname[MAXBASENAME] = '\0';
13013638Ssam 		if (*u->us_lname == '\0' && Logdef == NULL)
13113638Ssam 			Logdef = u;
13217767Sralph 		if (*u->us_mname == '\0' && Mchdef == NULL)
13313638Ssam 			Mchdef = u;
13413638Ssam 		i = 1;
13513638Ssam 		if (strcmp(pbuf[1], "c") == SAME) {
13613638Ssam 			u->us_callback = 1;
13713638Ssam 			i++;
13813638Ssam 		}
13913638Ssam 		else
14013638Ssam 			u->us_callback = 0;
14117767Sralph 		cp = (char **)calloc((unsigned)(nargs-i+1), sizeof(char *));
14217767Sralph 		if (cp == NULL) {
14313638Ssam 			/*  can not allocate space */
14413638Ssam 			DEBUG (1, "Userpath calloc 2 failed!\n", 0);
14513638Ssam 			fclose(uf);
14613638Ssam 			return;
14713638Ssam 		}
14817767Sralph 		u->us_path = cp;
14913638Ssam 
15013638Ssam 		while (i < nargs)
15113638Ssam 			*cp++ = pbuf[i++];
15213638Ssam 		*cp = NULL;
15313638Ssam 		u->unext = Uhead;
15413638Ssam 		Uhead = u;
15513638Ssam 	}
15613638Ssam 
15713638Ssam 	fclose(uf);
15813638Ssam 	return;
15913638Ssam }
16013638Ssam 
16113638Ssam /***
16213638Ssam  *	callback(name)	check for callback
16313638Ssam  *	char *name;
16413638Ssam  *
16513638Ssam  *	return codes:
16613638Ssam  *		0  -  no call back
16713638Ssam  *		1  -  call back
16813638Ssam  */
16913638Ssam 
17013638Ssam callback(name)
17113638Ssam register char *name;
17213638Ssam {
17313638Ssam 	register struct userpath *u;
17413638Ssam 
17513638Ssam 	if (Uptfirst) {
17613638Ssam 		rdpth();
17717767Sralph 		ASSERT(Uhead != NULL, "INIT USERFILE, No Users!", CNULL, 0);
17813638Ssam 		Uptfirst = 0;
17913638Ssam 	}
18013638Ssam 
18113638Ssam 	for (u = Uhead; u != NULL; ) {
18213638Ssam 		if (strcmp(u->us_lname, name) == SAME)
18313638Ssam 			/* found user name */
18417767Sralph 			return u->us_callback;
18513638Ssam 		u = u->unext;
18613638Ssam 	}
18713638Ssam 
18813638Ssam 	/* userid not found */
18917767Sralph 	return 0;
19013638Ssam }
19113638Ssam 
19213638Ssam 
19313638Ssam /***
19413638Ssam  *	chkperm(file, mopt)	check write permission of file
19513638Ssam  *	char *mopt;		none NULL - create directories
19613638Ssam  *
19713638Ssam  *	if mopt != NULL and permissions are ok,
19813638Ssam  *	a side effect of this routine is to make
19913638Ssam  *	directories up to the last part of the
20013638Ssam  *	filename (if they do not exist).
20113638Ssam  *
20217767Sralph  *	return SUCCESS | FAIL
20313638Ssam  */
20413638Ssam 
20513638Ssam chkperm(file, mopt)
20613638Ssam char *file, *mopt;
20713638Ssam {
20813638Ssam 	struct stat s;
20913638Ssam 	int ret;
21013638Ssam 	char dir[MAXFULLNAME];
21113638Ssam 	extern char *lastpart();
21213638Ssam 
21313638Ssam 	if (stat(subfile(file), &s) == 0) {
21418616Sralph 		if ((s.st_mode & ANYWRITE) == 0) {
21518616Sralph 			DEBUG(4,"file is not writable: mode %o\n", s.st_mode);
21617767Sralph 			return FAIL;
21718616Sralph 		}
21817767Sralph 		return SUCCESS;
21913638Ssam 	}
22013638Ssam 
22113638Ssam 	strcpy(dir, file);
22213638Ssam 	*lastpart(dir) = '\0';
22318616Sralph 	if ((ret = stat(subfile(dir), &s)) == -1 && mopt == NULL) {
22418616Sralph 		DEBUG(4, "can't stat directory %s\n", subfile(dir));
22517767Sralph 		return FAIL;
22618616Sralph 	}
22713638Ssam 
22813638Ssam 	if (ret != -1) {
22913638Ssam 		if ((s.st_mode & ANYWRITE) == 0)
23017767Sralph 			return FAIL;
23113638Ssam 		else
23217767Sralph 			return SUCCESS;
23313638Ssam 	}
23413638Ssam 
23513638Ssam 	/*  make directories  */
23617767Sralph 	return mkdirs(file);
23713638Ssam }
23813638Ssam 
23913638Ssam /*
24013638Ssam  * Check for sufficient privilege to request debugging.
24113638Ssam  */
24217767Sralph chkdebug()
24313638Ssam {
24417767Sralph 	if (access(SYSFILE, 04) < 0) {
24517767Sralph 		fprintf(stderr, "Sorry, you must be able to read L.sys for debugging\n");
24613638Ssam 		cleanup(1);
24713638Ssam 		exit(1);	/* Just in case */
24813638Ssam 	}
24913638Ssam }
250