1: #if !defined(lint) && defined(DOSCCS) 2: static char sccsid[] = "@(#)chkpth.c 5.4.1 (2.11BSD) 1997/10/2"; 3: #endif 4: 5: #include "uucp.h" 6: #include <sys/stat.h> 7: 8: struct userpath { 9: char *us_lname; 10: char *us_mname; 11: char us_callback; 12: char **us_path; 13: struct userpath *unext; 14: }; 15: struct userpath *Uhead = NULL; 16: struct userpath *Mchdef = NULL, *Logdef = NULL; 17: int Uptfirst = 1; 18: 19: /*LINTLIBRARY*/ 20: 21: /* 22: * this routine will check the path table for the 23: * machine or log name (non-null parameter) to see if the 24: * input path (path) starts with an acceptable prefix. 25: * 26: * return codes: 0 | FAIL 27: */ 28: 29: chkpth(logname, mchname, path) 30: char *path, *logname, *mchname; 31: { 32: register struct userpath *u; 33: extern char *lastpart(); 34: register char **p, *s; 35: 36: /* Allow only rooted pathnames. Security wish. rti!trt */ 37: if (*path != '/') { 38: DEBUG(4, "filename doesn't begin with /\n", CNULL); 39: return FAIL; 40: } 41: 42: if (Uptfirst) { 43: rdpth(); 44: ASSERT(Uhead != NULL, "INIT USERFILE, No entrys!", CNULL, 0); 45: Uptfirst = 0; 46: } 47: for (u = Uhead; u != NULL; ) { 48: if (*logname != '\0' && strcmp(logname, u->us_lname) == SAME) 49: break; 50: if (*mchname != '\0' && strncmp(mchname, u->us_mname, MAXBASENAME) == SAME) 51: break; 52: u = u->unext; 53: } 54: if (u == NULL) { 55: if (*logname == '\0') 56: u = Mchdef; 57: else 58: u = Logdef; 59: if (u == NULL) 60: return FAIL; 61: } 62: 63: /* check for /../ in path name */ 64: for (s = path; *s != '\0'; s++) { 65: if (prefix("/../",s)) { 66: DEBUG(4, "filename has /../ in it\n", CNULL); 67: return FAIL; 68: } 69: } 70: 71: /* Check for access permission */ 72: for (p = u->us_path; *p != NULL; p++) 73: if (prefix(*p, path)) 74: return SUCCESS; 75: DEBUG(4, "filename not in list\n", CNULL); 76: 77: /* path name not valid */ 78: return FAIL; 79: } 80: 81: 82: /*** 83: * rdpth() 84: * 85: * rdpth - this routine will read the USERFILE and 86: * construct the userpath structure pointed to by (u); 87: * 88: */ 89: 90: rdpth() 91: { 92: char buf[100 + 1], *pbuf[50 + 1]; 93: register struct userpath *u; 94: register char *pc, **cp; 95: FILE *uf; 96: 97: if ((uf = fopen(USERFILE, "r")) == NULL) { 98: /* can not open file */ 99: return; 100: } 101: 102: while (cfgets(buf, sizeof(buf), uf) != NULL) { 103: int nargs, i; 104: 105: u = (struct userpath *)malloc(sizeof (struct userpath)); 106: if (u == NULL) { 107: DEBUG (1, "*** Userpath malloc failed\n", 0); 108: fclose (uf); 109: return; 110: } 111: if ((pc = (char *)calloc((unsigned)strlen(buf) + 1, sizeof (char))) 112: == NULL) { 113: /* can not allocate space */ 114: DEBUG (1, "Userpath calloc 1 failed\n", 0); 115: fclose(uf); 116: return; 117: } 118: 119: strcpy(pc, buf); 120: nargs = getargs(pc, pbuf, 50); 121: u->us_lname = pbuf[0]; 122: pc = index(u->us_lname, ','); 123: if (pc != NULL) 124: *pc++ = '\0'; 125: else 126: pc = u->us_lname + strlen(u->us_lname); 127: u->us_mname = pc; 128: if (strlen(u->us_mname) > MAXBASENAME) 129: u->us_mname[MAXBASENAME] = '\0'; 130: if (*u->us_lname == '\0' && Logdef == NULL) 131: Logdef = u; 132: if (*u->us_mname == '\0' && Mchdef == NULL) 133: Mchdef = u; 134: i = 1; 135: if (strcmp(pbuf[1], "c") == SAME) { 136: u->us_callback = 1; 137: i++; 138: } 139: else 140: u->us_callback = 0; 141: cp = (char **)calloc((unsigned)(nargs-i+1), sizeof(char *)); 142: if (cp == NULL) { 143: /* can not allocate space */ 144: DEBUG (1, "Userpath calloc 2 failed!\n", 0); 145: fclose(uf); 146: return; 147: } 148: u->us_path = cp; 149: 150: while (i < nargs) 151: *cp++ = pbuf[i++]; 152: *cp = NULL; 153: u->unext = Uhead; 154: Uhead = u; 155: } 156: 157: fclose(uf); 158: return; 159: } 160: 161: /*** 162: * callback(name) check for callback 163: * char *name; 164: * 165: * return codes: 166: * 0 - no call back 167: * 1 - call back 168: */ 169: 170: callback(name) 171: register char *name; 172: { 173: register struct userpath *u; 174: 175: if (Uptfirst) { 176: rdpth(); 177: ASSERT(Uhead != NULL, "INIT USERFILE, No Users!", CNULL, 0); 178: Uptfirst = 0; 179: } 180: 181: for (u = Uhead; u != NULL; ) { 182: if (strcmp(u->us_lname, name) == SAME) 183: /* found user name */ 184: return u->us_callback; 185: u = u->unext; 186: } 187: 188: /* userid not found */ 189: return 0; 190: } 191: 192: 193: /*** 194: * chkperm(file, mopt) check write permission of file 195: * char *mopt; none NULL - create directories 196: * 197: * if mopt != NULL and permissions are ok, 198: * a side effect of this routine is to make 199: * directories up to the last part of the 200: * filename (if they do not exist). 201: * 202: * return SUCCESS | FAIL 203: */ 204: 205: chkperm(file, mopt) 206: char *file, *mopt; 207: { 208: struct stat s; 209: int ret; 210: char dir[MAXFULLNAME]; 211: extern char *lastpart(); 212: 213: if (stat(subfile(file), &s) == 0) { 214: if ((s.st_mode & ANYWRITE) == 0) { 215: DEBUG(4,"file is not writable: mode %o\n", s.st_mode); 216: return FAIL; 217: } 218: return SUCCESS; 219: } 220: 221: strcpy(dir, file); 222: *lastpart(dir) = '\0'; 223: if ((ret = stat(subfile(dir), &s)) == -1 && mopt == NULL) { 224: DEBUG(4, "can't stat directory %s\n", subfile(dir)); 225: return FAIL; 226: } 227: 228: if (ret != -1) { 229: if ((s.st_mode & ANYWRITE) == 0) 230: return FAIL; 231: else 232: return SUCCESS; 233: } 234: 235: /* make directories */ 236: return mkdirs(file); 237: } 238: 239: /* 240: * Check for sufficient privilege to request debugging. 241: */ 242: chkdebug() 243: { 244: if (access(SYSFILE, 04) < 0) { 245: fprintf(stderr, "Sorry, you must be able to read L.sys for debugging\n"); 246: cleanup(1); 247: exit(1); /* Just in case */ 248: } 249: }