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