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-