xref: /netbsd-src/external/ibm-public/postfix/dist/src/master/master_listen.c (revision 33881f779a77dce6440bdc44610d94de75bebefe)
1 /*	$NetBSD: master_listen.c,v 1.2 2020/03/18 19:05:16 christos Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	master_listen 3
6 /* SUMMARY
7 /*	Postfix master - start/stop listeners
8 /* SYNOPSIS
9 /*	#include "master.h"
10 /*
11 /*	void	master_listen_init(serv)
12 /*	MASTER_SERV *serv;
13 /*
14 /*	void	master_listen_cleanup(serv)
15 /*	MASTER_SERV *serv;
16 /* DESCRIPTION
17 /*	master_listen_init() turns on the listener implemented by the
18 /*	named process. FIFOs and UNIX-domain sockets are created with
19 /*	mode 0622 and with ownership mail_owner.
20 /*
21 /*	master_listen_cleanup() turns off the listener implemented by the
22 /*	named process.
23 /* DIAGNOSTICS
24 /* BUGS
25 /* SEE ALSO
26 /*	inet_listen(3), internet-domain listener
27 /*	unix_listen(3), unix-domain listener
28 /*	fifo_listen(3), named-pipe listener
29 /*	upass_listen(3), file descriptor passing listener
30 /*	set_eugid(3), set effective user/group attributes
31 /* LICENSE
32 /* .ad
33 /* .fi
34 /*	The Secure Mailer license must be distributed with this software.
35 /* AUTHOR(S)
36 /*	Wietse Venema
37 /*	IBM T.J. Watson Research
38 /*	P.O. Box 704
39 /*	Yorktown Heights, NY 10598, USA
40 /*
41 /*	Wietse Venema
42 /*	Google, Inc.
43 /*	111 8th Avenue
44 /*	New York, NY 10011, USA
45 /*--*/
46 
47 /* System library. */
48 
49 #include <sys_defs.h>
50 #include <sys/socket.h>
51 #include <netinet/in.h>
52 #include <arpa/inet.h>
53 #include <unistd.h>
54 #include <string.h>
55 
56 /* Utility library. */
57 
58 #include <msg.h>
59 #include <listen.h>
60 #include <mymalloc.h>
61 #include <stringops.h>
62 #include <inet_addr_list.h>
63 #include <set_eugid.h>
64 #include <set_ugid.h>
65 #include <iostuff.h>
66 #include <myaddrinfo.h>
67 #include <sock_addr.h>
68 
69 /* Global library. */
70 
71 #include <mail_params.h>
72 
73 /* Application-specific. */
74 
75 #include "master.h"
76 
77 /* master_listen_init - enable connection requests */
78 
master_listen_init(MASTER_SERV * serv)79 void    master_listen_init(MASTER_SERV *serv)
80 {
81     const char *myname = "master_listen_init";
82     char   *end_point;
83     int     n;
84     MAI_HOSTADDR_STR hostaddr;
85     struct sockaddr *sa;
86 
87     /*
88      * Find out what transport we should use, then create one or more
89      * listener sockets. Make the listener sockets non-blocking, so that
90      * child processes don't block in accept() when multiple processes are
91      * selecting on the same socket and only one of them gets the connection.
92      */
93     switch (serv->type) {
94 
95 	/*
96 	 * UNIX-domain or stream listener endpoints always come as singlets.
97 	 */
98     case MASTER_SERV_TYPE_UNIX:
99 	set_eugid(var_owner_uid, var_owner_gid);
100 	serv->listen_fd[0] =
101 	    LOCAL_LISTEN(serv->name, serv->max_proc > var_proc_limit ?
102 			 serv->max_proc : var_proc_limit, NON_BLOCKING);
103 	close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
104 	set_ugid(getuid(), getgid());
105 	break;
106 
107 	/*
108 	 * UNIX-domain datagram listener endpoints always come as singlets.
109 	 */
110     case MASTER_SERV_TYPE_UXDG:
111 	set_eugid(var_owner_uid, var_owner_gid);
112 	serv->listen_fd[0] =
113 	    unix_dgram_listen(serv->name, NON_BLOCKING);
114 	close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
115 	set_ugid(getuid(), getgid());
116 	break;
117 
118 	/*
119 	 * FIFO listener endpoints always come as singlets.
120 	 */
121     case MASTER_SERV_TYPE_FIFO:
122 	set_eugid(var_owner_uid, var_owner_gid);
123 	serv->listen_fd[0] = fifo_listen(serv->name, 0622, NON_BLOCKING);
124 	close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
125 	set_ugid(getuid(), getgid());
126 	break;
127 
128 	/*
129 	 * INET-domain listener endpoints can be wildcarded (the default) or
130 	 * bound to specific interface addresses.
131 	 *
132 	 * With dual-stack IPv4/6 systems it does not matter, we have to specify
133 	 * the addresses anyway, either explicit or wild-card.
134 	 */
135     case MASTER_SERV_TYPE_INET:
136 	for (n = 0; n < serv->listen_fd_count; n++) {
137 	    sa = SOCK_ADDR_PTR(MASTER_INET_ADDRLIST(serv)->addrs + n);
138 	    SOCKADDR_TO_HOSTADDR(sa, SOCK_ADDR_LEN(sa), &hostaddr,
139 				 (MAI_SERVPORT_STR *) 0, 0);
140 	    end_point = concatenate(hostaddr.buf,
141 				    ":", MASTER_INET_PORT(serv), (char *) 0);
142 	    serv->listen_fd[n]
143 		= inet_listen(end_point, serv->max_proc > var_proc_limit ?
144 			      serv->max_proc : var_proc_limit, NON_BLOCKING);
145 	    close_on_exec(serv->listen_fd[n], CLOSE_ON_EXEC);
146 	    myfree(end_point);
147 	}
148 	break;
149 
150 	/*
151 	 * Descriptor passing endpoints always come as singlets.
152 	 */
153 #ifdef MASTER_SERV_TYPE_PASS
154     case MASTER_SERV_TYPE_PASS:
155 	set_eugid(var_owner_uid, var_owner_gid);
156 	serv->listen_fd[0] =
157 	    LOCAL_LISTEN(serv->name, serv->max_proc > var_proc_limit ?
158 			serv->max_proc : var_proc_limit, NON_BLOCKING);
159 	close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
160 	set_ugid(getuid(), getgid());
161 	break;
162 #endif
163     default:
164 	msg_panic("%s: unknown service type: %d", myname, serv->type);
165     }
166 }
167 
168 /* master_listen_cleanup - disable connection requests */
169 
master_listen_cleanup(MASTER_SERV * serv)170 void    master_listen_cleanup(MASTER_SERV *serv)
171 {
172     const char *myname = "master_listen_cleanup";
173     int     n;
174 
175     /*
176      * XXX The listen socket is shared with child processes. Closing the
177      * socket in the master process does not really disable listeners in
178      * child processes. There seems to be no documented way to turn off a
179      * listener. The 4.4BSD shutdown(2) man page promises an ENOTCONN error
180      * when shutdown(2) is applied to a socket that is not connected.
181      */
182     for (n = 0; n < serv->listen_fd_count; n++) {
183 	if (close(serv->listen_fd[n]) < 0)
184 	    msg_warn("%s: close listener socket %d: %m",
185 		     myname, serv->listen_fd[n]);
186 	serv->listen_fd[n] = -1;
187     }
188 }
189