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