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