xref: /csrg-svn/usr.bin/uucp/libuu/chkpth.c (revision 62386)
148652Sbostic /*-
2*62386Sbostic  * Copyright (c) 1985, 1993
3*62386Sbostic  *	The Regents of the University of California.  All rights reserved.
448652Sbostic  *
548652Sbostic  * %sccs.include.proprietary.c%
648652Sbostic  */
748652Sbostic 
813638Ssam #ifndef lint
9*62386Sbostic static char sccsid[] = "@(#)chkpth.c	8.1 (Berkeley) 06/06/93";
1048652Sbostic #endif /* not lint */
1113638Ssam 
1213638Ssam #include "uucp.h"
1313638Ssam #include <sys/stat.h>
1413638Ssam 
1513638Ssam struct userpath {
1613638Ssam 	char *us_lname;
1713638Ssam 	char *us_mname;
1813638Ssam 	char us_callback;
1913638Ssam 	char **us_path;
2013638Ssam 	struct userpath *unext;
2113638Ssam };
2233944Srick 
2313638Ssam struct userpath *Uhead = NULL;
2413638Ssam struct userpath *Mchdef = NULL, *Logdef = NULL;
2513638Ssam int Uptfirst = 1;
2613638Ssam 
2723588Sbloom /*LINTLIBRARY*/
2823588Sbloom 
2923588Sbloom /*
3023588Sbloom  *	this routine will check the path table for the
3113638Ssam  *	machine or log name (non-null parameter) to see if the
3223588Sbloom  *	input path (path) starts with an acceptable prefix.
3313638Ssam  *
3413638Ssam  *	return codes:  0  |  FAIL
3513638Ssam  */
3613638Ssam 
chkpth(logname,mchname,path)3713638Ssam chkpth(logname, mchname, path)
3813638Ssam char *path, *logname, *mchname;
3913638Ssam {
4013638Ssam 	register struct userpath *u;
4113638Ssam 	extern char *lastpart();
4213638Ssam 	register char **p, *s;
4313638Ssam 
4413638Ssam 	/* Allow only rooted pathnames.  Security wish.  rti!trt */
4518616Sralph 	if (*path != '/') {
4618616Sralph 		DEBUG(4, "filename doesn't begin with /\n", CNULL);
4717767Sralph 		return FAIL;
4818616Sralph 	}
4913638Ssam 
5013638Ssam 	if (Uptfirst) {
5113638Ssam 		rdpth();
5233944Srick 		if (Uhead == NULL) {
5333944Srick 			syslog(LOG_ERR, "USERFILE empty!");
5433944Srick 			cleanup(FAIL);
5533944Srick 		}
5613638Ssam 		Uptfirst = 0;
5713638Ssam 	}
5813638Ssam 	for (u = Uhead; u != NULL; ) {
5913638Ssam 		if (*logname != '\0' && strcmp(logname, u->us_lname) == SAME)
6013638Ssam 			break;
6123588Sbloom 		if (*mchname != '\0' && strncmp(mchname, u->us_mname, MAXBASENAME) == SAME)
6213638Ssam 			break;
6313638Ssam 		u = u->unext;
6413638Ssam 	}
6513638Ssam 	if (u == NULL) {
6613638Ssam 		if (*logname == '\0')
6713638Ssam 			u = Mchdef;
6813638Ssam 		else
6913638Ssam 			u = Logdef;
7013638Ssam 		if (u == NULL)
7117767Sralph 			return FAIL;
7213638Ssam 	}
7313638Ssam 
7413638Ssam 	/*  check for /../ in path name  */
7513638Ssam 	for (s = path; *s != '\0'; s++) {
7618616Sralph 		if (prefix("/../",s)) {
7718616Sralph 			DEBUG(4, "filename has /../ in it\n", CNULL);
7817767Sralph 			return FAIL;
7918616Sralph 		}
8013638Ssam 	}
8113638Ssam 
8213638Ssam 	/* Check for access permission */
8313638Ssam 	for (p = u->us_path; *p != NULL; p++)
8413638Ssam 		if (prefix(*p, path))
8517767Sralph 			return SUCCESS;
8618616Sralph 	DEBUG(4, "filename not in list\n", CNULL);
8713638Ssam 
8813638Ssam 	/* path name not valid */
8917767Sralph 	return FAIL;
9013638Ssam }
9113638Ssam 
9213638Ssam 
9313638Ssam /***
9413638Ssam  *	rdpth()
9513638Ssam  *
9613638Ssam  *	rdpth  -  this routine will read the USERFILE and
9713638Ssam  *	construct the userpath structure pointed to by (u);
9813638Ssam  *
9913638Ssam  */
10013638Ssam 
rdpth()10113638Ssam rdpth()
10213638Ssam {
10313638Ssam 	char buf[100 + 1], *pbuf[50 + 1];
10413638Ssam 	register struct userpath *u;
10513638Ssam 	register char *pc, **cp;
10613638Ssam 	FILE *uf;
10713638Ssam 
10813638Ssam 	if ((uf = fopen(USERFILE, "r")) == NULL) {
10913638Ssam 		/* can not open file */
11013638Ssam 		return;
11113638Ssam 	}
11213638Ssam 
11313638Ssam 	while (cfgets(buf, sizeof(buf), uf) != NULL) {
11413638Ssam 		int nargs, i;
11513638Ssam 
11617767Sralph 		u = (struct userpath *)malloc(sizeof (struct userpath));
11717767Sralph 		if (u == NULL) {
11813638Ssam 			DEBUG (1, "*** Userpath malloc failed\n", 0);
11913638Ssam 			fclose (uf);
12013638Ssam 			return;
12113638Ssam 		}
12213638Ssam 		if ((pc = calloc((unsigned)strlen(buf) + 1, sizeof (char)))
12313638Ssam 			== NULL) {
12413638Ssam 			/* can not allocate space */
12513638Ssam 			DEBUG (1, "Userpath calloc 1 failed\n", 0);
12613638Ssam 			fclose(uf);
12713638Ssam 			return;
12813638Ssam 		}
12913638Ssam 
13013638Ssam 		strcpy(pc, buf);
13117767Sralph 		nargs = getargs(pc, pbuf, 50);
13213638Ssam 		u->us_lname = pbuf[0];
13313638Ssam 		pc = index(u->us_lname, ',');
13413638Ssam 		if (pc != NULL)
13513638Ssam 			*pc++ = '\0';
13613638Ssam 		else
13713638Ssam 			pc = u->us_lname + strlen(u->us_lname);
13813638Ssam 		u->us_mname = pc;
13923588Sbloom 		if (strlen(u->us_mname) > MAXBASENAME)
14023588Sbloom 			u->us_mname[MAXBASENAME] = '\0';
14113638Ssam 		if (*u->us_lname == '\0' && Logdef == NULL)
14213638Ssam 			Logdef = u;
14317767Sralph 		if (*u->us_mname == '\0' && Mchdef == NULL)
14413638Ssam 			Mchdef = u;
14513638Ssam 		i = 1;
14613638Ssam 		if (strcmp(pbuf[1], "c") == SAME) {
14713638Ssam 			u->us_callback = 1;
14813638Ssam 			i++;
14913638Ssam 		}
15013638Ssam 		else
15113638Ssam 			u->us_callback = 0;
15217767Sralph 		cp = (char **)calloc((unsigned)(nargs-i+1), sizeof(char *));
15317767Sralph 		if (cp == NULL) {
15413638Ssam 			/*  can not allocate space */
15513638Ssam 			DEBUG (1, "Userpath calloc 2 failed!\n", 0);
15613638Ssam 			fclose(uf);
15713638Ssam 			return;
15813638Ssam 		}
15917767Sralph 		u->us_path = cp;
16013638Ssam 
16113638Ssam 		while (i < nargs)
16213638Ssam 			*cp++ = pbuf[i++];
16313638Ssam 		*cp = NULL;
16413638Ssam 		u->unext = Uhead;
16513638Ssam 		Uhead = u;
16613638Ssam 	}
16713638Ssam 
16813638Ssam 	fclose(uf);
16913638Ssam 	return;
17013638Ssam }
17113638Ssam 
17213638Ssam /***
17313638Ssam  *	callback(name)	check for callback
17413638Ssam  *	char *name;
17513638Ssam  *
17613638Ssam  *	return codes:
17713638Ssam  *		0  -  no call back
17813638Ssam  *		1  -  call back
17913638Ssam  */
18013638Ssam 
callback(name)18113638Ssam callback(name)
18213638Ssam register char *name;
18313638Ssam {
18413638Ssam 	register struct userpath *u;
18513638Ssam 
18613638Ssam 	if (Uptfirst) {
18713638Ssam 		rdpth();
18833944Srick 		if (Uhead == NULL) {
18933944Srick 			syslog(LOG_ERR, "USERFILE empty!");
19033944Srick 			cleanup(FAIL);
19133944Srick 		}
19213638Ssam 		Uptfirst = 0;
19313638Ssam 	}
19413638Ssam 
19513638Ssam 	for (u = Uhead; u != NULL; ) {
19613638Ssam 		if (strcmp(u->us_lname, name) == SAME)
19713638Ssam 			/* found user name */
19817767Sralph 			return u->us_callback;
19913638Ssam 		u = u->unext;
20013638Ssam 	}
20113638Ssam 
20213638Ssam 	/* userid not found */
20317767Sralph 	return 0;
20413638Ssam }
20513638Ssam 
20613638Ssam 
20713638Ssam /***
20813638Ssam  *	chkperm(file, mopt)	check write permission of file
20913638Ssam  *	char *mopt;		none NULL - create directories
21013638Ssam  *
21113638Ssam  *	if mopt != NULL and permissions are ok,
21213638Ssam  *	a side effect of this routine is to make
21313638Ssam  *	directories up to the last part of the
21413638Ssam  *	filename (if they do not exist).
21513638Ssam  *
21617767Sralph  *	return SUCCESS | FAIL
21713638Ssam  */
21813638Ssam 
chkperm(file,mopt)21913638Ssam chkperm(file, mopt)
22013638Ssam char *file, *mopt;
22113638Ssam {
22213638Ssam 	struct stat s;
22313638Ssam 	int ret;
22413638Ssam 	char dir[MAXFULLNAME];
22513638Ssam 	extern char *lastpart();
22613638Ssam 
22713638Ssam 	if (stat(subfile(file), &s) == 0) {
22818616Sralph 		if ((s.st_mode & ANYWRITE) == 0) {
22918616Sralph 			DEBUG(4,"file is not writable: mode %o\n", s.st_mode);
23017767Sralph 			return FAIL;
23118616Sralph 		}
23217767Sralph 		return SUCCESS;
23313638Ssam 	}
23413638Ssam 
23513638Ssam 	strcpy(dir, file);
23613638Ssam 	*lastpart(dir) = '\0';
23718616Sralph 	if ((ret = stat(subfile(dir), &s)) == -1 && mopt == NULL) {
23818616Sralph 		DEBUG(4, "can't stat directory %s\n", subfile(dir));
23917767Sralph 		return FAIL;
24018616Sralph 	}
24113638Ssam 
24213638Ssam 	if (ret != -1) {
24313638Ssam 		if ((s.st_mode & ANYWRITE) == 0)
24417767Sralph 			return FAIL;
24513638Ssam 		else
24617767Sralph 			return SUCCESS;
24713638Ssam 	}
24813638Ssam 
24913638Ssam 	/*  make directories  */
25017767Sralph 	return mkdirs(file);
25113638Ssam }
25213638Ssam 
25313638Ssam /*
25413638Ssam  * Check for sufficient privilege to request debugging.
25513638Ssam  */
chkdebug()25617767Sralph chkdebug()
25713638Ssam {
25817767Sralph 	if (access(SYSFILE, 04) < 0) {
25917767Sralph 		fprintf(stderr, "Sorry, you must be able to read L.sys for debugging\n");
26013638Ssam 		cleanup(1);
26113638Ssam 		exit(1);	/* Just in case */
26213638Ssam 	}
26313638Ssam }
264