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