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