Commit | Line | Data |
---|---|---|
9319b3c3 C |
1 | /* tsapd.c - OSI transport listener */ |
2 | ||
3 | #ifndef lint | |
4 | static char *rcsid = "$Header: /f/osi/support/RCS/tsapd.c,v 7.12 91/02/22 09:46:59 mrose Interim $"; | |
5 | #endif | |
6 | ||
7 | /* | |
8 | * $Header: /f/osi/support/RCS/tsapd.c,v 7.12 91/02/22 09:46:59 mrose Interim $ | |
9 | * | |
10 | * | |
11 | * $Log: tsapd.c,v $ | |
12 | * Revision 7.12 91/02/22 09:46:59 mrose | |
13 | * Interim 6.8 | |
14 | * | |
15 | * Revision 7.11 90/12/19 09:16:14 mrose | |
16 | * touch-up | |
17 | * | |
18 | * Revision 7.10 90/12/17 22:13:27 mrose | |
19 | * -call | |
20 | * | |
21 | * Revision 7.9 90/12/11 10:52:29 mrose | |
22 | * lock-and-load | |
23 | * | |
24 | * Revision 7.8 90/11/05 14:10:32 mrose | |
25 | * oops | |
26 | * | |
27 | * Revision 7.7 90/10/30 14:25:32 mrose | |
28 | * update | |
29 | * | |
30 | * Revision 7.6 90/10/29 18:37:25 mrose | |
31 | * updates | |
32 | * | |
33 | * Revision 7.5 90/10/16 11:21:04 mrose | |
34 | * update | |
35 | * | |
36 | * Revision 7.4 90/10/15 22:54:26 mrose | |
37 | * typo | |
38 | * | |
39 | * Revision 7.3 90/10/15 18:18:47 mrose | |
40 | * iaed | |
41 | * | |
42 | * Revision 7.2 90/07/09 14:51:00 mrose | |
43 | * sync | |
44 | * | |
45 | * Revision 7.1 90/02/19 13:09:53 mrose | |
46 | * update | |
47 | * | |
48 | * Revision 7.0 89/11/23 22:27:46 mrose | |
49 | * Release 6.0 | |
50 | * | |
51 | */ | |
52 | ||
53 | /* | |
54 | * NOTICE | |
55 | * | |
56 | * Acquisition, use, and distribution of this module and related | |
57 | * materials are subject to the restrictions of a license agreement. | |
58 | * Consult the Preface in the User's Manual for the full terms of | |
59 | * this agreement. | |
60 | * | |
61 | */ | |
62 | ||
63 | ||
64 | #include <errno.h> | |
65 | #include <signal.h> | |
66 | #include <stdio.h> | |
67 | #include <varargs.h> | |
68 | #include "manifest.h" | |
69 | #include <sys/ioctl.h> | |
70 | #include <sys/stat.h> | |
71 | #ifdef BSD42 | |
72 | #include <sys/file.h> | |
73 | #endif | |
74 | #ifdef SYS5 | |
75 | #include <fcntl.h> | |
76 | #endif | |
77 | #ifndef X_OK | |
78 | #define X_OK 1 | |
79 | #endif | |
80 | ||
81 | #ifdef IAE | |
82 | #include <quipu/util.h> | |
83 | #include <quipu/bind.h> | |
84 | #include <quipu/list.h> | |
85 | #include <quipu/ds_search.h> | |
86 | ||
87 | #define NOGOSIP | |
88 | #endif | |
89 | ||
90 | #ifndef NOGOSIP | |
91 | #include "rosap.h" | |
92 | #include "rtsap.h" | |
93 | #include "psap2.h" | |
94 | #include "ssap.h" | |
95 | #endif | |
96 | #include "tpkt.h" | |
97 | ||
98 | #ifdef TCP | |
99 | #include "internet.h" | |
100 | #endif | |
101 | #ifdef X25 | |
102 | #include "x25.h" | |
103 | #endif | |
104 | #ifdef TP4 | |
105 | #include "tp4.h" | |
106 | #endif | |
107 | #ifndef IAE | |
108 | #include "isoservent.h" | |
109 | #endif | |
110 | #include "tailor.h" | |
111 | ||
112 | /* \f */ | |
113 | ||
114 | static int debug = 0; | |
115 | static int nbits = FD_SETSIZE; | |
116 | ||
117 | static LLog _pgm_log = { | |
118 | #ifndef IAE | |
119 | "tsapd.log", | |
120 | #else | |
121 | "iaed.log", | |
122 | #endif | |
123 | NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, | |
124 | LLOG_FATAL, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK | |
125 | }; | |
126 | LLog *pgm_log = &_pgm_log; | |
127 | ||
128 | static char *pgmname = "tsapd"; | |
129 | static char myhost[BUFSIZ]; | |
130 | ||
131 | static int tcpservice = 1; | |
132 | static int x25service = 1; | |
133 | static int bridgeservice = 1; | |
134 | static int tp4service = 1; | |
135 | ||
136 | static int *services[] = { | |
137 | &tp4service, &tcpservice, &x25service, &bridgeservice | |
138 | }; | |
139 | ||
140 | ||
141 | #define NTADDRS FD_SETSIZE | |
142 | ||
143 | static int listening = 0; | |
144 | ||
145 | static struct TSAPaddr *tz; | |
146 | static struct TSAPaddr tas[NTADDRS]; | |
147 | ||
148 | ||
149 | #ifdef IAE | |
150 | #define IAETIME (24 * 60 * 60L) | |
151 | ||
152 | static int isbound = 0; | |
153 | static int main_dsa = NOTOK; | |
154 | static int referral_dsa = NOTOK; | |
155 | ||
156 | static long nextime; | |
157 | ||
158 | static DN userdn = NULL; | |
159 | static char passwd[DBA_MAX_PASSWD_LEN]; | |
160 | ||
161 | static AttributeType t_ev; | |
162 | static AttributeType t_pa; | |
163 | ||
164 | static struct ds_search_arg search_arg; | |
165 | ||
166 | struct IAEntry { | |
167 | struct TSAPaddr is_addr; | |
168 | ||
169 | char *is_vector; | |
170 | char **is_vec; | |
171 | char **is_tail; | |
172 | }; | |
173 | ||
174 | #define NENTRIES 100 | |
175 | static struct IAEntry *iz; | |
176 | static struct IAEntry iae[NENTRIES]; | |
177 | ||
178 | ||
179 | int str2dnY (); | |
180 | ||
181 | ||
182 | extern int dsa_ad; | |
183 | extern int dsa_dead; | |
184 | extern char *local_dit; | |
185 | extern struct PSAPaddr dsa_bound; | |
186 | ||
187 | extern int as_print (), dn_print (), de_print (), fi_print (); | |
188 | #endif | |
189 | ||
190 | ||
191 | void adios (), advise (); | |
192 | void ts_advise (); | |
193 | ||
194 | #ifdef NOGOSIP | |
195 | #define ssapd NULLIFP | |
196 | #else | |
197 | int ssapd (), psapd (); | |
198 | #endif | |
199 | ||
200 | ||
201 | extern int errno; | |
202 | ||
203 | #ifdef IAE | |
204 | long time (); | |
205 | #endif | |
206 | ||
207 | /* \f */ | |
208 | ||
209 | /* ARGSUSED */ | |
210 | ||
211 | main (argc, argv, envp) | |
212 | int argc; | |
213 | char **argv, | |
214 | **envp; | |
215 | { | |
216 | int failed, | |
217 | vecp; | |
218 | char *vec[4]; | |
219 | register struct TSAPaddr *ta; | |
220 | struct TSAPdisconnect tds; | |
221 | register struct TSAPdisconnect *td = &tds; | |
222 | ||
223 | arginit (argv); | |
224 | envinit (); | |
225 | ||
226 | failed = 0; | |
227 | ||
228 | for (ta = tas; ta < tz; ta++) { | |
229 | register struct NSAPaddr *na; | |
230 | ||
231 | if (ta -> ta_naddr) { | |
232 | if (((na = ta -> ta_addrs) -> na_stack < 0 | |
233 | || na -> na_stack | |
234 | >= sizeof services / sizeof services[0])) | |
235 | adios (NULLCP, "unknown network type 0x%x", na -> na_stack); | |
236 | } | |
237 | else | |
238 | na = NULLNA; | |
239 | ||
240 | if (!*services[na ? na -> na_stack : NA_NSAP]) | |
241 | continue; | |
242 | ||
243 | advise (LLOG_NOTICE, NULLCP, "listening on %s", taddr2str (ta)); | |
244 | ||
245 | if (TNetListen (ta, td) == NOTOK) { | |
246 | ts_advise (td, LLOG_EXCEPTIONS, "TNetListen failed"); | |
247 | failed++; | |
248 | } | |
249 | else | |
250 | listening++; | |
251 | } | |
252 | ||
253 | if (!listening) | |
254 | adios (NULLCP, failed ? "no successful listens" | |
255 | : "no network services selected"); | |
256 | ||
257 | for (;;) { | |
258 | #ifdef IAE | |
259 | int secs; | |
260 | long now; | |
261 | ||
262 | (void) time (&now); | |
263 | now++; | |
264 | ||
265 | if ((secs = (int) (nextime - now)) <= 0) { | |
266 | search_directory (0); | |
267 | ||
268 | secs = IAETIME; | |
269 | } | |
270 | #else | |
271 | #define secs NOTOK | |
272 | #endif | |
273 | ||
274 | if (TNetAccept (&vecp, vec, 0, NULLFD, NULLFD, NULLFD, secs, td) | |
275 | == NOTOK) { | |
276 | ts_advise (td, LLOG_EXCEPTIONS, "TNetAccept failed"); | |
277 | continue; | |
278 | } | |
279 | ||
280 | if (vecp <= 0) | |
281 | continue; | |
282 | ||
283 | if (debug) | |
284 | break; | |
285 | ||
286 | switch (TNetFork (vecp, vec, td)) { | |
287 | case OK: | |
288 | #ifdef IAE | |
289 | (void) signal (SIGHUP, SIG_DFL); | |
290 | #endif | |
291 | ll_hdinit (pgm_log, pgmname); | |
292 | break; | |
293 | ||
294 | case NOTOK: | |
295 | ts_advise (td, LLOG_EXCEPTIONS, "TNetFork failed"); | |
296 | default: | |
297 | continue; | |
298 | } | |
299 | break; | |
300 | } | |
301 | ||
302 | tsapd (vecp, vec); | |
303 | } | |
304 | ||
305 | /* \f */ | |
306 | ||
307 | static char buffer1[4096]; | |
308 | static char buffer2[32768]; | |
309 | ||
310 | ||
311 | static int tsapd (vecp, vec) | |
312 | int vecp; | |
313 | char **vec; | |
314 | { | |
315 | char buffer[BUFSIZ]; | |
316 | #ifndef IAE | |
317 | register struct isoservent *is; | |
318 | #else | |
319 | register struct IAEntry *is; | |
320 | #endif | |
321 | struct tsapblk *tb; | |
322 | struct TSAPstart tss; | |
323 | register struct TSAPstart *ts = &tss; | |
324 | struct TSAPdisconnect tds; | |
325 | register struct TSAPdisconnect *td = &tds; | |
326 | IFP hook; | |
327 | ||
328 | /* begin UGLY */ | |
329 | (void) strcpy (buffer1, vec[1]); | |
330 | (void) strcpy (buffer2, vec[2]); | |
331 | /* end UGLY */ | |
332 | ||
333 | if (TInit (vecp, vec, ts, td) == NOTOK) { | |
334 | ts_advise (td, LLOG_EXCEPTIONS, "T-CONNECT.INDICATION"); | |
335 | return; | |
336 | } | |
337 | ||
338 | /* used to print this in ssapd()... */ | |
339 | advise (LLOG_NOTICE, NULLCP, | |
340 | "T-CONNECT.INDICATION: <%d, %s, %s, %d, %d>", | |
341 | ts -> ts_sd, | |
342 | taddr2str (&ts -> ts_calling), taddr2str (&ts -> ts_called), | |
343 | ts -> ts_expedited, ts -> ts_tsdusize); | |
344 | ||
345 | hook = ssapd; | |
346 | if (ts -> ts_called.ta_selectlen) { | |
347 | #ifndef IAE | |
348 | if ((is = getisoserventbyselector ("tsap", ts -> ts_called.ta_selector, | |
349 | ts -> ts_called.ta_selectlen)) | |
350 | == NULL) { | |
351 | #else | |
352 | for (is = iae; is < iz; is++) | |
353 | if (is -> is_addr.ta_selectlen == ts -> ts_called.ta_selectlen | |
354 | && bcmp (is -> is_addr.ta_selector, | |
355 | ts -> ts_called.ta_selector, | |
356 | is -> is_addr.ta_selectlen) == 0) | |
357 | break; | |
358 | if (is >= iz) { | |
359 | #endif | |
360 | (void) sprintf (buffer, "OSI service tsap/%s not found", | |
361 | sel2str (ts -> ts_called.ta_selector, | |
362 | ts -> ts_called.ta_selectlen, 1)); | |
363 | goto out; | |
364 | } | |
365 | } | |
366 | else | |
367 | #ifndef IAE | |
368 | if (hook == NULLIFP | |
369 | || (is = getisoserventbyname ("session", "tsap")) == NULL) | |
370 | #endif | |
371 | { | |
372 | (void) strcpy (buffer, "default session service not found"); | |
373 | goto out; | |
374 | } | |
375 | ||
376 | #ifndef IAE | |
377 | *is -> is_tail++ = buffer1; | |
378 | *is -> is_tail++ = buffer2; | |
379 | *is -> is_tail = NULL; | |
380 | #else | |
381 | is -> is_tail[0] = buffer1; | |
382 | is -> is_tail[1] = buffer2; | |
383 | is -> is_tail[2] = NULL; | |
384 | #endif | |
385 | ||
386 | if (tb = findtblk (ts -> ts_sd)) | |
387 | tb -> tb_fd = NOTOK; | |
388 | switch (hook ? (*hook) (is, td) : OK) { | |
389 | case NOTOK: | |
390 | ts_advise (td, LLOG_EXCEPTIONS, "service not started at tsap"); | |
391 | case DONE: | |
392 | exit (1); | |
393 | /* NOTREACHED */ | |
394 | ||
395 | case OK: | |
396 | default: | |
397 | (void) setperms (is); | |
398 | (void) execv (*is -> is_vec, is -> is_vec); | |
399 | (void) sprintf (buffer, "unable to exec %s: %s", | |
400 | *is -> is_vec, sys_errname (errno)); | |
401 | SLOG (pgm_log, LLOG_FATAL, NULLCP, ("%s", buffer)); | |
402 | break; | |
403 | } | |
404 | ||
405 | out: ; | |
406 | advise (LLOG_EXCEPTIONS, NULLCP, "%s", buffer); | |
407 | if (strlen (buffer) >= TD_SIZE) | |
408 | buffer[0] = NULL; | |
409 | (void) TDiscRequest (ts -> ts_sd, buffer, strlen (buffer) + 1, td); | |
410 | ||
411 | exit (1); | |
412 | } | |
413 | ||
414 | /* \f */ | |
415 | ||
416 | static int setperms (is) | |
417 | #ifndef IAE | |
418 | register struct isoservent *is; | |
419 | #else | |
420 | register struct IAEntry *is; | |
421 | #endif | |
422 | { | |
423 | struct stat st; | |
424 | ||
425 | if (stat (*is -> is_vec, &st) == NOTOK) { | |
426 | (void) setgid (1); | |
427 | (void) setuid (1); | |
428 | } | |
429 | else { | |
430 | (void) setgid (st.st_gid); | |
431 | (void) setuid (st.st_uid); | |
432 | } | |
433 | } | |
434 | ||
435 | /* \f */ | |
436 | ||
437 | static void ts_advise (td, code, event) | |
438 | register struct TSAPdisconnect *td; | |
439 | int code; | |
440 | char *event; | |
441 | { | |
442 | char buffer[BUFSIZ]; | |
443 | ||
444 | if (td -> td_cc > 0) | |
445 | (void) sprintf (buffer, "[%s] %*.*s", | |
446 | TErrString (td -> td_reason), | |
447 | td -> td_cc, td -> td_cc, td -> td_data); | |
448 | else | |
449 | (void) sprintf (buffer, "[%s]", TErrString (td -> td_reason)); | |
450 | ||
451 | advise (code, NULLCP, "%s: %s", event, buffer); | |
452 | } | |
453 | ||
454 | /* \f */ | |
455 | ||
456 | #ifndef NOGOSIP | |
457 | static int ssapd (is, td) | |
458 | register struct isoservent *is; | |
459 | register struct TSAPdisconnect *td; | |
460 | { | |
461 | int sd; | |
462 | struct TSAPstart tss; | |
463 | register struct TSAPstart *ts = &tss; | |
464 | struct SSAPindication sis; | |
465 | register struct SSAPabort *sa = &sis.si_abort; | |
466 | ||
467 | if (strcmp (is -> is_entity, "session") | |
468 | || strcmp (is -> is_provider, "tsap")) | |
469 | return OK; | |
470 | ||
471 | if (TInit (is -> is_tail - is -> is_vec, is -> is_vec, ts, td) == NOTOK) | |
472 | return NOTOK; | |
473 | ||
474 | sd = ts -> ts_sd; | |
475 | ||
476 | if (TConnResponse (sd, &ts -> ts_called, ts -> ts_expedited, NULLCP, 0, | |
477 | NULLQOS, td) == NOTOK) | |
478 | return NOTOK; | |
479 | ||
480 | if (SExec (ts, &sis, psapd, setperms) == NOTOK) { | |
481 | advise (LLOG_EXCEPTIONS, NULLCP, "service not started at ssap: %s", | |
482 | SErrString (sa -> sa_reason)); | |
483 | if (sa -> sa_cc > 0) | |
484 | advise (LLOG_EXCEPTIONS, NULLCP, " %*.*s", | |
485 | sa -> sa_cc, sa -> sa_cc, sa -> sa_data); | |
486 | ||
487 | SAFREE (sa); | |
488 | } | |
489 | ||
490 | return DONE; | |
491 | } | |
492 | ||
493 | /* \f */ | |
494 | ||
495 | #define RMASK \ | |
496 | "\020\01HALFDUPLEX\02DUPLEX\03EXPEDITED\04MINORSYNC\05MAJORSYNC\06RESYNC\ | |
497 | \07ACTIVITY\010NEGOTIATED\011CAPABILITY\012EXCEPTIONS\013TYPEDATA" | |
498 | ||
499 | ||
500 | static int psapd (is, si) | |
501 | register struct isoservent *is; | |
502 | register struct SSAPindication *si; | |
503 | { | |
504 | struct SSAPstart sss; | |
505 | register struct SSAPstart *ss = &sss; | |
506 | struct PSAPindication pis; | |
507 | register struct PSAPabort *pa = &pis.pi_abort; | |
508 | struct RtSAPindication rtis; | |
509 | register struct RtSAPabort *rta = &rtis.rti_abort; | |
510 | struct RoSAPindication rois; | |
511 | register struct RoSAPpreject *rop = &rois.roi_preject; | |
512 | ||
513 | if (strcmp (is -> is_provider, "ssap")) | |
514 | return OK; | |
515 | ||
516 | if (strcmp (is -> is_entity, "presentation") | |
517 | && strcmp (is -> is_entity, "rts") | |
518 | && strcmp (is -> is_entity, "ros")) | |
519 | return OK; | |
520 | ||
521 | /* begin UGLY */ | |
522 | (void) strcpy (buffer1, *(is -> is_tail - 2)); | |
523 | (void) strcpy (buffer2, *(is -> is_tail - 1)); | |
524 | /* end UGLY */ | |
525 | if (SInit (is -> is_tail - is -> is_vec, is -> is_vec, ss, si) == NOTOK) | |
526 | return NOTOK; | |
527 | advise (LLOG_NOTICE, NULLCP, | |
528 | "S-CONNECT.INDICATION: <%d, %s, %s, %s, %s, %ld, %d>", | |
529 | ss -> ss_sd, sprintref (&ss -> ss_connect), | |
530 | saddr2str (&ss -> ss_calling), saddr2str (&ss -> ss_called), | |
531 | sprintb (ss -> ss_requirements, RMASK), ss -> ss_isn, | |
532 | ss -> ss_ssdusize); | |
533 | ||
534 | if (strcmp (is -> is_entity, "presentation") == 0) { | |
535 | if (PExec (ss, &pis, buffer1, buffer2, NULLIFP, setperms) == NOTOK) { | |
536 | advise (LLOG_EXCEPTIONS, NULLCP, | |
537 | "service not started at psap: %s", | |
538 | PErrString (pa -> pa_reason)); | |
539 | if (pa -> pa_cc > 0) | |
540 | advise (LLOG_EXCEPTIONS, NULLCP, " %*.*s", | |
541 | pa -> pa_cc, pa -> pa_cc, pa -> pa_data); | |
542 | } | |
543 | ||
544 | return DONE; | |
545 | } | |
546 | ||
547 | if (strcmp (is -> is_entity, "rts") == 0) { | |
548 | if (RtExec (ss, &rtis, buffer1, buffer2, NULLIFP, setperms) == NOTOK) { | |
549 | advise (LLOG_EXCEPTIONS, NULLCP, | |
550 | "service not started at rtsap: %s", | |
551 | RtErrString (rta -> rta_reason)); | |
552 | if (rta -> rta_cc > 0) | |
553 | advise (LLOG_EXCEPTIONS, NULLCP, " %*.*s", | |
554 | rta -> rta_cc, rta -> rta_cc, rta -> rta_data); | |
555 | } | |
556 | } | |
557 | else { | |
558 | if (RoExec (ss, &rois, buffer1, buffer2, NULLIFP, setperms) == NOTOK) { | |
559 | advise (LLOG_EXCEPTIONS, NULLCP, | |
560 | "service not started at rosap: %s", | |
561 | RoErrString (rop -> rop_reason)); | |
562 | if (rop -> rop_cc > 0) | |
563 | advise (LLOG_EXCEPTIONS, NULLCP, " %*.*s", | |
564 | rop -> rop_cc, rop -> rop_cc, rop -> rop_data); | |
565 | } | |
566 | } | |
567 | ||
568 | return DONE; | |
569 | } | |
570 | #endif | |
571 | ||
572 | /* \f */ | |
573 | ||
574 | #ifndef IAE | |
575 | static arginit (vec) | |
576 | char **vec; | |
577 | { | |
578 | int rflag; | |
579 | register char *ap; | |
580 | #ifdef TCP | |
581 | int port; | |
582 | struct NSAPaddr *tcp_na; | |
583 | register struct servent *sp; | |
584 | #endif | |
585 | #ifdef X25 | |
586 | struct NSAPaddr *x25_na; | |
587 | #endif | |
588 | #ifdef BRIDGE_X25 | |
589 | struct NSAPaddr *bridge_na; | |
590 | #endif | |
591 | #ifdef TP4 | |
592 | register struct isoservent *is; | |
593 | #endif | |
594 | struct stat st; | |
595 | ||
596 | if (pgmname = rindex (*vec, '/')) | |
597 | pgmname++; | |
598 | if (pgmname == NULL || *pgmname == NULL) | |
599 | pgmname = *vec; | |
600 | ||
601 | isodetailor (pgmname, 0); | |
602 | ll_hdinit (pgm_log, pgmname); | |
603 | ||
604 | rflag = 0; | |
605 | ||
606 | (void) strcpy (myhost, TLocalHostName ()); | |
607 | ||
608 | bzero ((char *) tas, sizeof tas); | |
609 | tz = tas; | |
610 | ||
611 | #ifdef TCP | |
612 | if (!(ts_stacks & TS_TCP)) | |
613 | tcpservice = 0; | |
614 | if ((sp = getservbyname ("tsap", "tcp")) == NULL | |
615 | && (sp = getservbyname ("iso-tsap", "tcp")) == NULL) | |
616 | advise (LLOG_EXCEPTIONS, NULLCP, "tcp/tsap: unknown service"); | |
617 | ||
618 | tcp_na = tz -> ta_addrs; | |
619 | tcp_na -> na_stack = NA_TCP; | |
620 | tcp_na -> na_community = ts_comm_tcp_default; | |
621 | tcp_na -> na_domain[0] = NULL; | |
622 | tcp_na -> na_port = sp ? sp -> s_port : htons ((u_short) 102); | |
623 | tz -> ta_naddr = 1; | |
624 | ||
625 | tz++; | |
626 | #endif | |
627 | ||
628 | #ifdef X25 | |
629 | if (!(ts_stacks & TS_X25)) | |
630 | x25service = 0; | |
631 | ||
632 | x25_na = tz -> ta_addrs; | |
633 | x25_na -> na_stack = NA_X25; | |
634 | x25_na -> na_community = ts_comm_x25_default; | |
635 | if (x25_local_dte && *x25_local_dte) { | |
636 | (void) strcpy (x25_na -> na_dte, x25_local_dte); | |
637 | x25_na -> na_dtelen = strlen (x25_na -> na_dte); | |
638 | } | |
639 | if (x25_local_pid && *x25_local_pid) | |
640 | x25_na -> na_pidlen = | |
641 | str2sel (x25_local_pid, -1, x25_na -> na_pid, NPSIZE); | |
642 | tz -> ta_naddr = 1; | |
643 | ||
644 | tz++; | |
645 | #endif | |
646 | ||
647 | #ifdef BRIDGE_X25 | |
648 | if (!(ts_stacks & TS_BRG)) | |
649 | bridgeservice = 0; | |
650 | ||
651 | bridge_na = tz -> ta_addrs; | |
652 | bridge_na -> na_stack = NA_BRG; | |
653 | bridge_na -> na_community = ts_comm_x25_default; | |
654 | if (x25_bridge_listen && *x25_bridge_listen) { | |
655 | (void) strcpy (bridge_na -> na_dte, x25_bridge_listen); | |
656 | bridge_na -> na_dtelen = strlen (bridge_na -> na_dte); | |
657 | } | |
658 | if (x25_bridge_pid && *x25_bridge_pid) | |
659 | bridge_na -> na_pidlen = | |
660 | str2sel (x25_bridge_pid, -1, bridge_na -> na_pid, NPSIZE); | |
661 | tz -> ta_naddr = 1; | |
662 | ||
663 | tz++; | |
664 | #endif | |
665 | ||
666 | #ifdef TP4 | |
667 | if (!(ts_stacks & TS_TP4)) | |
668 | tp4service = 0; | |
669 | ||
670 | (void) setisoservent (0); | |
671 | while (is = getisoservent ()) | |
672 | if (strcmp (is -> is_provider, "tsap") == 0 | |
673 | && (strcmp (*is -> is_vec, "tsapd-bootstrap") == 0 | |
674 | || access (*is -> is_vec, X_OK) != NOTOK)) { | |
675 | if (strcmp (is -> is_entity, "isore") == 0) | |
676 | continue; | |
677 | ||
678 | if (tz >= tas + NTADDRS) { | |
679 | advise (LLOG_EXCEPTIONS, NULLCP, | |
680 | "too many services, starting with %s", | |
681 | is -> is_entity); | |
682 | break; | |
683 | } | |
684 | ||
685 | bcopy (is -> is_selector, tz -> ta_selector, | |
686 | tz -> ta_selectlen = is -> is_selectlen); | |
687 | tz -> ta_naddr = 0; | |
688 | ||
689 | tz++; | |
690 | } | |
691 | (void) endisoservent (); | |
692 | #endif | |
693 | ||
694 | for (vec++; ap = *vec; vec++) { | |
695 | if (*ap == '-') | |
696 | switch (*++ap) { | |
697 | case 'd': | |
698 | debug++; | |
699 | continue; | |
700 | ||
701 | case 't': | |
702 | ts_stacks = TS_TCP; | |
703 | tcpservice = 1; | |
704 | x25service = bridgeservice = tp4service = 0; | |
705 | continue; | |
706 | ||
707 | case 'x': | |
708 | ts_stacks = TS_X25; | |
709 | x25service = 1; | |
710 | tcpservice = bridgeservice = tp4service = 0; | |
711 | continue; | |
712 | ||
713 | case 'z': | |
714 | ts_stacks = TS_TP4; | |
715 | tp4service = 1; | |
716 | tcpservice = x25service = bridgeservice = 0; | |
717 | continue; | |
718 | ||
719 | case 'b': | |
720 | ts_stacks = TS_BRG; | |
721 | bridgeservice = 1; | |
722 | tcpservice = x25service = tp4service = 0; | |
723 | continue; | |
724 | ||
725 | case 'r': | |
726 | rflag = 1; | |
727 | continue; | |
728 | ||
729 | #ifdef TCP | |
730 | case 'p': | |
731 | if ((ap = *++vec) == NULL | |
732 | || *ap == '-' | |
733 | || (port = atoi (ap)) <= 0) | |
734 | adios (NULLCP, "usage: %s -p portno", pgmname); | |
735 | tcp_na -> na_port = htons ((u_short) port); | |
736 | continue; | |
737 | #endif | |
738 | ||
739 | #ifdef X25 | |
740 | /* This permits listening on a specific subaddress. */ | |
741 | case 'a': | |
742 | if ((ap = *++vec) == NULL || *ap == '-') | |
743 | adios (NULLCP, "usage: %s -a x121address", pgmname); | |
744 | (void) strcpy (x25_na -> na_dte, ap); | |
745 | x25_na -> na_dtelen = strlen (ap); | |
746 | continue; | |
747 | ||
748 | /* This permits listening on a specific protocol id. | |
749 | In fact, SunLink X.25 lets you listen on a protocol | |
750 | id mask, but let's keep it simple. */ | |
751 | case 'i': | |
752 | if ((ap = *++vec) == NULL || *ap == '-' ) | |
753 | adios (NULLCP, "usage: %s -i pid", pgmname); | |
754 | x25_na -> na_pidlen = | |
755 | str2sel (ap, -1, x25_na -> na_pid, NPSIZE); | |
756 | continue; | |
757 | #endif | |
758 | ||
759 | #ifdef BRIDGE_X25 | |
760 | case 'A': | |
761 | if ((ap = *++vec) == NULL || | |
762 | *ap == '-') | |
763 | adios (NULLCP, "usage: %s -A x121address", pgmname); | |
764 | (void) strcpy (bridge_na -> na_dte, ap); | |
765 | bridge_na -> na_dtelen = strlen (ap); | |
766 | continue; | |
767 | ||
768 | case 'I': | |
769 | if ((ap = *++vec) == NULL || *ap == '-') | |
770 | adios (NULLCP, "usage: %s -I pid", pgmname); | |
771 | bridge_na -> na_pidlen = | |
772 | str2sel (ap, -1, bridge_na -> na_pid, NPSIZE); | |
773 | continue; | |
774 | #endif | |
775 | ||
776 | default: | |
777 | adios (NULLCP, "-%s: unknown switch", ap); | |
778 | } | |
779 | ||
780 | adios (NULLCP, "usage: %s [switches]", pgmname); | |
781 | } | |
782 | ||
783 | if (!rflag | |
784 | && getuid () == 0 | |
785 | && stat (ap = isodefile ("isoservices", 0), &st) != NOTOK | |
786 | && st.st_uid != 0) | |
787 | adios (NULLCP, "%s not owned by root", ap); | |
788 | } | |
789 | ||
790 | /* \f */ | |
791 | ||
792 | #else | |
793 | static arginit (vec) | |
794 | char **vec; | |
795 | { | |
796 | int argp, | |
797 | options; | |
798 | register char *ap; | |
799 | char base[BUFSIZ], | |
800 | **argptr, | |
801 | *args[4]; | |
802 | ||
803 | if (pgmname = rindex (*vec, '/')) | |
804 | pgmname++; | |
805 | if (pgmname == NULL || *pgmname == NULL) | |
806 | pgmname = *vec; | |
807 | ||
808 | isodetailor (pgmname, 0); | |
809 | ll_hdinit (pgm_log, pgmname); | |
810 | ||
811 | quipu_syntaxes (); | |
812 | ||
813 | argp = 0; | |
814 | args[argp++] = pgmname; | |
815 | for (argptr = vec, argptr++; ap = *argptr; argptr++) { | |
816 | if (*ap == '-') | |
817 | switch (*++ap) { | |
818 | case 'D': | |
819 | case 'u': | |
820 | case 'p': | |
821 | if ((ap = *++argptr) == NULL || *ap == '-') | |
822 | break; | |
823 | continue; | |
824 | ||
825 | case 'c': | |
826 | if ((ap = *++argptr) == NULL || *ap == '-') | |
827 | break; | |
828 | args[argp++] = "-c"; | |
829 | args[argp++] = ap; | |
830 | break; | |
831 | ||
832 | default: | |
833 | continue; | |
834 | } | |
835 | ||
836 | break; | |
837 | } | |
838 | args[argp] = NULLCP; | |
839 | ||
840 | dsap_init (&argp, (argptr = args, &argptr)); | |
841 | ||
842 | (void) strcpy (myhost, TLocalHostName ()); | |
843 | (void) strcpy (base, local_dit); | |
844 | ||
845 | if (!(ts_stacks & TS_TCP)) | |
846 | tcpservice = 0; | |
847 | if (!(ts_stacks & TS_X25)) | |
848 | x25service = 0; | |
849 | if (!(ts_stacks & TS_BRG)) | |
850 | bridgeservice = 0; | |
851 | if (!(ts_stacks & TS_TP4)) | |
852 | tp4service = 0; | |
853 | ||
854 | options = SVC_OPT_PREFERCHAIN; | |
855 | userdn = NULLDN, passwd[0] = NULL; | |
856 | for (vec++; ap = *vec; vec++) { | |
857 | if (*ap == '-') | |
858 | switch (*++ap) { | |
859 | case 'd': | |
860 | debug++; | |
861 | ll_dbinit (pgm_log, pgmname); | |
862 | continue; | |
863 | ||
864 | case 't': | |
865 | ts_stacks = TS_TCP; | |
866 | tcpservice = 1; | |
867 | x25service = bridgeservice = tp4service = 0; | |
868 | continue; | |
869 | ||
870 | case 'x': | |
871 | ts_stacks = TS_X25; | |
872 | x25service = 1; | |
873 | tcpservice = bridgeservice = tp4service = 0; | |
874 | continue; | |
875 | ||
876 | case 'z': | |
877 | ts_stacks = TS_TP4; | |
878 | tp4service = 1; | |
879 | tcpservice = x25service = bridgeservice = 0; | |
880 | continue; | |
881 | ||
882 | case 'b': | |
883 | ts_stacks = TS_BRG; | |
884 | bridgeservice = 1; | |
885 | tcpservice = x25service = tp4service = 0; | |
886 | continue; | |
887 | ||
888 | case 'r': /* ignored... */ | |
889 | continue; | |
890 | ||
891 | case 'D': | |
892 | if ((ap = *++vec) == NULL || *ap == '-') | |
893 | adios (NULLCP, "usage: %s -D DIT", pgmname); | |
894 | if (*ap == '@') | |
895 | (void) strcpy (base, ap); | |
896 | else | |
897 | (void) sprintf (base, "%s@%s", local_dit, ap); | |
898 | continue; | |
899 | ||
900 | case 'm': | |
901 | options |= SVC_OPT_DONTUSECOPY; | |
902 | continue; | |
903 | ||
904 | case 'c': | |
905 | if ((ap = *++vec) == NULL || *ap == '-') | |
906 | adios (NULLCP, "usage: %s -c DSA-name-or-address", | |
907 | pgmname); | |
908 | continue; | |
909 | ||
910 | case 'u': | |
911 | if ((ap = *++vec) == NULL || *ap == '-') | |
912 | adios (NULLCP, "usage: %s -u username", pgmname); | |
913 | if ((userdn = str2dn (*ap != '@' ? ap : ap + 1)) == NULLDN) | |
914 | adios (NULLCP, "invalid DN for username: %s", ap); | |
915 | bzero ((char *) ap, strlen (ap)); | |
916 | continue; | |
917 | ||
918 | case 'p': | |
919 | if ((ap = *++vec) == NULL || *ap == '-') | |
920 | adios (NULLCP, "usage: %s -p password", pgmname); | |
921 | (void) strcpy (passwd, ap); | |
922 | bzero ((char *) ap, strlen (ap)); | |
923 | continue; | |
924 | ||
925 | default: | |
926 | adios (NULLCP, "-%s: unknown switch", ap); | |
927 | } | |
928 | ||
929 | adios (NULLCP, "usage: %s [switches]", pgmname); | |
930 | } | |
931 | ||
932 | { | |
933 | Attr_Sequence as; | |
934 | AttributeType t_oc; | |
935 | DN local_dn; | |
936 | register Filter fi; | |
937 | register struct ds_search_arg *sa = &search_arg; | |
938 | ||
939 | if ((t_ev = str2AttrT ("execVector")) == NULL) | |
940 | adios (NULLCP, "unknown attribute type \"%s\"", "execVector"); | |
941 | if ((t_oc = str2AttrT ("objectClass")) == NULL) | |
942 | adios (NULLCP, "unknown attribute type \"%s\"", "objectClass"); | |
943 | if ((t_pa = str2AttrT ("presentationAddress")) == NULL) | |
944 | adios (NULLCP, "unknown attribute type \"%s\"", | |
945 | "presentationAddress"); | |
946 | ||
947 | if (str2dnY (*base != '@' ? base : base + 1, &local_dn) == NOTOK) | |
948 | adios (NULLCP, "DIT subtree invalid: \"%s\"", base); | |
949 | ||
950 | fi = filter_alloc (); | |
951 | bzero ((char *) fi, sizeof *fi); | |
952 | ||
953 | fi -> flt_type = FILTER_ITEM; | |
954 | fi -> FUITEM.fi_type = FILTERITEM_EQUALITY; | |
955 | fi -> FUITEM.UNAVA.ava_type = AttrT_cpy (t_oc); | |
956 | if ((fi -> FUITEM.UNAVA.ava_value = | |
957 | str2AttrV ("iSODEApplicationEntity", | |
958 | fi -> FUITEM.UNAVA.ava_type -> oa_syntax)) | |
959 | == NULL) | |
960 | adios (NULLCP, "unknown attribute value \"%s\" for \"%s\"", | |
961 | "iSODEApplicationEntity", "objectClass"); | |
962 | ||
963 | as = as_merge (as_comp_new (AttrT_cpy (t_ev), NULLAV, NULLACL_INFO), | |
964 | as_comp_new (AttrT_cpy (t_pa), NULLAV, NULLACL_INFO)); | |
965 | ||
966 | bzero ((char *) sa, sizeof *sa); | |
967 | ||
968 | sa -> sra_common.ca_servicecontrol.svc_options = options; | |
969 | sa -> sra_common.ca_servicecontrol.svc_timelimit = SVC_NOTIMELIMIT; | |
970 | sa -> sra_common.ca_servicecontrol.svc_sizelimit = SVC_NOSIZELIMIT; | |
971 | sa -> sra_baseobject = local_dn; | |
972 | sa -> sra_subset = SRA_WHOLESUBTREE; | |
973 | sa -> sra_filter = fi; | |
974 | sa -> sra_searchaliases = TRUE; | |
975 | sa -> sra_eis.eis_allattributes = FALSE; | |
976 | sa -> sra_eis.eis_select = as; | |
977 | sa -> sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES; | |
978 | ||
979 | search_directory (1); | |
980 | } | |
981 | } | |
982 | ||
983 | /* \f */ | |
984 | ||
985 | static search_directory (firstime) | |
986 | int firstime; | |
987 | { | |
988 | int i; | |
989 | register struct ds_search_arg *sa = &search_arg; | |
990 | struct ds_search_result search_result; | |
991 | register struct ds_search_result *sr = &search_result; | |
992 | struct DSError error; | |
993 | register struct DSError *se = &error; | |
994 | register EntryInfo *ptr; | |
995 | register struct IAEntry *ia; | |
996 | register struct TSAPaddr *ta, | |
997 | *tb, | |
998 | *ty; | |
999 | struct TSAPaddr tys[NTADDRS]; | |
1000 | ||
1001 | advise (LLOG_NOTICE, NULLCP, | |
1002 | "searching directory for iSODEApplicationEntity objects"); | |
1003 | ||
1004 | while (rebind_to_directory () == NOTOK) { | |
1005 | if (!firstime) | |
1006 | return; | |
1007 | ||
1008 | if (debug) | |
1009 | advise (LLOG_DEBUG, NULLCP, "sleeping for 5 minutes..."); | |
1010 | sleep ((unsigned) 5 * 60); | |
1011 | } | |
1012 | ||
1013 | for (;;) { | |
1014 | if (debug) { | |
1015 | pslog (pgm_log, LLOG_DEBUG, "performing subtree search of", | |
1016 | dn_print, (caddr_t) sa -> sra_baseobject); | |
1017 | pslog (pgm_log, LLOG_DEBUG, " for", fi_print, | |
1018 | (caddr_t) sa -> sra_filter); | |
1019 | } | |
1020 | ||
1021 | if (ds_search (sa, se, sr) == DS_OK) | |
1022 | break; | |
1023 | if (do_error (se) == NOTOK) { | |
1024 | if (!firstime) | |
1025 | return; | |
1026 | ||
1027 | adios (NULLCP, "search failed"); | |
1028 | } | |
1029 | ||
1030 | sa -> sra_baseobject = | |
1031 | se -> ERR_REFERRAL.DSE_ref_candidates -> cr_name; | |
1032 | } | |
1033 | ||
1034 | if (sr -> srr_correlated != TRUE) | |
1035 | correlate_search_results (sr); | |
1036 | ||
1037 | if (!firstime) | |
1038 | for (ia = iae; ia < iz; ia++) { | |
1039 | free (ia -> is_vector); | |
1040 | free (ia -> is_vec[0]); | |
1041 | free ((char *) ia -> is_vec); | |
1042 | } | |
1043 | ||
1044 | bzero ((char *) iae, sizeof iae); | |
1045 | iz = iae; | |
1046 | ||
1047 | bzero ((char *) tys, sizeof tys); | |
1048 | ty = tys; | |
1049 | ||
1050 | i = 0; | |
1051 | for (ptr = sr -> CSR_entries; ptr; ptr = ptr -> ent_next) { | |
1052 | Attr_Sequence eptr; | |
1053 | AV_Sequence avs; | |
1054 | ||
1055 | if (iz >= iae + NENTRIES) { | |
1056 | pslog (pgm_log, LLOG_EXCEPTIONS, | |
1057 | "too many services, starting with", dn_print, | |
1058 | (caddr_t) ptr -> ent_dn); | |
1059 | break; | |
1060 | } | |
1061 | ||
1062 | if (debug) { | |
1063 | pslog (pgm_log, LLOG_DEBUG, "processing", dn_print, | |
1064 | (caddr_t) ptr -> ent_dn); | |
1065 | pslog (pgm_log, LLOG_DEBUG, " attributes", as_print, | |
1066 | (caddr_t) ptr -> ent_attr); | |
1067 | } | |
1068 | ||
1069 | for (eptr = ptr -> ent_attr; eptr; eptr = eptr -> attr_link) { | |
1070 | if (AttrT_cmp (eptr -> attr_type, t_pa) == 0) { | |
1071 | if (avs = eptr -> attr_value) { | |
1072 | register struct PSAPaddr *pa = | |
1073 | (struct PSAPaddr *) avs -> avseq_av.av_struct; | |
1074 | ||
1075 | if ((ta = &pa -> pa_addr.sa_addr) -> ta_selectlen == 0 | |
1076 | || pa -> pa_selectlen > 0 | |
1077 | || pa -> pa_addr.sa_selectlen > 0) | |
1078 | continue; | |
1079 | ||
1080 | iz -> is_addr = *ta; /* struct copy */ | |
1081 | } | |
1082 | ||
1083 | continue; | |
1084 | } | |
1085 | ||
1086 | if (AttrT_cmp (eptr -> attr_type, t_ev) == 0) { | |
1087 | if (avs = eptr -> attr_value) { | |
1088 | int vecp; | |
1089 | register char **vp; | |
1090 | char *cp, | |
1091 | *evec[NVEC + NSLACK + 1]; | |
1092 | ||
1093 | cp = (char *) avs -> avseq_av.av_struct; | |
1094 | if ((iz -> is_vector = | |
1095 | malloc ((unsigned) (strlen (cp) + 1))) | |
1096 | == NULL) | |
1097 | adios (NULLCP, "out of memory allocating iaeVector"); | |
1098 | (void) strcpy (iz -> is_vector, cp); | |
1099 | ||
1100 | if ((vecp = str2vec (iz -> is_vector, evec)) < 1) | |
1101 | goto losing_iae; | |
1102 | if ((iz -> is_vec = | |
1103 | (char **) calloc ((unsigned) (vecp + 3), | |
1104 | sizeof *iz -> is_vec)) | |
1105 | == NULL) | |
1106 | adios (NULLCP, "out of memory allocating execVector"); | |
1107 | iz -> is_tail = iz -> is_vec, vp = evec; | |
1108 | while (*iz -> is_tail++ = *vp++) | |
1109 | continue; | |
1110 | iz -> is_tail--; | |
1111 | ||
1112 | if (access (cp = isodefile (iz -> is_vec[0], 1), X_OK) | |
1113 | == NOTOK) { | |
1114 | advise (LLOG_EXCEPTIONS, cp, "unable to find program"); | |
1115 | iz -> is_vec[0] = NULL; | |
1116 | goto losing_iae; | |
1117 | } | |
1118 | if ((iz -> is_vec[0] = | |
1119 | malloc ((unsigned) (strlen (cp) + 1))) | |
1120 | == NULL) | |
1121 | adios (NULLCP, "out of memory allocating pgmVector"); | |
1122 | (void) strcpy (iz -> is_vec[0], cp); | |
1123 | } | |
1124 | continue; | |
1125 | } | |
1126 | } | |
1127 | if ((ta = &iz -> is_addr) -> ta_selectlen == 0 | |
1128 | || iz -> is_vector == NULL) { | |
1129 | pslog (pgm_log, LLOG_EXCEPTIONS, "invalid entry", dn_print, | |
1130 | (caddr_t) ptr -> ent_dn); | |
1131 | ||
1132 | losing_iae: ; | |
1133 | if (iz -> is_vector) | |
1134 | free (iz -> is_vector); | |
1135 | if (iz -> is_vec) { | |
1136 | if (iz -> is_vec[0]) | |
1137 | free (iz -> is_vec[0]); | |
1138 | free ((char *) iz -> is_vec); | |
1139 | } | |
1140 | bzero ((char *) iz, sizeof *iz); | |
1141 | continue; | |
1142 | } | |
1143 | ||
1144 | if (ta -> ta_naddr == 0) | |
1145 | *ty++ = *ta; /* struct copy */ | |
1146 | else { | |
1147 | register int n = ta -> ta_naddr; | |
1148 | register struct NSAPaddr *na = ta -> ta_addrs; | |
1149 | ||
1150 | for (; n > 0; na++, n--) { | |
1151 | for (tb = tys; tb < ty; tb++) | |
1152 | if (tb -> ta_naddr != 0 | |
1153 | && bcmp ((char *) na, (char *) tb -> ta_addrs, | |
1154 | sizeof *na) == 0) | |
1155 | break; | |
1156 | if (tb >= ty) { | |
1157 | if (na -> na_type == NA_NSAP) | |
1158 | bcopy (ta -> ta_selector, ty -> ta_selector, | |
1159 | ty -> ta_selectlen = ta -> ta_selectlen); | |
1160 | else | |
1161 | ty -> ta_selectlen = 0; | |
1162 | ty -> ta_naddr = 1; | |
1163 | ty -> ta_addrs[0] = *na; /* struct copy */ | |
1164 | ||
1165 | ty++; | |
1166 | } | |
1167 | } | |
1168 | } | |
1169 | ||
1170 | for (ia = iae; ia < iz; ia++) { | |
1171 | tb = &ia -> is_addr; | |
1172 | ||
1173 | if (ta -> ta_selectlen == tb -> ta_selectlen | |
1174 | && bcmp (ta -> ta_selector, tb -> ta_selector, | |
1175 | ta -> ta_selectlen) == 0) { | |
1176 | char buffer[BUFSIZ]; | |
1177 | ||
1178 | (void) strcpy (buffer, taddr2str (tb)); | |
1179 | advise (LLOG_EXCEPTIONS, NULLCP, | |
1180 | "two services with the same transport selector: %s and %s", | |
1181 | buffer, taddr2str (ta)); | |
1182 | pslog (pgm_log, LLOG_EXCEPTIONS, "starting with", dn_print, | |
1183 | (caddr_t) ptr -> ent_dn); | |
1184 | adios (NULLCP, "you lose big"); | |
1185 | } | |
1186 | } | |
1187 | ||
1188 | iz++, i++; | |
1189 | } | |
1190 | ||
1191 | if (sr -> CSR_cr) { | |
1192 | advise (LLOG_EXCEPTIONS, NULLCP, | |
1193 | "partial results only (not all DSAs could be reached)"); | |
1194 | } | |
1195 | else | |
1196 | if (sr -> CSR_limitproblem != LSR_NOLIMITPROBLEM) { | |
1197 | advise (LLOG_EXCEPTIONS, NULLCP, "%s limit exceeded", | |
1198 | sr -> CSR_limitproblem == LSR_TIMELIMITEXCEEDED | |
1199 | ? "time" | |
1200 | : sr -> CSR_limitproblem == LSR_SIZELIMITEXCEEDED | |
1201 | ? "size" : "administrative"); | |
1202 | } | |
1203 | ||
1204 | if (i == 0) | |
1205 | adios (NULLCP, "search failed to find anything"); | |
1206 | else | |
1207 | if (debug) | |
1208 | advise (LLOG_DEBUG, NULLCP, "%d match%s found", | |
1209 | i, i != 1 ? "es" : ""); | |
1210 | ||
1211 | dn_free (sr -> CSR_object); | |
1212 | entryinfo_free (sr -> CSR_entries, 0); | |
1213 | crefs_free (sr -> CSR_cr); | |
1214 | ||
1215 | (void) unbind_from_directory (); | |
1216 | ||
1217 | if (!firstime) { | |
1218 | int failed = 0; | |
1219 | struct TSAPdisconnect tds; | |
1220 | ||
1221 | for (ta = tas; ta < tz; ta++) { | |
1222 | for (tb = tys; tb < ty; tb++) | |
1223 | if (bcmp ((char *) ta, (char *) tb, sizeof *ta) == 0) | |
1224 | break; | |
1225 | if (tb >= ty) { | |
1226 | advise (LLOG_NOTICE, NULLCP, "closing %s", taddr2str (ta)); | |
1227 | ||
1228 | if (TNetClose (ta, &tds) == NOTOK) | |
1229 | ts_advise (&tds, LLOG_EXCEPTIONS, "TNetClose failed"); | |
1230 | ||
1231 | listening--; | |
1232 | } | |
1233 | } | |
1234 | ||
1235 | for (ta = tys; ta < ty; ta++) { | |
1236 | for (tb = tas; tb < tz; tb++) | |
1237 | if (bcmp ((char *) ta, (char *) tb, sizeof *ta) == 0) | |
1238 | break; | |
1239 | if (tb >= tz) { | |
1240 | register struct NSAPaddr *na; | |
1241 | ||
1242 | if (ta -> ta_naddr) { | |
1243 | if (((na = ta -> ta_addrs) -> na_stack < 0 | |
1244 | || na -> na_stack | |
1245 | >= sizeof services / sizeof services[0])) | |
1246 | adios (NULLCP, "unknown network type 0x%x", | |
1247 | na -> na_stack); | |
1248 | } | |
1249 | else | |
1250 | na = NULLNA; | |
1251 | ||
1252 | if (!*services[na ? na -> na_stack : NA_NSAP]) | |
1253 | continue; | |
1254 | ||
1255 | advise (LLOG_NOTICE, NULLCP, "listening on %s", | |
1256 | taddr2str (ta)); | |
1257 | ||
1258 | if (TNetListen (ta, &tds) == NOTOK) { | |
1259 | ts_advise (&tds, LLOG_EXCEPTIONS, "TNetListen failed"); | |
1260 | failed++; | |
1261 | } | |
1262 | else | |
1263 | listening++; | |
1264 | } | |
1265 | } | |
1266 | ||
1267 | if (!listening) | |
1268 | adios (NULLCP, failed ? "no successful listens" | |
1269 | : "no network services selected"); | |
1270 | ||
1271 | } | |
1272 | bzero ((char *) tas, sizeof tas); | |
1273 | tz = tas; | |
1274 | ||
1275 | for (ta = tys; ta < ty; *tz++ = *ta++) /* struct copy */ | |
1276 | continue; | |
1277 | ||
1278 | if (debug) { | |
1279 | advise (LLOG_DEBUG, NULLCP, "application entitites..."); | |
1280 | for (ia = iae; ia < iz; ia++) | |
1281 | advise (LLOG_DEBUG, NULLCP, " addr=%s vector=%s", | |
1282 | taddr2str (&ia -> is_addr), ia -> is_vector); | |
1283 | ||
1284 | advise (LLOG_DEBUG, NULLCP, "transport addresses..."); | |
1285 | for (ta = tas; ta < tz; ta++) | |
1286 | advise (LLOG_DEBUG, NULLCP, " addr=%s", taddr2str (ta)); | |
1287 | } | |
1288 | ||
1289 | (void) time (&nextime); | |
1290 | nextime += IAETIME; | |
1291 | } | |
1292 | ||
1293 | /* \f */ | |
1294 | ||
1295 | static bind_to_directory () | |
1296 | { | |
1297 | struct ds_bind_arg bind_arg, | |
1298 | bind_result; | |
1299 | register struct ds_bind_arg *ba = &bind_arg, | |
1300 | *br = &bind_result; | |
1301 | struct ds_bind_error bind_error; | |
1302 | register struct ds_bind_error *be = &bind_error; | |
1303 | static int very_first_time = 1; | |
1304 | ||
1305 | (void) unbind_from_directory (); | |
1306 | ||
1307 | make_bind_args (ba, br, be); | |
1308 | ||
1309 | if (debug) | |
1310 | advise (LLOG_DEBUG, NULLCP, "connecting to DSA..."); | |
1311 | ||
1312 | if (secure_ds_bind (ba, be, br) != DS_OK) { | |
1313 | if (very_first_time) | |
1314 | very_first_time = 0; | |
1315 | else | |
1316 | advise (LLOG_EXCEPTIONS, NULLCP, "unable to connect: %s", | |
1317 | be -> dbe_type == DBE_TYPE_SECURITY ? "security error" | |
1318 | : "DSA unavailable"); | |
1319 | ||
1320 | isbound = 0; | |
1321 | ||
1322 | return; | |
1323 | } | |
1324 | very_first_time = 0; | |
1325 | dn_free (br -> dba_dn); | |
1326 | ||
1327 | main_dsa = dsap_ad; | |
1328 | ||
1329 | advise (LLOG_NOTICE, NULLCP, "connected to %s", pa2str (&dsa_bound)); | |
1330 | ||
1331 | isbound = 1; | |
1332 | } | |
1333 | ||
1334 | /* \f */ | |
1335 | ||
1336 | static int rebind_to_directory () | |
1337 | { | |
1338 | if (referral_dsa != NOTOK) { | |
1339 | if (debug) | |
1340 | advise (LLOG_DEBUG, NULLCP, "dap_unbind from referral dsa"); | |
1341 | ||
1342 | (void) dap_unbind (referral_dsa); | |
1343 | referral_dsa = NOTOK; | |
1344 | dsap_ad = main_dsa; | |
1345 | } | |
1346 | ||
1347 | if (!isbound) | |
1348 | (void) bind_to_directory (); | |
1349 | ||
1350 | return (isbound ? OK : NOTOK); | |
1351 | } | |
1352 | ||
1353 | /* \f */ | |
1354 | ||
1355 | static int make_bind_args (ba, br, be) | |
1356 | register struct ds_bind_arg *ba, | |
1357 | *br; | |
1358 | register struct ds_bind_error *be; | |
1359 | { | |
1360 | bzero ((char *) ba, sizeof *ba); | |
1361 | bzero ((char *) br, sizeof *br); | |
1362 | bzero ((char *) be, sizeof *be); | |
1363 | ||
1364 | ba -> dba_version = DBA_VERSION_V1988; | |
1365 | if (ba -> dba_dn = userdn) | |
1366 | ba -> dba_auth_type = DBA_AUTH_SIMPLE; | |
1367 | if (ba -> dba_passwd_len = strlen (passwd)) | |
1368 | (void) strcpy (ba -> dba_passwd, passwd); | |
1369 | } | |
1370 | ||
1371 | /* \f */ | |
1372 | ||
1373 | static int unbind_from_directory () | |
1374 | { | |
1375 | int wasbound; | |
1376 | ||
1377 | if (wasbound = isbound) { | |
1378 | if (referral_dsa != NOTOK) { | |
1379 | if (debug) | |
1380 | advise (LLOG_DEBUG, NULLCP, "dap_unbind from referral dsa"); | |
1381 | ||
1382 | (void) dap_unbind (referral_dsa); | |
1383 | referral_dsa = NOTOK; | |
1384 | dsap_ad = main_dsa; | |
1385 | } | |
1386 | ||
1387 | (void) ds_unbind (); | |
1388 | isbound = 0; | |
1389 | } | |
1390 | ||
1391 | dsa_dead = 0; | |
1392 | ||
1393 | return wasbound; | |
1394 | } | |
1395 | ||
1396 | /* \f */ | |
1397 | ||
1398 | static int do_error (de) | |
1399 | register struct DSError *de; | |
1400 | { | |
1401 | if (de -> dse_type == DSE_REFERRAL | |
1402 | && de -> ERR_REFERRAL.DSE_ref_candidates) { | |
1403 | register struct access_point *ap; | |
1404 | struct ds_bind_arg bind_arg, | |
1405 | bind_result; | |
1406 | register struct ds_bind_arg *ba = &bind_arg, | |
1407 | *br = &bind_result; | |
1408 | struct ds_bind_error bind_error; | |
1409 | register struct ds_bind_error *be = &bind_error; | |
1410 | ||
1411 | ap = de -> ERR_REFERRAL.DSE_ref_candidates -> cr_accesspoints; | |
1412 | ||
1413 | if (referral_dsa != NOTOK) { | |
1414 | if (debug) | |
1415 | advise (LLOG_DEBUG, NULLCP, "dap_unbind from referral dsa"); | |
1416 | ||
1417 | (void) dap_unbind (referral_dsa); | |
1418 | referral_dsa = NOTOK; | |
1419 | dsap_ad = main_dsa; | |
1420 | } | |
1421 | ||
1422 | make_bind_args (ba, br, be); | |
1423 | ||
1424 | pslog (pgm_log, LLOG_NOTICE, "referring to", dn_print, | |
1425 | (caddr_t) ap -> ap_name); | |
1426 | ||
1427 | if (dap_bind (&referral_dsa, ba, be, br, ap -> ap_address) != DS_OK) { | |
1428 | advise (LLOG_EXCEPTIONS, NULLCP, "unable to connect: %s", | |
1429 | be -> dbe_type == DBE_TYPE_SECURITY ? "security error" | |
1430 | : "DSA unavailable"); | |
1431 | ||
1432 | dsap_ad = main_dsa; | |
1433 | ||
1434 | ds_error_free (de); | |
1435 | return NOTOK; | |
1436 | } | |
1437 | dsap_ad = referral_dsa; | |
1438 | ||
1439 | if (debug) | |
1440 | advise (LLOG_DEBUG, NULLCP, "referral in progress"); | |
1441 | ||
1442 | ds_error_free (de); | |
1443 | return OK; | |
1444 | } | |
1445 | ||
1446 | pslog (pgm_log, LLOG_EXCEPTIONS, "DAP error:", de_print, (caddr_t) de); | |
1447 | ||
1448 | if (dsa_dead) { | |
1449 | dsa_dead = 0; | |
1450 | ||
1451 | if (referral_dsa != NOTOK) { | |
1452 | if (debug) | |
1453 | advise (LLOG_DEBUG, NULLCP, "dap_unbind from referral dsa"); | |
1454 | ||
1455 | (void) dap_unbind (referral_dsa); | |
1456 | referral_dsa = NOTOK; | |
1457 | dsap_ad = main_dsa; | |
1458 | } | |
1459 | else | |
1460 | (void) unbind_from_directory (); | |
1461 | } | |
1462 | ||
1463 | return NOTOK; | |
1464 | } | |
1465 | ||
1466 | /* \f */ | |
1467 | ||
1468 | int str2dnY (str, dn) | |
1469 | char *str; | |
1470 | DN *dn; | |
1471 | { | |
1472 | if (*str == NULL) { | |
1473 | *dn = NULLDN; | |
1474 | return OK; | |
1475 | } | |
1476 | ||
1477 | return ((*dn = str2dn (str)) != NULLDN ? OK : NOTOK); | |
1478 | } | |
1479 | ||
1480 | /* \f */ | |
1481 | ||
1482 | #ifdef BSD42 | |
1483 | /* ARGSUSED */ | |
1484 | #endif | |
1485 | ||
1486 | static SFD hupser (sig) | |
1487 | int sig; | |
1488 | { | |
1489 | #ifndef BSD42 | |
1490 | (void) signal (sig, hupser); | |
1491 | #endif | |
1492 | ||
1493 | search_directory (0); | |
1494 | } | |
1495 | #endif | |
1496 | ||
1497 | /* \f */ | |
1498 | ||
1499 | static envinit () { | |
1500 | int i, | |
1501 | sd; | |
1502 | ||
1503 | nbits = getdtablesize (); | |
1504 | ||
1505 | if (debug == 0 && !(debug = isatty (2))) { | |
1506 | for (i = 0; i < 5; i++) { | |
1507 | switch (fork ()) { | |
1508 | case NOTOK: | |
1509 | sleep (5); | |
1510 | continue; | |
1511 | ||
1512 | case OK: | |
1513 | break; | |
1514 | ||
1515 | default: | |
1516 | _exit (0); | |
1517 | } | |
1518 | break; | |
1519 | } | |
1520 | ||
1521 | (void) chdir ("/"); | |
1522 | ||
1523 | if ((sd = open ("/dev/null", O_RDWR)) == NOTOK) | |
1524 | adios ("/dev/null", "unable to read"); | |
1525 | if (sd != 0) | |
1526 | (void) dup2 (sd, 0), (void) close (sd); | |
1527 | (void) dup2 (0, 1); | |
1528 | (void) dup2 (0, 2); | |
1529 | ||
1530 | #ifdef SETSID | |
1531 | if (setsid () == NOTOK) | |
1532 | advise (LLOG_EXCEPTIONS, "failed", "setsid"); | |
1533 | #endif | |
1534 | #ifdef TIOCNOTTY | |
1535 | if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) { | |
1536 | (void) ioctl (sd, TIOCNOTTY, NULLCP); | |
1537 | (void) close (sd); | |
1538 | } | |
1539 | #else | |
1540 | #ifdef SYS5 | |
1541 | (void) setpgrp (); | |
1542 | (void) signal (SIGINT, SIG_IGN); | |
1543 | (void) signal (SIGQUIT, SIG_IGN); | |
1544 | #endif | |
1545 | #endif | |
1546 | } | |
1547 | else | |
1548 | ll_dbinit (pgm_log, pgmname); | |
1549 | ||
1550 | #ifndef sun /* damn YP... */ | |
1551 | for (sd = 3; sd < nbits; sd++) | |
1552 | if (pgm_log -> ll_fd != sd) | |
1553 | (void) close (sd); | |
1554 | #endif | |
1555 | ||
1556 | (void) signal (SIGPIPE, SIG_IGN); | |
1557 | ||
1558 | ll_hdinit (pgm_log, pgmname); | |
1559 | advise (LLOG_NOTICE, NULLCP, "starting"); | |
1560 | ||
1561 | #ifdef IAE | |
1562 | (void) signal (SIGHUP, hupser); | |
1563 | #endif | |
1564 | } | |
1565 | ||
1566 | /* \f ERRORS */ | |
1567 | ||
1568 | #ifndef lint | |
1569 | void adios (va_alist) | |
1570 | va_dcl | |
1571 | { | |
1572 | va_list ap; | |
1573 | ||
1574 | va_start (ap); | |
1575 | ||
1576 | _ll_log (pgm_log, LLOG_FATAL, ap); | |
1577 | ||
1578 | va_end (ap); | |
1579 | ||
1580 | _exit (1); | |
1581 | } | |
1582 | #else | |
1583 | /* VARARGS */ | |
1584 | ||
1585 | void adios (what, fmt) | |
1586 | char *what, | |
1587 | *fmt; | |
1588 | { | |
1589 | adios (what, fmt); | |
1590 | } | |
1591 | #endif | |
1592 | ||
1593 | ||
1594 | #ifndef lint | |
1595 | void advise (va_alist) | |
1596 | va_dcl | |
1597 | { | |
1598 | int code; | |
1599 | va_list ap; | |
1600 | ||
1601 | va_start (ap); | |
1602 | ||
1603 | code = va_arg (ap, int); | |
1604 | ||
1605 | _ll_log (pgm_log, code, ap); | |
1606 | ||
1607 | va_end (ap); | |
1608 | } | |
1609 | #else | |
1610 | /* VARARGS */ | |
1611 | ||
1612 | void advise (code, what, fmt) | |
1613 | char *what, | |
1614 | *fmt; | |
1615 | int code; | |
1616 | { | |
1617 | advise (code, what, fmt); | |
1618 | } | |
1619 | #endif |