|
|
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.