|
|
1.1 root 1: /* tsapd.c - OSI transport server */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/support/RCS/tsapd.c,v 7.2 90/07/09 14:51:00 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/support/RCS/tsapd.c,v 7.2 90/07/09 14:51:00 mrose Exp $
9: *
10: *
11: * $Log: tsapd.c,v $
12: * Revision 7.2 90/07/09 14:51:00 mrose
13: * sync
14: *
15: * Revision 7.1 90/02/19 13:09:53 mrose
16: * update
17: *
18: * Revision 7.0 89/11/23 22:27:46 mrose
19: * Release 6.0
20: *
21: */
22:
23: /*
24: * NOTICE
25: *
26: * Acquisition, use, and distribution of this module and related
27: * materials are subject to the restrictions of a license agreement.
28: * Consult the Preface in the User's Manual for the full terms of
29: * this agreement.
30: *
31: */
32:
33:
34: #include <errno.h>
35: #include <signal.h>
36: #include <stdio.h>
37: #include <varargs.h>
38: #include "manifest.h"
39: #include <sys/ioctl.h>
40: #include <sys/stat.h>
41: #ifdef BSD42
42: #include <sys/file.h>
43: #endif
44: #ifdef SYS5
45: #include <fcntl.h>
46: #endif
47: #ifndef X_OK
48: #define X_OK 1
49: #endif
50:
51: #ifndef NOGOSIP
52: #include "rosap.h"
53: #include "rtsap.h"
54: #include "psap2.h"
55: #include "ssap.h"
56: #endif
57: #include "tpkt.h"
58:
59: #ifdef TCP
60: #include "internet.h"
61: #endif
62: #ifdef X25
63: #include "x25.h"
64: #endif
65: #ifdef TP4
66: #include "tp4.h"
67: #endif
68: #include "isoservent.h"
69: #include "tailor.h"
70:
71: /* */
72:
73: static int debug = 0;
74: static int nbits = FD_SETSIZE;
75:
76: static LLog _pgm_log = {
77: "tsapd.log", NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE,
78: LLOG_FATAL, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK
79: };
80: LLog *pgm_log = &_pgm_log;
81:
82: static char *myname = "tsapd";
83: static char myhost[BUFSIZ];
84:
85: static int tcpservice = 1;
86: static int x25service = 1;
87: static int bridgeservice = 1;
88: static int tp4service = 1;
89:
90:
91: #define NTADDRS FD_SETSIZE
92:
93: static struct TSAPaddr *tz;
94: static struct TSAPaddr tas[NTADDRS];
95:
96:
97:
98:
99: void adios (), advise ();
100: void ts_advise ();
101:
102: #ifdef NOGOSIP
103: #define ssapd NULLIFP
104: #else
105: int ssapd (), psapd ();
106: #endif
107:
108:
109:
110: extern int errno;
111:
112: /* */
113:
114: /* ARGSUSED */
115:
116: main (argc, argv, envp)
117: int argc;
118: char **argv,
119: **envp;
120: {
121: int failed,
122: listening,
123: vecp;
124: char *vec[4];
125: register struct NSAPaddr *na;
126: register struct TSAPaddr *ta;
127: struct TSAPdisconnect tds;
128: register struct TSAPdisconnect *td = &tds;
129:
130: arginit (argv);
131: envinit ();
132:
133: failed = listening = 0;
134:
135: for (ta = tas; ta < tz; ta++) {
136: if (ta -> ta_naddr == 0) {
137: if (!tp4service)
138: continue;
139: }
140: else {
141: na = ta -> ta_addrs;
142:
143: switch (na -> na_stack) {
144: case NA_TCP:
145: if (!tcpservice)
146: continue;
147: break;
148:
149: case NA_X25:
150: if (!x25service)
151: continue;
152: break;
153:
154: case NA_BRG:
155: if (!bridgeservice)
156: continue;
157: break;
158:
159: case NA_NSAP:
160: if (!tp4service)
161: continue;
162: break;
163:
164: default:
165: adios (NULLCP, "unknown network type 0x%x", na -> na_stack);
166: /* NOTREACHED */
167: }
168: }
169:
170: advise (LLOG_NOTICE, NULLCP, "listening on %s", taddr2str (ta));
171:
172: if (TNetListen (ta, td) == NOTOK) {
173: ts_advise (td, LLOG_EXCEPTIONS, "TNetListen failed");
174: failed++;
175: }
176: else
177: listening++;
178: }
179:
180: if (!listening)
181: adios (NULLCP, failed ? "no successful listens"
182: : "no network services selected");
183:
184: for (;;) {
185: if (TNetAccept (&vecp, vec, 0, NULLFD, NULLFD, NULLFD, NOTOK, td)
186: == NOTOK) {
187: ts_advise (td, LLOG_EXCEPTIONS, "TNetAccept failed");
188: continue;
189: }
190:
191: if (vecp <= 0)
192: continue;
193:
194: switch (TNetFork (vecp, vec, td)) {
195: case OK:
196: ll_hdinit (pgm_log, myname);
197: tsapd (vecp, vec);
198: exit (1);
199: /* NOTREACHED */
200:
201: case NOTOK:
202: ts_advise (td, LLOG_EXCEPTIONS, "TNetFork failed");
203: default:
204: break;
205: }
206: }
207: }
208:
209: /* */
210:
211: static char buffer1[4096];
212: static char buffer2[32768];
213:
214:
215: static int tsapd (vecp, vec)
216: int vecp;
217: char **vec;
218: {
219: char buffer[BUFSIZ];
220: register struct isoservent *is;
221: struct tsapblk *tb;
222: struct TSAPstart tss;
223: register struct TSAPstart *ts = &tss;
224: struct TSAPdisconnect tds;
225: register struct TSAPdisconnect *td = &tds;
226: IFP hook;
227:
228: /* begin UGLY */
229: (void) strcpy (buffer1, vec[1]);
230: (void) strcpy (buffer2, vec[2]);
231: /* end UGLY */
232:
233: if (TInit (vecp, vec, ts, td) == NOTOK) {
234: ts_advise (td, LLOG_EXCEPTIONS, "T-CONNECT.INDICATION");
235: return;
236: }
237:
238: /* used to print this in ssapd()... */
239: advise (LLOG_NOTICE, NULLCP,
240: "T-CONNECT.INDICATION: <%d, %s, %s, %d, %d>",
241: ts -> ts_sd,
242: taddr2str (&ts -> ts_calling), taddr2str (&ts -> ts_called),
243: ts -> ts_expedited, ts -> ts_tsdusize);
244:
245:
246: hook = ssapd;
247: if (ts -> ts_called.ta_selectlen) {
248: if ((is = getisoserventbyselector ("tsap", ts -> ts_called.ta_selector,
249: ts -> ts_called.ta_selectlen))
250: == NULL) {
251: (void) sprintf (buffer, "OSI service tsap/%s not found",
252: sel2str (ts -> ts_called.ta_selector,
253: ts -> ts_called.ta_selectlen, 1));
254: goto out;
255: }
256: }
257: else
258: if (hook == NULLIFP
259: || (is = getisoserventbyname ("session", "tsap")) == NULL) {
260: (void) strcpy (buffer, "default session service not found");
261: goto out;
262: }
263:
264: *is -> is_tail++ = buffer1;
265: *is -> is_tail++ = buffer2;
266: *is -> is_tail = NULL;
267:
268: if (tb = findtblk (ts -> ts_sd))
269: tb -> tb_fd = NOTOK;
270: switch (hook ? (*hook) (is, td) : OK) {
271: case NOTOK:
272: ts_advise (td, LLOG_EXCEPTIONS, "service not started at tsap");
273: case DONE:
274: exit (1);
275: /* NOTREACHED */
276:
277: case OK:
278: default:
279: (void) setperms (is);
280: (void) execv (*is -> is_vec, is -> is_vec);
281: (void) sprintf (buffer, "unable to exec %s: %s",
282: *is -> is_vec, sys_errname (errno));
283: SLOG (pgm_log, LLOG_FATAL, NULLCP, ("%s", buffer));
284: break;
285: }
286:
287: out: ;
288: advise (LLOG_EXCEPTIONS, NULLCP, "%s", buffer);
289: if (strlen (buffer) >= TD_SIZE)
290: buffer[0] = NULL;
291: (void) TDiscRequest (ts -> ts_sd, buffer, strlen (buffer) + 1, td);
292:
293: exit (1);
294: }
295:
296: /* */
297:
298: static int setperms (is)
299: register struct isoservent *is;
300: {
301: struct stat st;
302:
303: if (stat (*is -> is_vec, &st) == NOTOK) {
304: (void) setgid (1);
305: (void) setuid (1);
306: }
307: else {
308: (void) setgid (st.st_gid);
309: (void) setuid (st.st_uid);
310: }
311: }
312:
313: /* */
314:
315: static void ts_advise (td, code, event)
316: register struct TSAPdisconnect *td;
317: int code;
318: char *event;
319: {
320: char buffer[BUFSIZ];
321:
322: if (td -> td_cc > 0)
323: (void) sprintf (buffer, "[%s] %*.*s",
324: TErrString (td -> td_reason),
325: td -> td_cc, td -> td_cc, td -> td_data);
326: else
327: (void) sprintf (buffer, "[%s]", TErrString (td -> td_reason));
328:
329: advise (code, NULLCP, "%s: %s", event, buffer);
330: }
331:
332: /* */
333:
334: #ifndef NOGOSIP
335: static int ssapd (is, td)
336: register struct isoservent *is;
337: register struct TSAPdisconnect *td;
338: {
339: int sd;
340: struct TSAPstart tss;
341: register struct TSAPstart *ts = &tss;
342: struct SSAPindication sis;
343: register struct SSAPabort *sa = &sis.si_abort;
344:
345: if (strcmp (is -> is_entity, "session")
346: || strcmp (is -> is_provider, "tsap"))
347: return OK;
348:
349: if (TInit (is -> is_tail - is -> is_vec, is -> is_vec, ts, td) == NOTOK)
350: return NOTOK;
351:
352: sd = ts -> ts_sd;
353:
354: if (TConnResponse (sd, &ts -> ts_called, ts -> ts_expedited, NULLCP, 0,
355: NULLQOS, td) == NOTOK)
356: return NOTOK;
357:
358: if (SExec (ts, &sis, psapd, setperms) == NOTOK) {
359: advise (LLOG_EXCEPTIONS, NULLCP, "service not started at ssap: %s",
360: SErrString (sa -> sa_reason));
361: if (sa -> sa_cc > 0)
362: advise (LLOG_EXCEPTIONS, NULLCP, " %*.*s",
363: sa -> sa_cc, sa -> sa_cc, sa -> sa_data);
364:
365: SAFREE (sa);
366: }
367:
368: return DONE;
369: }
370:
371: /* */
372:
373: #define RMASK \
374: "\020\01HALFDUPLEX\02DUPLEX\03EXPEDITED\04MINORSYNC\05MAJORSYNC\06RESYNC\
375: \07ACTIVITY\010NEGOTIATED\011CAPABILITY\012EXCEPTIONS\013TYPEDATA"
376:
377:
378: static int psapd (is, si)
379: register struct isoservent *is;
380: register struct SSAPindication *si;
381: {
382: struct SSAPstart sss;
383: register struct SSAPstart *ss = &sss;
384: struct PSAPindication pis;
385: register struct PSAPabort *pa = &pis.pi_abort;
386: struct RtSAPindication rtis;
387: register struct RtSAPabort *rta = &rtis.rti_abort;
388: struct RoSAPindication rois;
389: register struct RoSAPpreject *rop = &rois.roi_preject;
390:
391: if (strcmp (is -> is_provider, "ssap"))
392: return OK;
393:
394: if (strcmp (is -> is_entity, "presentation")
395: && strcmp (is -> is_entity, "rts")
396: && strcmp (is -> is_entity, "ros"))
397: return OK;
398:
399: /* begin UGLY */
400: (void) strcpy (buffer1, *(is -> is_tail - 2));
401: (void) strcpy (buffer2, *(is -> is_tail - 1));
402: /* end UGLY */
403: if (SInit (is -> is_tail - is -> is_vec, is -> is_vec, ss, si) == NOTOK)
404: return NOTOK;
405: advise (LLOG_NOTICE, NULLCP,
406: "S-CONNECT.INDICATION: <%d, %s, %s, %s, %s, %ld, %d>",
407: ss -> ss_sd, sprintref (&ss -> ss_connect),
408: saddr2str (&ss -> ss_calling), saddr2str (&ss -> ss_called),
409: sprintb (ss -> ss_requirements, RMASK), ss -> ss_isn,
410: ss -> ss_ssdusize);
411:
412: if (strcmp (is -> is_entity, "presentation") == 0) {
413: if (PExec (ss, &pis, buffer1, buffer2, NULLIFP, setperms) == NOTOK) {
414: advise (LLOG_EXCEPTIONS, NULLCP,
415: "service not started at psap: %s",
416: PErrString (pa -> pa_reason));
417: if (pa -> pa_cc > 0)
418: advise (LLOG_EXCEPTIONS, NULLCP, " %*.*s",
419: pa -> pa_cc, pa -> pa_cc, pa -> pa_data);
420: }
421:
422: return DONE;
423: }
424:
425: if (strcmp (is -> is_entity, "rts") == 0) {
426: if (RtExec (ss, &rtis, buffer1, buffer2, NULLIFP, setperms) == NOTOK) {
427: advise (LLOG_EXCEPTIONS, NULLCP,
428: "service not started at rtsap: %s",
429: RtErrString (rta -> rta_reason));
430: if (rta -> rta_cc > 0)
431: advise (LLOG_EXCEPTIONS, NULLCP, " %*.*s",
432: rta -> rta_cc, rta -> rta_cc, rta -> rta_data);
433: }
434: }
435: else {
436: if (RoExec (ss, &rois, buffer1, buffer2, NULLIFP, setperms) == NOTOK) {
437: advise (LLOG_EXCEPTIONS, NULLCP,
438: "service not started at rosap: %s",
439: RoErrString (rop -> rop_reason));
440: if (rop -> rop_cc > 0)
441: advise (LLOG_EXCEPTIONS, NULLCP, " %*.*s",
442: rop -> rop_cc, rop -> rop_cc, rop -> rop_data);
443: }
444: }
445:
446: return DONE;
447: }
448: #endif
449:
450: /* */
451:
452: static arginit (vec)
453: char **vec;
454: {
455: int rflag;
456: register char *ap;
457: #ifdef TCP
458: int port;
459: struct NSAPaddr *tcp_na;
460: register struct servent *sp;
461: #endif
462: #ifdef X25
463: struct NSAPaddr *x25_na;
464: #endif
465: #ifdef BRIDGE_X25
466: struct NSAPaddr *bridge_na;
467: #endif
468: #ifdef TP4
469: register struct isoservent *is;
470: #endif
471: struct stat st;
472:
473: if (myname = rindex (*vec, '/'))
474: myname++;
475: if (myname == NULL || *myname == NULL)
476: myname = *vec;
477:
478: isodetailor (myname, 0);
479: ll_hdinit (pgm_log, myname);
480:
481: rflag = 0;
482:
483: (void) strcpy (myhost, TLocalHostName ());
484:
485: bzero ((char *) tas, sizeof tas);
486: tz = tas;
487:
488: #ifdef TCP
489: if (!(ts_stacks & TS_TCP))
490: tcpservice = 0;
491: if ((sp = getservbyname ("tsap", "tcp")) == NULL
492: && (sp = getservbyname ("iso-tsap", "tcp")) == NULL)
493: advise (LLOG_EXCEPTIONS, NULLCP, "tcp/tsap: unknown service");
494:
495: tcp_na = tz -> ta_addrs;
496: tcp_na -> na_stack = NA_TCP;
497: tcp_na -> na_community = ts_comm_tcp_default;
498: tcp_na -> na_domain[0] = NULL;
499: tcp_na -> na_port = sp ? sp -> s_port : htons ((u_short) 102);
500: tz -> ta_naddr = 1;
501:
502: tz++;
503: #endif
504:
505: #ifdef X25
506: if (!(ts_stacks & TS_X25))
507: x25service = 0;
508:
509: x25_na = tz -> ta_addrs;
510: x25_na -> na_stack = NA_X25;
511: x25_na -> na_community = ts_comm_x25_default;
512: if (x25_local_dte && *x25_local_dte) {
513: (void) strcpy (x25_na -> na_dte, x25_local_dte);
514: x25_na -> na_dtelen = strlen (x25_na -> na_dte);
515: }
516: if (x25_local_pid && *x25_local_pid)
517: x25_na -> na_pidlen =
518: str2sel (x25_local_pid, -1, x25_na -> na_pid, NPSIZE);
519: tz -> ta_naddr = 1;
520:
521: tz++;
522: #endif
523:
524: #ifdef BRIDGE_X25
525: if (!(ts_stacks & TS_BRG))
526: bridgeservice = 0;
527:
528: bridge_na = tz -> ta_addrs;
529: bridge_na -> na_stack = NA_BRG;
530: bridge_na -> na_community = ts_comm_x25_default;
531: if (x25_bridge_listen && *x25_bridge_listen) {
532: (void) strcpy (bridge_na -> na_dte, x25_bridge_listen);
533: bridge_na -> na_dtelen = strlen (bridge_na -> na_dte);
534: }
535: if (x25_bridge_pid && *x25_bridge_pid)
536: bridge_na -> na_pidlen =
537: str2sel (x25_bridge_pid, -1, bridge_na -> na_pid, NPSIZE);
538: tz -> ta_naddr = 1;
539:
540: tz++;
541: #endif
542:
543: #ifdef TP4
544: if (!(ts_stacks & TS_TP4))
545: tp4service = 0;
546:
547: (void) setisoservent (0);
548: while (is = getisoservent ())
549: if (strcmp (is -> is_provider, "tsap") == 0
550: && (strcmp (*is -> is_vec, "tsapd-bootstrap") == 0
551: || access (*is -> is_vec, X_OK) != NOTOK)) {
552: if (strcmp (is -> is_entity, "isore") == 0)
553: continue;
554:
555: if (tz >= tas + NTADDRS) {
556: advise (LLOG_EXCEPTIONS, NULLCP,
557: "too many services, starting with %s",
558: is -> is_entity);
559: break;
560: }
561:
562: bcopy (is -> is_selector, tz -> ta_selector,
563: tz -> ta_selectlen = is -> is_selectlen);
564: tz -> ta_naddr = 0;
565:
566: tz++;
567: }
568: (void) endisoservent ();
569: #endif
570:
571: for (vec++; ap = *vec; vec++) {
572: if (*ap == '-')
573: switch (*++ap) {
574: case 'd':
575: debug++;
576: continue;
577:
578: case 't':
579: ts_stacks = TS_TCP;
580: tcpservice = 1;
581: x25service = bridgeservice = tp4service = 0;
582: continue;
583:
584: case 'x':
585: ts_stacks = TS_X25;
586: x25service = 1;
587: tcpservice = bridgeservice = tp4service = 0;
588: continue;
589:
590: case 'z':
591: ts_stacks = TS_TP4;
592: tp4service = 1;
593: tcpservice = x25service = bridgeservice = 0;
594: continue;
595:
596: case 'b':
597: ts_stacks = TS_BRG;
598: bridgeservice = 1;
599: tcpservice = x25service = tp4service = 0;
600: continue;
601:
602: case 'r':
603: rflag = 1;
604: continue;
605:
606: #ifdef TCP
607: case 'p':
608: if ((ap = *++vec) == NULL
609: || *ap == '-'
610: || (port = atoi (ap)) <= 0)
611: adios (NULLCP, "usage: %s -p portno", myname);
612: tcp_na -> na_port = htons ((u_short) port);
613: continue;
614: #endif
615:
616: #ifdef X25
617: /* This permits listening on a specific subaddress. */
618: case 'a':
619: if ((ap = *++vec) == NULL || *ap == '-')
620: adios (NULLCP, "usage: %s -a x121address", myname);
621: (void) strcpy (x25_na -> na_dte, ap);
622: x25_na -> na_dtelen = strlen (ap);
623: continue;
624:
625: /* This permits listening on a specific protocol id.
626: In fact, SunLink X.25 lets you listen on a protocol
627: id mask, but let's keep it simple. */
628: case 'i':
629: if ((ap = *++vec) == NULL || *ap == '-' )
630: adios (NULLCP, "usage: %s -i pid", myname);
631: x25_na -> na_pidlen =
632: str2sel (ap, -1, x25_na -> na_pid, NPSIZE);
633: continue;
634: #endif
635:
636: #ifdef BRIDGE_X25
637: case 'A':
638: if ((ap = *++vec) == NULL ||
639: *ap == '-')
640: adios (NULLCP, "usage: %s -A x121address", myname);
641: (void) strcpy (bridge_na -> na_dte, ap);
642: bridge_na -> na_dtelen = strlen (ap);
643: continue;
644:
645: case 'I':
646: if ((ap = *++vec) == NULL || *ap == '-')
647: adios (NULLCP, "usage: %s -I pid", myname);
648: bridge_na -> na_pidlen =
649: str2sel (ap, -1, bridge_na -> na_pid, NPSIZE);
650: continue;
651: #endif
652:
653: default:
654: adios (NULLCP, "-%s: unknown switch", ap);
655: }
656:
657: adios (NULLCP, "usage: %s [switches]", myname);
658: }
659:
660: if (!rflag
661: && getuid () == 0
662: && stat (ap = isodefile ("isoservices", 0), &st) != NOTOK
663: && st.st_uid != 0)
664: adios (NULLCP, "%s not owned by root", ap);
665: }
666:
667: /* */
668:
669: static envinit () {
670: int i,
671: sd;
672:
673: nbits = getdtablesize ();
674:
675: if (debug == 0 && !(debug = isatty (2))) {
676: for (i = 0; i < 5; i++) {
677: switch (fork ()) {
678: case NOTOK:
679: sleep (5);
680: continue;
681:
682: case OK:
683: break;
684:
685: default:
686: _exit (0);
687: }
688: break;
689: }
690:
691: (void) chdir ("/");
692:
693: if ((sd = open ("/dev/null", O_RDWR)) == NOTOK)
694: adios ("/dev/null", "unable to read");
695: if (sd != 0)
696: (void) dup2 (sd, 0), (void) close (sd);
697: (void) dup2 (0, 1);
698: (void) dup2 (0, 2);
699:
700: #ifdef SETSID
701: if (setsid () == NOTOK)
702: advise (LLOG_EXCEPTIONS, "failed", "setsid");
703: #endif
704: #ifdef TIOCNOTTY
705: if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) {
706: (void) ioctl (sd, TIOCNOTTY, NULLCP);
707: (void) close (sd);
708: }
709: #else
710: #ifdef SYS5
711: (void) setpgrp ();
712: (void) signal (SIGINT, SIG_IGN);
713: (void) signal (SIGQUIT, SIG_IGN);
714: #endif
715: #endif
716: }
717: else
718: ll_dbinit (pgm_log, myname);
719:
720: #ifndef sun /* damn YP... */
721: for (sd = 3; sd < nbits; sd++)
722: if (pgm_log -> ll_fd != sd)
723: (void) close (sd);
724: #endif
725:
726: (void) signal (SIGPIPE, SIG_IGN);
727:
728: ll_hdinit (pgm_log, myname);
729: advise (LLOG_NOTICE, NULLCP, "starting");
730: }
731:
732: /* ERRORS */
733:
734: #ifndef lint
735: void adios (va_alist)
736: va_dcl
737: {
738: va_list ap;
739:
740: va_start (ap);
741:
742: _ll_log (pgm_log, LLOG_FATAL, ap);
743:
744: va_end (ap);
745:
746: _exit (1);
747: }
748: #else
749: /* VARARGS */
750:
751: void adios (what, fmt)
752: char *what,
753: *fmt;
754: {
755: adios (what, fmt);
756: }
757: #endif
758:
759:
760: #ifndef lint
761: void advise (va_alist)
762: va_dcl
763: {
764: int code;
765: va_list ap;
766:
767: va_start (ap);
768:
769: code = va_arg (ap, int);
770:
771: _ll_log (pgm_log, code, ap);
772:
773: va_end (ap);
774: }
775: #else
776: /* VARARGS */
777:
778: void advise (code, what, fmt)
779: char *what,
780: *fmt;
781: int code;
782: {
783: advise (code, what, fmt);
784: }
785: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.