xref: /freebsd/contrib/sendmail/src/daemon.c (revision 1f474190)
1 /*
2  * Copyright (c) 1998-2007, 2009, 2010 Proofpoint, Inc. and its suppliers.
3  *	All rights reserved.
4  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
5  * Copyright (c) 1988, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * By using this file, you agree to the terms and conditions set
9  * forth in the LICENSE file which can be found at the top level of
10  * the sendmail distribution.
11  *
12  */
13 
14 #include <sendmail.h>
15 #include "map.h"
16 
17 SM_RCSID("@(#)$Id: daemon.c,v 8.698 2013-11-22 20:51:55 ca Exp $")
18 
19 #if defined(SOCK_STREAM) || defined(__GNU_LIBRARY__)
20 # define USE_SOCK_STREAM	1
21 #endif
22 
23 #if defined(USE_SOCK_STREAM)
24 # if NETINET || NETINET6
25 #  include <arpa/inet.h>
26 # endif
27 # if NAMED_BIND
28 #  ifndef NO_DATA
29 #   define NO_DATA	NO_ADDRESS
30 #  endif
31 # endif /* NAMED_BIND */
32 #endif /* defined(USE_SOCK_STREAM) */
33 
34 #if STARTTLS
35 # include <openssl/rand.h>
36 # if DANE
37 #  include "tls.h"
38 #  include "sm_resolve.h"
39 # endif
40 #endif
41 
42 #if NETINET6
43 # define FREEHOSTENT(h, s)			\
44 	do					\
45 	{					\
46 		if ((h) != (s) && (h) != NULL)	\
47 		{				\
48 			freehostent((h));	\
49 			(h) = NULL;		\
50 		}				\
51 	} while (0)
52 #else
53 #  define FREEHOSTENT(h, s)
54 #endif
55 
56 #include <sm/time.h>
57 
58 #if IP_SRCROUTE && NETINET
59 # include <netinet/in_systm.h>
60 # include <netinet/ip.h>
61 # if HAS_IN_H
62 #  include <netinet/in.h>
63 #  ifndef IPOPTION
64 #   define IPOPTION	ip_opts
65 #   define IP_LIST	ip_opts
66 #   define IP_DST	ip_dst
67 #  endif /* ! IPOPTION */
68 # else /* HAS_IN_H */
69 #  include <netinet/ip_var.h>
70 #  ifndef IPOPTION
71 #   define IPOPTION	ipoption
72 #   define IP_LIST	ipopt_list
73 #   define IP_DST	ipopt_dst
74 #  endif /* ! IPOPTION */
75 # endif /* HAS_IN_H */
76 #endif /* IP_SRCROUTE && NETINET */
77 
78 #include <sm/fdset.h>
79 
80 #include <ratectrl.h>
81 
82 #define DAEMON_C 1
83 #include <daemon.h>
84 
85 static void		connecttimeout __P((int));
86 static int		opendaemonsocket __P((DAEMON_T *, bool));
87 static unsigned short	setupdaemon __P((SOCKADDR *));
88 static void		getrequests_checkdiskspace __P((ENVELOPE *e));
89 static void		setsockaddroptions __P((char *, DAEMON_T *));
90 static void		printdaemonflags __P((DAEMON_T *));
91 static int		addr_family __P((char *));
92 static int		addrcmp __P((struct hostent *, char *, SOCKADDR *));
93 static void		authtimeout __P((int));
94 
95 /*
96 **  DAEMON.C -- routines to use when running as a daemon.
97 **
98 **	This entire file is highly dependent on the 4.2 BSD
99 **	interprocess communication primitives.  No attempt has
100 **	been made to make this file portable to Version 7,
101 **	Version 6, MPX files, etc.  If you should try such a
102 **	thing yourself, I recommend chucking the entire file
103 **	and starting from scratch.  Basic semantics are:
104 **
105 **	getrequests(e)
106 **		Opens a port and initiates a connection.
107 **		Returns in a child.  Must set InChannel and
108 **		OutChannel appropriately.
109 **	clrdaemon()
110 **		Close any open files associated with getting
111 **		the connection; this is used when running the queue,
112 **		etc., to avoid having extra file descriptors during
113 **		the queue run and to avoid confusing the network
114 **		code (if it cares).
115 **	makeconnection(host, port, mci, e, enough)
116 **		Make a connection to the named host on the given
117 **		port. Returns zero on success, else an exit status
118 **		describing the error.
119 **	host_map_lookup(map, hbuf, avp, pstat)
120 **		Convert the entry in hbuf into a canonical form.
121 */
122 
123 static int	NDaemons = 0;			/* actual number of daemons */
124 
125 static time_t	NextDiskSpaceCheck = 0;
126 
127 /*
128 **  GETREQUESTS -- open mail IPC port and get requests.
129 **
130 **	Parameters:
131 **		e -- the current envelope.
132 **
133 **	Returns:
134 **		pointer to flags.
135 **
136 **	Side Effects:
137 **		Waits until some interesting activity occurs.  When
138 **		it does, a child is created to process it, and the
139 **		parent waits for completion.  Return from this
140 **		routine is always in the child.  The file pointers
141 **		"InChannel" and "OutChannel" should be set to point
142 **		to the communication channel.
143 **		May restart persistent queue runners if they have ended
144 **		for some reason.
145 */
146 
147 BITMAP256 *
148 getrequests(e)
149 	ENVELOPE *e;
150 {
151 	int t;
152 	int idx, curdaemon = -1;
153 	int i, olddaemon = 0;
154 #if XDEBUG
155 	bool j_has_dot;
156 #endif
157 	char status[MAXLINE];
158 	SOCKADDR sa;
159 	SOCKADDR_LEN_T len = sizeof(sa);
160 #if _FFR_QUEUE_RUN_PARANOIA
161 	time_t lastrun;
162 #endif
163 #if NETUNIX
164 	extern int ControlSocket;
165 #endif
166 	extern ENVELOPE BlankEnvelope;
167 
168 
169 	/* initialize data for function that generates queue ids */
170 	init_qid_alg();
171 	for (idx = 0; idx < NDaemons; idx++)
172 	{
173 		Daemons[idx].d_port = setupdaemon(&(Daemons[idx].d_addr));
174 		Daemons[idx].d_firsttime = true;
175 		Daemons[idx].d_refuse_connections_until = (time_t) 0;
176 	}
177 
178 	/*
179 	**  Try to actually open the connection.
180 	*/
181 
182 	if (tTd(15, 1))
183 	{
184 		for (idx = 0; idx < NDaemons; idx++)
185 		{
186 			sm_dprintf("getrequests: daemon %s: port %d\n",
187 				   Daemons[idx].d_name,
188 				   ntohs(Daemons[idx].d_port));
189 		}
190 	}
191 
192 	/* get a socket for the SMTP connection */
193 	for (idx = 0; idx < NDaemons; idx++)
194 		Daemons[idx].d_socksize = opendaemonsocket(&Daemons[idx], true);
195 
196 	if (opencontrolsocket() < 0)
197 		sm_syslog(LOG_WARNING, NOQID,
198 			  "daemon could not open control socket %s: %s",
199 			  ControlSocketName, sm_errstring(errno));
200 
201 	/* If there are any queue runners released reapchild() co-ord's */
202 	(void) sm_signal(SIGCHLD, reapchild);
203 
204 	/* write the pid to file, command line args to syslog */
205 	log_sendmail_pid(e);
206 
207 #if XDEBUG
208 	{
209 		char jbuf[MAXHOSTNAMELEN];
210 
211 		expand("\201j", jbuf, sizeof(jbuf), e);
212 		j_has_dot = strchr(jbuf, '.') != NULL;
213 	}
214 #endif /* XDEBUG */
215 
216 	/* Add parent process as first item */
217 	proc_list_add(CurrentPid, "Sendmail daemon", PROC_DAEMON, 0, -1, NULL);
218 
219 	if (tTd(15, 1))
220 	{
221 		for (idx = 0; idx < NDaemons; idx++)
222 			sm_dprintf("getrequests: daemon %s: socket %d\n",
223 				Daemons[idx].d_name,
224 				Daemons[idx].d_socket);
225 	}
226 
227 	for (;;)
228 	{
229 		register pid_t pid;
230 		auto SOCKADDR_LEN_T lotherend;
231 		bool timedout = false;
232 		bool control = false;
233 		int save_errno;
234 		int pipefd[2];
235 		time_t now;
236 #if STARTTLS
237 		long seed;
238 #endif
239 
240 		/* see if we are rejecting connections */
241 		(void) sm_blocksignal(SIGALRM);
242 		CHECK_RESTART;
243 
244 		for (idx = 0; idx < NDaemons; idx++)
245 		{
246 			/*
247 			**  XXX do this call outside the loop?
248 			**	no: refuse_connections may sleep().
249 			*/
250 
251 			now = curtime();
252 			if (now < Daemons[idx].d_refuse_connections_until)
253 				continue;
254 			if (bitnset(D_DISABLE, Daemons[idx].d_flags))
255 				continue;
256 			if (refuseconnections(e, idx, curdaemon == idx))
257 			{
258 				if (Daemons[idx].d_socket >= 0)
259 				{
260 					/* close socket so peer fails quickly */
261 					(void) close(Daemons[idx].d_socket);
262 					Daemons[idx].d_socket = -1;
263 				}
264 
265 				/* refuse connections for next 15 seconds */
266 				Daemons[idx].d_refuse_connections_until = now + 15;
267 			}
268 			else if (Daemons[idx].d_socket < 0 ||
269 				 Daemons[idx].d_firsttime)
270 			{
271 				if (!Daemons[idx].d_firsttime && LogLevel > 8)
272 					sm_syslog(LOG_INFO, NOQID,
273 						"accepting connections again for daemon %s",
274 						Daemons[idx].d_name);
275 
276 				/* arrange to (re)open the socket if needed */
277 				(void) opendaemonsocket(&Daemons[idx], false);
278 				Daemons[idx].d_firsttime = false;
279 			}
280 		}
281 
282 		/* May have been sleeping above, check again */
283 		CHECK_RESTART;
284 
285 		getrequests_checkdiskspace(e);
286 
287 #if XDEBUG
288 		/* check for disaster */
289 		{
290 			char jbuf[MAXHOSTNAMELEN];
291 
292 			expand("\201j", jbuf, sizeof(jbuf), e);
293 			if (!wordinclass(jbuf, 'w'))
294 			{
295 				dumpstate("daemon lost $j");
296 				sm_syslog(LOG_ALERT, NOQID,
297 					  "daemon process doesn't have $j in $=w; see syslog");
298 				abort();
299 			}
300 			else if (j_has_dot && strchr(jbuf, '.') == NULL)
301 			{
302 				dumpstate("daemon $j lost dot");
303 				sm_syslog(LOG_ALERT, NOQID,
304 					  "daemon process $j lost dot; see syslog");
305 				abort();
306 			}
307 		}
308 #endif /* XDEBUG */
309 
310 #if 0
311 		/*
312 		**  Andrew Sun <asun@ieps-sun.ml.com> claims that this will
313 		**  fix the SVr4 problem.  But it seems to have gone away,
314 		**  so is it worth doing this?
315 		*/
316 
317 		if (DaemonSocket >= 0 &&
318 		    SetNonBlocking(DaemonSocket, false) < 0)
319 			log an error here;
320 #endif /* 0 */
321 		(void) sm_releasesignal(SIGALRM);
322 
323 		for (;;)
324 		{
325 			bool setproc = false;
326 			int highest = -1;
327 			fd_set readfds;
328 			struct timeval timeout;
329 
330 			CHECK_RESTART;
331 			FD_ZERO(&readfds);
332 			for (idx = 0; idx < NDaemons; idx++)
333 			{
334 				/* wait for a connection */
335 				if (Daemons[idx].d_socket >= 0)
336 				{
337 					if (!setproc &&
338 					    !bitnset(D_ETRNONLY,
339 						     Daemons[idx].d_flags))
340 					{
341 						sm_setproctitle(true, e,
342 								"accepting connections");
343 						setproc = true;
344 					}
345 					if (Daemons[idx].d_socket > highest)
346 						highest = Daemons[idx].d_socket;
347 					SM_FD_SET(Daemons[idx].d_socket,
348 						  &readfds);
349 				}
350 			}
351 
352 #if NETUNIX
353 			if (ControlSocket >= 0)
354 			{
355 				if (ControlSocket > highest)
356 					highest = ControlSocket;
357 				SM_FD_SET(ControlSocket, &readfds);
358 			}
359 #endif /* NETUNIX */
360 
361 			timeout.tv_sec = 5;
362 			timeout.tv_usec = 0;
363 
364 			t = select(highest + 1, FDSET_CAST &readfds,
365 				   NULL, NULL, &timeout);
366 
367 			/* Did someone signal while waiting? */
368 			CHECK_RESTART;
369 
370 			curdaemon = -1;
371 			if (doqueuerun())
372 			{
373 				(void) runqueue(true, false, false, false);
374 #if _FFR_QUEUE_RUN_PARANOIA
375 				lastrun = now;
376 #endif
377 			}
378 #if _FFR_QUEUE_RUN_PARANOIA
379 			else if (CheckQueueRunners > 0 && QueueIntvl > 0 &&
380 				 lastrun + QueueIntvl + CheckQueueRunners < now)
381 			{
382 
383 				/*
384 				**  set lastrun unconditionally to avoid
385 				**  calling checkqueuerunner() all the time.
386 				**  That's also why we currently ignore the
387 				**  result of the function call.
388 				*/
389 
390 				(void) checkqueuerunner();
391 				lastrun = now;
392 			}
393 #endif /* _FFR_QUEUE_RUN_PARANOIA */
394 
395 			if (t <= 0)
396 			{
397 				timedout = true;
398 				break;
399 			}
400 
401 			control = false;
402 			errno = 0;
403 
404 			/* look "round-robin" for an active socket */
405 			if ((idx = olddaemon + 1) >= NDaemons)
406 				idx = 0;
407 			for (i = 0; i < NDaemons; i++)
408 			{
409 				if (Daemons[idx].d_socket >= 0 &&
410 				    SM_FD_ISSET(Daemons[idx].d_socket,
411 						&readfds))
412 				{
413 					lotherend = Daemons[idx].d_socksize;
414 					memset(&RealHostAddr, '\0',
415 					       sizeof(RealHostAddr));
416 					t = accept(Daemons[idx].d_socket,
417 						   (struct sockaddr *)&RealHostAddr,
418 						   &lotherend);
419 
420 					/*
421 					**  If remote side closes before
422 					**  accept() finishes, sockaddr
423 					**  might not be fully filled in.
424 					*/
425 
426 					if (t >= 0 &&
427 					    (lotherend == 0 ||
428 #ifdef BSD4_4_SOCKADDR
429 					     RealHostAddr.sa.sa_len == 0 ||
430 #endif
431 					     RealHostAddr.sa.sa_family != Daemons[idx].d_addr.sa.sa_family))
432 					{
433 						(void) close(t);
434 						t = -1;
435 						errno = EINVAL;
436 					}
437 					olddaemon = curdaemon = idx;
438 					break;
439 				}
440 				if (++idx >= NDaemons)
441 					idx = 0;
442 			}
443 #if NETUNIX
444 			if (curdaemon == -1 && ControlSocket >= 0 &&
445 			    SM_FD_ISSET(ControlSocket, &readfds))
446 			{
447 				struct sockaddr_un sa_un;
448 
449 				lotherend = sizeof(sa_un);
450 				memset(&sa_un, '\0', sizeof(sa_un));
451 				t = accept(ControlSocket,
452 					   (struct sockaddr *)&sa_un,
453 					   &lotherend);
454 
455 				/*
456 				**  If remote side closes before
457 				**  accept() finishes, sockaddr
458 				**  might not be fully filled in.
459 				*/
460 
461 				if (t >= 0 &&
462 				    (lotherend == 0 ||
463 # ifdef BSD4_4_SOCKADDR
464 				     sa_un.sun_len == 0 ||
465 # endif
466 				     sa_un.sun_family != AF_UNIX))
467 				{
468 					(void) close(t);
469 					t = -1;
470 					errno = EINVAL;
471 				}
472 				if (t >= 0)
473 					control = true;
474 			}
475 #else /* NETUNIX */
476 			if (curdaemon == -1)
477 			{
478 				/* No daemon to service */
479 				continue;
480 			}
481 #endif /* NETUNIX */
482 			if (t >= 0 || errno != EINTR)
483 				break;
484 		}
485 		if (timedout)
486 		{
487 			timedout = false;
488 			continue;
489 		}
490 		save_errno = errno;
491 		(void) sm_blocksignal(SIGALRM);
492 		if (t < 0)
493 		{
494 			errno = save_errno;
495 
496 			/* let's ignore these temporary errors */
497 			if (save_errno == EINTR
498 #ifdef EAGAIN
499 			    || save_errno == EAGAIN
500 #endif
501 #ifdef ECONNABORTED
502 			    || save_errno == ECONNABORTED
503 #endif
504 #ifdef EWOULDBLOCK
505 			    || save_errno == EWOULDBLOCK
506 #endif
507 			   )
508 				continue;
509 
510 			syserr("getrequests: accept");
511 
512 			if (curdaemon >= 0)
513 			{
514 				/* arrange to re-open socket next time around */
515 				(void) close(Daemons[curdaemon].d_socket);
516 				Daemons[curdaemon].d_socket = -1;
517 #if SO_REUSEADDR_IS_BROKEN
518 				/*
519 				**  Give time for bound socket to be released.
520 				**  This creates a denial-of-service if you can
521 				**  force accept() to fail on affected systems.
522 				*/
523 
524 				Daemons[curdaemon].d_refuse_connections_until =
525 					curtime() + 15;
526 #endif /* SO_REUSEADDR_IS_BROKEN */
527 			}
528 			continue;
529 		}
530 
531 		if (!control)
532 		{
533 			/* set some daemon related macros */
534 			switch (Daemons[curdaemon].d_addr.sa.sa_family)
535 			{
536 			  case AF_UNSPEC:
537 				macdefine(&BlankEnvelope.e_macro, A_PERM,
538 					macid("{daemon_family}"), "unspec");
539 				break;
540 #if NETUNIX
541 			  case AF_UNIX:
542 				macdefine(&BlankEnvelope.e_macro, A_PERM,
543 					macid("{daemon_family}"), "local");
544 				break;
545 #endif
546 #if NETINET
547 			  case AF_INET:
548 				macdefine(&BlankEnvelope.e_macro, A_PERM,
549 					macid("{daemon_family}"), "inet");
550 				break;
551 #endif
552 #if NETINET6
553 			  case AF_INET6:
554 				macdefine(&BlankEnvelope.e_macro, A_PERM,
555 					macid("{daemon_family}"), "inet6");
556 				break;
557 #endif
558 #if NETISO
559 			  case AF_ISO:
560 				macdefine(&BlankEnvelope.e_macro, A_PERM,
561 					macid("{daemon_family}"), "iso");
562 				break;
563 #endif
564 #if NETNS
565 			  case AF_NS:
566 				macdefine(&BlankEnvelope.e_macro, A_PERM,
567 					macid("{daemon_family}"), "ns");
568 				break;
569 #endif
570 #if NETX25
571 			  case AF_CCITT:
572 				macdefine(&BlankEnvelope.e_macro, A_PERM,
573 					macid("{daemon_family}"), "x.25");
574 				break;
575 #endif
576 			}
577 			macdefine(&BlankEnvelope.e_macro, A_PERM,
578 				macid("{daemon_name}"),
579 				Daemons[curdaemon].d_name);
580 			if (Daemons[curdaemon].d_mflags != NULL)
581 				macdefine(&BlankEnvelope.e_macro, A_PERM,
582 					macid("{daemon_flags}"),
583 					Daemons[curdaemon].d_mflags);
584 			else
585 				macdefine(&BlankEnvelope.e_macro, A_PERM,
586 					macid("{daemon_flags}"), "");
587 		}
588 
589 		/*
590 		**  If connection rate is exceeded here, connection shall be
591 		**  refused later by a new call after fork() by the
592 		**  validate_connection() function. Closing the connection
593 		**  at this point violates RFC 2821.
594 		**  Do NOT remove this call, its side effects are needed.
595 		*/
596 
597 		connection_rate_check(&RealHostAddr, NULL);
598 
599 		/*
600 		**  Create a subprocess to process the mail.
601 		*/
602 
603 		if (tTd(15, 2))
604 			sm_dprintf("getrequests: forking (fd = %d)\n", t);
605 
606 		/*
607 		**  Advance state of PRNG.
608 		**  This is necessary because otherwise all child processes
609 		**  will produce the same PRN sequence and hence the selection
610 		**  of a queue directory (and other things, e.g., MX selection)
611 		**  are not "really" random.
612 		*/
613 #if STARTTLS
614 		/* XXX get some better "random" data? */
615 		seed = get_random();
616 		RAND_seed((void *) &NextDiskSpaceCheck,
617 			  sizeof(NextDiskSpaceCheck));
618 		RAND_seed((void *) &now, sizeof(now));
619 		RAND_seed((void *) &seed, sizeof(seed));
620 #else /* STARTTLS */
621 		(void) get_random();
622 #endif /* STARTTLS */
623 
624 #if NAMED_BIND
625 		/*
626 		**  Update MX records for FallbackMX.
627 		**  Let's hope this is fast otherwise we screw up the
628 		**  response time.
629 		*/
630 
631 		if (FallbackMX != NULL)
632 			(void) getfallbackmxrr(FallbackMX);
633 #endif /* NAMED_BIND */
634 
635 		if (tTd(93, 100))
636 		{
637 			/* don't fork, handle connection in this process */
638 			pid = 0;
639 			pipefd[0] = pipefd[1] = -1;
640 		}
641 		else
642 		{
643 			/*
644 			**  Create a pipe to keep the child from writing to
645 			**  the socket until after the parent has closed
646 			**  it.  Otherwise the parent may hang if the child
647 			**  has closed it first.
648 			*/
649 
650 			if (pipe(pipefd) < 0)
651 				pipefd[0] = pipefd[1] = -1;
652 
653 			(void) sm_blocksignal(SIGCHLD);
654 			pid = fork();
655 			if (pid < 0)
656 			{
657 				syserr("daemon: cannot fork");
658 				if (pipefd[0] != -1)
659 				{
660 					(void) close(pipefd[0]);
661 					(void) close(pipefd[1]);
662 				}
663 				(void) sm_releasesignal(SIGCHLD);
664 				(void) sleep(10);
665 				(void) close(t);
666 				continue;
667 			}
668 		}
669 
670 		if (pid == 0)
671 		{
672 			char *p;
673 			SM_FILE_T *inchannel, *outchannel = NULL;
674 
675 			/*
676 			**  CHILD -- return to caller.
677 			**	Collect verified idea of sending host.
678 			**	Verify calling user id if possible here.
679 			*/
680 
681 			/* Reset global flags */
682 			RestartRequest = NULL;
683 			RestartWorkGroup = false;
684 			ShutdownRequest = NULL;
685 			PendingSignal = 0;
686 			CurrentPid = getpid();
687 			close_sendmail_pid();
688 
689 			(void) sm_releasesignal(SIGALRM);
690 			(void) sm_releasesignal(SIGCHLD);
691 			(void) sm_signal(SIGCHLD, SIG_DFL);
692 			(void) sm_signal(SIGHUP, SIG_DFL);
693 			(void) sm_signal(SIGTERM, intsig);
694 
695 			/* turn on profiling */
696 			/* SM_PROF(0); */
697 
698 			/*
699 			**  Initialize exception stack and default exception
700 			**  handler for child process.
701 			*/
702 
703 			sm_exc_newthread(fatal_error);
704 
705 			if (!control)
706 			{
707 				macdefine(&BlankEnvelope.e_macro, A_TEMP,
708 					macid("{daemon_addr}"),
709 					anynet_ntoa(&Daemons[curdaemon].d_addr));
710 				(void) sm_snprintf(status, sizeof(status), "%d",
711 						ntohs(Daemons[curdaemon].d_port));
712 				macdefine(&BlankEnvelope.e_macro, A_TEMP,
713 					macid("{daemon_port}"), status);
714 			}
715 
716 			for (idx = 0; idx < NDaemons; idx++)
717 			{
718 				if (Daemons[idx].d_socket >= 0)
719 					(void) close(Daemons[idx].d_socket);
720 				Daemons[idx].d_socket = -1;
721 			}
722 			clrcontrol();
723 
724 			/* Avoid SMTP daemon actions if control command */
725 			if (control)
726 			{
727 				/* Add control socket process */
728 				proc_list_add(CurrentPid,
729 					      "console socket child",
730 					      PROC_CONTROL_CHILD, 0, -1, NULL);
731 			}
732 			else
733 			{
734 				proc_list_clear();
735 
736 				/* clean up background delivery children */
737 				(void) sm_signal(SIGCHLD, reapchild);
738 
739 				/* Add parent process as first child item */
740 				proc_list_add(CurrentPid, "daemon child",
741 					      PROC_DAEMON_CHILD, 0, -1, NULL);
742 				/* don't schedule queue runs if ETRN */
743 				QueueIntvl = 0;
744 
745 				/*
746 				**  Hack: override global variables if
747 				**	the corresponding DaemonPortOption
748 				**	is set.
749 				*/
750 #if _FFR_SS_PER_DAEMON
751 				if (Daemons[curdaemon].d_supersafe !=
752 				    DPO_NOTSET)
753 					SuperSafe = Daemons[curdaemon].
754 								d_supersafe;
755 #endif /* _FFR_SS_PER_DAEMON */
756 				if (Daemons[curdaemon].d_dm != DM_NOTSET)
757 					set_delivery_mode(
758 						Daemons[curdaemon].d_dm, e);
759 
760 				if (Daemons[curdaemon].d_refuseLA !=
761 				    DPO_NOTSET)
762 					RefuseLA = Daemons[curdaemon].
763 								d_refuseLA;
764 				if (Daemons[curdaemon].d_queueLA != DPO_NOTSET)
765 					QueueLA = Daemons[curdaemon].d_queueLA;
766 				if (Daemons[curdaemon].d_delayLA != DPO_NOTSET)
767 					DelayLA = Daemons[curdaemon].d_delayLA;
768 				if (Daemons[curdaemon].d_maxchildren !=
769 				    DPO_NOTSET)
770 					MaxChildren = Daemons[curdaemon].
771 								d_maxchildren;
772 
773 				sm_setproctitle(true, e, "startup with %s",
774 						anynet_ntoa(&RealHostAddr));
775 			}
776 
777 			if (pipefd[0] != -1)
778 			{
779 				auto char c;
780 
781 				/*
782 				**  Wait for the parent to close the write end
783 				**  of the pipe, which we will see as an EOF.
784 				**  This guarantees that we won't write to the
785 				**  socket until after the parent has closed
786 				**  the pipe.
787 				*/
788 
789 				/* close the write end of the pipe */
790 				(void) close(pipefd[1]);
791 
792 				/* we shouldn't be interrupted, but ... */
793 				while (read(pipefd[0], &c, 1) < 0 &&
794 				       errno == EINTR)
795 					continue;
796 				(void) close(pipefd[0]);
797 			}
798 
799 			/* control socket processing */
800 			if (control)
801 			{
802 				control_command(t, e);
803 				/* NOTREACHED */
804 				exit(EX_SOFTWARE);
805 			}
806 
807 			/* determine host name */
808 			p = hostnamebyanyaddr(&RealHostAddr);
809 			if (strlen(p) > MAXNAME) /* XXX  - 1 ? */
810 				p[MAXNAME] = '\0';
811 			RealHostName = newstr(p);
812 			if (RealHostName[0] == '[')
813 			{
814 				macdefine(&BlankEnvelope.e_macro, A_PERM,
815 					macid("{client_resolve}"),
816 					h_errno == TRY_AGAIN ? "TEMP" : "FAIL");
817 			}
818 			else
819 			{
820 				macdefine(&BlankEnvelope.e_macro, A_PERM,
821 					  macid("{client_resolve}"), "OK");
822 			}
823 			sm_setproctitle(true, e, "startup with %s", p);
824 			markstats(e, NULL, STATS_CONNECT);
825 
826 			if ((inchannel = sm_io_open(SmFtStdiofd,
827 						    SM_TIME_DEFAULT,
828 						    (void *) &t,
829 						    SM_IO_RDONLY_B,
830 						    NULL)) == NULL ||
831 			    (t = dup(t)) < 0 ||
832 			    (outchannel = sm_io_open(SmFtStdiofd,
833 						     SM_TIME_DEFAULT,
834 						     (void *) &t,
835 						     SM_IO_WRONLY_B,
836 						     NULL)) == NULL)
837 			{
838 				syserr("cannot open SMTP server channel, fd=%d",
839 					t);
840 				finis(false, true, EX_OK);
841 			}
842 			sm_io_automode(inchannel, outchannel);
843 
844 			InChannel = inchannel;
845 			OutChannel = outchannel;
846 			DisConnected = false;
847 
848 #if _FFR_XCNCT
849 			t = xconnect(inchannel);
850 			if (t <= 0)
851 			{
852 				clrbitn(D_XCNCT, Daemons[curdaemon].d_flags);
853 				clrbitn(D_XCNCT_M, Daemons[curdaemon].d_flags);
854 			}
855 			else
856 				setbitn(t, Daemons[curdaemon].d_flags);
857 
858 #endif /* _FFR_XCNCT */
859 
860 #if XLA
861 			if (!xla_host_ok(RealHostName))
862 			{
863 				message("421 4.4.5 Too many SMTP sessions for this host");
864 				finis(false, true, EX_OK);
865 			}
866 #endif /* XLA */
867 			/* find out name for interface of connection */
868 			if (getsockname(sm_io_getinfo(InChannel, SM_IO_WHAT_FD,
869 						      NULL), &sa.sa, &len) == 0)
870 			{
871 				p = hostnamebyanyaddr(&sa);
872 				if (tTd(15, 9))
873 					sm_dprintf("getreq: got name %s\n", p);
874 				macdefine(&BlankEnvelope.e_macro, A_TEMP,
875 					macid("{if_name}"), p);
876 
877 				/*
878 				**  Do this only if it is not the loopback
879 				**  interface.
880 				*/
881 
882 				if (!isloopback(sa))
883 				{
884 					char *addr;
885 					char family[5];
886 
887 					addr = anynet_ntoa(&sa);
888 					(void) sm_snprintf(family,
889 						sizeof(family),
890 						"%d", sa.sa.sa_family);
891 					macdefine(&BlankEnvelope.e_macro,
892 						A_TEMP,
893 						macid("{if_addr}"), addr);
894 					macdefine(&BlankEnvelope.e_macro,
895 						A_TEMP,
896 						macid("{if_family}"), family);
897 					if (tTd(15, 7))
898 						sm_dprintf("getreq: got addr %s and family %s\n",
899 							addr, family);
900 				}
901 				else
902 				{
903 					macdefine(&BlankEnvelope.e_macro,
904 						A_PERM,
905 						macid("{if_addr}"), NULL);
906 					macdefine(&BlankEnvelope.e_macro,
907 						A_PERM,
908 						macid("{if_family}"), NULL);
909 				}
910 			}
911 			else
912 			{
913 				if (tTd(15, 7))
914 					sm_dprintf("getreq: getsockname failed\n");
915 				macdefine(&BlankEnvelope.e_macro, A_PERM,
916 					macid("{if_name}"), NULL);
917 				macdefine(&BlankEnvelope.e_macro, A_PERM,
918 					macid("{if_addr}"), NULL);
919 				macdefine(&BlankEnvelope.e_macro, A_PERM,
920 					macid("{if_family}"), NULL);
921 			}
922 			break;
923 		}
924 
925 		/* parent -- keep track of children */
926 		if (control)
927 		{
928 			(void) sm_snprintf(status, sizeof(status),
929 					   "control socket server child");
930 			proc_list_add(pid, status, PROC_CONTROL, 0, -1, NULL);
931 		}
932 		else
933 		{
934 			(void) sm_snprintf(status, sizeof(status),
935 					   "SMTP server child for %s",
936 					   anynet_ntoa(&RealHostAddr));
937 			proc_list_add(pid, status, PROC_DAEMON, 0, -1,
938 					&RealHostAddr);
939 		}
940 		(void) sm_releasesignal(SIGCHLD);
941 
942 		/* close the read end of the synchronization pipe */
943 		if (pipefd[0] != -1)
944 		{
945 			(void) close(pipefd[0]);
946 			pipefd[0] = -1;
947 		}
948 
949 		/* close the port so that others will hang (for a while) */
950 		(void) close(t);
951 
952 		/* release the child by closing the read end of the sync pipe */
953 		if (pipefd[1] != -1)
954 		{
955 			(void) close(pipefd[1]);
956 			pipefd[1] = -1;
957 		}
958 	}
959 	if (tTd(15, 2))
960 		sm_dprintf("getreq: returning\n");
961 
962 #if MILTER
963 	/* set the filters for this daemon */
964 	if (Daemons[curdaemon].d_inputfilterlist != NULL)
965 	{
966 		for (i = 0;
967 		     (i < MAXFILTERS &&
968 		      Daemons[curdaemon].d_inputfilters[i] != NULL);
969 		     i++)
970 		{
971 			InputFilters[i] = Daemons[curdaemon].d_inputfilters[i];
972 		}
973 		if (i < MAXFILTERS)
974 			InputFilters[i] = NULL;
975 	}
976 #endif /* MILTER */
977 	return &Daemons[curdaemon].d_flags;
978 }
979 
980 /*
981 **  GETREQUESTS_CHECKDISKSPACE -- check available diskspace.
982 **
983 **	Parameters:
984 **		e -- envelope.
985 **
986 **	Returns:
987 **		none.
988 **
989 **	Side Effects:
990 **		Modifies Daemon flags (D_ETRNONLY) if not enough disk space.
991 */
992 
993 static void
994 getrequests_checkdiskspace(e)
995 	ENVELOPE *e;
996 {
997 	bool logged = false;
998 	int idx;
999 	time_t now;
1000 
1001 	now = curtime();
1002 	if (now < NextDiskSpaceCheck)
1003 		return;
1004 
1005 	/* Check if there is available disk space in all queue groups. */
1006 	if (!enoughdiskspace(0, NULL))
1007 	{
1008 		for (idx = 0; idx < NDaemons; ++idx)
1009 		{
1010 			if (bitnset(D_ETRNONLY, Daemons[idx].d_flags))
1011 				continue;
1012 
1013 			/* log only if not logged before */
1014 			if (!logged)
1015 			{
1016 				if (LogLevel > 8)
1017 					sm_syslog(LOG_INFO, NOQID,
1018 						  "rejecting new messages: min free: %ld",
1019 						  MinBlocksFree);
1020 				sm_setproctitle(true, e,
1021 						"rejecting new messages: min free: %ld",
1022 						MinBlocksFree);
1023 				logged = true;
1024 			}
1025 			setbitn(D_ETRNONLY, Daemons[idx].d_flags);
1026 		}
1027 	}
1028 	else
1029 	{
1030 		for (idx = 0; idx < NDaemons; ++idx)
1031 		{
1032 			if (!bitnset(D_ETRNONLY, Daemons[idx].d_flags))
1033 				continue;
1034 
1035 			/* log only if not logged before */
1036 			if (!logged)
1037 			{
1038 				if (LogLevel > 8)
1039 					sm_syslog(LOG_INFO, NOQID,
1040 						  "accepting new messages (again)");
1041 				logged = true;
1042 			}
1043 
1044 			/* title will be set later */
1045 			clrbitn(D_ETRNONLY, Daemons[idx].d_flags);
1046 		}
1047 	}
1048 
1049 	/* only check disk space once a minute */
1050 	NextDiskSpaceCheck = now + 60;
1051 }
1052 
1053 /*
1054 **  OPENDAEMONSOCKET -- open SMTP socket
1055 **
1056 **	Deals with setting all appropriate options.
1057 **
1058 **	Parameters:
1059 **		d -- the structure for the daemon to open.
1060 **		firsttime -- set if this is the initial open.
1061 **
1062 **	Returns:
1063 **		Size in bytes of the daemon socket addr.
1064 **
1065 **	Side Effects:
1066 **		Leaves DaemonSocket set to the open socket.
1067 **		Exits if the socket cannot be created.
1068 */
1069 
1070 #define MAXOPENTRIES	10	/* maximum number of tries to open connection */
1071 
1072 static int
1073 opendaemonsocket(d, firsttime)
1074 	DAEMON_T *d;
1075 	bool firsttime;
1076 {
1077 	int on = 1;
1078 	int fdflags;
1079 	SOCKADDR_LEN_T socksize = 0;
1080 	int ntries = 0;
1081 	int save_errno;
1082 
1083 	if (tTd(15, 2))
1084 		sm_dprintf("opendaemonsocket(%s)\n", d->d_name);
1085 
1086 	do
1087 	{
1088 		if (ntries > 0)
1089 			(void) sleep(5);
1090 		if (firsttime || d->d_socket < 0)
1091 		{
1092 #if NETUNIX
1093 			if (d->d_addr.sa.sa_family == AF_UNIX)
1094 			{
1095 				int rval;
1096 				long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_ROOTOK|SFF_EXECOK|SFF_CREAT;
1097 
1098 				/* if not safe, don't use it */
1099 				rval = safefile(d->d_addr.sunix.sun_path,
1100 						RunAsUid, RunAsGid,
1101 						RunAsUserName, sff,
1102 						S_IRUSR|S_IWUSR, NULL);
1103 				if (rval != 0)
1104 				{
1105 					save_errno = errno;
1106 					syserr("opendaemonsocket: daemon %s: unsafe domain socket %s",
1107 					       d->d_name,
1108 					       d->d_addr.sunix.sun_path);
1109 					goto fail;
1110 				}
1111 
1112 				/* Don't try to overtake an existing socket */
1113 				(void) unlink(d->d_addr.sunix.sun_path);
1114 			}
1115 #endif /* NETUNIX */
1116 			d->d_socket = socket(d->d_addr.sa.sa_family,
1117 					     SOCK_STREAM, 0);
1118 			if (d->d_socket < 0)
1119 			{
1120 				save_errno = errno;
1121 				syserr("opendaemonsocket: daemon %s: can't create server SMTP socket",
1122 				       d->d_name);
1123 			  fail:
1124 				if (bitnset(D_OPTIONAL, d->d_flags) &&
1125 				    (!transienterror(save_errno) ||
1126 				     ntries >= MAXOPENTRIES - 1))
1127 				{
1128 					syserr("opendaemonsocket: daemon %s: optional socket disabled",
1129 					       d->d_name);
1130 					setbitn(D_DISABLE, d->d_flags);
1131 					d->d_socket = -1;
1132 					return -1;
1133 				}
1134 			  severe:
1135 				if (LogLevel > 0)
1136 					sm_syslog(LOG_ALERT, NOQID,
1137 						  "daemon %s: problem creating SMTP socket",
1138 						  d->d_name);
1139 				d->d_socket = -1;
1140 				continue;
1141 			}
1142 
1143 			if (!SM_FD_OK_SELECT(d->d_socket))
1144 			{
1145 				save_errno = EINVAL;
1146 				syserr("opendaemonsocket: daemon %s: server SMTP socket (%d) too large",
1147 				       d->d_name, d->d_socket);
1148 				goto fail;
1149 			}
1150 
1151 			/* turn on network debugging? */
1152 			if (tTd(15, 101))
1153 				(void) setsockopt(d->d_socket, SOL_SOCKET,
1154 						  SO_DEBUG, (char *)&on,
1155 						  sizeof(on));
1156 
1157 			(void) setsockopt(d->d_socket, SOL_SOCKET,
1158 					  SO_REUSEADDR, (char *)&on, sizeof(on));
1159 			(void) setsockopt(d->d_socket, SOL_SOCKET,
1160 					  SO_KEEPALIVE, (char *)&on, sizeof(on));
1161 
1162 #ifdef SO_RCVBUF
1163 			if (d->d_tcprcvbufsize > 0)
1164 			{
1165 				if (setsockopt(d->d_socket, SOL_SOCKET,
1166 					       SO_RCVBUF,
1167 					       (char *) &d->d_tcprcvbufsize,
1168 					       sizeof(d->d_tcprcvbufsize)) < 0)
1169 					syserr("opendaemonsocket: daemon %s: setsockopt(SO_RCVBUF)", d->d_name);
1170 			}
1171 #endif /* SO_RCVBUF */
1172 #ifdef SO_SNDBUF
1173 			if (d->d_tcpsndbufsize > 0)
1174 			{
1175 				if (setsockopt(d->d_socket, SOL_SOCKET,
1176 					       SO_SNDBUF,
1177 					       (char *) &d->d_tcpsndbufsize,
1178 					       sizeof(d->d_tcpsndbufsize)) < 0)
1179 					syserr("opendaemonsocket: daemon %s: setsockopt(SO_SNDBUF)", d->d_name);
1180 			}
1181 #endif /* SO_SNDBUF */
1182 
1183 			if ((fdflags = fcntl(d->d_socket, F_GETFD, 0)) == -1 ||
1184 			    fcntl(d->d_socket, F_SETFD,
1185 				  fdflags | FD_CLOEXEC) == -1)
1186 			{
1187 				save_errno = errno;
1188 				syserr("opendaemonsocket: daemon %s: failed to %s close-on-exec flag: %s",
1189 				       d->d_name,
1190 				       fdflags == -1 ? "get" : "set",
1191 				       sm_errstring(save_errno));
1192 				(void) close(d->d_socket);
1193 				goto severe;
1194 			}
1195 
1196 			switch (d->d_addr.sa.sa_family)
1197 			{
1198 #ifdef NETUNIX
1199 			  case AF_UNIX:
1200 				socksize = sizeof(d->d_addr.sunix);
1201 				break;
1202 #endif
1203 #if NETINET
1204 			  case AF_INET:
1205 				socksize = sizeof(d->d_addr.sin);
1206 				break;
1207 #endif
1208 
1209 #if NETINET6
1210 			  case AF_INET6:
1211 				socksize = sizeof(d->d_addr.sin6);
1212 				break;
1213 #endif
1214 
1215 #if NETISO
1216 			  case AF_ISO:
1217 				socksize = sizeof(d->d_addr.siso);
1218 				break;
1219 #endif
1220 
1221 			  default:
1222 				socksize = sizeof(d->d_addr);
1223 				break;
1224 			}
1225 
1226 			if (bind(d->d_socket, &d->d_addr.sa, socksize) < 0)
1227 			{
1228 				/* probably another daemon already */
1229 				save_errno = errno;
1230 				syserr("opendaemonsocket: daemon %s: cannot bind",
1231 				       d->d_name);
1232 				(void) close(d->d_socket);
1233 				goto fail;
1234 			}
1235 		}
1236 		if (!firsttime &&
1237 		    listen(d->d_socket, d->d_listenqueue) < 0)
1238 		{
1239 			save_errno = errno;
1240 			syserr("opendaemonsocket: daemon %s: cannot listen",
1241 			       d->d_name);
1242 			(void) close(d->d_socket);
1243 			goto severe;
1244 		}
1245 		return socksize;
1246 	} while (ntries++ < MAXOPENTRIES && transienterror(save_errno));
1247 	syserr("!opendaemonsocket: daemon %s: server SMTP socket wedged: exiting",
1248 	       d->d_name);
1249 	/* NOTREACHED */
1250 	return -1;  /* avoid compiler warning on IRIX */
1251 }
1252 /*
1253 **  SETUPDAEMON -- setup socket for daemon
1254 **
1255 **	Parameters:
1256 **		daemonaddr -- socket for daemon
1257 **
1258 **	Returns:
1259 **		port number on which daemon should run
1260 **
1261 */
1262 
1263 static unsigned short
1264 setupdaemon(daemonaddr)
1265 	SOCKADDR *daemonaddr;
1266 {
1267 	unsigned short port;
1268 
1269 	/*
1270 	**  Set up the address for the mailer.
1271 	*/
1272 
1273 	if (daemonaddr->sa.sa_family == AF_UNSPEC)
1274 	{
1275 		memset(daemonaddr, '\0', sizeof(*daemonaddr));
1276 #if NETINET
1277 		daemonaddr->sa.sa_family = AF_INET;
1278 #endif
1279 	}
1280 
1281 	switch (daemonaddr->sa.sa_family)
1282 	{
1283 #if NETINET
1284 	  case AF_INET:
1285 		if (daemonaddr->sin.sin_addr.s_addr == 0)
1286 			daemonaddr->sin.sin_addr.s_addr =
1287 			    LocalDaemon ? htonl(INADDR_LOOPBACK) : INADDR_ANY;
1288 		port = daemonaddr->sin.sin_port;
1289 		break;
1290 #endif /* NETINET */
1291 
1292 #if NETINET6
1293 	  case AF_INET6:
1294 		if (IN6_IS_ADDR_UNSPECIFIED(&daemonaddr->sin6.sin6_addr))
1295 			daemonaddr->sin6.sin6_addr =
1296 			    (LocalDaemon && V6LoopbackAddrFound) ?
1297 			    in6addr_loopback : in6addr_any;
1298 		port = daemonaddr->sin6.sin6_port;
1299 		break;
1300 #endif /* NETINET6 */
1301 
1302 	  default:
1303 		/* unknown protocol */
1304 		port = 0;
1305 		break;
1306 	}
1307 	if (port == 0)
1308 	{
1309 #ifdef NO_GETSERVBYNAME
1310 		port = htons(25);
1311 #else /* NO_GETSERVBYNAME */
1312 		{
1313 			register struct servent *sp;
1314 
1315 			sp = getservbyname("smtp", "tcp");
1316 			if (sp == NULL)
1317 			{
1318 				syserr("554 5.3.5 service \"smtp\" unknown");
1319 				port = htons(25);
1320 			}
1321 			else
1322 				port = sp->s_port;
1323 		}
1324 #endif /* NO_GETSERVBYNAME */
1325 	}
1326 
1327 	switch (daemonaddr->sa.sa_family)
1328 	{
1329 #if NETINET
1330 	  case AF_INET:
1331 		daemonaddr->sin.sin_port = port;
1332 		break;
1333 #endif
1334 
1335 #if NETINET6
1336 	  case AF_INET6:
1337 		daemonaddr->sin6.sin6_port = port;
1338 		break;
1339 #endif
1340 
1341 	  default:
1342 		/* unknown protocol */
1343 		break;
1344 	}
1345 	return port;
1346 }
1347 /*
1348 **  CLRDAEMON -- reset the daemon connection
1349 **
1350 **	Parameters:
1351 **		none.
1352 **
1353 **	Returns:
1354 **		none.
1355 **
1356 **	Side Effects:
1357 **		releases any resources used by the passive daemon.
1358 */
1359 
1360 void
1361 clrdaemon()
1362 {
1363 	int i;
1364 
1365 	for (i = 0; i < NDaemons; i++)
1366 	{
1367 		if (Daemons[i].d_socket >= 0)
1368 			(void) close(Daemons[i].d_socket);
1369 		Daemons[i].d_socket = -1;
1370 	}
1371 }
1372 
1373 /*
1374 **  GETMODIFIERS -- get modifier flags
1375 **
1376 **	Parameters:
1377 **		v -- the modifiers (input text line).
1378 **		modifiers -- pointer to flag field to represent modifiers.
1379 **
1380 **	Returns:
1381 **		(xallocat()ed) string representation of modifiers.
1382 **
1383 **	Side Effects:
1384 **		fills in modifiers.
1385 */
1386 
1387 char *
1388 getmodifiers(v, modifiers)
1389 	char *v;
1390 	BITMAP256 modifiers;
1391 {
1392 	int l;
1393 	char *h, *f, *flags;
1394 
1395 	/* maximum length of flags: upper case Option -> "OO " */
1396 	l = 3 * strlen(v) + 3;
1397 
1398 	/* is someone joking? */
1399 	if (l < 0 || l > 256)
1400 	{
1401 		if (LogLevel > 2)
1402 			sm_syslog(LOG_ERR, NOQID,
1403 				  "getmodifiers too long, ignored");
1404 		return NULL;
1405 	}
1406 	flags = xalloc(l);
1407 	f = flags;
1408 	clrbitmap(modifiers);
1409 	for (h = v; *h != '\0'; h++)
1410 	{
1411 		if (isascii(*h) && !isspace(*h) && isprint(*h))
1412 		{
1413 			setbitn(*h, modifiers);
1414 			if (flags != f)
1415 				*flags++ = ' ';
1416 			*flags++ = *h;
1417 			if (isupper(*h))
1418 				*flags++ = *h;
1419 		}
1420 	}
1421 	*flags++ = '\0';
1422 	return f;
1423 }
1424 
1425 /*
1426 **  CHKDAEMONMODIFIERS -- check whether all daemons have set a flag.
1427 **
1428 **	Parameters:
1429 **		flag -- the flag to test.
1430 **
1431 **	Returns:
1432 **		true iff all daemons have set flag.
1433 */
1434 
1435 bool
1436 chkdaemonmodifiers(flag)
1437 	int flag;
1438 {
1439 	int i;
1440 
1441 	for (i = 0; i < NDaemons; i++)
1442 		if (!bitnset((char) flag, Daemons[i].d_flags))
1443 			return false;
1444 	return true;
1445 }
1446 
1447 /*
1448 **  SETSOCKADDROPTIONS -- set options for SOCKADDR (daemon or client)
1449 **
1450 **	Parameters:
1451 **		p -- the options line.
1452 **		d -- the daemon structure to fill in.
1453 **
1454 **	Returns:
1455 **		none.
1456 */
1457 
1458 static void
1459 setsockaddroptions(p, d)
1460 	char *p;
1461 	DAEMON_T *d;
1462 {
1463 #if NETISO
1464 	short portno;
1465 #endif
1466 	char *port = NULL;
1467 	char *addr = NULL;
1468 
1469 #if NETINET
1470 	if (d->d_addr.sa.sa_family == AF_UNSPEC)
1471 		d->d_addr.sa.sa_family = AF_INET;
1472 #endif
1473 #if _FFR_SS_PER_DAEMON
1474 	d->d_supersafe = DPO_NOTSET;
1475 #endif
1476 	d->d_dm = DM_NOTSET;
1477 	d->d_refuseLA = DPO_NOTSET;
1478 	d->d_queueLA = DPO_NOTSET;
1479 	d->d_delayLA = DPO_NOTSET;
1480 	d->d_maxchildren = DPO_NOTSET;
1481 
1482 	while (p != NULL)
1483 	{
1484 		register char *f;
1485 		register char *v;
1486 
1487 		while (SM_ISSPACE(*p))
1488 			p++;
1489 		if (*p == '\0')
1490 			break;
1491 		f = p;
1492 		p = strchr(p, ',');
1493 		if (p != NULL)
1494 			*p++ = '\0';
1495 		v = strchr(f, '=');
1496 		if (v == NULL)
1497 			continue;
1498 		while (isascii(*++v) && isspace(*v))
1499 			continue;
1500 
1501 		switch (*f)
1502 		{
1503 		  case 'A':		/* address */
1504 #if !_FFR_DPO_CS
1505 		  case 'a':
1506 #endif
1507 			addr = v;
1508 			break;
1509 
1510 		  case 'c':
1511 			d->d_maxchildren = atoi(v);
1512 			break;
1513 
1514 		  case 'D':		/* DeliveryMode */
1515 			switch (*v)
1516 			{
1517 			  case SM_QUEUE:
1518 			  case SM_DEFER:
1519 			  case SM_DELIVER:
1520 			  case SM_FORK:
1521 #if _FFR_PROXY
1522 			  case SM_PROXY_REQ:
1523 #endif
1524 				d->d_dm = *v;
1525 				break;
1526 			  default:
1527 				syserr("554 5.3.5 Unknown delivery mode %c",
1528 					*v);
1529 				break;
1530 			}
1531 			break;
1532 
1533 		  case 'd':		/* delayLA */
1534 			d->d_delayLA = atoi(v);
1535 			break;
1536 
1537 		  case 'F':		/* address family */
1538 #if !_FFR_DPO_CS
1539 		  case 'f':
1540 #endif
1541 			if (isascii(*v) && isdigit(*v))
1542 				d->d_addr.sa.sa_family = atoi(v);
1543 #ifdef NETUNIX
1544 			else if (sm_strcasecmp(v, "unix") == 0 ||
1545 				 sm_strcasecmp(v, "local") == 0)
1546 				d->d_addr.sa.sa_family = AF_UNIX;
1547 #endif
1548 #if NETINET
1549 			else if (sm_strcasecmp(v, "inet") == 0)
1550 				d->d_addr.sa.sa_family = AF_INET;
1551 #endif
1552 #if NETINET6
1553 			else if (sm_strcasecmp(v, "inet6") == 0)
1554 				d->d_addr.sa.sa_family = AF_INET6;
1555 #endif
1556 #if NETISO
1557 			else if (sm_strcasecmp(v, "iso") == 0)
1558 				d->d_addr.sa.sa_family = AF_ISO;
1559 #endif
1560 #if NETNS
1561 			else if (sm_strcasecmp(v, "ns") == 0)
1562 				d->d_addr.sa.sa_family = AF_NS;
1563 #endif
1564 #if NETX25
1565 			else if (sm_strcasecmp(v, "x.25") == 0)
1566 				d->d_addr.sa.sa_family = AF_CCITT;
1567 #endif
1568 			else
1569 				syserr("554 5.3.5 Unknown address family %s in Family=option",
1570 				       v);
1571 			break;
1572 
1573 #if MILTER
1574 		  case 'I':
1575 # if !_FFR_DPO_CS
1576 		  case 'i':
1577 # endif
1578 			d->d_inputfilterlist = v;
1579 			break;
1580 #endif /* MILTER */
1581 
1582 		  case 'L':		/* listen queue size */
1583 #if !_FFR_DPO_CS
1584 		  case 'l':
1585 #endif
1586 			d->d_listenqueue = atoi(v);
1587 			break;
1588 
1589 		  case 'M':		/* modifiers (flags) */
1590 #if !_FFR_DPO_CS
1591 		  case 'm':
1592 #endif
1593 			d->d_mflags = getmodifiers(v, d->d_flags);
1594 			break;
1595 
1596 		  case 'N':		/* name */
1597 #if !_FFR_DPO_CS
1598 		  case 'n':
1599 #endif
1600 			d->d_name = v;
1601 			break;
1602 
1603 		  case 'P':		/* port */
1604 #if !_FFR_DPO_CS
1605 		  case 'p':
1606 #endif
1607 			port = v;
1608 			break;
1609 
1610 		  case 'q':
1611 			d->d_queueLA = atoi(v);
1612 			break;
1613 
1614 		  case 'R':		/* receive buffer size */
1615 			d->d_tcprcvbufsize = atoi(v);
1616 			break;
1617 
1618 		  case 'r':
1619 			d->d_refuseLA = atoi(v);
1620 			break;
1621 
1622 		  case 'S':		/* send buffer size */
1623 #if !_FFR_DPO_CS
1624 		  case 's':
1625 #endif
1626 			d->d_tcpsndbufsize = atoi(v);
1627 			break;
1628 
1629 #if _FFR_SS_PER_DAEMON
1630 		  case 'T':		/* SuperSafe */
1631 			if (tolower(*v) == 'i')
1632 				d->d_supersafe = SAFE_INTERACTIVE;
1633 			else if (tolower(*v) == 'p')
1634 # if MILTER
1635 				d->d_supersafe = SAFE_REALLY_POSTMILTER;
1636 # else /* MILTER */
1637 				(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
1638 					"Warning: SuperSafe=PostMilter requires Milter support (-DMILTER)\n");
1639 # endif /* MILTER */
1640 			else
1641 				d->d_supersafe = atobool(v) ? SAFE_REALLY
1642 							: SAFE_NO;
1643 			break;
1644 #endif /* _FFR_SS_PER_DAEMON */
1645 
1646 		  default:
1647 			syserr("554 5.3.5 PortOptions parameter \"%s\" unknown",
1648 			       f);
1649 		}
1650 	}
1651 
1652 	/* Check addr and port after finding family */
1653 	if (addr != NULL)
1654 	{
1655 		switch (d->d_addr.sa.sa_family)
1656 		{
1657 #if NETUNIX
1658 		  case AF_UNIX:
1659 			if (strlen(addr) >= sizeof(d->d_addr.sunix.sun_path))
1660 			{
1661 				errno = ENAMETOOLONG;
1662 				syserr("setsockaddroptions: domain socket name too long: %s > %ld",
1663 				       addr,
1664 				       (long) sizeof(d->d_addr.sunix.sun_path));
1665 				break;
1666 			}
1667 
1668 			/* file safety check done in opendaemonsocket() */
1669 			(void) memset(&d->d_addr.sunix.sun_path, '\0',
1670 				      sizeof(d->d_addr.sunix.sun_path));
1671 			(void) sm_strlcpy((char *)&d->d_addr.sunix.sun_path,
1672 					  addr,
1673 					  sizeof(d->d_addr.sunix.sun_path));
1674 			break;
1675 #endif /* NETUNIX */
1676 #if NETINET
1677 		  case AF_INET:
1678 			if (!isascii(*addr) || !isdigit(*addr) ||
1679 			    ((d->d_addr.sin.sin_addr.s_addr = inet_addr(addr))
1680 			     == INADDR_NONE))
1681 			{
1682 				register struct hostent *hp;
1683 
1684 				hp = sm_gethostbyname(addr, AF_INET);
1685 				if (hp == NULL)
1686 					syserr("554 5.3.0 host \"%s\" unknown",
1687 					       addr);
1688 				else
1689 				{
1690 					while (*(hp->h_addr_list) != NULL &&
1691 					       hp->h_addrtype != AF_INET)
1692 						hp->h_addr_list++;
1693 					if (*(hp->h_addr_list) == NULL)
1694 						syserr("554 5.3.0 host \"%s\" unknown",
1695 						       addr);
1696 					else
1697 						memmove(&d->d_addr.sin.sin_addr,
1698 							*(hp->h_addr_list),
1699 							INADDRSZ);
1700 					FREEHOSTENT(hp, NULL);
1701 				}
1702 			}
1703 			break;
1704 #endif /* NETINET */
1705 
1706 #if NETINET6
1707 		  case AF_INET6:
1708 			if (anynet_pton(AF_INET6, addr,
1709 					&d->d_addr.sin6.sin6_addr) != 1)
1710 			{
1711 				register struct hostent *hp;
1712 
1713 				hp = sm_gethostbyname(addr, AF_INET6);
1714 				if (hp == NULL)
1715 					syserr("554 5.3.0 host \"%s\" unknown",
1716 					       addr);
1717 				else
1718 				{
1719 					while (*(hp->h_addr_list) != NULL &&
1720 					       hp->h_addrtype != AF_INET6)
1721 						hp->h_addr_list++;
1722 					if (*(hp->h_addr_list) == NULL)
1723 						syserr("554 5.3.0 host \"%s\" unknown",
1724 						       addr);
1725 					else
1726 						memmove(&d->d_addr.sin6.sin6_addr,
1727 							*(hp->h_addr_list),
1728 							IN6ADDRSZ);
1729 					FREEHOSTENT(hp, NULL);
1730 				}
1731 			}
1732 			break;
1733 #endif /* NETINET6 */
1734 
1735 		  default:
1736 			syserr("554 5.3.5 address= option unsupported for family %d",
1737 			       d->d_addr.sa.sa_family);
1738 			break;
1739 		}
1740 	}
1741 
1742 	if (port != NULL)
1743 	{
1744 		switch (d->d_addr.sa.sa_family)
1745 		{
1746 #if NETINET
1747 		  case AF_INET:
1748 			if (isascii(*port) && isdigit(*port))
1749 				d->d_addr.sin.sin_port = htons((unsigned short)
1750 						     atoi((const char *) port));
1751 			else
1752 			{
1753 # ifdef NO_GETSERVBYNAME
1754 				syserr("554 5.3.5 invalid port number: %s",
1755 				       port);
1756 # else /* NO_GETSERVBYNAME */
1757 				register struct servent *sp;
1758 
1759 				sp = getservbyname(port, "tcp");
1760 				if (sp == NULL)
1761 					syserr("554 5.3.5 service \"%s\" unknown",
1762 					       port);
1763 				else
1764 					d->d_addr.sin.sin_port = sp->s_port;
1765 # endif /* NO_GETSERVBYNAME */
1766 			}
1767 			break;
1768 #endif /* NETINET */
1769 
1770 #if NETINET6
1771 		  case AF_INET6:
1772 			if (isascii(*port) && isdigit(*port))
1773 				d->d_addr.sin6.sin6_port = htons((unsigned short)
1774 								  atoi(port));
1775 			else
1776 			{
1777 # ifdef NO_GETSERVBYNAME
1778 				syserr("554 5.3.5 invalid port number: %s",
1779 				       port);
1780 # else /* NO_GETSERVBYNAME */
1781 				register struct servent *sp;
1782 
1783 				sp = getservbyname(port, "tcp");
1784 				if (sp == NULL)
1785 					syserr("554 5.3.5 service \"%s\" unknown",
1786 					       port);
1787 				else
1788 					d->d_addr.sin6.sin6_port = sp->s_port;
1789 # endif /* NO_GETSERVBYNAME */
1790 			}
1791 			break;
1792 #endif /* NETINET6 */
1793 
1794 #if NETISO
1795 		  case AF_ISO:
1796 			/* assume two byte transport selector */
1797 			if (isascii(*port) && isdigit(*port))
1798 				portno = htons((unsigned short) atoi(port));
1799 			else
1800 			{
1801 # ifdef NO_GETSERVBYNAME
1802 				syserr("554 5.3.5 invalid port number: %s",
1803 				       port);
1804 # else /* NO_GETSERVBYNAME */
1805 				register struct servent *sp;
1806 
1807 				sp = getservbyname(port, "tcp");
1808 				if (sp == NULL)
1809 					syserr("554 5.3.5 service \"%s\" unknown",
1810 					       port);
1811 				else
1812 					portno = sp->s_port;
1813 # endif /* NO_GETSERVBYNAME */
1814 			}
1815 			memmove(TSEL(&d->d_addr.siso),
1816 				(char *) &portno, 2);
1817 			break;
1818 #endif /* NETISO */
1819 
1820 		  default:
1821 			syserr("554 5.3.5 Port= option unsupported for family %d",
1822 			       d->d_addr.sa.sa_family);
1823 			break;
1824 		}
1825 	}
1826 }
1827 /*
1828 **  SETDAEMONOPTIONS -- set options for running the MTA daemon
1829 **
1830 **	Parameters:
1831 **		p -- the options line.
1832 **
1833 **	Returns:
1834 **		true if successful, false otherwise.
1835 **
1836 **	Side Effects:
1837 **		increments number of daemons.
1838 */
1839 
1840 #define DEF_LISTENQUEUE	10
1841 
1842 struct dflags
1843 {
1844 	char	*d_name;
1845 	int	d_flag;
1846 };
1847 
1848 static struct dflags	DaemonFlags[] =
1849 {
1850 	{ "AUTHREQ",		D_AUTHREQ	},
1851 	{ "BINDIF",		D_BINDIF	},
1852 	{ "CANONREQ",		D_CANONREQ	},
1853 	{ "IFNHELO",		D_IFNHELO	},
1854 	{ "FQMAIL",		D_FQMAIL	},
1855 	{ "FQRCPT",		D_FQRCPT	},
1856 	{ "SMTPS",		D_SMTPS		},
1857 	{ "UNQUALOK",		D_UNQUALOK	},
1858 	{ "NOAUTH",		D_NOAUTH	},
1859 	{ "NOCANON",		D_NOCANON	},
1860 	{ "NOETRN",		D_NOETRN	},
1861 	{ "NOTLS",		D_NOTLS		},
1862 	{ "ETRNONLY",		D_ETRNONLY	},
1863 	{ "OPTIONAL",		D_OPTIONAL	},
1864 	{ "DISABLE",		D_DISABLE	},
1865 	{ "ISSET",		D_ISSET		},
1866 	{ NULL,			0		}
1867 };
1868 
1869 static void
1870 printdaemonflags(d)
1871 	DAEMON_T *d;
1872 {
1873 	register struct dflags *df;
1874 	bool first = true;
1875 
1876 	for (df = DaemonFlags; df->d_name != NULL; df++)
1877 	{
1878 		if (!bitnset(df->d_flag, d->d_flags))
1879 			continue;
1880 		if (first)
1881 			sm_dprintf("<%s", df->d_name);
1882 		else
1883 			sm_dprintf(",%s", df->d_name);
1884 		first = false;
1885 	}
1886 	if (!first)
1887 		sm_dprintf(">");
1888 }
1889 
1890 bool
1891 setdaemonoptions(p)
1892 	register char *p;
1893 {
1894 	if (NDaemons >= MAXDAEMONS)
1895 		return false;
1896 	Daemons[NDaemons].d_socket = -1;
1897 	Daemons[NDaemons].d_listenqueue = DEF_LISTENQUEUE;
1898 	clrbitmap(Daemons[NDaemons].d_flags);
1899 	setsockaddroptions(p, &Daemons[NDaemons]);
1900 
1901 #if MILTER
1902 	if (Daemons[NDaemons].d_inputfilterlist != NULL)
1903 		Daemons[NDaemons].d_inputfilterlist = newstr(Daemons[NDaemons].d_inputfilterlist);
1904 #endif
1905 
1906 	if (Daemons[NDaemons].d_name != NULL)
1907 		Daemons[NDaemons].d_name = newstr(Daemons[NDaemons].d_name);
1908 	else
1909 	{
1910 		char num[30];
1911 
1912 		(void) sm_snprintf(num, sizeof(num), "Daemon%d", NDaemons);
1913 		Daemons[NDaemons].d_name = newstr(num);
1914 	}
1915 
1916 	if (tTd(37, 1))
1917 	{
1918 		sm_dprintf("Daemon %s flags: ", Daemons[NDaemons].d_name);
1919 		printdaemonflags(&Daemons[NDaemons]);
1920 		sm_dprintf("\n");
1921 	}
1922 	++NDaemons;
1923 	return true;
1924 }
1925 /*
1926 **  INITDAEMON -- initialize daemon if not yet done.
1927 **
1928 **	Parameters:
1929 **		none
1930 **
1931 **	Returns:
1932 **		none
1933 **
1934 **	Side Effects:
1935 **		initializes structure for one daemon.
1936 */
1937 
1938 void
1939 initdaemon()
1940 {
1941 	if (NDaemons == 0)
1942 	{
1943 		Daemons[NDaemons].d_socket = -1;
1944 		Daemons[NDaemons].d_listenqueue = DEF_LISTENQUEUE;
1945 		Daemons[NDaemons].d_name = "Daemon0";
1946 		NDaemons = 1;
1947 	}
1948 }
1949 /*
1950 **  SETCLIENTOPTIONS -- set options for running the client
1951 **
1952 **	Parameters:
1953 **		p -- the options line.
1954 **
1955 **	Returns:
1956 **		none.
1957 */
1958 
1959 static DAEMON_T	ClientSettings[AF_MAX + 1];
1960 
1961 void
1962 setclientoptions(p)
1963 	register char *p;
1964 {
1965 	int family;
1966 	DAEMON_T d;
1967 
1968 	memset(&d, '\0', sizeof(d));
1969 	setsockaddroptions(p, &d);
1970 
1971 	/* grab what we need */
1972 	family = d.d_addr.sa.sa_family;
1973 	STRUCTCOPY(d, ClientSettings[family]);
1974 	setbitn(D_ISSET, ClientSettings[family].d_flags); /* mark as set */
1975 	if (d.d_name != NULL)
1976 		ClientSettings[family].d_name = newstr(d.d_name);
1977 	else
1978 	{
1979 		char num[30];
1980 
1981 		(void) sm_snprintf(num, sizeof(num), "Client%d", family);
1982 		ClientSettings[family].d_name = newstr(num);
1983 	}
1984 }
1985 /*
1986 **  ADDR_FAMILY -- determine address family from address
1987 **
1988 **	Parameters:
1989 **		addr -- the string representation of the address
1990 **
1991 **	Returns:
1992 **		AF_INET, AF_INET6 or AF_UNSPEC
1993 **
1994 **	Side Effects:
1995 **		none.
1996 */
1997 
1998 static int
1999 addr_family(addr)
2000 	char *addr;
2001 {
2002 #if NETINET6
2003 	SOCKADDR clt_addr;
2004 #endif
2005 
2006 #if NETINET
2007 	if (inet_addr(addr) != INADDR_NONE)
2008 	{
2009 		if (tTd(16, 9))
2010 			sm_dprintf("addr_family(%s): INET\n", addr);
2011 		return AF_INET;
2012 	}
2013 #endif /* NETINET */
2014 #if NETINET6
2015 	if (anynet_pton(AF_INET6, addr, &clt_addr.sin6.sin6_addr) == 1)
2016 	{
2017 		if (tTd(16, 9))
2018 			sm_dprintf("addr_family(%s): INET6\n", addr);
2019 		return AF_INET6;
2020 	}
2021 #endif /* NETINET6 */
2022 #if NETUNIX
2023 	if (*addr == '/')
2024 	{
2025 		if (tTd(16, 9))
2026 			sm_dprintf("addr_family(%s): LOCAL\n", addr);
2027 		return AF_UNIX;
2028 	}
2029 #endif /* NETUNIX */
2030 	if (tTd(16, 9))
2031 		sm_dprintf("addr_family(%s): UNSPEC\n", addr);
2032 	return AF_UNSPEC;
2033 }
2034 
2035 /*
2036 **  CHKCLIENTMODIFIERS -- check whether all clients have set a flag.
2037 **
2038 **	Parameters:
2039 **		flag -- the flag to test.
2040 **
2041 **	Returns:
2042 **		true iff all configured clients have set the flag.
2043 */
2044 
2045 bool
2046 chkclientmodifiers(flag)
2047 	int flag;
2048 {
2049 	int i;
2050 	bool flagisset;
2051 
2052 	flagisset = false;
2053 	for (i = 0; i < AF_MAX; i++)
2054 	{
2055 		if (bitnset(D_ISSET, ClientSettings[i].d_flags))
2056 		{
2057 			if (!bitnset((char) flag, ClientSettings[i].d_flags))
2058 				return false;
2059 			flagisset = true;
2060 		}
2061 	}
2062 	return flagisset;
2063 }
2064 
2065 #if MILTER
2066 /*
2067 **  SETUP_DAEMON_MILTERS -- Parse per-socket filters
2068 **
2069 **	Parameters:
2070 **		none
2071 **
2072 **	Returns:
2073 **		none
2074 */
2075 
2076 void
2077 setup_daemon_milters()
2078 {
2079 	int idx;
2080 
2081 	if (OpMode == MD_SMTP)
2082 	{
2083 		/* no need to configure the daemons */
2084 		return;
2085 	}
2086 
2087 	for (idx = 0; idx < NDaemons; idx++)
2088 	{
2089 		if (Daemons[idx].d_inputfilterlist != NULL)
2090 		{
2091 			milter_config(Daemons[idx].d_inputfilterlist,
2092 				      Daemons[idx].d_inputfilters,
2093 				      MAXFILTERS);
2094 		}
2095 	}
2096 }
2097 #endif /* MILTER */
2098 /*
2099 **  MAKECONNECTION -- make a connection to an SMTP socket on a machine.
2100 **
2101 **	Parameters:
2102 **		host -- the name of the host.
2103 **		port -- the port number to connect to.
2104 **		mci -- a pointer to the mail connection information
2105 **			structure to be filled in.
2106 **		e -- the current envelope.
2107 **		enough -- time at which to stop further connection attempts.
2108 **			(0 means no limit)
2109 **
2110 **	Returns:
2111 **		An exit code telling whether the connection could be
2112 **			made and if not why not.
2113 **
2114 **	Side Effects:
2115 **		none.
2116 */
2117 
2118 static jmp_buf	CtxConnectTimeout;
2119 
2120 SOCKADDR	CurHostAddr;		/* address of current host */
2121 
2122 int
2123 makeconnection(host, port, mci, e, enough
2124 #if DANE
2125 	, ptlsa_flags
2126 #endif
2127 	)
2128 	char *host;
2129 	volatile unsigned int port;
2130 	register MCI *mci;
2131 	ENVELOPE *e;
2132 	time_t enough;
2133 #if DANE
2134 	unsigned long *ptlsa_flags;
2135 #endif
2136 {
2137 	register volatile int addrno = 0;
2138 	volatile int s;
2139 	register struct hostent *volatile hp = (struct hostent *) NULL;
2140 	SOCKADDR addr;
2141 	SOCKADDR clt_addr;
2142 	int save_errno = 0;
2143 	volatile SOCKADDR_LEN_T addrlen;
2144 	volatile bool firstconnect = true;
2145 	SM_EVENT *volatile ev = NULL;
2146 #if NETINET6
2147 	volatile bool v6found = false;
2148 #endif
2149 	volatile int family = InetMode;
2150 	SOCKADDR_LEN_T len;
2151 	volatile SOCKADDR_LEN_T socksize = 0;
2152 	volatile bool clt_bind;
2153 	BITMAP256 d_flags;
2154 	char *p;
2155 	extern ENVELOPE BlankEnvelope;
2156 #if DANE
2157 	unsigned long tlsa_flags;
2158 #endif
2159 #if DANE && NETINET6
2160 	struct hostent *volatile hs = (struct hostent *) NULL;
2161 #else
2162 # define hs ((struct hostent *) NULL)
2163 #endif
2164 
2165 #if DANE
2166 	SM_REQUIRE(ptlsa_flags != NULL);
2167 	tlsa_flags = *ptlsa_flags;
2168 	*ptlsa_flags &= ~(TLSAFLALWAYS|TLSAFLSECURE);
2169 #endif
2170 
2171 	/* retranslate {daemon_flags} into bitmap */
2172 	clrbitmap(d_flags);
2173 	if ((p = macvalue(macid("{daemon_flags}"), e)) != NULL)
2174 	{
2175 		for (; *p != '\0'; p++)
2176 		{
2177 			if (!(SM_ISSPACE(*p)))
2178 				setbitn(bitidx(*p), d_flags);
2179 		}
2180 	}
2181 
2182 #if NETINET6
2183  v4retry:
2184 #endif
2185 	clt_bind = false;
2186 
2187 	/* Set up the address for outgoing connection. */
2188 	if (bitnset(D_BINDIF, d_flags) &&
2189 	    (p = macvalue(macid("{if_addr}"), e)) != NULL &&
2190 	    *p != '\0')
2191 	{
2192 #if NETINET6
2193 		char p6[INET6_ADDRSTRLEN];
2194 #endif
2195 
2196 		memset(&clt_addr, '\0', sizeof(clt_addr));
2197 
2198 		/* infer the address family from the address itself */
2199 		clt_addr.sa.sa_family = addr_family(p);
2200 		switch (clt_addr.sa.sa_family)
2201 		{
2202 #if NETINET
2203 		  case AF_INET:
2204 			clt_addr.sin.sin_addr.s_addr = inet_addr(p);
2205 			if (clt_addr.sin.sin_addr.s_addr != INADDR_NONE &&
2206 			    clt_addr.sin.sin_addr.s_addr !=
2207 				htonl(INADDR_LOOPBACK))
2208 			{
2209 				clt_bind = true;
2210 				socksize = sizeof(struct sockaddr_in);
2211 			}
2212 			break;
2213 #endif /* NETINET */
2214 
2215 #if NETINET6
2216 		  case AF_INET6:
2217 			if (inet_addr(p) != INADDR_NONE)
2218 				(void) sm_snprintf(p6, sizeof(p6),
2219 						   "IPv6:::ffff:%s", p);
2220 			else
2221 				(void) sm_strlcpy(p6, p, sizeof(p6));
2222 			if (anynet_pton(AF_INET6, p6,
2223 					&clt_addr.sin6.sin6_addr) == 1 &&
2224 			    !IN6_IS_ADDR_LOOPBACK(&clt_addr.sin6.sin6_addr))
2225 			{
2226 				clt_bind = true;
2227 				socksize = sizeof(struct sockaddr_in6);
2228 			}
2229 			break;
2230 #endif /* NETINET6 */
2231 
2232 #if 0
2233 		  default:
2234 			syserr("554 5.3.5 Address= option unsupported for family %d",
2235 			       clt_addr.sa.sa_family);
2236 			break;
2237 #endif /* 0 */
2238 		}
2239 		if (clt_bind)
2240 			family = clt_addr.sa.sa_family;
2241 	}
2242 
2243 	/* D_BINDIF not set or not available, fallback to ClientPortOptions */
2244 	if (!clt_bind)
2245 	{
2246 		STRUCTCOPY(ClientSettings[family].d_addr, clt_addr);
2247 		switch (clt_addr.sa.sa_family)
2248 		{
2249 #if NETINET
2250 		  case AF_INET:
2251 			if (clt_addr.sin.sin_addr.s_addr == 0)
2252 				clt_addr.sin.sin_addr.s_addr = LocalDaemon ?
2253 					htonl(INADDR_LOOPBACK) : INADDR_ANY;
2254 			else
2255 				clt_bind = true;
2256 			if (clt_addr.sin.sin_port != 0)
2257 				clt_bind = true;
2258 			socksize = sizeof(struct sockaddr_in);
2259 			break;
2260 #endif /* NETINET */
2261 #if NETINET6
2262 		  case AF_INET6:
2263 			if (IN6_IS_ADDR_UNSPECIFIED(&clt_addr.sin6.sin6_addr))
2264 				clt_addr.sin6.sin6_addr =
2265 					(LocalDaemon && V6LoopbackAddrFound) ?
2266 					in6addr_loopback : in6addr_any;
2267 			else
2268 				clt_bind = true;
2269 			socksize = sizeof(struct sockaddr_in6);
2270 			if (clt_addr.sin6.sin6_port != 0)
2271 				clt_bind = true;
2272 			break;
2273 #endif /* NETINET6 */
2274 #if NETISO
2275 		  case AF_ISO:
2276 			socksize = sizeof(clt_addr.siso);
2277 			clt_bind = true;
2278 			break;
2279 #endif /* NETISO */
2280 		  default:
2281 			break;
2282 		}
2283 	}
2284 
2285 	/*
2286 	**  Set up the address for the mailer.
2287 	**	Accept "[a.b.c.d]" syntax for host name.
2288 	*/
2289 
2290 	SM_SET_H_ERRNO(0);
2291 	errno = 0;
2292 	memset(&CurHostAddr, '\0', sizeof(CurHostAddr));
2293 	memset(&addr, '\0', sizeof(addr));
2294 	SmtpPhase = mci->mci_phase = "initial connection";
2295 	CurHostName = host;
2296 
2297 	if (host[0] == '[')
2298 	{
2299 		p = strchr(host, ']');
2300 		if (p != NULL)
2301 		{
2302 #if NETINET
2303 			unsigned long hid = INADDR_NONE;
2304 #endif
2305 #if NETINET6
2306 			struct sockaddr_in6 hid6;
2307 #endif
2308 
2309 			*p = '\0';
2310 #if NETINET6
2311 			memset(&hid6, '\0', sizeof(hid6));
2312 #endif
2313 #if NETINET
2314 			if (family == AF_INET &&
2315 			    (hid = inet_addr(&host[1])) != INADDR_NONE)
2316 			{
2317 				addr.sin.sin_family = AF_INET;
2318 				addr.sin.sin_addr.s_addr = hid;
2319 			}
2320 			else
2321 #endif /* NETINET */
2322 #if NETINET6
2323 			if (family == AF_INET6 &&
2324 			    anynet_pton(AF_INET6, &host[1],
2325 					&hid6.sin6_addr) == 1)
2326 			{
2327 				addr.sin6.sin6_family = AF_INET6;
2328 				addr.sin6.sin6_addr = hid6.sin6_addr;
2329 			}
2330 			else
2331 #endif /* NETINET6 */
2332 			{
2333 				/* try it as a host name (avoid MX lookup) */
2334 				hp = sm_gethostbyname(&host[1], family);
2335 				if (hp == NULL && p[-1] == '.')
2336 				{
2337 #if NAMED_BIND
2338 					int oldopts = _res.options;
2339 
2340 					_res.options &= ~(RES_DEFNAMES|RES_DNSRCH);
2341 #endif /* NAMED_BIND */
2342 					p[-1] = '\0';
2343 					hp = sm_gethostbyname(&host[1],
2344 							      family);
2345 					p[-1] = '.';
2346 #if NAMED_BIND
2347 					_res.options = oldopts;
2348 #endif
2349 				}
2350 				*p = ']';
2351 				goto gothostent;
2352 			}
2353 			*p = ']';
2354 		}
2355 		if (p == NULL)
2356 		{
2357 			extern char MsgBuf[];
2358 
2359 			usrerrenh("5.1.2",
2360 				  "553 Invalid numeric domain spec \"%s\"",
2361 				  host);
2362 			mci_setstat(mci, EX_NOHOST, "5.1.2", MsgBuf);
2363 			errno = EINVAL;
2364 			return EX_NOHOST;
2365 		}
2366 	}
2367 	else
2368 	{
2369 		/* contortion to get around SGI cc complaints */
2370 		{
2371 			p = &host[strlen(host) - 1];
2372 #if DANE
2373 			if (tTd(16, 40))
2374 				sm_dprintf("makeconnection: tlsa_flags=%lX, host=%s\n",
2375 					tlsa_flags, host);
2376 			if (DANEMODE(tlsa_flags) == DANE_SECURE
2377 # if DNSSEC_TEST
2378 			    || tTd(8, 120)
2379 # endif
2380 			    )
2381 			{
2382 				DNS_REPLY_T *rr;
2383 				int err, herr;
2384 
2385 				rr = dns_lookup_int(host, C_IN, FAM2T_(family),
2386 					0, 0, SM_RES_DNSSEC, 0, &err, &herr);
2387 
2388 				/*
2389 				**  Check for errors!
2390 				**  If no ad: turn off TLSA.
2391 				**  permail: use "normal" method?
2392 				**  tempfail: delay or use "normal" method?
2393 				*/
2394 
2395 				if (rr != NULL && rr->dns_r_h.ad == 1)
2396 				{
2397 					*ptlsa_flags |= DANE_SECURE;
2398 					if ((TLSAFLTEMP & *ptlsa_flags) != 0)
2399 					{
2400 						dns_free_data(rr);
2401 						rr = NULL;
2402 						return EX_TEMPFAIL;
2403 					}
2404 					hp = dns2he(rr, family);
2405 #if NETINET6
2406 					hs = hp;
2407 #endif
2408 				}
2409 
2410 				/* other possible "tempfails"? */
2411 				if (rr == NULL && h_errno == TRY_AGAIN)
2412 					goto gothostent;
2413 
2414 				dns_free_data(rr);
2415 				rr = NULL;
2416 			}
2417 #endif
2418 			if (hp == NULL)
2419 				hp = sm_gethostbyname(host, family);
2420 			if (hp == NULL && *p == '.')
2421 			{
2422 #if NAMED_BIND
2423 				int oldopts = _res.options;
2424 
2425 				_res.options &= ~(RES_DEFNAMES|RES_DNSRCH);
2426 #endif
2427 				*p = '\0';
2428 				hp = sm_gethostbyname(host, family);
2429 				*p = '.';
2430 #if NAMED_BIND
2431 				_res.options = oldopts;
2432 #endif
2433 			}
2434 		}
2435 gothostent:
2436 		if (hp == NULL || hp->h_addr == NULL)
2437 		{
2438 #if NAMED_BIND
2439 			/* check for name server timeouts */
2440 # if NETINET6
2441 			if (WorkAroundBrokenAAAA && family == AF_INET6 &&
2442 			    (h_errno == TRY_AGAIN || errno == ETIMEDOUT))
2443 			{
2444 				/*
2445 				**  An attempt with family AF_INET may
2446 				**  succeed. By skipping the next section
2447 				**  of code, we will try AF_INET before
2448 				**  failing.
2449 				*/
2450 
2451 				if (tTd(16, 10))
2452 					sm_dprintf("makeconnection: WorkAroundBrokenAAAA: Trying AF_INET lookup (AF_INET6 failed)\n");
2453 			}
2454 			else
2455 # endif /* NETINET6 */
2456 			{
2457 				if (errno == ETIMEDOUT ||
2458 # if _FFR_GETHBN_ExFILE
2459 #  ifdef EMFILE
2460 				   errno == EMFILE ||
2461 #  endif
2462 #  ifdef ENFILE
2463 				   errno == ENFILE ||
2464 #  endif
2465 # endif /* _FFR_GETHBN_ExFILE */
2466 				    h_errno == TRY_AGAIN ||
2467 				    (errno == ECONNREFUSED && UseNameServer))
2468 				{
2469 					save_errno = errno;
2470 					mci_setstat(mci, EX_TEMPFAIL,
2471 						    "4.4.3", NULL);
2472 					errno = save_errno;
2473 					return EX_TEMPFAIL;
2474 				}
2475 			}
2476 #endif /* NAMED_BIND */
2477 #if NETINET6
2478 			/*
2479 			**  Try v6 first, then fall back to v4.
2480 			**  If we found a v6 address, but no v4
2481 			**  addresses, then TEMPFAIL.
2482 			*/
2483 
2484 			if (family == AF_INET6)
2485 			{
2486 				family = AF_INET;
2487 				goto v4retry;
2488 			}
2489 			if (v6found)
2490 				goto v6tempfail;
2491 #endif /* NETINET6 */
2492 			save_errno = errno;
2493 			mci_setstat(mci, EX_NOHOST, "5.1.2", NULL);
2494 			errno = save_errno;
2495 			return EX_NOHOST;
2496 		}
2497 		addr.sa.sa_family = hp->h_addrtype;
2498 		switch (hp->h_addrtype)
2499 		{
2500 #if NETINET
2501 		  case AF_INET:
2502 			memmove(&addr.sin.sin_addr,
2503 				hp->h_addr,
2504 				INADDRSZ);
2505 			break;
2506 #endif /* NETINET */
2507 
2508 #if NETINET6
2509 		  case AF_INET6:
2510 			memmove(&addr.sin6.sin6_addr,
2511 				hp->h_addr,
2512 				IN6ADDRSZ);
2513 			break;
2514 #endif /* NETINET6 */
2515 
2516 		  default:
2517 			if (hp->h_length > sizeof(addr.sa.sa_data))
2518 			{
2519 				syserr("makeconnection: long sa_data: family %d len %d",
2520 					hp->h_addrtype, hp->h_length);
2521 				mci_setstat(mci, EX_NOHOST, "5.1.2", NULL);
2522 				errno = EINVAL;
2523 				return EX_NOHOST;
2524 			}
2525 			memmove(addr.sa.sa_data, hp->h_addr, hp->h_length);
2526 			break;
2527 		}
2528 		addrno = 1;
2529 	}
2530 
2531 #if _FFR_TESTS
2532 		/*
2533 		**  Hack for testing.
2534 		**  Hardcoded:
2535 		**  10.1.1.12: see meta1.tns XREF IP address
2536 		**  8754: see common.sh XREF SNKPORT2
2537 		*/
2538 
2539 		if (tTd(77, 101) && hp->h_addrtype == AF_INET &&
2540 		    addr.sin.sin_addr.s_addr == inet_addr("10.1.1.12"))
2541 		{
2542 			addr.sin.sin_addr.s_addr = inet_addr("127.0.0.1");
2543 			port = htons(8754);
2544 			sm_dprintf("hack host=%s addr=[%s].%d\n", host,
2545 				anynet_ntoa(&addr), ntohs(port));
2546 		}
2547 #endif
2548 
2549 	/*
2550 	**  Determine the port number.
2551 	*/
2552 
2553 	if (port == 0)
2554 	{
2555 #ifdef NO_GETSERVBYNAME
2556 		port = htons(25);
2557 #else /* NO_GETSERVBYNAME */
2558 		register struct servent *sp = getservbyname("smtp", "tcp");
2559 
2560 		if (sp == NULL)
2561 		{
2562 			if (LogLevel > 2)
2563 				sm_syslog(LOG_ERR, NOQID,
2564 					  "makeconnection: service \"smtp\" unknown");
2565 			port = htons(25);
2566 		}
2567 		else
2568 			port = sp->s_port;
2569 #endif /* NO_GETSERVBYNAME */
2570 	}
2571 
2572 #if NETINET6
2573 	if (addr.sa.sa_family == AF_INET6 &&
2574 	    IN6_IS_ADDR_V4MAPPED(&addr.sin6.sin6_addr) &&
2575 	    ClientSettings[AF_INET].d_addr.sa.sa_family != 0)
2576 	{
2577 		/*
2578 		**  Ignore mapped IPv4 address since
2579 		**  there is a ClientPortOptions setting
2580 		**  for IPv4.
2581 		*/
2582 
2583 		goto nextaddr;
2584 	}
2585 #endif /* NETINET6 */
2586 
2587 	switch (addr.sa.sa_family)
2588 	{
2589 #if NETINET
2590 	  case AF_INET:
2591 		addr.sin.sin_port = port;
2592 		addrlen = sizeof(struct sockaddr_in);
2593 		break;
2594 #endif /* NETINET */
2595 
2596 #if NETINET6
2597 	  case AF_INET6:
2598 		addr.sin6.sin6_port = port;
2599 		addrlen = sizeof(struct sockaddr_in6);
2600 		break;
2601 #endif /* NETINET6 */
2602 
2603 #if NETISO
2604 	  case AF_ISO:
2605 		/* assume two byte transport selector */
2606 		memmove(TSEL((struct sockaddr_iso *) &addr), (char *) &port, 2);
2607 		addrlen = sizeof(struct sockaddr_iso);
2608 		break;
2609 #endif /* NETISO */
2610 
2611 	  default:
2612 		syserr("Can't connect to address family %d", addr.sa.sa_family);
2613 		mci_setstat(mci, EX_NOHOST, "5.1.2", NULL);
2614 		errno = EINVAL;
2615 		FREEHOSTENT(hp, hs);
2616 		return EX_NOHOST;
2617 	}
2618 
2619 	/*
2620 	**  Try to actually open the connection.
2621 	*/
2622 
2623 #if XLA
2624 	/* if too many connections, don't bother trying */
2625 	if (!xla_noqueue_ok(host))
2626 	{
2627 		FREEHOSTENT(hp, hs);
2628 		return EX_TEMPFAIL;
2629 	}
2630 #endif /* XLA */
2631 
2632 #if _FFR_OCC
2633 # define OCC_CLOSE occ_close(e, mci, host, &addr)
2634 	/* HACK!!!! just to see if this can work at all... */
2635 	if (occ_exceeded(e, mci, host, &addr))
2636 	{
2637 		FREEHOSTENT(hp, hs);
2638 		sm_syslog(LOG_DEBUG, e->e_id,
2639 			"stat=occ_exceeded, host=%s, addr=%s",
2640 			host, anynet_ntoa(&addr));
2641 
2642 		/*
2643 		**  to get a more specific stat= message set errno
2644 		**  or make up one in sm, see sm_errstring()
2645 		*/
2646 
2647 		mci_setstat(mci, EX_TEMPFAIL, "4.4.5", "450 occ_exceeded"); /* check D.S.N */
2648 		errno = EAGAIN;
2649 		return EX_TEMPFAIL;
2650 	}
2651 #else /* _FFR_OCC */
2652 # define OCC_CLOSE
2653 #endif /* _FFR_OCC */
2654 
2655 	for (;;)
2656 	{
2657 		if (tTd(16, 1))
2658 			sm_dprintf("makeconnection (%s [%s].%d (%d))\n",
2659 				   host, anynet_ntoa(&addr), ntohs(port),
2660 				   (int) addr.sa.sa_family);
2661 
2662 		/* save for logging */
2663 		CurHostAddr = addr;
2664 
2665 #if HASRRESVPORT
2666 		if (bitnset(M_SECURE_PORT, mci->mci_mailer->m_flags))
2667 		{
2668 			int rport = IPPORT_RESERVED - 1;
2669 
2670 			s = rresvport(&rport);
2671 		}
2672 		else
2673 #endif /* HASRRESVPORT */
2674 		{
2675 			s = socket(addr.sa.sa_family, SOCK_STREAM, 0);
2676 		}
2677 		if (s < 0)
2678 		{
2679 			save_errno = errno;
2680 			syserr("makeconnection: cannot create socket");
2681 #if XLA
2682 			xla_host_end(host);
2683 #endif
2684 			mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL);
2685 			FREEHOSTENT(hp, hs);
2686 			errno = save_errno;
2687 			OCC_CLOSE;
2688 			return EX_TEMPFAIL;
2689 		}
2690 
2691 #ifdef SO_SNDBUF
2692 		if (ClientSettings[family].d_tcpsndbufsize > 0)
2693 		{
2694 			if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
2695 				       (char *) &ClientSettings[family].d_tcpsndbufsize,
2696 				       sizeof(ClientSettings[family].d_tcpsndbufsize)) < 0)
2697 				syserr("makeconnection: setsockopt(SO_SNDBUF)");
2698 		}
2699 #endif /* SO_SNDBUF */
2700 #ifdef SO_RCVBUF
2701 		if (ClientSettings[family].d_tcprcvbufsize > 0)
2702 		{
2703 			if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
2704 				       (char *) &ClientSettings[family].d_tcprcvbufsize,
2705 				       sizeof(ClientSettings[family].d_tcprcvbufsize)) < 0)
2706 				syserr("makeconnection: setsockopt(SO_RCVBUF)");
2707 		}
2708 #endif /* SO_RCVBUF */
2709 
2710 		if (tTd(16, 1))
2711 			sm_dprintf("makeconnection: fd=%d\n", s);
2712 
2713 		/* turn on network debugging? */
2714 		if (tTd(16, 101))
2715 		{
2716 			int on = 1;
2717 
2718 			(void) setsockopt(s, SOL_SOCKET, SO_DEBUG,
2719 					  (char *)&on, sizeof(on));
2720 		}
2721 		if (e->e_xfp != NULL)	/* for debugging */
2722 			(void) sm_io_flush(e->e_xfp, SM_TIME_DEFAULT);
2723 		errno = 0;		/* for debugging */
2724 
2725 		if (clt_bind)
2726 		{
2727 			int on = 1;
2728 
2729 			switch (clt_addr.sa.sa_family)
2730 			{
2731 #if NETINET
2732 			  case AF_INET:
2733 				if (clt_addr.sin.sin_port != 0)
2734 					(void) setsockopt(s, SOL_SOCKET,
2735 							  SO_REUSEADDR,
2736 							  (char *) &on,
2737 							  sizeof(on));
2738 				break;
2739 #endif /* NETINET */
2740 
2741 #if NETINET6
2742 			  case AF_INET6:
2743 				if (clt_addr.sin6.sin6_port != 0)
2744 					(void) setsockopt(s, SOL_SOCKET,
2745 							  SO_REUSEADDR,
2746 							  (char *) &on,
2747 							  sizeof(on));
2748 				break;
2749 #endif /* NETINET6 */
2750 			}
2751 
2752 			if (bind(s, &clt_addr.sa, socksize) < 0)
2753 			{
2754 				save_errno = errno;
2755 				(void) close(s);
2756 				errno = save_errno;
2757 				syserr("makeconnection: cannot bind socket [%s]",
2758 				       anynet_ntoa(&clt_addr));
2759 				FREEHOSTENT(hp, hs);
2760 				errno = save_errno;
2761 				OCC_CLOSE;
2762 				return EX_TEMPFAIL;
2763 			}
2764 		}
2765 
2766 		/*
2767 		**  Linux seems to hang in connect for 90 minutes (!!!).
2768 		**  Time out the connect to avoid this problem.
2769 		*/
2770 
2771 		if (setjmp(CtxConnectTimeout) == 0)
2772 		{
2773 			int i;
2774 
2775 			if (e->e_ntries <= 0 && TimeOuts.to_iconnect != 0)
2776 				ev = sm_setevent(TimeOuts.to_iconnect,
2777 						 connecttimeout, 0);
2778 			else if (TimeOuts.to_connect != 0)
2779 				ev = sm_setevent(TimeOuts.to_connect,
2780 						 connecttimeout, 0);
2781 			else
2782 				ev = NULL;
2783 
2784 			switch (ConnectOnlyTo.sa.sa_family)
2785 			{
2786 #if NETINET
2787 			  case AF_INET:
2788 				addr.sin.sin_addr.s_addr = ConnectOnlyTo.sin.sin_addr.s_addr;
2789 				addr.sa.sa_family = ConnectOnlyTo.sa.sa_family;
2790 				if (ConnectOnlyTo.sin.sin_port != 0)
2791 				{
2792 					port = ConnectOnlyTo.sin.sin_port;
2793 					addr.sin.sin_port = port;
2794 				}
2795 				break;
2796 #endif /* NETINET */
2797 
2798 #if NETINET6
2799 			  case AF_INET6:
2800 				memmove(&addr.sin6.sin6_addr,
2801 					&ConnectOnlyTo.sin6.sin6_addr,
2802 					IN6ADDRSZ);
2803 				if (ConnectOnlyTo.sin6.sin6_port != 0)
2804 				{
2805 					port = ConnectOnlyTo.sin6.sin6_port;
2806 					addr.sin6.sin6_port = port;
2807 				}
2808 				break;
2809 #endif /* NETINET6 */
2810 			}
2811 			if (tTd(16, 1))
2812 				sm_dprintf("Connecting to [%s].%d...\n",
2813 					anynet_ntoa(&addr), ntohs(port));
2814 
2815 			i = connect(s, (struct sockaddr *) &addr, addrlen);
2816 			save_errno = errno;
2817 			if (ev != NULL)
2818 				sm_clrevent(ev);
2819 			if (i >= 0)
2820 				break;
2821 		}
2822 		else
2823 			save_errno = errno;
2824 
2825 		/* couldn't connect.... figure out why */
2826 		(void) close(s);
2827 
2828 		/* if running demand-dialed connection, try again */
2829 		if (DialDelay > 0 && firstconnect &&
2830 		    bitnset(M_DIALDELAY, mci->mci_mailer->m_flags))
2831 		{
2832 			if (tTd(16, 1))
2833 				sm_dprintf("Connect failed (%s); trying again...\n",
2834 					   sm_errstring(save_errno));
2835 			firstconnect = false;
2836 			(void) sleep(DialDelay);
2837 			continue;
2838 		}
2839 
2840 		if (LogLevel > 13)
2841 			sm_syslog(LOG_INFO, e->e_id,
2842 				  "makeconnection (%s [%s].%d (%d)) failed: %s",
2843 				  host, anynet_ntoa(&addr), ntohs(port),
2844 				  (int) addr.sa.sa_family,
2845 				  sm_errstring(save_errno));
2846 
2847 #if NETINET6
2848 nextaddr:
2849 #endif /* NETINET6 */
2850 		if (hp != NULL && hp->h_addr_list[addrno] != NULL &&
2851 		    (enough == 0 || curtime() < enough))
2852 		{
2853 			if (tTd(16, 1))
2854 				sm_dprintf("Connect failed (%s); trying new address....\n",
2855 					   sm_errstring(save_errno));
2856 			switch (addr.sa.sa_family)
2857 			{
2858 #if NETINET
2859 			  case AF_INET:
2860 				memmove(&addr.sin.sin_addr,
2861 					hp->h_addr_list[addrno++],
2862 					INADDRSZ);
2863 				break;
2864 #endif /* NETINET */
2865 
2866 #if NETINET6
2867 			  case AF_INET6:
2868 				memmove(&addr.sin6.sin6_addr,
2869 					hp->h_addr_list[addrno++],
2870 					IN6ADDRSZ);
2871 				break;
2872 #endif /* NETINET6 */
2873 
2874 			  default:
2875 				memmove(addr.sa.sa_data,
2876 					hp->h_addr_list[addrno++],
2877 					hp->h_length);
2878 				break;
2879 			}
2880 			continue;
2881 		}
2882 		errno = save_errno;
2883 
2884 #if NETINET6
2885 		if (family == AF_INET6)
2886 		{
2887 			if (tTd(16, 1))
2888 				sm_dprintf("Connect failed (%s); retrying with AF_INET....\n",
2889 					   sm_errstring(save_errno));
2890 			v6found = true;
2891 			family = AF_INET;
2892 			FREEHOSTENT(hp, hs);
2893 			goto v4retry;
2894 		}
2895 	v6tempfail:
2896 #endif /* NETINET6 */
2897 		/* couldn't open connection */
2898 #if NETINET6
2899 		/* Don't clobber an already saved errno from v4retry */
2900 		if (errno > 0)
2901 #endif
2902 			save_errno = errno;
2903 		if (tTd(16, 1))
2904 			sm_dprintf("Connect failed (%s)\n",
2905 				   sm_errstring(save_errno));
2906 #if XLA
2907 		xla_host_end(host);
2908 #endif
2909 		mci_setstat(mci, EX_TEMPFAIL, "4.4.1", NULL);
2910 		FREEHOSTENT(hp, hs);
2911 		errno = save_errno;
2912 		OCC_CLOSE;
2913 		return EX_TEMPFAIL;
2914 	}
2915 
2916 	FREEHOSTENT(hp, hs);
2917 
2918 	/* connection ok, put it into canonical form */
2919 	mci->mci_out = NULL;
2920 	if ((mci->mci_out = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT,
2921 				       (void *) &s,
2922 				       SM_IO_WRONLY_B, NULL)) == NULL ||
2923 	    (s = dup(s)) < 0 ||
2924 	    (mci->mci_in = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT,
2925 				      (void *) &s,
2926 				      SM_IO_RDONLY_B, NULL)) == NULL)
2927 	{
2928 		save_errno = errno;
2929 		syserr("cannot open SMTP client channel, fd=%d", s);
2930 		mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL);
2931 		if (mci->mci_out != NULL)
2932 			(void) sm_io_close(mci->mci_out, SM_TIME_DEFAULT);
2933 		(void) close(s);
2934 		errno = save_errno;
2935 		OCC_CLOSE;
2936 		return EX_TEMPFAIL;
2937 	}
2938 	sm_io_automode(mci->mci_out, mci->mci_in);
2939 
2940 	/* set {client_flags} */
2941 	if (ClientSettings[addr.sa.sa_family].d_mflags != NULL)
2942 	{
2943 		macdefine(&mci->mci_macro, A_PERM,
2944 			  macid("{client_flags}"),
2945 			  ClientSettings[addr.sa.sa_family].d_mflags);
2946 	}
2947 	else
2948 		macdefine(&mci->mci_macro, A_PERM,
2949 			  macid("{client_flags}"), "");
2950 
2951 	/* "add" {client_flags} to bitmap */
2952 	if (bitnset(D_IFNHELO, ClientSettings[addr.sa.sa_family].d_flags))
2953 	{
2954 		/* look for just this one flag */
2955 		setbitn(D_IFNHELO, d_flags);
2956 	}
2957 
2958 	/* find out name for Interface through which we connect */
2959 	len = sizeof(addr);
2960 	if (getsockname(s, &addr.sa, &len) == 0)
2961 	{
2962 		char *name;
2963 
2964 		if (!isloopback(addr))
2965 		{
2966 			char familystr[5];
2967 
2968 			macdefine(&BlankEnvelope.e_macro, A_TEMP,
2969 				macid("{if_addr_out}"), anynet_ntoa(&addr));
2970 			(void) sm_snprintf(familystr, sizeof(familystr), "%d",
2971 				addr.sa.sa_family);
2972 			macdefine(&BlankEnvelope.e_macro, A_TEMP,
2973 				macid("{if_family_out}"), familystr);
2974 		}
2975 		else
2976 		{
2977 			macdefine(&BlankEnvelope.e_macro, A_PERM,
2978 				macid("{if_addr_out}"), NULL);
2979 			macdefine(&BlankEnvelope.e_macro, A_PERM,
2980 				macid("{if_family_out}"), NULL);
2981 		}
2982 
2983 		name = hostnamebyanyaddr(&addr);
2984 		macdefine(&BlankEnvelope.e_macro, A_TEMP,
2985 			macid("{if_name_out}"), name);
2986 		if (LogLevel > 11)
2987 		{
2988 			/* log connection information */
2989 			sm_syslog(LOG_INFO, e->e_id,
2990 				  "SMTP outgoing connect on %.40s", name);
2991 		}
2992 		if (bitnset(D_IFNHELO, d_flags))
2993 		{
2994 			if (name[0] != '[' && strchr(name, '.') != NULL)
2995 				mci->mci_heloname = newstr(name);
2996 		}
2997 	}
2998 	else
2999 	{
3000 		macdefine(&BlankEnvelope.e_macro, A_PERM,
3001 			macid("{if_name_out}"), NULL);
3002 		macdefine(&BlankEnvelope.e_macro, A_PERM,
3003 			macid("{if_addr_out}"), NULL);
3004 		macdefine(&BlankEnvelope.e_macro, A_PERM,
3005 			macid("{if_family_out}"), NULL);
3006 	}
3007 
3008 	/* Use the configured HeloName as appropriate */
3009 	if (HeloName != NULL && HeloName[0] != '\0')
3010 	{
3011 		SM_FREE(mci->mci_heloname);
3012 		mci->mci_heloname = newstr(HeloName);
3013 	}
3014 
3015 	mci_setstat(mci, EX_OK, NULL, NULL);
3016 	return EX_OK;
3017 }
3018 
3019 static void
3020 connecttimeout(ignore)
3021 	int ignore;
3022 {
3023 	/*
3024 	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
3025 	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
3026 	**	DOING.
3027 	*/
3028 
3029 	errno = ETIMEDOUT;
3030 	longjmp(CtxConnectTimeout, 1);
3031 }
3032 /*
3033 **  MAKECONNECTION_DS -- make a connection to a domain socket.
3034 **
3035 **	Parameters:
3036 **		mux_path -- the path of the socket to connect to.
3037 **		mci -- a pointer to the mail connection information
3038 **			structure to be filled in.
3039 **
3040 **	Returns:
3041 **		An exit code telling whether the connection could be
3042 **			made and if not why not.
3043 **
3044 **	Side Effects:
3045 **		none.
3046 */
3047 
3048 #if NETUNIX
3049 int
3050 makeconnection_ds(mux_path, mci)
3051 	char *mux_path;
3052 	register MCI *mci;
3053 {
3054 	int sock;
3055 	int rval, save_errno;
3056 	long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_ROOTOK|SFF_EXECOK;
3057 	struct sockaddr_un unix_addr;
3058 
3059 	/* if not safe, don't connect */
3060 	rval = safefile(mux_path, RunAsUid, RunAsGid, RunAsUserName,
3061 			sff, S_IRUSR|S_IWUSR, NULL);
3062 
3063 	if (rval != 0)
3064 	{
3065 		syserr("makeconnection_ds: unsafe domain socket %s",
3066 			mux_path);
3067 		mci_setstat(mci, EX_TEMPFAIL, "4.3.5", NULL);
3068 		errno = rval;
3069 		return EX_TEMPFAIL;
3070 	}
3071 
3072 	/* prepare address structure */
3073 	memset(&unix_addr, '\0', sizeof(unix_addr));
3074 	unix_addr.sun_family = AF_UNIX;
3075 
3076 	if (strlen(mux_path) >= sizeof(unix_addr.sun_path))
3077 	{
3078 		syserr("makeconnection_ds: domain socket name %s too long",
3079 			mux_path);
3080 
3081 		/* XXX why TEMPFAIL but 5.x.y ? */
3082 		mci_setstat(mci, EX_TEMPFAIL, "5.3.5", NULL);
3083 		errno = ENAMETOOLONG;
3084 		return EX_UNAVAILABLE;
3085 	}
3086 	(void) sm_strlcpy(unix_addr.sun_path, mux_path,
3087 			  sizeof(unix_addr.sun_path));
3088 
3089 	/* initialize domain socket */
3090 	sock = socket(AF_UNIX, SOCK_STREAM, 0);
3091 	if (sock == -1)
3092 	{
3093 		save_errno = errno;
3094 		syserr("makeconnection_ds: could not create domain socket %s",
3095 			mux_path);
3096 		mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL);
3097 		errno = save_errno;
3098 		return EX_TEMPFAIL;
3099 	}
3100 
3101 	/* connect to server */
3102 	if (connect(sock, (struct sockaddr *) &unix_addr,
3103 		    sizeof(unix_addr)) == -1)
3104 	{
3105 		save_errno = errno;
3106 		syserr("Could not connect to socket %s", mux_path);
3107 		mci_setstat(mci, EX_TEMPFAIL, "4.4.1", NULL);
3108 		(void) close(sock);
3109 		errno = save_errno;
3110 		return EX_TEMPFAIL;
3111 	}
3112 
3113 	/* connection ok, put it into canonical form */
3114 	mci->mci_out = NULL;
3115 	if ((mci->mci_out = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT,
3116 				       (void *) &sock, SM_IO_WRONLY_B, NULL))
3117 					== NULL
3118 	    || (sock = dup(sock)) < 0 ||
3119 	    (mci->mci_in = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT,
3120 				      (void *) &sock, SM_IO_RDONLY_B, NULL))
3121 					== NULL)
3122 	{
3123 		save_errno = errno;
3124 		syserr("cannot open SMTP client channel, fd=%d", sock);
3125 		mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL);
3126 		if (mci->mci_out != NULL)
3127 			(void) sm_io_close(mci->mci_out, SM_TIME_DEFAULT);
3128 		(void) close(sock);
3129 		errno = save_errno;
3130 		return EX_TEMPFAIL;
3131 	}
3132 	sm_io_automode(mci->mci_out, mci->mci_in);
3133 
3134 	mci_setstat(mci, EX_OK, NULL, NULL);
3135 	errno = 0;
3136 	return EX_OK;
3137 }
3138 #endif /* NETUNIX */
3139 /*
3140 **  SHUTDOWN_DAEMON -- Performs a clean shutdown of the daemon
3141 **
3142 **	Parameters:
3143 **		none.
3144 **
3145 **	Returns:
3146 **		none.
3147 **
3148 **	Side Effects:
3149 **		closes control socket, exits.
3150 */
3151 
3152 void
3153 shutdown_daemon()
3154 {
3155 	int i;
3156 	char *reason;
3157 
3158 	sm_allsignals(true);
3159 
3160 	reason = ShutdownRequest;
3161 	ShutdownRequest = NULL;
3162 	PendingSignal = 0;
3163 
3164 	if (LogLevel > 9)
3165 		sm_syslog(LOG_INFO, CurEnv->e_id, "stopping daemon, reason=%s",
3166 			  reason == NULL ? "implicit call" : reason);
3167 
3168 	FileName = NULL;
3169 	closecontrolsocket(true);
3170 #if XLA
3171 	xla_all_end();
3172 #endif
3173 
3174 	for (i = 0; i < NDaemons; i++)
3175 	{
3176 		if (Daemons[i].d_socket >= 0)
3177 		{
3178 			(void) close(Daemons[i].d_socket);
3179 			Daemons[i].d_socket = -1;
3180 
3181 #if NETUNIX
3182 			/* Remove named sockets */
3183 			if (Daemons[i].d_addr.sa.sa_family == AF_UNIX)
3184 			{
3185 				int rval;
3186 				long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_MUSTOWN|SFF_EXECOK|SFF_CREAT;
3187 
3188 				/* if not safe, don't use it */
3189 				rval = safefile(Daemons[i].d_addr.sunix.sun_path,
3190 						RunAsUid, RunAsGid,
3191 						RunAsUserName, sff,
3192 						S_IRUSR|S_IWUSR, NULL);
3193 				if (rval == 0 &&
3194 				    unlink(Daemons[i].d_addr.sunix.sun_path) < 0)
3195 				{
3196 					sm_syslog(LOG_WARNING, NOQID,
3197 						  "Could not remove daemon %s socket: %s: %s",
3198 						  Daemons[i].d_name,
3199 						  Daemons[i].d_addr.sunix.sun_path,
3200 						  sm_errstring(errno));
3201 				}
3202 			}
3203 #endif /* NETUNIX */
3204 		}
3205 	}
3206 
3207 	finis(false, true, EX_OK);
3208 }
3209 /*
3210 **  RESTART_DAEMON -- Performs a clean restart of the daemon
3211 **
3212 **	Parameters:
3213 **		none.
3214 **
3215 **	Returns:
3216 **		none.
3217 **
3218 **	Side Effects:
3219 **		restarts the daemon or exits if restart fails.
3220 */
3221 
3222 /* Make a non-DFL/IGN signal a noop */
3223 #define SM_NOOP_SIGNAL(sig, old)				\
3224 do								\
3225 {								\
3226 	(old) = sm_signal((sig), sm_signal_noop);		\
3227 	if ((old) == SIG_IGN || (old) == SIG_DFL)		\
3228 		(void) sm_signal((sig), (old));			\
3229 } while (0)
3230 
3231 void
3232 restart_daemon()
3233 {
3234 	bool drop;
3235 	int save_errno;
3236 	char *reason;
3237 	sigfunc_t ignore, oalrm, ousr1;
3238 	extern int DtableSize;
3239 
3240 	/* clear the events to turn off SIGALRMs */
3241 	sm_clear_events();
3242 	sm_allsignals(true);
3243 
3244 	reason = RestartRequest;
3245 	RestartRequest = NULL;
3246 	PendingSignal = 0;
3247 
3248 	if (SaveArgv[0][0] != '/')
3249 	{
3250 		if (LogLevel > 3)
3251 			sm_syslog(LOG_INFO, NOQID,
3252 				  "could not restart: need full path");
3253 		finis(false, true, EX_OSFILE);
3254 		/* NOTREACHED */
3255 	}
3256 	if (LogLevel > 3)
3257 		sm_syslog(LOG_INFO, NOQID, "restarting %s due to %s",
3258 			  SaveArgv[0],
3259 			  reason == NULL ? "implicit call" : reason);
3260 
3261 	closecontrolsocket(true);
3262 #if SM_CONF_SHM
3263 	cleanup_shm(DaemonPid == getpid());
3264 #endif
3265 
3266 	/* close locked pid file */
3267 	close_sendmail_pid();
3268 
3269 	/*
3270 	**  Want to drop to the user who started the process in all cases
3271 	**  *but* when running as "smmsp" for the clientmqueue queue run
3272 	**  daemon.  In that case, UseMSP will be true, RunAsUid should not
3273 	**  be root, and RealUid should be either 0 or RunAsUid.
3274 	*/
3275 
3276 	drop = !(UseMSP && RunAsUid != 0 &&
3277 		 (RealUid == 0 || RealUid == RunAsUid));
3278 
3279 	if (drop_privileges(drop) != EX_OK)
3280 	{
3281 		if (LogLevel > 0)
3282 			sm_syslog(LOG_ALERT, NOQID,
3283 				  "could not drop privileges: %s",
3284 				  sm_errstring(errno));
3285 		finis(false, true, EX_OSERR);
3286 		/* NOTREACHED */
3287 	}
3288 
3289 	sm_close_on_exec(STDERR_FILENO + 1, DtableSize);
3290 
3291 	/*
3292 	**  Need to allow signals before execve() to make them "harmless".
3293 	**  However, the default action can be "terminate", so it isn't
3294 	**  really harmless.  Setting signals to IGN will cause them to be
3295 	**  ignored in the new process to, so that isn't a good alternative.
3296 	*/
3297 
3298 	SM_NOOP_SIGNAL(SIGALRM, oalrm);
3299 	SM_NOOP_SIGNAL(SIGCHLD, ignore);
3300 	SM_NOOP_SIGNAL(SIGHUP, ignore);
3301 	SM_NOOP_SIGNAL(SIGINT, ignore);
3302 	SM_NOOP_SIGNAL(SIGPIPE, ignore);
3303 	SM_NOOP_SIGNAL(SIGTERM, ignore);
3304 #ifdef SIGUSR1
3305 	SM_NOOP_SIGNAL(SIGUSR1, ousr1);
3306 #endif
3307 
3308 	/* Turn back on signals */
3309 	sm_allsignals(false);
3310 
3311 	(void) execve(SaveArgv[0], (ARGV_T) SaveArgv, (ARGV_T) ExternalEnviron);
3312 	save_errno = errno;
3313 
3314 	/* block signals again and restore needed signals */
3315 	sm_allsignals(true);
3316 
3317 	/* For finis() events */
3318 	(void) sm_signal(SIGALRM, oalrm);
3319 
3320 #ifdef SIGUSR1
3321 	/* For debugging finis() */
3322 	(void) sm_signal(SIGUSR1, ousr1);
3323 #endif
3324 
3325 	errno = save_errno;
3326 	if (LogLevel > 0)
3327 		sm_syslog(LOG_ALERT, NOQID, "could not exec %s: %s",
3328 			  SaveArgv[0], sm_errstring(errno));
3329 	finis(false, true, EX_OSFILE);
3330 	/* NOTREACHED */
3331 }
3332 /*
3333 **  MYHOSTNAME -- return the name of this host.
3334 **
3335 **	Parameters:
3336 **		hostbuf -- a place to return the name of this host.
3337 **		size -- the size of hostbuf.
3338 **
3339 **	Returns:
3340 **		A list of aliases for this host.
3341 **
3342 **	Side Effects:
3343 **		Adds numeric codes to $=w.
3344 */
3345 
3346 struct hostent *
3347 myhostname(hostbuf, size)
3348 	char hostbuf[];
3349 	int size;
3350 {
3351 	register struct hostent *hp;
3352 
3353 	if (gethostname(hostbuf, size) < 0 || hostbuf[0] == '\0')
3354 		(void) sm_strlcpy(hostbuf, "localhost", size);
3355 	hp = sm_gethostbyname(hostbuf, InetMode);
3356 #if NETINET && NETINET6
3357 	if (hp == NULL && InetMode == AF_INET6)
3358 	{
3359 		/*
3360 		**  It's possible that this IPv6 enabled machine doesn't
3361 		**  actually have any IPv6 interfaces and, therefore, no
3362 		**  IPv6 addresses.  Fall back to AF_INET.
3363 		*/
3364 
3365 		hp = sm_gethostbyname(hostbuf, AF_INET);
3366 	}
3367 #endif /* NETINET && NETINET6 */
3368 	if (hp == NULL)
3369 		return NULL;
3370 	if (strchr(hp->h_name, '.') != NULL || strchr(hostbuf, '.') == NULL)
3371 		(void) cleanstrcpy(hostbuf, hp->h_name, size);
3372 
3373 #if NETINFO
3374 	if (strchr(hostbuf, '.') == NULL)
3375 	{
3376 		char *domainname;
3377 
3378 		domainname = ni_propval("/locations", NULL, "resolver",
3379 					"domain", '\0');
3380 		if (domainname != NULL &&
3381 		    strlen(domainname) + strlen(hostbuf) + 1 < size)
3382 			(void) sm_strlcat2(hostbuf, ".", domainname, size);
3383 	}
3384 #endif /* NETINFO */
3385 
3386 	/*
3387 	**  If there is still no dot in the name, try looking for a
3388 	**  dotted alias.
3389 	*/
3390 
3391 	if (strchr(hostbuf, '.') == NULL)
3392 	{
3393 		char **ha;
3394 
3395 		for (ha = hp->h_aliases; ha != NULL && *ha != NULL; ha++)
3396 		{
3397 			if (strchr(*ha, '.') != NULL)
3398 			{
3399 				(void) cleanstrcpy(hostbuf, *ha, size - 1);
3400 				hostbuf[size - 1] = '\0';
3401 				break;
3402 			}
3403 		}
3404 	}
3405 
3406 	/*
3407 	**  If _still_ no dot, wait for a while and try again -- it is
3408 	**  possible that some service is starting up.  This can result
3409 	**  in excessive delays if the system is badly configured, but
3410 	**  there really isn't a way around that, particularly given that
3411 	**  the config file hasn't been read at this point.
3412 	**  All in all, a bit of a mess.
3413 	*/
3414 
3415 	if (strchr(hostbuf, '.') == NULL &&
3416 	    getcanonname(hostbuf, size, true, NULL) == HOST_NOTFOUND)
3417 	{
3418 		sm_syslog(LocalDaemon ? LOG_WARNING : LOG_CRIT, NOQID,
3419 			  "My unqualified host name (%s) unknown; sleeping for retry",
3420 			  hostbuf);
3421 		message("My unqualified host name (%s) unknown; sleeping for retry",
3422 			hostbuf);
3423 		(void) sleep(60);
3424 		if (getcanonname(hostbuf, size, true, NULL) == HOST_NOTFOUND)
3425 		{
3426 			sm_syslog(LocalDaemon ? LOG_WARNING : LOG_ALERT, NOQID,
3427 				  "unable to qualify my own domain name (%s) -- using short name",
3428 				  hostbuf);
3429 			message("WARNING: unable to qualify my own domain name (%s) -- using short name",
3430 				hostbuf);
3431 		}
3432 	}
3433 	return hp;
3434 }
3435 /*
3436 **  ADDRCMP -- compare two host addresses
3437 **
3438 **	Parameters:
3439 **		hp -- hostent structure for the first address
3440 **		ha -- actual first address
3441 **		sa -- second address
3442 **
3443 **	Returns:
3444 **		0 -- if ha and sa match
3445 **		else -- they don't match
3446 */
3447 
3448 static int
3449 addrcmp(hp, ha, sa)
3450 	struct hostent *hp;
3451 	char *ha;
3452 	SOCKADDR *sa;
3453 {
3454 #if NETINET6
3455 	unsigned char *a;
3456 #endif
3457 
3458 	switch (sa->sa.sa_family)
3459 	{
3460 #if NETINET
3461 	  case AF_INET:
3462 		if (hp->h_addrtype == AF_INET)
3463 			return memcmp(ha, (char *) &sa->sin.sin_addr, INADDRSZ);
3464 		break;
3465 #endif
3466 
3467 #if NETINET6
3468 	  case AF_INET6:
3469 		a = (unsigned char *) &sa->sin6.sin6_addr;
3470 
3471 		/* Straight binary comparison */
3472 		if (hp->h_addrtype == AF_INET6)
3473 			return memcmp(ha, a, IN6ADDRSZ);
3474 
3475 		/* If IPv4-mapped IPv6 address, compare the IPv4 section */
3476 		if (hp->h_addrtype == AF_INET &&
3477 		    IN6_IS_ADDR_V4MAPPED(&sa->sin6.sin6_addr))
3478 			return memcmp(a + IN6ADDRSZ - INADDRSZ, ha, INADDRSZ);
3479 		break;
3480 #endif /* NETINET6 */
3481 	}
3482 	return -1;
3483 }
3484 /*
3485 **  GETAUTHINFO -- get the real host name associated with a file descriptor
3486 **
3487 **	Uses RFC1413 protocol to try to get info from the other end.
3488 **
3489 **	Parameters:
3490 **		fd -- the descriptor
3491 **		may_be_forged -- an outage that is set to true if the
3492 **			forward lookup of RealHostName does not match
3493 **			RealHostAddr; set to false if they do match.
3494 **
3495 **	Returns:
3496 **		The user@host information associated with this descriptor.
3497 */
3498 
3499 static jmp_buf	CtxAuthTimeout;
3500 
3501 static void
3502 authtimeout(ignore)
3503 	int ignore;
3504 {
3505 	/*
3506 	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
3507 	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
3508 	**	DOING.
3509 	*/
3510 
3511 	errno = ETIMEDOUT;
3512 	longjmp(CtxAuthTimeout, 1);
3513 }
3514 
3515 char *
3516 getauthinfo(fd, may_be_forged)
3517 	int fd;
3518 	bool *may_be_forged;
3519 {
3520 	unsigned short SM_NONVOLATILE port = 0;
3521 	SOCKADDR_LEN_T falen;
3522 	register char *volatile p = NULL;
3523 	SOCKADDR la;
3524 	SOCKADDR_LEN_T lalen;
3525 #ifndef NO_GETSERVBYNAME
3526 	register struct servent *sp;
3527 # if NETINET
3528 	static unsigned short port4 = 0;
3529 # endif
3530 # if NETINET6
3531 	static unsigned short port6 = 0;
3532 # endif
3533 #endif /* ! NO_GETSERVBYNAME */
3534 	volatile int s;
3535 	int i = 0;
3536 	size_t len;
3537 	SM_EVENT *ev;
3538 	int nleft;
3539 	struct hostent *hp;
3540 	char *ostype = NULL;
3541 	char **ha;
3542 	char ibuf[MAXNAME + 1];
3543 	static char hbuf[MAXNAME + MAXAUTHINFO + 11];
3544 
3545 	*may_be_forged = true;
3546 	falen = sizeof(RealHostAddr);
3547 	if (isatty(fd) || (i = getpeername(fd, &RealHostAddr.sa, &falen)) < 0 ||
3548 	    falen <= 0 || RealHostAddr.sa.sa_family == 0)
3549 	{
3550 		if (i < 0)
3551 		{
3552 			/*
3553 			**  ENOTSOCK is OK: bail on anything else, but reset
3554 			**  errno in this case, so a mis-report doesn't
3555 			**  happen later.
3556 			*/
3557 
3558 			if (errno != ENOTSOCK)
3559 				return NULL;
3560 			errno = 0;
3561 		}
3562 
3563 		*may_be_forged = false;
3564 		(void) sm_strlcpyn(hbuf, sizeof(hbuf), 2, RealUserName,
3565 				   "@localhost");
3566 		if (tTd(9, 1))
3567 			sm_dprintf("getauthinfo: %s\n", hbuf);
3568 		return hbuf;
3569 	}
3570 
3571 	if (RealHostName == NULL)
3572 	{
3573 		/* translate that to a host name */
3574 		RealHostName = newstr(hostnamebyanyaddr(&RealHostAddr));
3575 		if (strlen(RealHostName) > MAXNAME)
3576 			RealHostName[MAXNAME] = '\0'; /* XXX - 1 ? */
3577 	}
3578 
3579 	/* cross check RealHostName with forward DNS lookup */
3580 	if (anynet_ntoa(&RealHostAddr)[0] == '[' ||
3581 	    RealHostName[0] == '[')
3582 		*may_be_forged = false;
3583 	else
3584 	{
3585 		int family;
3586 
3587 		family = RealHostAddr.sa.sa_family;
3588 #if NETINET6 && NEEDSGETIPNODE
3589 		/*
3590 		**  If RealHostAddr is an IPv6 connection with an
3591 		**  IPv4-mapped address, we need RealHostName's IPv4
3592 		**  address(es) for addrcmp() to compare against
3593 		**  RealHostAddr.
3594 		**
3595 		**  Actually, we only need to do this for systems
3596 		**  which NEEDSGETIPNODE since the real getipnodebyname()
3597 		**  already does V4MAPPED address via the AI_V4MAPPEDCFG
3598 		**  flag.  A better fix to this problem is to add this
3599 		**  functionality to our stub getipnodebyname().
3600 		*/
3601 
3602 		if (family == AF_INET6 &&
3603 		    IN6_IS_ADDR_V4MAPPED(&RealHostAddr.sin6.sin6_addr))
3604 			family = AF_INET;
3605 #endif /* NETINET6 && NEEDSGETIPNODE */
3606 
3607 		/* try to match the reverse against the forward lookup */
3608 		hp = sm_gethostbyname(RealHostName, family);
3609 		if (hp != NULL)
3610 		{
3611 			for (ha = hp->h_addr_list; *ha != NULL; ha++)
3612 			{
3613 				if (addrcmp(hp, *ha, &RealHostAddr) == 0)
3614 				{
3615 					*may_be_forged = false;
3616 					break;
3617 				}
3618 			}
3619 			FREEHOSTENT(hp, NULL);
3620 		}
3621 	}
3622 
3623 	if (TimeOuts.to_ident == 0)
3624 		goto noident;
3625 
3626 	lalen = sizeof(la);
3627 	switch (RealHostAddr.sa.sa_family)
3628 	{
3629 #if NETINET
3630 	  case AF_INET:
3631 		if (getsockname(fd, &la.sa, &lalen) < 0 ||
3632 		    lalen <= 0 ||
3633 		    la.sa.sa_family != AF_INET)
3634 		{
3635 			/* no ident info */
3636 			goto noident;
3637 		}
3638 		port = RealHostAddr.sin.sin_port;
3639 
3640 		/* create ident query */
3641 		(void) sm_snprintf(ibuf, sizeof(ibuf), "%d,%d\r\n",
3642 				ntohs(RealHostAddr.sin.sin_port),
3643 				ntohs(la.sin.sin_port));
3644 
3645 		/* create local address */
3646 		la.sin.sin_port = 0;
3647 
3648 		/* create foreign address */
3649 # ifdef NO_GETSERVBYNAME
3650 		RealHostAddr.sin.sin_port = htons(113);
3651 # else /* NO_GETSERVBYNAME */
3652 
3653 		/*
3654 		**  getservbyname() consumes about 5% of the time
3655 		**  when receiving a small message (almost all of the time
3656 		**  spent in this routine).
3657 		**  Hence we store the port in a static variable
3658 		**  to save this time.
3659 		**  The portnumber shouldn't change very often...
3660 		**  This code makes the assumption that the port number
3661 		**  is not 0.
3662 		*/
3663 
3664 		if (port4 == 0)
3665 		{
3666 			sp = getservbyname("auth", "tcp");
3667 			if (sp != NULL)
3668 				port4 = sp->s_port;
3669 			else
3670 				port4 = htons(113);
3671 		}
3672 		RealHostAddr.sin.sin_port = port4;
3673 		break;
3674 # endif /* NO_GETSERVBYNAME */
3675 #endif /* NETINET */
3676 
3677 #if NETINET6
3678 	  case AF_INET6:
3679 		if (getsockname(fd, &la.sa, &lalen) < 0 ||
3680 		    lalen <= 0 ||
3681 		    la.sa.sa_family != AF_INET6)
3682 		{
3683 			/* no ident info */
3684 			goto noident;
3685 		}
3686 		port = RealHostAddr.sin6.sin6_port;
3687 
3688 		/* create ident query */
3689 		(void) sm_snprintf(ibuf, sizeof(ibuf), "%d,%d\r\n",
3690 				ntohs(RealHostAddr.sin6.sin6_port),
3691 				ntohs(la.sin6.sin6_port));
3692 
3693 		/* create local address */
3694 		la.sin6.sin6_port = 0;
3695 
3696 		/* create foreign address */
3697 # ifdef NO_GETSERVBYNAME
3698 		RealHostAddr.sin6.sin6_port = htons(113);
3699 # else /* NO_GETSERVBYNAME */
3700 		if (port6 == 0)
3701 		{
3702 			sp = getservbyname("auth", "tcp");
3703 			if (sp != NULL)
3704 				port6 = sp->s_port;
3705 			else
3706 				port6 = htons(113);
3707 		}
3708 		RealHostAddr.sin6.sin6_port = port6;
3709 		break;
3710 # endif /* NO_GETSERVBYNAME */
3711 #endif /* NETINET6 */
3712 	  default:
3713 		/* no ident info */
3714 		goto noident;
3715 	}
3716 
3717 	s = -1;
3718 	if (setjmp(CtxAuthTimeout) != 0)
3719 	{
3720 		if (s >= 0)
3721 			(void) close(s);
3722 		goto noident;
3723 	}
3724 
3725 	/* put a timeout around the whole thing */
3726 	ev = sm_setevent(TimeOuts.to_ident, authtimeout, 0);
3727 
3728 	/* connect to foreign IDENT server using same address as SMTP socket */
3729 	s = socket(la.sa.sa_family, SOCK_STREAM, 0);
3730 	if (s < 0)
3731 	{
3732 		sm_clrevent(ev);
3733 		goto noident;
3734 	}
3735 	if (bind(s, &la.sa, lalen) < 0 ||
3736 	    connect(s, &RealHostAddr.sa, lalen) < 0)
3737 		goto closeident;
3738 
3739 	if (tTd(9, 10))
3740 		sm_dprintf("getauthinfo: sent %s", ibuf);
3741 
3742 	/* send query */
3743 	if (write(s, ibuf, strlen(ibuf)) < 0)
3744 		goto closeident;
3745 
3746 	/* get result */
3747 	p = &ibuf[0];
3748 	nleft = sizeof(ibuf) - 1;
3749 	while ((i = read(s, p, nleft)) > 0)
3750 	{
3751 		char *s;
3752 
3753 		p += i;
3754 		nleft -= i;
3755 		*p = '\0';
3756 		if ((s = strchr(ibuf, '\n')) != NULL)
3757 		{
3758 			if (p > s + 1)
3759 			{
3760 				p = s + 1;
3761 				*p = '\0';
3762 			}
3763 			break;
3764 		}
3765 		if (nleft <= 0)
3766 			break;
3767 	}
3768 	(void) close(s);
3769 	sm_clrevent(ev);
3770 	if (i < 0 || p == &ibuf[0])
3771 		goto noident;
3772 
3773 	if (p >= &ibuf[2] && *--p == '\n' && *--p == '\r')
3774 		p--;
3775 	*++p = '\0';
3776 
3777 	if (tTd(9, 3))
3778 		sm_dprintf("getauthinfo:  got %s\n", ibuf);
3779 
3780 	/* parse result */
3781 	p = strchr(ibuf, ':');
3782 	if (p == NULL)
3783 	{
3784 		/* malformed response */
3785 		goto noident;
3786 	}
3787 	while (isascii(*++p) && isspace(*p))
3788 		continue;
3789 	if (sm_strncasecmp(p, "userid", 6) != 0)
3790 	{
3791 		/* presumably an error string */
3792 		goto noident;
3793 	}
3794 	p += 6;
3795 	while (SM_ISSPACE(*p))
3796 		p++;
3797 	if (*p++ != ':')
3798 	{
3799 		/* either useridxx or malformed response */
3800 		goto noident;
3801 	}
3802 
3803 	/* p now points to the OSTYPE field */
3804 	while (SM_ISSPACE(*p))
3805 		p++;
3806 	ostype = p;
3807 	p = strchr(p, ':');
3808 	if (p == NULL)
3809 	{
3810 		/* malformed response */
3811 		goto noident;
3812 	}
3813 	else
3814 	{
3815 		char *charset;
3816 
3817 		*p = '\0';
3818 		charset = strchr(ostype, ',');
3819 		if (charset != NULL)
3820 			*charset = '\0';
3821 	}
3822 
3823 	/* 1413 says don't do this -- but it's broken otherwise */
3824 	while (isascii(*++p) && isspace(*p))
3825 		continue;
3826 
3827 	/* p now points to the authenticated name -- copy carefully */
3828 	if (sm_strncasecmp(ostype, "other", 5) == 0 &&
3829 	    (ostype[5] == ' ' || ostype[5] == '\0'))
3830 	{
3831 		(void) sm_strlcpy(hbuf, "IDENT:", sizeof(hbuf));
3832 		cleanstrcpy(&hbuf[6], p, MAXAUTHINFO);
3833 	}
3834 	else
3835 		cleanstrcpy(hbuf, p, MAXAUTHINFO);
3836 	len = strlen(hbuf);
3837 	(void) sm_strlcpyn(&hbuf[len], sizeof(hbuf) - len, 2, "@",
3838 			   RealHostName == NULL ? "localhost" : RealHostName);
3839 	goto postident;
3840 
3841 closeident:
3842 	(void) close(s);
3843 	sm_clrevent(ev);
3844 
3845 noident:
3846 	/* put back the original incoming port */
3847 	switch (RealHostAddr.sa.sa_family)
3848 	{
3849 #if NETINET
3850 	  case AF_INET:
3851 		if (port > 0)
3852 			RealHostAddr.sin.sin_port = port;
3853 		break;
3854 #endif /* NETINET */
3855 
3856 #if NETINET6
3857 	  case AF_INET6:
3858 		if (port > 0)
3859 			RealHostAddr.sin6.sin6_port = port;
3860 		break;
3861 #endif /* NETINET6 */
3862 	}
3863 
3864 	if (RealHostName == NULL)
3865 	{
3866 		if (tTd(9, 1))
3867 			sm_dprintf("getauthinfo: NULL\n");
3868 		return NULL;
3869 	}
3870 	(void) sm_strlcpy(hbuf, RealHostName, sizeof(hbuf));
3871 
3872 postident:
3873 #if IP_SRCROUTE
3874 # ifndef GET_IPOPT_DST
3875 #  define GET_IPOPT_DST(dst)	(dst)
3876 # endif
3877 	/*
3878 	**  Extract IP source routing information.
3879 	**
3880 	**	Format of output for a connection from site a through b
3881 	**	through c to d:
3882 	**		loose:      @site-c@site-b:site-a
3883 	**		strict:	   !@site-c@site-b:site-a
3884 	**
3885 	**	o - pointer within ipopt_list structure.
3886 	**	q - pointer within ls/ss rr route data
3887 	**	p - pointer to hbuf
3888 	*/
3889 
3890 	if (RealHostAddr.sa.sa_family == AF_INET)
3891 	{
3892 		SOCKOPT_LEN_T ipoptlen;
3893 		int j;
3894 		unsigned char *q;
3895 		unsigned char *o;
3896 		int l;
3897 		struct IPOPTION ipopt;
3898 
3899 		ipoptlen = sizeof(ipopt);
3900 		if (getsockopt(fd, IPPROTO_IP, IP_OPTIONS,
3901 			       (char *) &ipopt, &ipoptlen) < 0)
3902 			goto noipsr;
3903 		if (ipoptlen == 0)
3904 			goto noipsr;
3905 		o = (unsigned char *) ipopt.IP_LIST;
3906 		while (o != NULL && o < (unsigned char *) &ipopt + ipoptlen)
3907 		{
3908 			switch (*o)
3909 			{
3910 			  case IPOPT_EOL:
3911 				o = NULL;
3912 				break;
3913 
3914 			  case IPOPT_NOP:
3915 				o++;
3916 				break;
3917 
3918 			  case IPOPT_SSRR:
3919 			  case IPOPT_LSRR:
3920 				/*
3921 				**  Source routing.
3922 				**	o[0] is the option type (loose/strict).
3923 				**	o[1] is the length of this option,
3924 				**		including option type and
3925 				**		length.
3926 				**	o[2] is the pointer into the route
3927 				**		data.
3928 				**	o[3] begins the route data.
3929 				*/
3930 
3931 				p = &hbuf[strlen(hbuf)];
3932 				l = sizeof(hbuf) - (hbuf - p) - 6;
3933 				(void) sm_snprintf(p, SPACELEFT(hbuf, p),
3934 					" [%s@%.*s",
3935 					*o == IPOPT_SSRR ? "!" : "",
3936 					l > 240 ? 120 : l / 2,
3937 					inet_ntoa(GET_IPOPT_DST(ipopt.IP_DST)));
3938 				i = strlen(p);
3939 				p += i;
3940 				l -= strlen(p);
3941 
3942 				j = o[1] / sizeof(struct in_addr) - 1;
3943 
3944 				/* q skips length and router pointer to data */
3945 				q = &o[3];
3946 				for ( ; j >= 0; j--)
3947 				{
3948 					struct in_addr addr;
3949 
3950 					memcpy(&addr, q, sizeof(addr));
3951 					(void) sm_snprintf(p,
3952 						SPACELEFT(hbuf, p),
3953 						"%c%.*s",
3954 						j != 0 ? '@' : ':',
3955 						l > 240 ? 120 :
3956 							j == 0 ? l : l / 2,
3957 						inet_ntoa(addr));
3958 					i = strlen(p);
3959 					p += i;
3960 					l -= i + 1;
3961 					q += sizeof(struct in_addr);
3962 				}
3963 				o += o[1];
3964 				break;
3965 
3966 			  default:
3967 				/* Skip over option */
3968 				o += o[1];
3969 				break;
3970 			}
3971 		}
3972 		(void) sm_snprintf(p, SPACELEFT(hbuf, p), "]");
3973 		goto postipsr;
3974 	}
3975 
3976 noipsr:
3977 #endif /* IP_SRCROUTE */
3978 	if (RealHostName != NULL && RealHostName[0] != '[')
3979 	{
3980 		p = &hbuf[strlen(hbuf)];
3981 		(void) sm_snprintf(p, SPACELEFT(hbuf, p), " [%.100s]",
3982 				   anynet_ntoa(&RealHostAddr));
3983 	}
3984 	if (*may_be_forged)
3985 	{
3986 		p = &hbuf[strlen(hbuf)];
3987 		(void) sm_strlcpy(p, " (may be forged)", SPACELEFT(hbuf, p));
3988 		macdefine(&BlankEnvelope.e_macro, A_PERM,
3989 			  macid("{client_resolve}"), "FORGED");
3990 	}
3991 
3992 #if IP_SRCROUTE
3993 postipsr:
3994 #endif /* IP_SRCROUTE */
3995 
3996 	/* put back the original incoming port */
3997 	switch (RealHostAddr.sa.sa_family)
3998 	{
3999 #if NETINET
4000 	  case AF_INET:
4001 		if (port > 0)
4002 			RealHostAddr.sin.sin_port = port;
4003 		break;
4004 #endif /* NETINET */
4005 
4006 #if NETINET6
4007 	  case AF_INET6:
4008 		if (port > 0)
4009 			RealHostAddr.sin6.sin6_port = port;
4010 		break;
4011 #endif /* NETINET6 */
4012 	}
4013 
4014 	if (tTd(9, 1))
4015 		sm_dprintf("getauthinfo: %s\n", hbuf);
4016 	return hbuf;
4017 }
4018 /*
4019 **  HOST_MAP_LOOKUP -- turn a hostname into canonical form
4020 **
4021 **	Parameters:
4022 **		map -- a pointer to this map.
4023 **		name -- the (presumably unqualified) hostname.
4024 **		av -- unused -- for compatibility with other mapping
4025 **			functions.
4026 **		statp -- an exit status (out parameter) -- set to
4027 **			EX_TEMPFAIL if the name server is unavailable.
4028 **
4029 **	Returns:
4030 **		The mapping, if found.
4031 **		NULL if no mapping found.
4032 **
4033 **	Side Effects:
4034 **		Looks up the host specified in hbuf.  If it is not
4035 **		the canonical name for that host, return the canonical
4036 **		name (unless MF_MATCHONLY is set, which will cause the
4037 **		status only to be returned).
4038 */
4039 
4040 char *
4041 host_map_lookup(map, name, av, statp)
4042 	MAP *map;
4043 	char *name;
4044 	char **av;
4045 	int *statp;
4046 {
4047 	register struct hostent *hp;
4048 #if NETINET
4049 	struct in_addr in_addr;
4050 #endif
4051 #if NETINET6
4052 	struct in6_addr in6_addr;
4053 #endif
4054 	char *cp, *ans = NULL;
4055 	register STAB *s;
4056 	time_t now;
4057 #if NAMED_BIND
4058 	time_t SM_NONVOLATILE retrans = 0;
4059 	int SM_NONVOLATILE retry = 0;
4060 #endif
4061 	char hbuf[MAXNAME + 1];
4062 
4063 	/*
4064 	**  See if we have already looked up this name.  If so, just
4065 	**  return it (unless expired).
4066 	*/
4067 
4068 	now = curtime();
4069 	s = stab(name, ST_NAMECANON, ST_ENTER);
4070 	if (bitset(NCF_VALID, s->s_namecanon.nc_flags) &&
4071 	    s->s_namecanon.nc_exp >= now)
4072 	{
4073 		if (tTd(9, 1))
4074 			sm_dprintf("host_map_lookup(%s) => CACHE %s\n",
4075 				    name,
4076 				    s->s_namecanon.nc_cname == NULL
4077 					? "NULL"
4078 					: s->s_namecanon.nc_cname);
4079 		errno = s->s_namecanon.nc_errno;
4080 		SM_SET_H_ERRNO(s->s_namecanon.nc_herrno);
4081 		*statp = s->s_namecanon.nc_stat;
4082 		if (*statp == EX_TEMPFAIL)
4083 		{
4084 			CurEnv->e_status = "4.4.3";
4085 			message("851 %s: Name server timeout",
4086 				shortenstring(name, 33));
4087 		}
4088 		if (*statp != EX_OK)
4089 			return NULL;
4090 		if (s->s_namecanon.nc_cname == NULL)
4091 		{
4092 			syserr("host_map_lookup(%s): bogus NULL cache entry, errno=%d, h_errno=%d",
4093 			       name,
4094 			       s->s_namecanon.nc_errno,
4095 			       s->s_namecanon.nc_herrno);
4096 			return NULL;
4097 		}
4098 		if (bitset(NCF_SECURE, s->s_namecanon.nc_flags))
4099 			map->map_mflags |= MF_SECURE;
4100 		else
4101 			map->map_mflags &= ~MF_SECURE;
4102 		if (bitset(MF_MATCHONLY, map->map_mflags))
4103 			cp = map_rewrite(map, name, strlen(name), NULL);
4104 		else
4105 			cp = map_rewrite(map,
4106 					 s->s_namecanon.nc_cname,
4107 					 strlen(s->s_namecanon.nc_cname),
4108 					 av);
4109 		return cp;
4110 	}
4111 
4112 	/*
4113 	**  If we are running without a regular network connection (usually
4114 	**  dial-on-demand) and we are just queueing, we want to avoid DNS
4115 	**  lookups because those could try to connect to a server.
4116 	*/
4117 
4118 	if (CurEnv->e_sendmode == SM_DEFER &&
4119 	    bitset(MF_DEFER, map->map_mflags))
4120 	{
4121 		if (tTd(9, 1))
4122 			sm_dprintf("host_map_lookup(%s) => DEFERRED\n", name);
4123 		*statp = EX_TEMPFAIL;
4124 		return NULL;
4125 	}
4126 
4127 	/*
4128 	**  If first character is a bracket, then it is an address
4129 	**  lookup.  Address is copied into a temporary buffer to
4130 	**  strip the brackets and to preserve name if address is
4131 	**  unknown.
4132 	*/
4133 
4134 	if (tTd(9, 1))
4135 		sm_dprintf("host_map_lookup(%s) => ", name);
4136 #if NAMED_BIND
4137 	if (map->map_timeout > 0)
4138 	{
4139 		retrans = _res.retrans;
4140 		_res.retrans = map->map_timeout;
4141 	}
4142 	if (map->map_retry > 0)
4143 	{
4144 		retry = _res.retry;
4145 		_res.retry = map->map_retry;
4146 	}
4147 #endif /* NAMED_BIND */
4148 
4149 	/* set default TTL */
4150 	s->s_namecanon.nc_exp = now + SM_DEFAULT_TTL;
4151 	if (*name != '[')
4152 	{
4153 		int ttl, r;
4154 
4155 		(void) sm_strlcpy(hbuf, name, sizeof(hbuf));
4156 
4157 		r = getcanonname(hbuf, sizeof(hbuf) - 1, !HasWildcardMX, &ttl);
4158 		if (r != HOST_NOTFOUND)
4159 		{
4160 			ans = hbuf;
4161 			if (ttl > 0)
4162 				s->s_namecanon.nc_exp = now + SM_MIN(ttl,
4163 								SM_DEFAULT_TTL);
4164 
4165 			if (HOST_SECURE == r)
4166 			{
4167 				s->s_namecanon.nc_flags |= NCF_SECURE;
4168 				map->map_mflags |= MF_SECURE;
4169 			}
4170 			else
4171 			{
4172 				s->s_namecanon.nc_flags &= ~NCF_SECURE;
4173 				map->map_mflags &= ~MF_SECURE;
4174 			}
4175 		}
4176 	}
4177 	else
4178 	{
4179 		if ((cp = strchr(name, ']')) == NULL)
4180 		{
4181 			if (tTd(9, 1))
4182 				sm_dprintf("FAILED\n");
4183 			return NULL;
4184 		}
4185 		*cp = '\0';
4186 
4187 		hp = NULL;
4188 
4189 		/* should this be considered secure? */
4190 		map->map_mflags &= ~MF_SECURE;
4191 #if NETINET
4192 		if ((in_addr.s_addr = inet_addr(&name[1])) != INADDR_NONE)
4193 			hp = sm_gethostbyaddr((char *)&in_addr,
4194 					      INADDRSZ, AF_INET);
4195 #endif /* NETINET */
4196 #if NETINET6
4197 		if (hp == NULL &&
4198 		    anynet_pton(AF_INET6, &name[1], &in6_addr) == 1)
4199 			hp = sm_gethostbyaddr((char *)&in6_addr,
4200 					      IN6ADDRSZ, AF_INET6);
4201 #endif /* NETINET6 */
4202 		*cp = ']';
4203 
4204 		if (hp != NULL)
4205 		{
4206 			/* found a match -- copy out */
4207 			ans = denlstring((char *) hp->h_name, true, true);
4208 #if NETINET6
4209 			if (ans == hp->h_name)
4210 			{
4211 				static char n[MAXNAME + 1];
4212 
4213 				/* hp->h_name is about to disappear */
4214 				(void) sm_strlcpy(n, ans, sizeof(n));
4215 				ans = n;
4216 			}
4217 			FREEHOSTENT(hp, NULL);
4218 #endif /* NETINET6 */
4219 		}
4220 	}
4221 #if NAMED_BIND
4222 	if (map->map_timeout > 0)
4223 		_res.retrans = retrans;
4224 	if (map->map_retry > 0)
4225 		_res.retry = retry;
4226 #endif /* NAMED_BIND */
4227 
4228 	s->s_namecanon.nc_flags |= NCF_VALID;	/* will be soon */
4229 
4230 	/* Found an answer */
4231 	if (ans != NULL)
4232 	{
4233 		s->s_namecanon.nc_stat = *statp = EX_OK;
4234 		if (s->s_namecanon.nc_cname != NULL)
4235 			sm_free(s->s_namecanon.nc_cname);
4236 		s->s_namecanon.nc_cname = sm_strdup_x(ans);
4237 		if (bitset(MF_MATCHONLY, map->map_mflags))
4238 			cp = map_rewrite(map, name, strlen(name), NULL);
4239 		else
4240 			cp = map_rewrite(map, ans, strlen(ans), av);
4241 		if (tTd(9, 1))
4242 			sm_dprintf("FOUND %s\n", ans);
4243 		return cp;
4244 	}
4245 
4246 
4247 	/* No match found */
4248 	s->s_namecanon.nc_errno = errno;
4249 #if NAMED_BIND
4250 	s->s_namecanon.nc_herrno = h_errno;
4251 	if (tTd(9, 1))
4252 		sm_dprintf("FAIL (%d)\n", h_errno);
4253 	switch (h_errno)
4254 	{
4255 	  case TRY_AGAIN:
4256 		if (UseNameServer)
4257 		{
4258 			CurEnv->e_status = "4.4.3";
4259 			message("851 %s: Name server timeout",
4260 				shortenstring(name, 33));
4261 		}
4262 		*statp = EX_TEMPFAIL;
4263 		break;
4264 
4265 	  case HOST_NOT_FOUND:
4266 	  case NO_DATA:
4267 		*statp = EX_NOHOST;
4268 		break;
4269 
4270 	  case NO_RECOVERY:
4271 		*statp = EX_SOFTWARE;
4272 		break;
4273 
4274 	  default:
4275 		*statp = EX_UNAVAILABLE;
4276 		break;
4277 	}
4278 #else /* NAMED_BIND */
4279 	if (tTd(9, 1))
4280 		sm_dprintf("FAIL\n");
4281 	*statp = EX_NOHOST;
4282 #endif /* NAMED_BIND */
4283 	s->s_namecanon.nc_stat = *statp;
4284 	return NULL;
4285 }
4286 /*
4287 **  HOST_MAP_INIT -- initialize host class structures
4288 **
4289 **	Parameters:
4290 **		map -- a pointer to this map.
4291 **		args -- argument string.
4292 **
4293 **	Returns:
4294 **		true.
4295 */
4296 
4297 bool
4298 host_map_init(map, args)
4299 	MAP *map;
4300 	char *args;
4301 {
4302 	register char *p = args;
4303 
4304 	for (;;)
4305 	{
4306 		while (SM_ISSPACE(*p))
4307 			p++;
4308 		if (*p != '-')
4309 			break;
4310 		switch (*++p)
4311 		{
4312 		  case 'a':
4313 			map->map_app = ++p;
4314 			break;
4315 
4316 		  case 'T':
4317 			map->map_tapp = ++p;
4318 			break;
4319 
4320 		  case 'm':
4321 			map->map_mflags |= MF_MATCHONLY;
4322 			break;
4323 
4324 		  case 't':
4325 			map->map_mflags |= MF_NODEFER;
4326 			break;
4327 
4328 		  case 'S':	/* only for consistency */
4329 			map->map_spacesub = *++p;
4330 			break;
4331 
4332 		  case 'D':
4333 			map->map_mflags |= MF_DEFER;
4334 			break;
4335 
4336 		  case 'd':
4337 			{
4338 				char *h;
4339 
4340 				while (isascii(*++p) && isspace(*p))
4341 					continue;
4342 				h = strchr(p, ' ');
4343 				if (h != NULL)
4344 					*h = '\0';
4345 				map->map_timeout = convtime(p, 's');
4346 				if (h != NULL)
4347 					*h = ' ';
4348 			}
4349 			break;
4350 
4351 		  case 'r':
4352 			while (isascii(*++p) && isspace(*p))
4353 				continue;
4354 			map->map_retry = atoi(p);
4355 			break;
4356 		}
4357 		while (*p != '\0' && !(SM_ISSPACE(*p)))
4358 			p++;
4359 		if (*p != '\0')
4360 			*p++ = '\0';
4361 	}
4362 	if (map->map_app != NULL)
4363 		map->map_app = newstr(map->map_app);
4364 	if (map->map_tapp != NULL)
4365 		map->map_tapp = newstr(map->map_tapp);
4366 	return true;
4367 }
4368 
4369 #if NETINET6
4370 /*
4371 **  ANYNET_NTOP -- convert an IPv6 network address to printable form.
4372 **
4373 **	Parameters:
4374 **		s6a -- a pointer to an in6_addr structure.
4375 **		dst -- buffer to store result in
4376 **		dst_len -- size of dst buffer
4377 **
4378 **	Returns:
4379 **		A printable version of that structure.
4380 */
4381 
4382 char *
4383 anynet_ntop(s6a, dst, dst_len)
4384 	struct in6_addr *s6a;
4385 	char *dst;
4386 	size_t dst_len;
4387 {
4388 	register char *ap;
4389 
4390 	if (IN6_IS_ADDR_V4MAPPED(s6a))
4391 		ap = (char *) inet_ntop(AF_INET,
4392 					&s6a->s6_addr[IN6ADDRSZ - INADDRSZ],
4393 					dst, dst_len);
4394 	else
4395 	{
4396 		char *d;
4397 		size_t sz;
4398 
4399 		/* Save pointer to beginning of string */
4400 		d = dst;
4401 
4402 		/* Add IPv6: protocol tag */
4403 		sz = sm_strlcpy(dst, "IPv6:", dst_len);
4404 		if (sz >= dst_len)
4405 			return NULL;
4406 		dst += sz;
4407 		dst_len -= sz;
4408 		if (UseCompressedIPv6Addresses)
4409 			ap = (char *) inet_ntop(AF_INET6, s6a, dst, dst_len);
4410 		else
4411 			ap = sm_inet6_ntop(s6a, dst, dst_len);
4412 		/* Restore pointer to beginning of string */
4413 		if (ap != NULL)
4414 			ap = d;
4415 	}
4416 	return ap;
4417 }
4418 
4419 /*
4420 **  ANYNET_PTON -- convert printed form to network address.
4421 **
4422 **	Wrapper for inet_pton() which handles IPv6: labels.
4423 **
4424 **	Parameters:
4425 **		family -- address family
4426 **		src -- string
4427 **		dst -- destination address structure
4428 **
4429 **	Returns:
4430 **		1 if the address was valid
4431 **		0 if the address wasn't parsable
4432 **		-1 if error
4433 */
4434 
4435 int
4436 anynet_pton(family, src, dst)
4437 	int family;
4438 	const char *src;
4439 	void *dst;
4440 {
4441 	if (family == AF_INET6 && sm_strncasecmp(src, "IPv6:", 5) == 0)
4442 		src += 5;
4443 	return inet_pton(family, src, dst);
4444 }
4445 #endif /* NETINET6 */
4446 /*
4447 **  ANYNET_NTOA -- convert a network address to printable form.
4448 **
4449 **	Parameters:
4450 **		sap -- a pointer to a sockaddr structure.
4451 **
4452 **	Returns:
4453 **		A printable version of that sockaddr.
4454 */
4455 
4456 #ifdef USE_SOCK_STREAM
4457 
4458 # if NETLINK
4459 #  include <net/if_dl.h>
4460 # endif
4461 
4462 char *
4463 anynet_ntoa(sap)
4464 	register SOCKADDR *sap;
4465 {
4466 	register char *bp;
4467 	register char *ap;
4468 	int l;
4469 	static char buf[100];
4470 
4471 	/* check for null/zero family */
4472 	if (sap == NULL)
4473 		return "NULLADDR";
4474 	if (sap->sa.sa_family == 0)
4475 		return "0";
4476 
4477 	switch (sap->sa.sa_family)
4478 	{
4479 # if NETUNIX
4480 	  case AF_UNIX:
4481 		if (sap->sunix.sun_path[0] != '\0')
4482 			(void) sm_snprintf(buf, sizeof(buf), "[UNIX: %.64s]",
4483 					   sap->sunix.sun_path);
4484 		else
4485 			(void) sm_strlcpy(buf, "[UNIX: localhost]", sizeof(buf));
4486 		return buf;
4487 # endif /* NETUNIX */
4488 
4489 # if NETINET
4490 	  case AF_INET:
4491 		return (char *) inet_ntoa(sap->sin.sin_addr);
4492 # endif
4493 
4494 # if NETINET6
4495 	  case AF_INET6:
4496 		ap = anynet_ntop(&sap->sin6.sin6_addr, buf, sizeof(buf));
4497 		if (ap != NULL)
4498 			return ap;
4499 		break;
4500 # endif /* NETINET6 */
4501 
4502 # if NETLINK
4503 	  case AF_LINK:
4504 		(void) sm_snprintf(buf, sizeof(buf), "[LINK: %s]",
4505 				   link_ntoa((struct sockaddr_dl *) &sap->sa));
4506 		return buf;
4507 # endif /* NETLINK */
4508 	  default:
4509 		/* this case is needed when nothing is #defined */
4510 		/* in order to keep the switch syntactically correct */
4511 		break;
4512 	}
4513 
4514 	/* unknown family -- just dump bytes */
4515 	(void) sm_snprintf(buf, sizeof(buf), "Family %d: ", sap->sa.sa_family);
4516 	bp = &buf[strlen(buf)];
4517 	ap = sap->sa.sa_data;
4518 	for (l = sizeof(sap->sa.sa_data); --l >= 0; )
4519 	{
4520 		(void) sm_snprintf(bp, SPACELEFT(buf, bp), "%02x:",
4521 				   *ap++ & 0377);
4522 		bp += 3;
4523 	}
4524 	*--bp = '\0';
4525 	return buf;
4526 }
4527 /*
4528 **  HOSTNAMEBYANYADDR -- return name of host based on address
4529 **
4530 **	Parameters:
4531 **		sap -- SOCKADDR pointer
4532 **
4533 **	Returns:
4534 **		text representation of host name.
4535 **
4536 **	Side Effects:
4537 **		none.
4538 */
4539 
4540 char *
4541 hostnamebyanyaddr(sap)
4542 	register SOCKADDR *sap;
4543 {
4544 	register struct hostent *hp;
4545 # if NAMED_BIND
4546 	int saveretry;
4547 # endif
4548 # if NETINET6
4549 	struct in6_addr in6_addr;
4550 # endif /* NETINET6 */
4551 
4552 # if NAMED_BIND
4553 	/* shorten name server timeout to avoid higher level timeouts */
4554 	saveretry = _res.retry;
4555 	if (_res.retry * _res.retrans > 20)
4556 		_res.retry = 20 / _res.retrans;
4557 	if (_res.retry == 0)
4558 		_res.retry = 1;
4559 # endif /* NAMED_BIND */
4560 
4561 	switch (sap->sa.sa_family)
4562 	{
4563 # if NETINET
4564 	  case AF_INET:
4565 		hp = sm_gethostbyaddr((char *) &sap->sin.sin_addr,
4566 				      INADDRSZ, AF_INET);
4567 		break;
4568 # endif /* NETINET */
4569 
4570 # if NETINET6
4571 	  case AF_INET6:
4572 		hp = sm_gethostbyaddr((char *) &sap->sin6.sin6_addr,
4573 				      IN6ADDRSZ, AF_INET6);
4574 		break;
4575 # endif /* NETINET6 */
4576 
4577 # if NETISO
4578 	  case AF_ISO:
4579 		hp = sm_gethostbyaddr((char *) &sap->siso.siso_addr,
4580 				      sizeof(sap->siso.siso_addr), AF_ISO);
4581 		break;
4582 # endif /* NETISO */
4583 
4584 # if NETUNIX
4585 	  case AF_UNIX:
4586 		hp = NULL;
4587 		break;
4588 # endif /* NETUNIX */
4589 
4590 	  default:
4591 		hp = sm_gethostbyaddr(sap->sa.sa_data, sizeof(sap->sa.sa_data),
4592 				      sap->sa.sa_family);
4593 		break;
4594 	}
4595 
4596 # if NAMED_BIND
4597 	_res.retry = saveretry;
4598 # endif
4599 
4600 # if NETINET || NETINET6
4601 	if (hp != NULL && hp->h_name[0] != '['
4602 #  if NETINET6
4603 	    && inet_pton(AF_INET6, hp->h_name, &in6_addr) != 1
4604 #  endif /* NETINET6 */
4605 #  if NETINET
4606 	    && inet_addr(hp->h_name) == INADDR_NONE
4607 #  endif
4608 	    )
4609 	{
4610 		char *name;
4611 
4612 		name = denlstring((char *) hp->h_name, true, true);
4613 #  if NETINET6
4614 		if (name == hp->h_name)
4615 		{
4616 			static char n[MAXNAME + 1];
4617 
4618 			/* Copy the string, hp->h_name is about to disappear */
4619 			(void) sm_strlcpy(n, name, sizeof(n));
4620 			name = n;
4621 		}
4622 		FREEHOSTENT(hp, NULL);
4623 #  endif /* NETINET6 */
4624 		return name;
4625 	}
4626 # endif /* NETINET || NETINET6 */
4627 
4628 	FREEHOSTENT(hp, NULL);
4629 
4630 # if NETUNIX
4631 	if (sap->sa.sa_family == AF_UNIX && sap->sunix.sun_path[0] == '\0')
4632 		return "localhost";
4633 # endif
4634 	{
4635 		static char buf[203];
4636 
4637 		(void) sm_snprintf(buf, sizeof(buf), "[%.200s]",
4638 				   anynet_ntoa(sap));
4639 		return buf;
4640 	}
4641 }
4642 #endif /* USE_SOCK_STREAM */
4643