|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)chkpth.c 5.4 (Berkeley) 6/19/85"; ! 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 = 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.