1: #include "uucp.h" 2: #include <sys/types.h> 3: #include <sys/stat.h> 4: 5: 6: #define DFLTNAME "default" 7: #define MAXUSERS 20 8: struct userpath { 9: char *us_lname; 10: char *us_mname; 11: char us_callback; 12: char **us_path; 13: }; 14: struct userpath Upt[15]; 15: struct userpath *Mchdef = NULL, *Logdef = NULL; 16: int Nbrusers = 0; 17: int Uptfirst = 1; 18: 19: /******* 20: * chkpth(logname, mchname, path) 21: * char *path, *logname, *mchname; 22: * 23: * chkpth - 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) 26: * starts with an acceptable prefix. 27: * 28: * return codes: 0 | FAIL 29: */ 30: 31: chkpth(logname, mchname, path) 32: char *path, *logname, *mchname; 33: { 34: struct userpath *u; 35: extern char *lastpart(); 36: char **p, *s; 37: char c; 38: int ret, i; 39: 40: if (prefix(THISDIR, path)) 41: return(FAIL); 42: if (Uptfirst) { 43: ret = rdpth(Upt); 44: ASSERT(ret == 0, "INIT USERFILE %d", Nbrusers); 45: Uptfirst = 0; 46: } 47: for (u = Upt, i = 0; i < Nbrusers; i++, u++) { 48: if (*logname != '\0' && strcmp(logname, u->us_lname) == SAME) 49: break; 50: if (*mchname != '\0' && strcmp(mchname, u->us_mname) == SAME) 51: break; 52: 53: } 54: if (i >= Nbrusers) { 55: if (*logname == '\0') 56: u = Mchdef; 57: else 58: u = Logdef; 59: if (u == NULL) 60: return(FAIL); 61: } 62: /* found user name */ 63: p = u->us_path; 64: /* check for /../ in path name */ 65: for (s = path; *s != '\0'; s++) { 66: if (*s == '/' && prefix("../", (++s))) 67: return(FAIL); 68: } 69: 70: if (chklnk(path) > LINKLEVEL) 71: return(FAIL); 72: for (p = u->us_path; *p != NULL; p++) 73: if (prefix(*p, path)) 74: return(0); 75: 76: if (prefix(Spool, path)) { 77: if ((c = *lastpart(path)) == DATAPRE 78: || c == XQTPRE) 79: return(0); 80: } 81: /* path name not valid */ 82: return(FAIL); 83: } 84: 85: 86: /*** 87: * rdpth(u) 88: * struct userpath *u; 89: * 90: * rdpth - this routine will read the USFILE and 91: * construct the userpath structure pointed to by (u); 92: * 93: * return codes: 0 | FAIL 94: */ 95: 96: rdpth(u) 97: struct userpath *u; 98: { 99: char buf[BUFSIZ + 1], *pbuf[BUFSIZ + 1], *pc, **cp; 100: extern char *calloc(), *index(); 101: FILE *uf; 102: 103: if ((uf = fopen(USERFILE, "r")) == NULL) { 104: /* can not open file */ 105: return(FAIL); 106: } 107: 108: while (fgets(buf, BUFSIZ, uf) != NULL) { 109: int nargs, i; 110: if (++Nbrusers > MAXUSERS) { 111: fclose(uf); 112: return(FAIL); 113: } 114: if ((pc = calloc(strlen(buf) + 1, sizeof (char))) 115: == NULL) { 116: /* can not allocate space */ 117: fclose(uf); 118: return(FAIL); 119: } 120: 121: strcpy(pc, buf); 122: nargs = getargs(pc, pbuf); 123: u->us_lname = pbuf[0]; 124: pc = index(u->us_lname, ','); 125: if (pc != NULL) 126: *pc++ = '\0'; 127: else 128: pc = u + strlen(u->us_lname); 129: u->us_mname = pc; 130: if (*u->us_lname == '\0') 131: Logdef = u; 132: else if (*u->us_mname == '\0') 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: if ((cp = u->us_path = 142: calloc(nargs - i + 1, sizeof (char *))) == NULL) { 143: /* can not allocate space */ 144: fclose(uf); 145: return(FAIL); 146: } 147: 148: while (i < nargs) 149: *cp++ = pbuf[i++]; 150: *cp = NULL; 151: u++; 152: } 153: 154: fclose(uf); 155: return(0); 156: } 157: 158: 159: /*** 160: * callback(name) check for callback 161: * char *name; 162: * 163: * return codes: 164: * 0 - no call back 165: * 1 - call back 166: */ 167: 168: callback(name) 169: char *name; 170: { 171: struct userpath *u; 172: int ret, i; 173: 174: if (Uptfirst) { 175: ret = rdpth(Upt); 176: ASSERT(ret == 0, "INIT USERFILE %d", Nbrusers); 177: Uptfirst = 0; 178: } 179: 180: for (u = Upt, i = 0; i < Nbrusers; u++, i++) { 181: if (strcmp(u->us_lname, name) != SAME) 182: continue; 183: 184: /* found user name */ 185: return(u->us_callback); 186: } 187: 188: /* userid not found */ 189: return(0); 190: } 191: 192: 193: /*** 194: * chklnk(name) get number of links 195: * char *name; 196: * 197: * return codes: 0 - stat failed or directory | number of links 198: */ 199: 200: chklnk(name) 201: char *name; 202: { 203: struct stat s; 204: 205: if (stat(name, &s) == -1) 206: return(0); 207: if ((s.st_mode & S_IFMT) == S_IFDIR) 208: return(0); 209: return(s.st_nlinks); 210: } 211: 212: 213: /*** 214: * chkperm(file, user, mopt) check write permission of file 215: * char *file, *user; 216: * char *mopt; none NULL - create directories 217: * 218: * if mopt != NULL and permissions are ok, 219: * a side effect of this routine is to make 220: * directories up to the last part of the 221: * filename (if they do not exist). 222: * 223: * return 0 | FAIL 224: */ 225: 226: chkperm(file, user, mopt) 227: char *file, *user, *mopt; 228: { 229: struct stat s; 230: int ret, bits; 231: char dir[MAXFULLNAME]; 232: extern char *lastpart(); 233: 234: if (stat(file, &s) != -1) 235: return(0); 236: 237: strcpy(dir, file); 238: *lastpart(dir) = '\0'; 239: if ((ret = stat(dir, &s)) == -1 240: && mopt == NULL) 241: return(FAIL); 242: 243: bits = (geteuid() == 0) ? 02 : 0200; 244: if (ret != -1) { 245: if ((s.st_mode & bits) == 0) 246: return(FAIL); 247: else 248: return(0); 249: } 250: 251: /* make directories */ 252: return(mkdirs(file)); 253: }