|
|
1.1 ! root 1: /* ! 2: * processor manager for UNIX systems ! 3: */ ! 4: ! 5: #include <dk.h> ! 6: #include <dkmgr.h> ! 7: #include <pwd.h> ! 8: #include <stdio.h> ! 9: #include <signal.h> ! 10: #include <sys/ioctl.h> ! 11: #include <utmp.h> ! 12: #include <errno.h> ! 13: #include <sys/types.h> ! 14: #include <sys/stat.h> ! 15: #include <sys/param.h> ! 16: #include <wait.h> ! 17: ! 18: #define CTLFILE "/etc/procctl" ! 19: #define LOGLVL 1 ! 20: ! 21: #define SYSERR 010 /* system error, "something is wrong" */ ! 22: #define BUSY 011 /* destination busy */ ! 23: #define NOCMC 012 /* remote node not answering */ ! 24: #define NODEST 013 /* destination not answering */ ! 25: #define INTERT 014 /* unassigned number */ ! 26: #define REORT 015 /* system overload */ ! 27: ! 28: /* ! 29: * format of procctl file entry -- ! 30: * ! 31: * field 1 - source name, or * for any, of requester for this entry ! 32: * field 2 - service type requested, character string ! 33: * field 3 - converted service name for local use in this program ! 34: * ! 35: / ! 36: ! 37: /* ! 38: * defines for a character string "switch" statement ! 39: * SSWITCH(string) { ! 40: * SCASE("value") ! 41: * statements ; ! 42: * SCASE("value") ! 43: * statements ; ! 44: * } ! 45: */ ! 46: #define SSWITCH(c) SSTR=c;if(0) ! 47: #define SCASE(c) }else if (strcmp(SSTR,c)==0){ ! 48: char * SSTR ; ! 49: ! 50: char sname[32] ; /* system name from ctl file */ ! 51: char code[16] ; /* service code from ctl file */ ! 52: char ncode[16] ; /* converted service code */ ! 53: char uid[16] ; /* uid if special */ ! 54: char remuid[16] ; /* uid from remote system to map */ ! 55: char dkname[32] ; /* system name from /etc/whoami */ ! 56: ! 57: char parmbuf[512] ; /* for additional parameters */ ! 58: short parmlen ; /* length of additional stuff */ ! 59: char env1[64]; ! 60: extern char **environ ; ! 61: static char *envinit[] = { ! 62: env1, ! 63: 0 ! 64: } ; ! 65: ! 66: char *oursrv ; /* pointer to our server name */ ! 67: struct mgrmsg *imsg ; /* pointer to request message from remote */ ! 68: struct passwd *pwent, *pwsearch(); /* password entry */ ! 69: struct passwd *getnam(); ! 70: char pwline[256]; /* line from password file */ ! 71: char *strchr(); ! 72: int proctab[512]; ! 73: void chdies(), rmut() ; ! 74: ! 75: char *logfile = "/usr/dk/LOGPROC" ; ! 76: char logbuf[BUFSIZ]; ! 77: int loglvl = LOGLVL ; ! 78: FILE *logf ; ! 79: struct sgttyb term ; ! 80: ! 81: extern int getopt(), optind; ! 82: extern char *optarg; ! 83: extern char *dkfilename(); ! 84: ! 85: main(argc, argv) ! 86: char **argv ; ! 87: { ! 88: register short i ; ! 89: register short fi ; ! 90: short f2 ; ! 91: FILE * fip ; ! 92: extern int dkmgropen ; ! 93: struct mgrmsg *dkmgr() ; ! 94: extern int errno, dkp_ld, tty_ld, cdkp_ld, rmesg_ld ; ! 95: register char *cp, *filename; ! 96: int msg, tty; ! 97: int traffic = 2; ! 98: ! 99: fi = open("/etc/whoami", 0) ; ! 100: if (fi < 0) { ! 101: perror("mgrproc: open /etc/whoami: ") ; ! 102: exit(1) ; ! 103: } ! 104: i = read(fi, dkname, sizeof(dkname)) ; ! 105: if (i <= 0) { ! 106: printf("bad read of /etc/whoami\n") ; ! 107: exit(1) ; ! 108: } ! 109: dkname[i] = '\0' ; ! 110: if ((cp = strchr(dkname, '\n'))) ! 111: *cp = '\0'; ! 112: close(fi) ; ! 113: oursrv = dkname; ! 114: while ((i = getopt(argc, argv, "s:t:v:l:")) != EOF) { ! 115: switch(i) { ! 116: case 's': /* server */ ! 117: oursrv = optarg; ! 118: continue; ! 119: ! 120: case 't': /* traffic class */ ! 121: traffic = atoi(optarg); ! 122: continue; ! 123: ! 124: case 'v': /* verbosity of logfile comments */ ! 125: loglvl = atoi(optarg); ! 126: continue; ! 127: ! 128: case 'l': /* name of logfile */ ! 129: logfile = optarg; ! 130: continue; ! 131: ! 132: default: ! 133: exit(1); ! 134: ! 135: } ! 136: } ! 137: if (i = fork()) { ! 138: printf("mgrproc: starting server %s on system %s, pid %d\n", ! 139: oursrv, dkname, i) ; ! 140: exit(0) ; /* parent exits, child continues */ ! 141: } ! 142: logf = fopen(logfile, "a") ; ! 143: if (logf == NULL) ! 144: printf("cannot open/create log file\n") ; ! 145: else ! 146: setbuf(logf, logbuf); ! 147: ! 148: ! 149: signal(SIGINT, SIG_IGN) ; ! 150: signal(SIGQUIT, SIG_IGN) ; ! 151: signal(SIGHUP, SIG_IGN) ; ! 152: signal(SIGTERM, SIG_IGN) ; ! 153: signal(SIGPIPE, SIG_IGN) ; ! 154: signal(SIGALRM, SIG_IGN) ; ! 155: signal(SIGCHLD, chdies) ; ! 156: pwsearch("root", -1, pwline); /* prime passwd file lookup */ ! 157: fip = fopen(CTLFILE, "r") ; ! 158: if (fip == NULL) { ! 159: printf("mgrproc: can't open /etc/procctl\n"); ! 160: exit(1); ! 161: } ! 162: for (;;) { ! 163: imsg = dkmgr(oursrv, traffic) ; ! 164: if (imsg == NULL) { ! 165: if (errno == EINTR) { ! 166: # define INULL (int *)NULL ! 167: while ((i = wait3(INULL, WNOHANG, INULL)) > 0) { ! 168: register j; ! 169: for (j=0; j<512; j++) ! 170: if (proctab[j]==i) { ! 171: rmut(j); ! 172: proctab[j] = 0; ! 173: break; ! 174: } ! 175: dolog(3, "CHILD DIES c=%d\n", j) ; ! 176: } ! 177: continue ; ! 178: } ! 179: perror("mgrproc error in dkmgr: ") ; ! 180: exit(1) ; ! 181: } ! 182: if (imsg->m_service == NULL) ! 183: imsg->m_service = "(NULL)" ; /* default service */ ! 184: if (imsg->m_uid == NULL) ! 185: imsg->m_uid = "(NULL)" ; ! 186: if (imsg->m_source == NULL) ! 187: imsg->m_source = "(NULL)" ; ! 188: dolog(1, "REQUEST c=%d, t=%s, UID=%s, from %s\n", ! 189: imsg->m_chan, imsg->m_service, imsg->m_uid, imsg->m_source) ; ! 190: for (cp=imsg->m_service; *cp; cp++) ! 191: if (*cp == '.') ! 192: *cp = '\0' ; ! 193: fseek(fip, 0L, 0); ! 194: while (fscanf(fip, "%s %s %s %[^\n]\n", ! 195: sname, code, ncode, parmbuf) != EOF) { ! 196: if (strcmp(code, imsg->m_service) == 0 && ! 197: cksource(sname, imsg->m_source) ) ! 198: goto gotit ; ! 199: } ! 200: dolog(0, "ILLEGAL REQUEST chan %d\n", imsg->m_chan) ; ! 201: dkmgrnak(imsg->m_chan, INTERT) ; ! 202: continue ; ! 203: ! 204: gotit: ! 205: if (ncode[0] == '*') ! 206: strcpy(ncode, code) ; ! 207: pwent = NULL; ! 208: if (strcmp(imsg->m_uid, "(NULL)")) ! 209: pwent = pwsearch(imsg->m_uid, -1, pwline); ! 210: if ((i = fork()) > 0) { ! 211: proctab[imsg->m_chan] = i; ! 212: continue ; ! 213: } else if (i < 0) { ! 214: dolog(0, "ERROR can't fork"); ! 215: dkmgrnak(imsg->m_chan, NODEST); ! 216: continue; ! 217: } ! 218: filename = dkfilename(imsg->m_chan); ! 219: if (filename == NULL) { ! 220: dolog(0, "Can't find file for chan %d\n", imsg->m_chan); ! 221: dkmgrnak(imsg->m_chan, NODEST); ! 222: exit(1); ! 223: } ! 224: f2 = open(filename, 2) ; ! 225: if (f2 < 0) { ! 226: dolog(0, "ERROR cannot open %s\n", filename); ! 227: dkmgrnak(imsg->m_chan, NODEST) ; /* error */ ! 228: exit(1) ; ! 229: } ! 230: dolog(7, "DEBUG ncode %s\n", ncode) ; ! 231: environ = envinit ; ! 232: sprintf(environ[0], "DKSOURCE=%s.%s", imsg->m_source, ! 233: imsg->m_uid); ! 234: ! 235: SSWITCH(ncode) { ! 236: ! 237: SCASE("login") ! 238: if (dkproto(f2, cdkp_ld) < 0 || ! 239: ioctl(f2, FIOPUSHLD, &tty_ld) < 0) { ! 240: dolog(0, "FAILED PUSHLD %s\n", ncode) ; ! 241: dkmgrnak(imsg->m_chan, REORT) ; ! 242: exit(1) ; ! 243: } ! 244: dkmgrack(imsg->m_chan) ; ! 245: setfd(f2) ; ! 246: execl("/etc/login", "login", 0) ; ! 247: execl("/bin/login", "login", 0) ; ! 248: dolog(0, "FAILED EXEC login\n") ; ! 249: exit(1) ; ! 250: ! 251: SCASE("dcon") ! 252: msg = 0; ! 253: goto dc; ! 254: ! 255: SCASE("mesgdcon") ! 256: msg = 1; ! 257: ! 258: dc: ! 259: if (dkproto(f2, dkp_ld) < 0) { ! 260: dolog(0, "FAILED PUSHLD %s\n", ncode) ; ! 261: dkmgrnak(imsg->m_chan, REORT) ; ! 262: exit(1) ; ! 263: } ! 264: dkmgrack(imsg->m_chan) ; ! 265: pwent = getnam(imsg->m_uid, f2, pwent) ; ! 266: if (pwent == NULL) { ! 267: dolog(0,"FAILED passwd %s\n",imsg->m_uid); ! 268: exit(1) ; ! 269: } ! 270: setfd(f2) ; ! 271: if (msg) ! 272: ioctl(0, FIOPUSHLD, &rmesg_ld); ! 273: else ! 274: ioctl(0, FIOPUSHLD, &tty_ld); ! 275: execl("/etc/login", "login", "-p", pwline, 0) ; ! 276: execl("/bin/login", "login", "-p", pwline, 0) ; ! 277: dolog(0, "FAILED EXEC login\n") ; ! 278: exit(1); ! 279: ! 280: SCASE("mesgexec") ! 281: msg = 1; ! 282: tty = 0; ! 283: goto ex; ! 284: ! 285: SCASE("exec") ! 286: msg = 0; ! 287: tty = 0; ! 288: goto ex; ! 289: ! 290: SCASE("ttyexec") ! 291: msg = 0; ! 292: tty = 1; ! 293: ex: ! 294: if (dkproto(f2, dkp_ld)<0) { ! 295: dolog(0, "FAILED PUSHLD %s\n", ncode) ; ! 296: dkmgrnak(imsg->m_chan, REORT) ; ! 297: exit(1) ; ! 298: } ! 299: dkmgrack(imsg->m_chan) ; ! 300: pwent = getnam(imsg->m_uid, f2, pwent) ; ! 301: if (pwent == NULL) ! 302: exit(0) ; ! 303: setfd(f2) ; ! 304: if (rparm(0) < 0) ! 305: exit(0) ; ! 306: if (msg) { ! 307: if (ioctl(0, FIOPUSHLD, &rmesg_ld) < 0) { ! 308: dolog(0, "FAILED PUSHLD(rmesg)\n"); ! 309: exit(1) ; ! 310: } ! 311: } ! 312: if (tty) { ! 313: if (ioctl(0, FIOPUSHLD, &tty_ld)<0) { ! 314: dolog(0, "FAILED PUSHLD(tty)\n"); ! 315: exit(1) ; ! 316: } ! 317: } ! 318: execl("/etc/login", "login", "-p", pwline, parmbuf, 0); ! 319: execl("/bin/login", "login", "-p", pwline, parmbuf, 0); ! 320: dolog(0, "FAILED EXEC login\n"); ! 321: exit(1) ; ! 322: ! 323: SCASE("cmd") ! 324: /* first param is uid, rest go to sh */ ! 325: dolog(7, "DEBUG cmd %s\n", parmbuf) ; ! 326: if (dkproto(f2, dkp_ld)<0) { ! 327: dolog(0, "FAILED PUSHLD %s\n", ncode) ; ! 328: dkmgrnak(imsg->m_chan, REORT) ; ! 329: exit(1) ; ! 330: } ! 331: dkmgrack(imsg->m_chan) ; ! 332: setfd(f2) ; ! 333: cp = parmbuf ; ! 334: while (*cp != ' ' && *cp != '\t' && *cp != '\0') ! 335: cp++ ; ! 336: *cp++ = '\0' ; ! 337: while (*cp == ' ' || *cp == '\t') ! 338: cp++ ; ! 339: dolog(7, "DEBUG cmd uid %s cmd %s\n", parmbuf, cp) ; ! 340: execl("/etc/login", "login", "-f", parmbuf, cp, 0) ; ! 341: execl("/bin/login", "login", "-f", parmbuf, cp, 0) ; ! 342: dolog(0, "FAILED EXEC login %s\n", cp) ; ! 343: exit(1) ; ! 344: ! 345: } ! 346: dolog(0, "ILLEGAL CODE %s\n", ncode) ; ! 347: dkmgrnak(imsg->m_chan, INTERT) ; ! 348: exit(1) ; ! 349: } ! 350: } ! 351: ! 352: /* VARARGS2 */ ! 353: dolog(level, fmt, a1, a2, a3, a4, a5) ! 354: char *fmt; ! 355: { ! 356: long clock ; ! 357: long time() ; ! 358: char *ctime() ; ! 359: ! 360: if (loglvl<level || logf==NULL) ! 361: return; ! 362: clock = time(0) ; ! 363: fseek(logf, 0L, 2); ! 364: fprintf(logf, "%.15s-%d(%d) ", ctime(&clock)+4, getpid(), loglvl) ; ! 365: fprintf(logf, fmt, a1, a2, a3, a4, a5); ! 366: fflush(logf); ! 367: } ! 368: ! 369: ! 370: /* ! 371: * Interrupt routine for child death ! 372: */ ! 373: void ! 374: chdies() ! 375: { ! 376: signal(SIGCHLD, chdies); ! 377: } ! 378: ! 379: /* ! 380: * delete entry from utmp file ! 381: */ ! 382: void ! 383: rmut(i) ! 384: { ! 385: register f; ! 386: register char *line; ! 387: struct utmp wtmp; ! 388: ! 389: line = dkfilename(i); ! 390: if (line==0) ! 391: return; ! 392: line += sizeof("/dev/") - 1; ! 393: f = open("/etc/utmp", 2); ! 394: if(f >= 0) { ! 395: while(read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) { ! 396: if (strncmp(wtmp.ut_line, line, sizeof(wtmp.ut_line))) ! 397: continue; ! 398: lseek(f, -(long)sizeof(wtmp), 1); ! 399: strncpy(wtmp.ut_name, "", sizeof(wtmp.ut_name)); ! 400: time(&wtmp.ut_time); ! 401: write(f, (char *)&wtmp, sizeof(wtmp)); ! 402: } ! 403: close(f); ! 404: } ! 405: f = open("/usr/adm/wtmp", 1); ! 406: if (f >= 0) { ! 407: strncpy(wtmp.ut_line, line, sizeof(wtmp.ut_line)); ! 408: strncpy(wtmp.ut_name, "", sizeof(wtmp.ut_name)); ! 409: time(&wtmp.ut_time); ! 410: lseek(f, (long)0, 2); ! 411: write(f, (char *)&wtmp, sizeof(wtmp)); ! 412: close(f); ! 413: } ! 414: } ! 415: ! 416: /* ! 417: * check a source name against a prototype name ! 418: * in the control file ! 419: * return 0 if no match ! 420: * return 1 if ok match ! 421: */ ! 422: cksource(ck, src) ! 423: register char *ck, *src ; ! 424: { ! 425: ! 426: while (*ck == *src) { ! 427: if (*ck == 0) ! 428: break ; ! 429: ck++ ; src++ ; ! 430: } ! 431: if (*ck == *src) ! 432: return 1 ; ! 433: if (*ck == '*') ! 434: return 1 ; ! 435: return 0 ; ! 436: } ! 437: ! 438: struct passwd * ! 439: getnam(try1, f2, pw) ! 440: char * try1; ! 441: register struct passwd *pw ; ! 442: { ! 443: register char * cp ; ! 444: ! 445: if (pw && pw->pw_uid) { ! 446: write(f2, "OK", 2) ; ! 447: return pw ; ! 448: } ! 449: write(f2, "NO", 2); ! 450: while (1) { ! 451: if (rparm(f2) < 0) { ! 452: dolog(2, "HANGUP c=%d receiving uid\n", imsg->m_chan) ; ! 453: exit(1) ; ! 454: } ! 455: for (cp = parmbuf; *cp; cp++) { ! 456: if (*cp == ' ' || *cp == '.' || *cp == ',') { ! 457: *cp++ = '\0'; ! 458: break ; ! 459: } ! 460: } ! 461: pw = pwsearch(parmbuf, -1, pwline) ; ! 462: if (pw && (pw->pw_passwd==NULL ! 463: || strcmp(crypt(cp, pw->pw_passwd), pw->pw_passwd)==0)) ! 464: break; ! 465: write(f2, "NO", 2) ; ! 466: } ! 467: dolog(4, "TRACE UID %s\n", parmbuf) ; ! 468: write(f2, "OK", 2) ; ! 469: return pw ; ! 470: } ! 471: ! 472: ! 473: rparm(f) ! 474: { ! 475: register len ; ! 476: register rlen ; ! 477: register char *cp ; ! 478: ! 479: ! 480: rlen = sizeof(parmbuf) ; ! 481: parmlen = 0 ; ! 482: cp = parmbuf ; ! 483: while (1) { ! 484: len = read(f, cp, rlen) ; ! 485: if (len <= 0) ! 486: return -1 ; ! 487: parmlen += len ; ! 488: rlen -= len ; ! 489: cp += len - 1 ; ! 490: if (*cp == '\n' || ! 491: *cp == '\r') { ! 492: *cp = '\0' ; ! 493: dolog(7, "DEBUG rparam %s\n", parmbuf) ; ! 494: return 0 ; ! 495: } ! 496: cp++ ; ! 497: } ! 498: } ! 499: ! 500: setfd(f) ! 501: { ! 502: int i ; ! 503: ! 504: signal(SIGTERM, SIG_DFL) ; ! 505: signal(SIGPIPE, SIG_DFL) ; ! 506: signal(SIGQUIT, SIG_DFL) ; ! 507: signal(SIGINT, SIG_DFL) ; ! 508: signal(SIGALRM, SIG_DFL) ; ! 509: signal(SIGHUP, SIG_DFL) ; ! 510: signal(SIGCHLD, SIG_DFL) ; ! 511: ioctl(f, TIOCSPGRP, 0) ; ! 512: close(0) ; ! 513: close(1) ; ! 514: close(2) ; ! 515: close(3) ; ! 516: dup(f) ; ! 517: dup(f) ; ! 518: dup(f) ; ! 519: dup(f) ; ! 520: for (i=NSYSFILE; i<9; i++) ! 521: if (i != fileno(logf)) ! 522: close(i) ; ! 523: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.