1 /*
2 * ProFTPD - FTP server daemon
3 * Copyright (c) 2001-2020 The ProFTPD Project team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18 *
19 * As a special exemption, The ProFTPD Project team and other respective
20 * copyright holders give permission to link this program with OpenSSL, and
21 * distribute the resulting executable, without including the source code for
22 * OpenSSL in the source distribution.
23 */
24
25 /* Routines to work with ProFTPD bindings. */
26
27 #include "conf.h"
28
29 /* From src/dirtree.c */
30 extern xaset_t *server_list;
31 extern server_rec *main_server;
32
33 static pr_ipbind_t *ipbind_table[PR_BINDINGS_TABLE_SIZE];
34 static int ipbind_table_initialized = FALSE;
35
36 static pool *binding_pool = NULL;
37 static pr_ipbind_t *ipbind_default_server = NULL,
38 *ipbind_localhost_server = NULL;
39
40 static const char *trace_channel = "binding";
41
42 static void trace_ipbind_table(void);
43
init_ipbind_table(void)44 static void init_ipbind_table(void) {
45 if (ipbind_table_initialized == TRUE) {
46 return;
47 }
48
49 memset(ipbind_table, 0, sizeof(ipbind_table));
50 ipbind_table_initialized = TRUE;
51 }
52
53 /* Server cleanup callback function */
server_cleanup_cb(void * conn)54 static void server_cleanup_cb(void *conn) {
55 *((conn_t **) conn) = NULL;
56 }
57
58 /* The hashing function for the hash table of bindings. This algorithm
59 * is stolen from Apache's http_vhost.c
60 */
ipbind_hash_addr(const pr_netaddr_t * addr)61 static unsigned int ipbind_hash_addr(const pr_netaddr_t *addr) {
62 size_t offset;
63 unsigned int key;
64
65 offset = pr_netaddr_get_inaddr_len(addr);
66
67 /* The key is the last four bytes of the IP address.
68 * For IPv4, this is the entire address, as always.
69 * For IPv6, this is usually part of the MAC address.
70 */
71 key = *(unsigned *) ((char *) pr_netaddr_get_inaddr(addr) + offset - 4);
72
73 key ^= (key >> 16);
74 return ((key >> 8) ^ key) % PR_BINDINGS_TABLE_SIZE;
75 }
76
77 static pool *listening_conn_pool = NULL;
78 static xaset_t *listening_conn_list = NULL;
79 struct listener_rec {
80 struct listener_rec *next, *prev;
81
82 pool *pool;
83 const pr_netaddr_t *addr;
84 unsigned int port;
85 conn_t *conn;
86 int claimed;
87 };
88
pr_ipbind_get_listening_conn(server_rec * server,const pr_netaddr_t * addr,unsigned int port)89 conn_t *pr_ipbind_get_listening_conn(server_rec *server,
90 const pr_netaddr_t *addr, unsigned int port) {
91 conn_t *l;
92 pool *p;
93 struct listener_rec *lr;
94
95 if (listening_conn_list) {
96 for (lr = (struct listener_rec *) listening_conn_list->xas_list; lr;
97 lr = lr->next) {
98 int use_elt = FALSE;
99
100 pr_signals_handle();
101
102 if (addr != NULL &&
103 lr->addr != NULL) {
104 const char *lr_ipstr = NULL;
105
106 lr_ipstr = pr_netaddr_get_ipstr(lr->addr);
107
108 /* Note: lr_ipstr should never be null. If it is, it means that
109 * the lr->addr object never had its IP address resolved/stashed,
110 * and in attempting to do, getnameinfo(3) failed for some reason.
111 *
112 * The IP address on which it's listening, if not available via
113 * lr->addr, should thus be available via lr->conn->local_addr.
114 */
115
116 if (lr_ipstr == NULL &&
117 lr->conn != NULL) {
118 lr_ipstr = pr_netaddr_get_ipstr(lr->conn->local_addr);
119 }
120
121 if (lr_ipstr != NULL) {
122 if (strcmp(pr_netaddr_get_ipstr(addr), lr_ipstr) == 0 &&
123 port == lr->port) {
124 use_elt = TRUE;
125 }
126 }
127
128 } else if (addr == NULL &&
129 port == lr->port) {
130 use_elt = TRUE;
131 }
132
133 if (use_elt) {
134 lr->claimed = TRUE;
135 return lr->conn;
136 }
137 }
138 }
139
140 if (listening_conn_pool == NULL) {
141 listening_conn_pool = make_sub_pool(permanent_pool);
142 pr_pool_tag(listening_conn_pool, "Listening Connection Pool");
143
144 listening_conn_list = xaset_create(listening_conn_pool, NULL);
145 }
146
147 p = make_sub_pool(listening_conn_pool);
148 pr_pool_tag(p, "Listening conn subpool");
149
150 l = pr_inet_create_conn(p, -1, addr, port, FALSE);
151 if (l == NULL) {
152 return NULL;
153 }
154
155 /* Inform any interested listeners that this socket was opened. */
156 pr_inet_generate_socket_event("core.ctrl-listen", server, l->local_addr,
157 l->listen_fd);
158
159 lr = pcalloc(p, sizeof(struct listener_rec));
160 lr->pool = p;
161 lr->conn = l;
162 lr->addr = pr_netaddr_dup(p, addr);
163 if (lr->addr == NULL &&
164 errno != EINVAL) {
165 return NULL;
166 }
167 lr->port = port;
168 lr->claimed = TRUE;
169
170 xaset_insert(listening_conn_list, (xasetmember_t *) lr);
171 return l;
172 }
173
174 /* Slight (clever?) optimization: the loop in server_loop() always
175 * calls pr_ipbind_listen(), selects, then pr_ipbind_accept_conn(). Now,
176 * rather than having both pr_ipbind_listen() and pr_ipbind_accept_conn()
177 * scan the entire ipbind table looking for matches, what if pr_ipbind_listen
178 * kept track of which listeners (connt_s) it used, so that
179 * pr_ipbind_accept_conn() need merely check those listeners, rather than
180 * scanning the entire table itself?
181 */
182
183 static array_header *listener_list = NULL;
184
pr_ipbind_accept_conn(fd_set * readfds,int * listenfd)185 conn_t *pr_ipbind_accept_conn(fd_set *readfds, int *listenfd) {
186 conn_t **listeners = listener_list->elts;
187 register unsigned int i = 0;
188
189 if (readfds == NULL ||
190 listenfd == NULL) {
191 errno = EINVAL;
192 return NULL;
193 }
194
195 for (i = 0; i < listener_list->nelts; i++) {
196 conn_t *listener = listeners[i];
197
198 pr_signals_handle();
199 if (FD_ISSET(listener->listen_fd, readfds) &&
200 listener->mode == CM_LISTEN) {
201 int fd = pr_inet_accept_nowait(listener->pool, listener);
202
203 if (fd == -1) {
204 int xerrno = errno;
205
206 /* Handle errors gracefully. If we're here, then
207 * ipbind->ib_server->listen contains either error information, or
208 * we just got caught in a blocking condition.
209 */
210 if (listener->mode == CM_ERROR) {
211
212 /* Ignore ECONNABORTED, as they tend to be health checks/probes by
213 * e.g. load balancers and other naive TCP clients.
214 */
215 if (listener->xerrno != ECONNABORTED) {
216 pr_log_pri(PR_LOG_ERR, "error: unable to accept an incoming "
217 "connection: %s", strerror(listener->xerrno));
218 }
219
220 listener->xerrno = 0;
221 listener->mode = CM_LISTEN;
222
223 errno = xerrno;
224 return NULL;
225 }
226 }
227
228 *listenfd = fd;
229 return listener;
230 }
231 }
232
233 errno = ENOENT;
234 return NULL;
235 }
236
pr_ipbind_add_binds(server_rec * serv)237 int pr_ipbind_add_binds(server_rec *serv) {
238 int res = 0;
239 config_rec *c = NULL;
240 conn_t *listen_conn = NULL;
241 const pr_netaddr_t *addr = NULL;
242
243 if (serv == NULL) {
244 errno = EINVAL;
245 return -1;
246 }
247
248 c = find_config(serv->conf, CONF_PARAM, "_bind_", FALSE);
249 while (c != NULL) {
250 listen_conn = NULL;
251
252 pr_signals_handle();
253
254 addr = pr_netaddr_get_addr(serv->pool, c->argv[0], NULL);
255 if (addr == NULL) {
256 pr_log_pri(PR_LOG_WARNING,
257 "notice: unable to determine IP address of '%s'", (char *) c->argv[0]);
258 c = find_config_next(c, c->next, CONF_PARAM, "_bind_", FALSE);
259 continue;
260 }
261
262 /* If the SocketBindTight directive is in effect, create a separate
263 * listen socket for this address, and add it to the binding list.
264 */
265 if (SocketBindTight &&
266 serv->ServerPort) {
267 listen_conn = pr_ipbind_get_listening_conn(serv, addr, serv->ServerPort);
268 if (listen_conn == NULL) {
269 return -1;
270 }
271
272 PR_CREATE_IPBIND(serv, addr, serv->ServerPort);
273 PR_OPEN_IPBIND(addr, serv->ServerPort, listen_conn, FALSE, FALSE, TRUE);
274
275 } else {
276
277 PR_CREATE_IPBIND(serv, addr, serv->ServerPort);
278 PR_OPEN_IPBIND(addr, serv->ServerPort, serv->listen, FALSE, FALSE, TRUE);
279 }
280
281 c = find_config_next(c, c->next, CONF_PARAM, "_bind_", FALSE);
282 }
283
284 return 0;
285 }
286
pr_ipbind_close(const pr_netaddr_t * addr,unsigned int port,unsigned char close_namebinds)287 int pr_ipbind_close(const pr_netaddr_t *addr, unsigned int port,
288 unsigned char close_namebinds) {
289 register unsigned int i = 0;
290
291 if (addr != NULL) {
292 pr_ipbind_t *ipbind = NULL;
293 unsigned char have_ipbind = FALSE;
294
295 i = ipbind_hash_addr(addr);
296
297 if (ipbind_table[i] == NULL) {
298 pr_log_pri(PR_LOG_NOTICE, "notice: no ipbind found for %s:%d",
299 pr_netaddr_get_ipstr(addr), port);
300 errno = ENOENT;
301 return -1;
302 }
303
304 for (ipbind = ipbind_table[i]; ipbind; ipbind = ipbind->ib_next) {
305 if (pr_netaddr_cmp(ipbind->ib_addr, addr) == 0 &&
306 (!ipbind->ib_port || ipbind->ib_port == port)) {
307 have_ipbind = TRUE;
308 break;
309 }
310 }
311
312 if (!have_ipbind) {
313 pr_log_pri(PR_LOG_NOTICE, "notice: no ipbind found for %s:%d",
314 pr_netaddr_get_ipstr(addr), port);
315 errno = ENOENT;
316 return -1;
317 }
318
319 /* If already closed, exit now. */
320 if (!ipbind->ib_isactive) {
321 errno = EPERM;
322 return -1;
323 }
324
325 /* Close the ipbinding's listen connection, if present. The trick
326 * here is determining whether this binding's listen member is
327 * _the_ listening socket for the master daemon, or whether it's
328 * been created for SocketBindTight, and can be closed.
329 *
330 * Actually, it's not that hard. It's only _the_ listening socket
331 * for the master daemon in inetd mode, in which case virtual servers
332 * can't be shutdown via ftpdctl, anyway.
333 */
334 if (SocketBindTight && ipbind->ib_listener != NULL) {
335 pr_inet_close(ipbind->ib_server->pool, ipbind->ib_listener);
336 ipbind->ib_listener = ipbind->ib_server->listen = NULL;
337 }
338
339 /* Mark this ipbind as inactive. For SocketBindTight sockets, the
340 * closing of the listening connection will suffice, from the clients'
341 * point of view. However, this covers the non-SocketBindTight case,
342 * and will prevent this binding from returning its server_rec pointer
343 * on future lookup requests via pr_ipbind_get_server().
344 */
345 ipbind->ib_isactive = FALSE;
346
347 if (close_namebinds && ipbind->ib_namebinds) {
348 register unsigned int j = 0;
349 pr_namebind_t **namebinds = NULL;
350
351 namebinds = (pr_namebind_t **) ipbind->ib_namebinds->elts;
352 for (j = 0; j < ipbind->ib_namebinds->nelts; j++) {
353 pr_namebind_t *nb = namebinds[j];
354
355 if (pr_namebind_close(nb->nb_name, nb->nb_server->addr) < 0) {
356 pr_trace_msg(trace_channel, 7,
357 "notice: error closing namebind '%s' for address %s: %s",
358 nb->nb_name, pr_netaddr_get_ipstr(nb->nb_server->addr),
359 strerror(errno));
360 }
361 }
362 }
363
364 } else {
365 /* A NULL addr has a special meaning: close _all_ ipbinds in the list. */
366 for (i = 0; i < PR_BINDINGS_TABLE_SIZE; i++) {
367 pr_ipbind_t *ipbind = NULL;
368
369 for (ipbind = ipbind_table[i]; ipbind; ipbind = ipbind->ib_next) {
370 if (SocketBindTight &&
371 ipbind->ib_listener != NULL) {
372 pr_inet_close(main_server->pool, ipbind->ib_listener);
373 ipbind->ib_listener = ipbind->ib_server->listen = NULL;
374 }
375
376 /* Note: do not need to check if this ipbind was previously closed,
377 * for the NULL addr is a request to shut down all ipbinds,
378 * regardless of their current state.
379 */
380 ipbind->ib_isactive = FALSE;
381
382 if (close_namebinds &&
383 ipbind->ib_namebinds != NULL) {
384 register unsigned int j = 0;
385 pr_namebind_t **namebinds = NULL;
386
387 namebinds = (pr_namebind_t **) ipbind->ib_namebinds->elts;
388 for (j = 0; j < ipbind->ib_namebinds->nelts; j++) {
389 pr_namebind_t *nb = namebinds[j];
390
391 if (pr_namebind_close(nb->nb_name, nb->nb_server->addr) < 0) {
392 pr_trace_msg(trace_channel, 7,
393 "notice: error closing namebind '%s' for address %s: %s",
394 nb->nb_name, pr_netaddr_get_ipstr(nb->nb_server->addr),
395 strerror(errno));
396 }
397 }
398 }
399 }
400 }
401 }
402
403 return 0;
404 }
405
406 /* Need a way to close all listening fds in a child process. */
pr_ipbind_close_listeners(void)407 int pr_ipbind_close_listeners(void) {
408 conn_t **listeners;
409 register unsigned int i = 0;
410
411 if (!listener_list ||
412 listener_list->nelts == 0)
413 return 0;
414
415 listeners = listener_list->elts;
416 for (i = 0; i < listener_list->nelts; i++) {
417 conn_t *listener = listeners[i];
418
419 pr_signals_handle();
420
421 if (listener->listen_fd != -1) {
422 close(listener->listen_fd);
423 listener->listen_fd = -1;
424 }
425 }
426
427 return 0;
428 }
429
pr_ipbind_create(server_rec * server,const pr_netaddr_t * addr,unsigned int port)430 int pr_ipbind_create(server_rec *server, const pr_netaddr_t *addr,
431 unsigned int port) {
432 pr_ipbind_t *existing = NULL, *ipbind = NULL;
433 register unsigned int i = 0;
434
435 if (server == NULL||
436 addr == NULL) {
437 errno = EINVAL;
438 return -1;
439 }
440
441 /* Ensure the ipbind table has been initialized. */
442 init_ipbind_table();
443
444 i = ipbind_hash_addr(addr);
445 pr_trace_msg(trace_channel, 29, "hashed address '%s' to index %u",
446 pr_netaddr_get_ipstr(addr), i);
447
448 /* Make sure the address is not already in use */
449 for (ipbind = ipbind_table[i]; ipbind; ipbind = ipbind->ib_next) {
450 if (pr_netaddr_cmp(ipbind->ib_addr, addr) == 0 &&
451 ipbind->ib_port == port) {
452 existing = ipbind;
453 break;
454 }
455 }
456
457 if (existing != NULL) {
458 config_rec *c;
459
460 /* If the given server config does not have any ServerAlias directives,
461 * then this is an IP/port collision, and we need to return an error.
462 *
463 * However, if there are ServerAliases, this is a name-based config and
464 * should be processed properly.
465 */
466
467 c = find_config(server->conf, CONF_PARAM, "ServerAlias", FALSE);
468 if (c == NULL) {
469 pr_log_pri(PR_LOG_WARNING, "notice: '%s' (%s:%u) already bound to '%s'",
470 server->ServerName, pr_netaddr_get_ipstr(addr), port,
471 ipbind->ib_server->ServerName);
472 errno = EADDRINUSE;
473 return -1;
474 }
475
476 pr_log_debug(DEBUG9, "notice: '%s' (%s:%u) already bound to '%s'",
477 server->ServerName, pr_netaddr_get_ipstr(addr), port,
478 ipbind->ib_server->ServerName);
479 }
480
481 if (binding_pool == NULL) {
482 binding_pool = make_sub_pool(permanent_pool);
483 pr_pool_tag(binding_pool, "Bindings Pool");
484 }
485
486 ipbind = pcalloc(server->pool, sizeof(pr_ipbind_t));
487 ipbind->ib_server = server;
488 ipbind->ib_addr = addr;
489 ipbind->ib_port = port;
490 ipbind->ib_namebinds = NULL;
491 ipbind->ib_isdefault = FALSE;
492 ipbind->ib_islocalhost = FALSE;
493 ipbind->ib_isactive = FALSE;
494
495 pr_trace_msg(trace_channel, 8, "created ipbind %p for %s#%u, server %p",
496 ipbind, pr_netaddr_get_ipstr(ipbind->ib_addr), ipbind->ib_port,
497 ipbind->ib_server);
498
499 /* Add the ipbind to the table. */
500 if (ipbind_table[i] != NULL) {
501 pr_trace_msg(trace_channel, 19,
502 "found existing ipbind %p (server %p) at index %u in iptable table, "
503 "adding to %p", ipbind_table[i], ipbind_table[i]->ib_server, i, ipbind);
504 ipbind->ib_next = ipbind_table[i];
505 }
506
507 ipbind_table[i] = ipbind;
508 return 0;
509 }
510
511 /* Returns the LAST matching ipbind for the given port, if any. If provided,
512 * the match_count pointer will contain the number of ipbinds found that
513 * matched that port.
514 */
ipbind_find_port(unsigned int port,unsigned char skip_inactive,unsigned int * match_count)515 static pr_ipbind_t *ipbind_find_port(unsigned int port,
516 unsigned char skip_inactive, unsigned int *match_count) {
517 register unsigned int i;
518 pr_ipbind_t *matched_ipbind = NULL;
519
520 for (i = 0; i < PR_BINDINGS_TABLE_SIZE; i++) {
521 pr_ipbind_t *ipbind;
522
523 for (ipbind = ipbind_table[i]; ipbind; ipbind = ipbind->ib_next) {
524 pr_signals_handle();
525
526 if (skip_inactive &&
527 !ipbind->ib_isactive) {
528 continue;
529 }
530
531 if (ipbind->ib_port == port) {
532 if (match_count != NULL) {
533 (*match_count)++;
534 }
535
536 matched_ipbind = ipbind;
537 }
538 }
539 }
540
541 if (matched_ipbind == NULL) {
542 errno = ENOENT;
543 return NULL;
544 }
545
546 return matched_ipbind;
547 }
548
pr_ipbind_find(const pr_netaddr_t * addr,unsigned int port,unsigned char skip_inactive)549 pr_ipbind_t *pr_ipbind_find(const pr_netaddr_t *addr, unsigned int port,
550 unsigned char skip_inactive) {
551 register unsigned int i;
552 pr_ipbind_t *ipbind = NULL;
553
554 if (addr == NULL) {
555 errno = EINVAL;
556 return NULL;
557 }
558
559 /* Ensure the ipbind table has been initialized. */
560 init_ipbind_table();
561
562 i = ipbind_hash_addr(addr);
563
564 for (ipbind = ipbind_table[i]; ipbind; ipbind = ipbind->ib_next) {
565 pr_signals_handle();
566
567 if (skip_inactive &&
568 !ipbind->ib_isactive) {
569 continue;
570 }
571
572 if (pr_netaddr_cmp(ipbind->ib_addr, addr) == 0) {
573 if (ipbind->ib_port == 0 ||
574 port == 0 ||
575 ipbind->ib_port == port) {
576 return ipbind;
577 }
578 }
579 }
580
581 errno = ENOENT;
582 return NULL;
583 }
584
pr_ipbind_get(pr_ipbind_t * prev)585 pr_ipbind_t *pr_ipbind_get(pr_ipbind_t *prev) {
586 static unsigned int i = 0;
587
588 if (prev) {
589
590 /* If there's another ipbind in this chain, simply return that. */
591 if (prev->ib_next) {
592 return prev->ib_next;
593 }
594
595 /* If the increment is at the maximum size, return NULL (no more chains
596 * to be examined).
597 */
598 if (i == PR_BINDINGS_TABLE_SIZE) {
599 errno = ENOENT;
600 return NULL;
601 }
602
603 /* Increment the index. At this point, we know that the given pointer is
604 * the last in the chain, and that there are more chains in the table
605 * to be examined.
606 */
607 i++;
608
609 } else {
610 /* Reset the index if prev is NULL. */
611 i = 0;
612 }
613
614 /* Search for the next non-empty chain in the table. */
615 for (; i < PR_BINDINGS_TABLE_SIZE; i++) {
616 if (ipbind_table[i] != NULL) {
617 return ipbind_table[i];
618 }
619 }
620
621 errno = ENOENT;
622 return NULL;
623 }
624
pr_ipbind_get_server(const pr_netaddr_t * addr,unsigned int port)625 server_rec *pr_ipbind_get_server(const pr_netaddr_t *addr, unsigned int port) {
626 pr_ipbind_t *ipbind = NULL;
627 pr_netaddr_t wildcard_addr;
628 int addr_family;
629 unsigned int match_count = 0;
630
631 /* If we've got a binding configured for this exact address, return it
632 * straight away.
633 */
634 ipbind = pr_ipbind_find(addr, port, TRUE);
635 if (ipbind != NULL) {
636 return ipbind->ib_server;
637 }
638
639 /* Look for a vhost bound to the wildcard address (i.e. INADDR_ANY).
640 *
641 * This allows for "<VirtualHost 0.0.0.0>" configurations, where the
642 * IP address to which the client might connect is not known at
643 * configuration time. (Usually happens when the same config file
644 * is deployed to multiple machines.)
645 */
646
647 addr_family = pr_netaddr_get_family(addr);
648
649 pr_netaddr_clear(&wildcard_addr);
650 pr_netaddr_set_family(&wildcard_addr, addr_family);
651 pr_netaddr_set_sockaddr_any(&wildcard_addr);
652
653 ipbind = pr_ipbind_find(&wildcard_addr, port, TRUE);
654 if (ipbind != NULL) {
655 pr_log_debug(DEBUG7, "no matching vhost found for %s#%u, using "
656 "'%s' listening on wildcard address", pr_netaddr_get_ipstr(addr), port,
657 ipbind->ib_server->ServerName);
658 return ipbind->ib_server;
659 }
660
661 #ifdef PR_USE_IPV6
662 if (addr_family == AF_INET6 &&
663 pr_netaddr_use_ipv6()) {
664
665 /* The pr_ipbind_find() probably returned NULL because there aren't any
666 * <VirtualHost> sections configured explicitly for the wildcard IPv6
667 * address of "::", just the IPv4 wildcard "0.0.0.0" address.
668 *
669 * So try the pr_ipbind_find() again, this time using the IPv4
670 * wildcard.
671 */
672 pr_netaddr_clear(&wildcard_addr);
673 pr_netaddr_set_family(&wildcard_addr, AF_INET);
674 pr_netaddr_set_sockaddr_any(&wildcard_addr);
675
676 ipbind = pr_ipbind_find(&wildcard_addr, port, TRUE);
677 if (ipbind != NULL) {
678 pr_log_debug(DEBUG7, "no matching vhost found for %s#%u, using "
679 "'%s' listening on wildcard address", pr_netaddr_get_ipstr(addr),
680 port, ipbind->ib_server->ServerName);
681 return ipbind->ib_server;
682 }
683 }
684 #endif /* PR_USE_IPV6 */
685
686 /* Check for any bindings that match the port. IF there is only one ONE
687 * vhost which matches the requested port, use that (Bug#4251).
688 */
689 ipbind = ipbind_find_port(port, TRUE, &match_count);
690 if (ipbind != NULL) {
691 pr_trace_msg(trace_channel, 18, "found %u possible %s for port %u",
692 match_count, match_count != 1 ? "ipbinds" : "ipbind", port);
693 if (match_count == 1) {
694 return ipbind->ib_server;
695 }
696 }
697
698 /* Use the default server, if set. */
699 if (ipbind_default_server &&
700 ipbind_default_server->ib_isactive) {
701 pr_log_debug(DEBUG7, "no matching vhost found for %s#%u, using "
702 "DefaultServer '%s'", pr_netaddr_get_ipstr(addr), port,
703 ipbind_default_server->ib_server->ServerName);
704 return ipbind_default_server->ib_server;
705 }
706
707 /* Not found in binding list, and no DefaultServer, so see if it's the
708 * loopback address
709 */
710 if (ipbind_localhost_server &&
711 pr_netaddr_is_loopback(addr)) {
712 return ipbind_localhost_server->ib_server;
713 }
714
715 return NULL;
716 }
717
pr_ipbind_listen(fd_set * readfds)718 int pr_ipbind_listen(fd_set *readfds) {
719 int listen_flags = PR_INET_LISTEN_FL_FATAL_ON_ERROR, maxfd = 0;
720 register unsigned int i = 0;
721
722 /* sanity check */
723 if (readfds == NULL) {
724 errno = EINVAL;
725 return -1;
726 }
727
728 FD_ZERO(readfds);
729
730 if (binding_pool == NULL) {
731 binding_pool = make_sub_pool(permanent_pool);
732 pr_pool_tag(binding_pool, "Bindings Pool");
733 }
734
735 /* Reset the listener list. */
736 if (listener_list == NULL) {
737 listener_list = make_array(binding_pool, 1, sizeof(conn_t *));
738
739 } else {
740 /* Nasty hack to "clear" the list by making it think it has no
741 * elements.
742 */
743 listener_list->nelts = 0;
744 }
745
746 /* Slower than the hash lookup, but...we have to check each and every
747 * ipbind in the table.
748 */
749 for (i = 0; i < PR_BINDINGS_TABLE_SIZE; i++) {
750 pr_ipbind_t *ipbind = NULL;
751
752 for (ipbind = ipbind_table[i]; ipbind; ipbind = ipbind->ib_next) {
753 /* Skip inactive bindings, but only if SocketBindTight is in effect. */
754 if (SocketBindTight &&
755 !ipbind->ib_isactive) {
756 continue;
757 }
758
759 if (ipbind->ib_listener != NULL) {
760 if (ipbind->ib_listener->mode == CM_NONE) {
761 pr_inet_listen(ipbind->ib_listener->pool, ipbind->ib_listener,
762 tcpBackLog, listen_flags);
763 }
764
765 if (ipbind->ib_listener->mode == CM_ACCEPT) {
766 if (pr_inet_resetlisten(ipbind->ib_listener->pool,
767 ipbind->ib_listener) < 0) {
768 pr_trace_msg(trace_channel, 3,
769 "error resetting %s#%u for listening: %s",
770 pr_netaddr_get_ipstr(ipbind->ib_addr), ipbind->ib_port,
771 strerror(errno));
772 }
773 }
774
775 if (ipbind->ib_listener->mode == CM_LISTEN) {
776 FD_SET(ipbind->ib_listener->listen_fd, readfds);
777 if (ipbind->ib_listener->listen_fd > maxfd)
778 maxfd = ipbind->ib_listener->listen_fd;
779
780 /* Add this to the listener list as well. */
781 *((conn_t **) push_array(listener_list)) = ipbind->ib_listener;
782 }
783 }
784 }
785 }
786
787 return maxfd;
788 }
789
pr_ipbind_open(const pr_netaddr_t * addr,unsigned int port,conn_t * listen_conn,unsigned char isdefault,unsigned char islocalhost,unsigned char open_namebinds)790 int pr_ipbind_open(const pr_netaddr_t *addr, unsigned int port,
791 conn_t *listen_conn, unsigned char isdefault, unsigned char islocalhost,
792 unsigned char open_namebinds) {
793 int res = 0;
794 pr_ipbind_t *ipbind = NULL;
795
796 if (addr == NULL) {
797 errno = EINVAL;
798 return -1;
799 }
800
801 /* Find the binding for this server/address */
802 ipbind = pr_ipbind_find(addr, port, FALSE);
803 if (ipbind == NULL) {
804 errno = ENOENT;
805 return -1;
806 }
807
808 if (listen_conn)
809 listen_conn->next = NULL;
810
811 ipbind->ib_listener = ipbind->ib_server->listen = listen_conn;
812 ipbind->ib_listener = listen_conn;
813 ipbind->ib_isdefault = isdefault;
814 ipbind->ib_islocalhost = islocalhost;
815
816 /* Stash a pointer to this ipbind, since it is designated as the
817 * default server (via the DefaultServer directive), for use in the
818 * lookup functions.
819 *
820 * Stash pointers to this ipbind for use in the lookup functions if:
821 *
822 * - It's the default server (specified via the DefaultServer directive)
823 * - It handles connections to the loopback interface
824 */
825 if (isdefault)
826 ipbind_default_server = ipbind;
827
828 if (islocalhost)
829 ipbind_localhost_server = ipbind;
830
831 /* If requested, look for any namebinds for this ipbind, and open them. */
832 if (open_namebinds &&
833 ipbind->ib_namebinds) {
834 register unsigned int i = 0;
835 pr_namebind_t **namebinds = NULL;
836
837 /* NOTE: in the future, these namebinds may need to be stored/
838 * manipulated in hash tables themselves, but, for now, linked lists
839 * should suffice.
840 */
841 namebinds = (pr_namebind_t **) ipbind->ib_namebinds->elts;
842 for (i = 0; i < ipbind->ib_namebinds->nelts; i++) {
843 pr_namebind_t *nb = namebinds[i];
844
845 res = pr_namebind_open(nb->nb_name, nb->nb_server->addr,
846 nb->nb_server_port);
847 if (res < 0) {
848 pr_trace_msg(trace_channel, 2,
849 "notice: unable to open namebind '%s': %s", nb->nb_name,
850 strerror(errno));
851 }
852 }
853 }
854
855 /* Mark this binding as now being active. */
856 ipbind->ib_isactive = TRUE;
857
858 return 0;
859 }
860
pr_namebind_close(const char * name,const pr_netaddr_t * addr)861 int pr_namebind_close(const char *name, const pr_netaddr_t *addr) {
862 pr_namebind_t *namebind = NULL;
863 unsigned int port;
864
865 if (name == NULL||
866 addr == NULL) {
867 errno = EINVAL;
868 return -1;
869 }
870
871 port = ntohs(pr_netaddr_get_port(addr));
872 namebind = pr_namebind_find(name, addr, port, FALSE);
873 if (namebind == NULL) {
874 errno = ENOENT;
875 return -1;
876 }
877
878 namebind->nb_isactive = FALSE;
879 return 0;
880 }
881
pr_namebind_create(server_rec * server,const char * name,pr_ipbind_t * ipbind,const pr_netaddr_t * addr,unsigned int server_port)882 int pr_namebind_create(server_rec *server, const char *name,
883 pr_ipbind_t *ipbind, const pr_netaddr_t *addr, unsigned int server_port) {
884 pr_namebind_t *namebind = NULL, **namebinds = NULL;
885 unsigned int port;
886
887 if (server == NULL ||
888 name == NULL) {
889 errno = EINVAL;
890 return -1;
891 }
892
893 /* First, find the ipbind to hold this namebind. */
894 port = ntohs(pr_netaddr_get_port(addr));
895 if (port == 0) {
896 port = server_port;
897 }
898
899 if (ipbind == NULL) {
900 pr_netaddr_t wildcard_addr;
901 int addr_family;
902
903 /* If not found, look for the wildcard address. */
904
905 addr_family = pr_netaddr_get_family(addr);
906 pr_netaddr_clear(&wildcard_addr);
907 pr_netaddr_set_family(&wildcard_addr, addr_family);
908 pr_netaddr_set_sockaddr_any(&wildcard_addr);
909
910 ipbind = pr_ipbind_find(&wildcard_addr, port, FALSE);
911 #ifdef PR_USE_IPV6
912 if (ipbind == FALSE &&
913 addr_family == AF_INET6 &&
914 pr_netaddr_use_ipv6()) {
915
916 /* No IPv6 wildcard address found; try the IPv4 wildcard address. */
917 pr_netaddr_clear(&wildcard_addr);
918 pr_netaddr_set_family(&wildcard_addr, AF_INET);
919 pr_netaddr_set_sockaddr_any(&wildcard_addr);
920
921 ipbind = pr_ipbind_find(&wildcard_addr, port, FALSE);
922 }
923 #endif /* PR_USE_IPV6 */
924
925 pr_trace_msg(trace_channel, 19,
926 "found wildcard ipbind %p for namebind (name '%s', addr %s, port %u)",
927 ipbind, name, pr_netaddr_get_ipstr(addr), port);
928 }
929
930 if (ipbind == NULL) {
931 errno = ENOENT;
932 return -1;
933 }
934
935 /* Make sure we can add this namebind. */
936 if (ipbind->ib_namebinds == NULL) {
937 ipbind->ib_namebinds = make_array(binding_pool, 0, sizeof(pr_namebind_t *));
938
939 } else {
940 register unsigned int i = 0;
941 namebinds = (pr_namebind_t **) ipbind->ib_namebinds->elts;
942
943 /* See if there is already a namebind for the given name. */
944 for (i = 0; i < ipbind->ib_namebinds->nelts; i++) {
945 namebind = namebinds[i];
946 if (namebind != NULL &&
947 namebind->nb_name != NULL) {
948
949 /* DNS names are case-insensitive, hence the case-insensitive check
950 * here.
951 *
952 * XXX Ideally, we should check whether any existing namebinds which
953 * are globs will match the newly added namebind as well.
954 */
955
956 if (strcasecmp(namebind->nb_name, name) == 0) {
957 errno = EEXIST;
958 return -1;
959 }
960 }
961 }
962 }
963
964 namebind = (pr_namebind_t *) pcalloc(server->pool, sizeof(pr_namebind_t));
965 namebind->nb_name = name;
966 namebind->nb_server = server;
967 namebind->nb_server_port = server_port;
968 namebind->nb_isactive = FALSE;
969
970 if (pr_str_is_fnmatch(name) == TRUE) {
971 namebind->nb_iswildcard = TRUE;
972 }
973
974 pr_trace_msg(trace_channel, 8,
975 "created namebind '%s' for %s#%u, server %p", name,
976 pr_netaddr_get_ipstr(server->addr), server->ServerPort, server);
977
978 /* The given server should already have the following populated:
979 *
980 * server->ServerName
981 * server->ServerAddress
982 * server->ServerFQDN
983 */
984
985 *((pr_namebind_t **) push_array(ipbind->ib_namebinds)) = namebind;
986 return 0;
987 }
988
pr_namebind_find(const char * name,const pr_netaddr_t * addr,unsigned int port,unsigned char skip_inactive)989 pr_namebind_t *pr_namebind_find(const char *name, const pr_netaddr_t *addr,
990 unsigned int port, unsigned char skip_inactive) {
991 pr_ipbind_t *ipbind = NULL;
992 pr_namebind_t *namebind = NULL;
993
994 if (name == NULL ||
995 addr == NULL) {
996 errno = EINVAL;
997 return NULL;
998 }
999
1000 /* First, find an active ipbind for the given address. */
1001 ipbind = pr_ipbind_find(addr, port, skip_inactive);
1002 if (ipbind == NULL) {
1003 pr_netaddr_t wildcard_addr;
1004 int addr_family;
1005
1006 /* If not found, look for the wildcard address. */
1007
1008 addr_family = pr_netaddr_get_family(addr);
1009 pr_netaddr_clear(&wildcard_addr);
1010 pr_netaddr_set_family(&wildcard_addr, addr_family);
1011 pr_netaddr_set_sockaddr_any(&wildcard_addr);
1012
1013 ipbind = pr_ipbind_find(&wildcard_addr, port, FALSE);
1014 #ifdef PR_USE_IPV6
1015 if (ipbind == FALSE &&
1016 addr_family == AF_INET6 &&
1017 pr_netaddr_use_ipv6()) {
1018
1019 /* No IPv6 wildcard address found; try the IPv4 wildcard address. */
1020 pr_netaddr_clear(&wildcard_addr);
1021 pr_netaddr_set_family(&wildcard_addr, AF_INET);
1022 pr_netaddr_set_sockaddr_any(&wildcard_addr);
1023
1024 ipbind = pr_ipbind_find(&wildcard_addr, port, FALSE);
1025 }
1026 #endif /* PR_USE_IPV6 */
1027 } else {
1028 pr_trace_msg(trace_channel, 17,
1029 "found ipbind %p (server %p) for %s#%u", ipbind, ipbind->ib_server,
1030 pr_netaddr_get_ipstr(addr), port);
1031 }
1032
1033 if (ipbind == NULL) {
1034 errno = ENOENT;
1035 return NULL;
1036 }
1037
1038 if (ipbind->ib_namebinds == NULL) {
1039 pr_trace_msg(trace_channel, 17,
1040 "ipbind %p (server %p) for %s#%u has no namebinds", ipbind,
1041 ipbind->ib_server, pr_netaddr_get_ipstr(addr), port);
1042 return NULL;
1043
1044 } else {
1045 register unsigned int i = 0;
1046 pr_namebind_t **namebinds = (pr_namebind_t **) ipbind->ib_namebinds->elts;
1047
1048 pr_trace_msg(trace_channel, 17,
1049 "ipbind %p (server %p) for %s#%u has namebinds (%d)", ipbind,
1050 ipbind->ib_server, pr_netaddr_get_ipstr(addr), port,
1051 ipbind->ib_namebinds->nelts);
1052
1053 for (i = 0; i < ipbind->ib_namebinds->nelts; i++) {
1054 namebind = namebinds[i];
1055 if (namebind == NULL) {
1056 continue;
1057 }
1058
1059 /* Skip inactive namebinds */
1060 if (skip_inactive == TRUE &&
1061 namebind->nb_isactive == FALSE) {
1062 pr_trace_msg(trace_channel, 17,
1063 "namebind #%u: %s is inactive, skipping", i, namebind->nb_name);
1064 continue;
1065 }
1066
1067 /* At present, this looks for an exactly matching name. In the future,
1068 * we may want to have something like Apache's matching scheme, which
1069 * looks for the most specific domain to the most general. Note that
1070 * that scheme, however, is specific to DNS; should any other naming
1071 * scheme be desired, that sort of matching will be unnecessary.
1072 */
1073 if (namebind->nb_name != NULL) {
1074 pr_trace_msg(trace_channel, 17,
1075 "namebind #%u: %s (%s)", i, namebind->nb_name,
1076 namebind->nb_isactive ? "active" : "inactive");
1077
1078 if (namebind->nb_iswildcard == FALSE) {
1079 if (strcasecmp(namebind->nb_name, name) == 0) {
1080 return namebind;
1081 }
1082
1083 } else {
1084 int match_flags = PR_FNM_NOESCAPE|PR_FNM_CASEFOLD;
1085
1086 if (pr_fnmatch(namebind->nb_name, name, match_flags) == 0) {
1087 pr_trace_msg(trace_channel, 9,
1088 "matched name '%s' against pattern '%s'", name,
1089 namebind->nb_name);
1090 return namebind;
1091 }
1092
1093 pr_trace_msg(trace_channel, 9,
1094 "failed to match name '%s' against pattern '%s'", name,
1095 namebind->nb_name);
1096 }
1097 }
1098 }
1099 }
1100
1101 return NULL;
1102 }
1103
pr_namebind_get_server(const char * name,const pr_netaddr_t * addr,unsigned int port)1104 server_rec *pr_namebind_get_server(const char *name, const pr_netaddr_t *addr,
1105 unsigned int port) {
1106 pr_namebind_t *namebind = NULL;
1107
1108 /* Basically, just a wrapper around pr_namebind_find() */
1109
1110 namebind = pr_namebind_find(name, addr, port, TRUE);
1111 if (namebind == NULL) {
1112 return NULL;
1113 }
1114
1115 return namebind->nb_server;
1116 }
1117
pr_namebind_count(server_rec * srv)1118 unsigned int pr_namebind_count(server_rec *srv) {
1119 unsigned int count = 0;
1120 pr_ipbind_t *ipbind = NULL;
1121
1122 if (srv == NULL) {
1123 return 0;
1124 }
1125
1126 ipbind = pr_ipbind_find(srv->addr, srv->ServerPort, FALSE);
1127 if (ipbind != NULL &&
1128 ipbind->ib_namebinds != NULL) {
1129 count = ipbind->ib_namebinds->nelts;
1130 }
1131
1132 return count;
1133 }
1134
pr_namebind_open(const char * name,const pr_netaddr_t * addr,unsigned int server_port)1135 int pr_namebind_open(const char *name, const pr_netaddr_t *addr,
1136 unsigned int server_port) {
1137 pr_namebind_t *namebind = NULL;
1138 unsigned int port;
1139
1140 if (name == NULL ||
1141 addr == NULL) {
1142 errno = EINVAL;
1143 return -1;
1144 }
1145
1146 port = ntohs(pr_netaddr_get_port(addr));
1147 if (port == 0) {
1148 port = server_port;
1149 }
1150
1151 namebind = pr_namebind_find(name, addr, port, FALSE);
1152 if (namebind == NULL) {
1153 errno = ENOENT;
1154 return -1;
1155 }
1156
1157 namebind->nb_isactive = TRUE;
1158 return 0;
1159 }
1160
free_bindings(void)1161 void free_bindings(void) {
1162 if (binding_pool) {
1163 destroy_pool(binding_pool);
1164 binding_pool = NULL;
1165 listener_list = NULL;
1166 }
1167
1168 memset(ipbind_table, 0, sizeof(ipbind_table));
1169 ipbind_table_initialized = FALSE;
1170
1171 /* Mark all listening conns as "unclaimed"; any that remaining unclaimed
1172 * after init_bindings() can be closed.
1173 */
1174 if (listening_conn_list) {
1175 struct listener_rec *lr;
1176
1177 for (lr = (struct listener_rec *) listening_conn_list->xas_list; lr; lr = lr->next) {
1178 lr->claimed = FALSE;
1179 }
1180 }
1181 }
1182
init_inetd_bindings(void)1183 static int init_inetd_bindings(void) {
1184 int res = 0;
1185 server_rec *serv = NULL;
1186 unsigned char *default_server = NULL, is_default = FALSE;
1187
1188 /* We explicitly do NOT use the get_listening_conn() function here, since
1189 * inetd-run daemons will not a) handle restarts, and thus b) will not have
1190 * already-open connections to choose from.
1191 */
1192
1193 main_server->listen = pr_inet_create_conn(main_server->pool, STDIN_FILENO,
1194 NULL, INPORT_ANY, FALSE);
1195 if (main_server->listen == NULL) {
1196 return -1;
1197 }
1198
1199 /* Note: Since we are being called via inetd/xinetd, any socket options
1200 * which may be attempted by listeners for this event may not work.
1201 */
1202 pr_inet_generate_socket_event("core.ctrl-listen", main_server,
1203 main_server->addr, main_server->listen->listen_fd);
1204
1205 /* Fill in all the important connection information. */
1206 if (pr_inet_get_conn_info(main_server->listen, STDIN_FILENO) == -1) {
1207 int xerrno = errno;
1208
1209 pr_log_pri(PR_LOG_WARNING, "fatal: unable to get connection info: %s",
1210 strerror(xerrno));
1211
1212 if (xerrno == ENOTSOCK) {
1213 pr_log_pri(PR_LOG_ERR, "(Running from command line? "
1214 "Use `ServerType standalone' in config file!)");
1215 }
1216
1217 exit(1);
1218 }
1219
1220 default_server = get_param_ptr(main_server->conf, "DefaultServer", FALSE);
1221 if (default_server != NULL &&
1222 *default_server == TRUE) {
1223 is_default = TRUE;
1224 }
1225
1226 PR_CREATE_IPBIND(main_server, main_server->addr, main_server->ServerPort);
1227 PR_OPEN_IPBIND(main_server->addr, main_server->ServerPort,
1228 main_server->listen, is_default, TRUE, TRUE);
1229 PR_ADD_IPBINDS(main_server);
1230
1231 /* Now attach the faked connection to all virtual servers. */
1232 for (serv = main_server->next; serv; serv = serv->next) {
1233
1234 /* Because this server is sharing the connection with the
1235 * main server, we need a cleanup handler to remove
1236 * the server's reference when the original connection's
1237 * pool is destroyed.
1238 */
1239
1240 serv->listen = main_server->listen;
1241 register_cleanup2(serv->listen->pool, &serv->listen, server_cleanup_cb);
1242
1243 is_default = FALSE;
1244 default_server = get_param_ptr(serv->conf, "DefaultServer", FALSE);
1245 if (default_server != NULL &&
1246 *default_server == TRUE) {
1247 is_default = TRUE;
1248 }
1249
1250 PR_CREATE_IPBIND(serv, serv->addr, serv->ServerPort);
1251 PR_OPEN_IPBIND(serv->addr, serv->ServerPort, serv->listen, is_default,
1252 FALSE, TRUE);
1253 PR_ADD_IPBINDS(serv);
1254 }
1255
1256 return 0;
1257 }
1258
find_server_ipbinds(pool * p,server_rec * s)1259 static array_header *find_server_ipbinds(pool *p, server_rec *s) {
1260 register unsigned int i;
1261 array_header *ipbinds = NULL;
1262
1263 for (i = 0; i < PR_BINDINGS_TABLE_SIZE; i++) {
1264 pr_ipbind_t *ipbind;
1265
1266 for (ipbind = ipbind_table[i]; ipbind != NULL; ipbind = ipbind->ib_next) {
1267 if (ipbind->ib_server == s) {
1268 if (ipbinds == NULL) {
1269 ipbinds = make_array(p, 16, sizeof(pr_ipbind_t *));
1270 }
1271
1272 *((pr_ipbind_t **) push_array(ipbinds)) = ipbind;
1273 }
1274 }
1275 }
1276
1277 return ipbinds;
1278 }
1279
process_serveralias(server_rec * s)1280 static unsigned int process_serveralias(server_rec *s) {
1281 unsigned namebind_count = 0;
1282 config_rec *c;
1283 array_header *ipbinds;
1284 pool *tmp_pool;
1285
1286 /* If there is no ipbind already for this server, we cannot associate
1287 * any ServerAlias-based namebinds to it.
1288 *
1289 * Keep in mind that there may be multiple ipbinds pointed at this server:
1290 *
1291 * <VirtualHost 1.2.3.4 5.6.7.8>
1292 * ServerAlias alias
1293 * </VirtualHost>
1294 */
1295
1296 tmp_pool = make_sub_pool(s->pool);
1297 pr_pool_tag(tmp_pool, "ServerAlias Processing Pool");
1298
1299 ipbinds = find_server_ipbinds(tmp_pool, s);
1300 if (ipbinds == NULL) {
1301 destroy_pool(tmp_pool);
1302 return 0;
1303 }
1304
1305 c = find_config(s->conf, CONF_PARAM, "ServerAlias", FALSE);
1306 while (c != NULL) {
1307 register unsigned int i;
1308 int res;
1309 pr_ipbind_t **elts;
1310
1311 pr_signals_handle();
1312
1313 elts = ipbinds->elts;
1314 for (i = 0; i < ipbinds->nelts; i++) {
1315 pr_ipbind_t *ipbind;
1316
1317 ipbind = elts[i];
1318 res = pr_namebind_create(s, c->argv[0], ipbind, s->addr, s->ServerPort);
1319 if (res == 0) {
1320 namebind_count++;
1321
1322 res = pr_namebind_open(c->argv[0], ipbind->ib_addr, ipbind->ib_port);
1323 if (res < 0) {
1324 pr_trace_msg(trace_channel, 2,
1325 "notice: unable to open namebind '%s': %s", (char *) c->argv[0],
1326 strerror(errno));
1327 }
1328
1329 } else {
1330 if (errno != ENOENT) {
1331 pr_trace_msg(trace_channel, 3,
1332 "unable to create namebind for '%s' to %s#%u: %s",
1333 (char *) c->argv[0], pr_netaddr_get_ipstr(ipbind->ib_addr),
1334 ipbind->ib_port, strerror(errno));
1335 }
1336 }
1337 }
1338
1339 c = find_config_next(c, c->next, CONF_PARAM, "ServerAlias", FALSE);
1340 }
1341
1342 destroy_pool(tmp_pool);
1343 return namebind_count;
1344 }
1345
trace_ipbind_table(void)1346 static void trace_ipbind_table(void) {
1347 register unsigned int i;
1348
1349 if (pr_trace_get_level(trace_channel) < 25) {
1350 return;
1351 }
1352
1353 pr_trace_msg(trace_channel, 25, "displaying ipbind table:");
1354 for (i = 0; i < PR_BINDINGS_TABLE_SIZE; i++) {
1355 register unsigned int j;
1356 pr_ipbind_t *ipbind;
1357
1358 if (ipbind_table[i] == NULL) {
1359 continue;
1360 }
1361
1362 pr_signals_handle();
1363
1364 pr_trace_msg(trace_channel, 25, " index %u:", i);
1365 for (j = 0, ipbind = ipbind_table[i]; ipbind; j++, ipbind = ipbind->ib_next) {
1366 array_header *namebinds;
1367
1368 namebinds = ipbind->ib_namebinds;
1369
1370 pr_trace_msg(trace_channel, 25, " ipbind %p:", ipbind);
1371 pr_trace_msg(trace_channel, 25, " address: %s#%u",
1372 pr_netaddr_get_ipstr(ipbind->ib_addr), ipbind->ib_port);
1373 pr_trace_msg(trace_channel, 25, " server: %p", ipbind->ib_server);
1374
1375 if (namebinds != NULL) {
1376 register unsigned int k;
1377 pr_namebind_t **elts;
1378
1379 pr_trace_msg(trace_channel, 25, " namebinds:");
1380 elts = namebinds->elts;
1381 for (k = 0; k < namebinds->nelts; k++) {
1382 pr_namebind_t *namebind;
1383
1384 namebind = elts[k];
1385 pr_trace_msg(trace_channel, 25, " #%u: %p", k+1, namebind);
1386 pr_trace_msg(trace_channel, 25, " name: %s",
1387 namebind->nb_name);
1388 pr_trace_msg(trace_channel, 25, " server: %p",
1389 namebind->nb_server);
1390 }
1391 }
1392 }
1393 }
1394 }
1395
init_standalone_bindings(void)1396 static int init_standalone_bindings(void) {
1397 int res = 0;
1398 server_rec *serv = NULL;
1399 unsigned char *default_server = NULL, is_default = FALSE;
1400
1401 /* Ensure the ipbind table has been initialized. */
1402 init_ipbind_table();
1403
1404 /* If a port is set to zero, the address/port is not bound to a socket
1405 * at all.
1406 */
1407 if (main_server->ServerPort) {
1408 /* If SocketBindTight is off, then pr_inet_create_conn() will
1409 * create and bind to a wildcard socket. However, should it be an
1410 * IPv4 or an IPv6 wildcard socket?
1411 */
1412 if (!SocketBindTight) {
1413 #ifdef PR_USE_IPV6
1414 if (pr_netaddr_use_ipv6()) {
1415 pr_inet_set_default_family(NULL, AF_INET6);
1416
1417 } else {
1418 int default_family;
1419
1420 default_family = pr_netaddr_get_family(main_server->addr);
1421 pr_inet_set_default_family(NULL, default_family);
1422 }
1423 #else
1424 pr_inet_set_default_family(NULL,
1425 pr_netaddr_get_family(main_server->addr));
1426 #endif /* PR_USE_IPV6 */
1427 }
1428
1429 main_server->listen = pr_ipbind_get_listening_conn(main_server,
1430 (SocketBindTight ? main_server->addr : NULL), main_server->ServerPort);
1431 if (main_server->listen == NULL) {
1432 return -1;
1433 }
1434
1435 } else {
1436 main_server->listen = NULL;
1437 }
1438
1439 default_server = get_param_ptr(main_server->conf, "DefaultServer", FALSE);
1440 if (default_server != NULL &&
1441 *default_server == TRUE) {
1442 is_default = TRUE;
1443 }
1444
1445 if (main_server->ServerPort ||
1446 is_default) {
1447 PR_CREATE_IPBIND(main_server, main_server->addr, main_server->ServerPort);
1448 PR_OPEN_IPBIND(main_server->addr, main_server->ServerPort,
1449 main_server->listen, is_default, TRUE, TRUE);
1450 PR_ADD_IPBINDS(main_server);
1451 }
1452
1453 for (serv = main_server->next; serv; serv = serv->next) {
1454 unsigned int namebind_count;
1455
1456 namebind_count = process_serveralias(serv);
1457 if (namebind_count > 0) {
1458 /* If we successfully added ServerAlias namebinds, move on to the next
1459 * server.
1460 */
1461 continue;
1462 }
1463
1464 if (serv->ServerPort != main_server->ServerPort ||
1465 SocketBindTight ||
1466 !main_server->listen) {
1467 is_default = FALSE;
1468
1469 default_server = get_param_ptr(serv->conf, "DefaultServer", FALSE);
1470 if (default_server != NULL &&
1471 *default_server == TRUE) {
1472 is_default = TRUE;
1473 }
1474
1475 if (serv->ServerPort) {
1476 if (!SocketBindTight) {
1477 #ifdef PR_USE_IPV6
1478 if (pr_netaddr_use_ipv6()) {
1479 pr_inet_set_default_family(NULL, AF_INET6);
1480
1481 } else {
1482 pr_inet_set_default_family(NULL, pr_netaddr_get_family(serv->addr));
1483 }
1484 #else
1485 pr_inet_set_default_family(NULL, pr_netaddr_get_family(serv->addr));
1486 #endif /* PR_USE_IPV6 */
1487 }
1488
1489 serv->listen = pr_ipbind_get_listening_conn(serv,
1490 (SocketBindTight ? serv->addr : NULL), serv->ServerPort);
1491 if (serv->listen == NULL) {
1492 return -1;
1493 }
1494
1495 PR_CREATE_IPBIND(serv, serv->addr, serv->ServerPort);
1496 PR_OPEN_IPBIND(serv->addr, serv->ServerPort, serv->listen, is_default,
1497 FALSE, TRUE);
1498 PR_ADD_IPBINDS(serv);
1499
1500 } else if (is_default) {
1501 serv->listen = NULL;
1502
1503 PR_CREATE_IPBIND(serv, serv->addr, serv->ServerPort);
1504 PR_OPEN_IPBIND(serv->addr, serv->ServerPort, serv->listen, is_default,
1505 FALSE, TRUE);
1506 PR_ADD_IPBINDS(serv);
1507
1508 } else {
1509 serv->listen = NULL;
1510 }
1511
1512 } else {
1513 /* Because this server is sharing the connection with the main server,
1514 * we need a cleanup handler to remove the server's reference when the
1515 * original connection's pool is destroyed.
1516 */
1517
1518 is_default = FALSE;
1519 default_server = get_param_ptr(serv->conf, "DefaultServer", FALSE);
1520 if (default_server != NULL &&
1521 *default_server == TRUE) {
1522 is_default = TRUE;
1523 }
1524
1525 serv->listen = main_server->listen;
1526 register_cleanup2(serv->listen->pool, &serv->listen, server_cleanup_cb);
1527
1528 PR_CREATE_IPBIND(serv, serv->addr, serv->ServerPort);
1529 PR_OPEN_IPBIND(serv->addr, serv->ServerPort, NULL, is_default, FALSE,
1530 TRUE);
1531 PR_ADD_IPBINDS(serv);
1532 }
1533
1534 /* Process any ServerAlias directives AFTER the server's ipbind has been
1535 * created/opened (Issue #932).
1536 */
1537 process_serveralias(serv);
1538 }
1539
1540 trace_ipbind_table();
1541
1542 /* Any "unclaimed" listening conns can be removed and closed. */
1543 if (listening_conn_list) {
1544 struct listener_rec *lr, *lrn;
1545
1546 for (lr = (struct listener_rec *) listening_conn_list->xas_list; lr; lr = lrn) {
1547 lrn = lr->next;
1548
1549 if (!lr->claimed) {
1550 xaset_remove(listening_conn_list, (xasetmember_t *) lr);
1551 destroy_pool(lr->pool);
1552 }
1553 }
1554 }
1555
1556 return 0;
1557 }
1558
init_bindings(void)1559 void init_bindings(void) {
1560 int res = 0;
1561
1562 #ifdef PR_USE_IPV6
1563 int sock;
1564
1565 /* Check to see whether we can actually create an IPv6 socket. */
1566 sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
1567 if (sock < 0) {
1568 pr_netaddr_disable_ipv6();
1569
1570 } else {
1571 (void) close(sock);
1572 }
1573 #endif /* PR_USE_IPV6 */
1574
1575 if (ServerType == SERVER_INETD) {
1576 res = init_inetd_bindings();
1577
1578 } else if (ServerType == SERVER_STANDALONE) {
1579 res = init_standalone_bindings();
1580 }
1581
1582 if (res < 0) {
1583 pr_log_pri(PR_LOG_ERR, "%s",
1584 "Unable to start proftpd; check logs for more details");
1585 exit(1);
1586 }
1587 }
1588
1589