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