dpk (07/31/82)
#N:brl-bmd:1400003:000:4893
brl-bmd!dpk Jul 31 14:12:00 1982
This is the repaired verison of chkpth.c. The only real
changes have to do with the userpath structure, which is now handled
as a dynamically allocated linked list. I checked the vanilla V7
and 2.8BSD distributions, and they both have this bug. It should
only be a problem on systems with USERFILE's of 16 or more entries.
Note that although defined, DFLTNAME is not used. Anyone have
the code implement this?
/* chkpth 3.1 10/26/79 11:21:30 */
/* Modified Doug Kingston, 30 July 82 to fix handling of */
/* of the "userpath" structures. */
#include "uucp.h"
#include <sys/types.h>
#include <sys/stat.h>
#define DFLTNAME "default" /* Not Implemented. ??? */
struct userpath {
char *us_lname;
char *us_mname;
char us_callback;
char **us_path;
struct userpath *unext;
};
struct userpath *Uhead = NULL;
struct userpath *Mchdef = NULL, *Logdef = NULL;
int Uptfirst = 1;
/*******
* chkpth(logname, mchname, path)
* char *path, *logname, *mchname;
*
* chkpth - this routine will check the path table for the
* machine or log name (non-null parameter) to see if the
* input path (path)
* starts with an acceptable prefix.
*
* return codes: 0 | FAIL
*/
chkpth(logname, mchname, path)
char *path, *logname, *mchname;
{
struct userpath *u;
extern char *lastpart();
char **p, *s;
char c;
int ret, i;
if (Uptfirst) {
rdpth();
ASSERT(Uhead != NULL, "INIT USERFILE, No entrys!", 0);
Uptfirst = 0;
}
for (u = Uhead; u != NULL; ) {
if (*logname != '\0' && strcmp(logname, u->us_lname) == SAME)
break;
if (*mchname != '\0' && strcmp(mchname, u->us_mname) == SAME)
break;
u = u->unext;
}
if (u == NULL) {
if (*logname == '\0')
u = Mchdef;
else
u = Logdef;
if (u == NULL)
return(FAIL);
}
/* found user name */
p = u->us_path;
/* check for /../ in path name */
for (s = path; *s != '\0'; s++) {
if(prefix("/../",s))
return(FAIL);
}
for (p = u->us_path; *p != NULL; p++)
if (prefix(*p, path))
return(0);
if (prefix(Spool, path)) {
if ((c = *lastpart(path)) == DATAPRE
|| c == XQTPRE)
return(0);
}
/* path name not valid */
return(FAIL);
}
/***
* rdpth()
*
* rdpth - this routine will read the USERFILE and
* construct the userpath structure pointed to by (u);
*
* return codes: 0 | FAIL
*/
rdpth()
{
char buf[BUFSIZ + 1], *pbuf[BUFSIZ + 1], *pc, **cp;
char *calloc(), *index();
FILE *uf;
if ((uf = fopen(USERFILE, "r")) == NULL) {
/* can not open file */
return;
}
while (fgets(buf, BUFSIZ, uf) != NULL) {
int nargs, i;
struct userpath *u;
if ((u = malloc (sizeof (struct userpath))) == NULL) {
DEBUG (1, "*** Userpath malloc failed\n", 0);
fclose (uf);
return;
}
if ((pc = calloc(strlen(buf) + 1, sizeof (char)))
== NULL) {
/* can not allocate space */
DEBUG (1, "Userpath calloc 1 failed\n", 0);
fclose(uf);
return;
}
strcpy(pc, buf);
nargs = getargs(pc, pbuf);
u->us_lname = pbuf[0];
pc = index(u->us_lname, ',');
if (pc != NULL)
*pc++ = '\0';
else
pc = u->us_lname + strlen(u->us_lname);
u->us_mname = pc;
if (*u->us_lname == '\0' && Logdef == NULL)
Logdef = u;
else if (*u->us_mname == '\0' && Mchdef == NULL)
Mchdef = u;
i = 1;
if (strcmp(pbuf[1], "c") == SAME) {
u->us_callback = 1;
i++;
}
else
u->us_callback = 0;
if ((cp = u->us_path =
(char **) calloc(nargs - i + 1, sizeof (char *))) == NULL) {
/* can not allocate space */
DEBUG (1, "Userpath calloc 2 failed!\n", 0);
fclose(uf);
return;
}
while (i < nargs)
*cp++ = pbuf[i++];
*cp = NULL;
u->unext = Uhead;
Uhead = u;
}
fclose(uf);
return;
}
/***
* callback(name) check for callback
* char *name;
*
* return codes:
* 0 - no call back
* 1 - call back
*/
callback(name)
char *name;
{
struct userpath *u;
int ret, i;
if (Uptfirst) {
rdpth();
ASSERT(Uhead == NULL, "INIT USERFILE, No Users!", 0);
Uptfirst = 0;
}
for (u = Uhead; u != NULL; ) {
if (strcmp(u->us_lname, name) == SAME)
/* found user name */
return(u->us_callback);
u = u->unext;
}
/* userid not found */
return(0);
}
/***
* chkperm(file, mopt) check write permission of file
* char *mopt; none NULL - create directories
*
* if mopt != NULL and permissions are ok,
* a side effect of this routine is to make
* directories up to the last part of the
* filename (if they do not exist).
*
* return 0 | FAIL
*/
chkperm(file, mopt)
char *file, *mopt;
{
struct stat s;
int ret;
char dir[MAXFULLNAME];
extern char *lastpart();
if (stat(file, &s) != -1)
return(0);
strcpy(dir, file);
*lastpart(dir) = '\0';
if ((ret = stat(dir, &s)) == -1
&& mopt == NULL)
return(FAIL);
if (ret != -1) {
if (prefix(SPOOL, dir))
return(0);
if ((s.st_mode & ANYWRITE) == 0)
return(FAIL);
else
return(0);
}
/* make directories */
return(mkdirs(file));
}dpk (09/02/82)
#R:brl-bmd:1400003:brl-bmd:1400004:004:374 brl-bmd!dpk Sep 1 19:22:00 1982 There is a bug in my bug fix for chkpth.c. In the function callback(), the assertion should read "Uhead != NULL" instead of "Uhead == NULL". This will cause your UUCICO to refuse all incoming calls with the AUDIT file showing something like: AERROR - (Uhead == NULL) INIT USERFILE, No Users! Sorry for the inconvenience, we don't have people poll us much. -Doug-